diff --git a/ethcore/src/account_diff.rs b/ethcore/src/account_diff.rs index 6c7e6573e..c02b7ec7b 100644 --- a/ethcore/src/account_diff.rs +++ b/ethcore/src/account_diff.rs @@ -72,14 +72,14 @@ impl AccountDiff { pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option { match (pre, post) { (None, Some(x)) => Some(AccountDiff { - balance: Diff::Born(x.balance.clone()), - nonce: Diff::Born(x.nonce.clone()), + balance: Diff::Born(x.balance), + nonce: Diff::Born(x.nonce), code: Diff::Born(x.code.clone()), storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Born(v.clone()))).collect(), }), (Some(x), None) => Some(AccountDiff { - balance: Diff::Died(x.balance.clone()), - nonce: Diff::Died(x.nonce.clone()), + balance: Diff::Died(x.balance), + nonce: Diff::Died(x.nonce), code: Diff::Died(x.code.clone()), storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Died(v.clone()))).collect(), }), @@ -88,8 +88,8 @@ impl AccountDiff { .filter(|k| pre.storage.get(k).unwrap_or(&H256::new()) != post.storage.get(k).unwrap_or(&H256::new())) .collect(); let r = AccountDiff { - balance: Diff::new(pre.balance.clone(), post.balance.clone()), - nonce: Diff::new(pre.nonce.clone(), post.nonce.clone()), + balance: Diff::new(pre.balance, post.balance), + nonce: Diff::new(pre.nonce, post.nonce), code: Diff::new(pre.code.clone(), post.code.clone()), storage: storage.into_iter().map(|k| (k.clone(), Diff::new( diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 43e3720d2..8fa695aca 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -242,19 +242,236 @@ impl Header { } } -#[test] -fn on_close_block() { - use super::*; - let engine = new_morden().to_engine().unwrap(); - let genesis_header = engine.spec().genesis_header(); - let mut db_result = get_temp_journal_db(); - let mut db = db_result.take(); - engine.spec().ensure_db_good(&mut db); - 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()); -} +#[cfg(test)] +mod tests { + extern crate ethash; + + use common::*; + use block::*; + use engine::*; + use tests::helpers::*; + use super::{Ethash}; + use super::super::new_morden; + + #[test] + fn on_close_block() { + let engine = new_morden().to_engine().unwrap(); + let genesis_header = engine.spec().genesis_header(); + let mut db_result = get_temp_journal_db(); + let mut db = db_result.take(); + engine.spec().ensure_db_good(&mut db); + 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()); + } + + #[test] + fn on_close_block_with_uncle() { + let engine = new_morden().to_engine().unwrap(); + let genesis_header = engine.spec().genesis_header(); + let mut db_result = get_temp_journal_db(); + let mut db = db_result.take(); + engine.spec().ensure_db_good(&mut db); + let last_hashes = vec![genesis_header.hash()]; + let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]); + let mut uncle = Header::new(); + let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); + uncle.author = uncle_author.clone(); + b.push_uncle(uncle).unwrap(); + + let b = b.close(); + assert_eq!(b.state().balance(&Address::zero()), U256::from_str("478eae0e571ba000").unwrap()); + assert_eq!(b.state().balance(&uncle_author), U256::from_str("3cb71f51fc558000").unwrap()); + } + + #[test] + fn has_valid_metadata() { + let engine = Ethash::new_boxed(new_morden()); + assert!(!engine.name().is_empty()); + assert!(engine.version().major >= 1); + } + + #[test] + fn can_return_params() { + let engine = Ethash::new_test(new_morden()); + assert!(engine.u64_param("durationLimit") > 0); + assert!(engine.u256_param("minimumDifficulty") > U256::zero()); + } + + #[test] + fn can_return_factory() { + let engine = Ethash::new_test(new_morden()); + engine.vm_factory(); + } + + #[test] + fn can_return_schedule() { + let engine = Ethash::new_test(new_morden()); + let schedule = engine.schedule(&EnvInfo { + number: 10000000, + author: x!(0), + timestamp: 0, + difficulty: x!(0), + last_hashes: vec![], + gas_used: x!(0), + gas_limit: x!(0) + }); + + assert!(schedule.stack_limit > 0); + + let schedule = engine.schedule(&EnvInfo { + number: 100, + author: x!(0), + timestamp: 0, + difficulty: x!(0), + last_hashes: vec![], + gas_used: x!(0), + gas_limit: x!(0) + }); + + assert!(!schedule.have_delegate_call); + } + + #[test] + fn can_do_seal_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let header: Header = Header::default(); + + let verify_result = engine.verify_block_basic(&header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidSealArity(_))) => {}, + Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_do_difficulty_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); + + let verify_result = engine.verify_block_basic(&header, None); + + match verify_result { + Err(Error::Block(BlockError::DifficultyOutOfBounds(_))) => {}, + Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_do_proof_of_work_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); + header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); + + let verify_result = engine.verify_block_basic(&header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {}, + Err(_) => { panic!("should be invalid proof of work error (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_do_seal_unordered_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let header: Header = Header::default(); + + let verify_result = engine.verify_block_unordered(&header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidSealArity(_))) => {}, + Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_do_seal256_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); + let verify_result = engine.verify_block_unordered(&header, None); + + match verify_result { + Err(Error::Block(BlockError::MismatchedH256SealElement(_))) => {}, + Err(_) => { panic!("should be invalid 256-bit seal fail (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_do_proof_of_work_unordered_verification_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_seal(vec![rlp::encode(&H256::from("b251bd2e0283d0658f2cadfdc8ca619b5de94eca5742725e2e757dd13ed7503d")).to_vec(), rlp::encode(&H64::zero()).to_vec()]); + header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); + + let verify_result = engine.verify_block_unordered(&header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {}, + Err(_) => { panic!("should be invalid proof-of-work fail (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_verify_block_family_genesis_fail() { + let engine = Ethash::new_test(new_morden()); + let header: Header = Header::default(); + let parent_header: Header = Header::default(); + + let verify_result = engine.verify_block_family(&header, &parent_header, None); + + match verify_result { + Err(Error::Block(BlockError::RidiculousNumber(_))) => {}, + Err(_) => { panic!("should be invalid block number fail (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_verify_block_family_difficulty_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_number(2); + let mut parent_header: Header = Header::default(); + parent_header.set_number(1); + + let verify_result = engine.verify_block_family(&header, &parent_header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidDifficulty(_))) => {}, + Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } + + #[test] + fn can_verify_block_family_gas_fail() { + let engine = Ethash::new_test(new_morden()); + let mut header: Header = Header::default(); + header.set_number(2); + header.set_difficulty(U256::from_str("0000000000000000000000000000000000000000000000000000000000020000").unwrap()); + let mut parent_header: Header = Header::default(); + parent_header.set_number(1); + + let verify_result = engine.verify_block_family(&header, &parent_header, None); + + match verify_result { + Err(Error::Block(BlockError::InvalidGasLimit(_))) => {}, + Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); }, + _ => { panic!("Should be error, got Ok"); }, + } + } +>>>>>>> f1b39ee... nightly fixes #[test] fn on_close_block_with_uncle() { diff --git a/ethcore/src/evm/interpreter.rs b/ethcore/src/evm/interpreter.rs index 8b8197526..92d5434d0 100644 --- a/ethcore/src/evm/interpreter.rs +++ b/ethcore/src/evm/interpreter.rs @@ -391,10 +391,7 @@ impl Interpreter { instructions::SLOAD => { InstructionCost::Gas(U256::from(schedule.sload_gas)) }, - instructions::MSTORE => { - InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32))) - }, - instructions::MLOAD => { + instructions::MSTORE | instructions::MLOAD => { InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32))) }, instructions::MSTORE8 => { @@ -736,8 +733,7 @@ impl Interpreter { }, instructions::CALLVALUE => { stack.push(match params.value { - ActionValue::Transfer(val) => val, - ActionValue::Apparent(val) => val, + ActionValue::Transfer(val) | ActionValue::Apparent(val) => val }); }, instructions::CALLDATALOAD => { diff --git a/ethcore/src/evm/tests.rs b/ethcore/src/evm/tests.rs index d0daf33e7..3eadef15a 100644 --- a/ethcore/src/evm/tests.rs +++ b/ethcore/src/evm/tests.rs @@ -84,7 +84,7 @@ impl Ext for FakeExt { } fn balance(&self, address: &Address) -> U256 { - self.balances.get(address).unwrap().clone() + *self.balances.get(address).unwrap() } fn blockhash(&self, number: &U256) -> H256 { @@ -94,10 +94,10 @@ impl Ext for FakeExt { fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { self.calls.insert(FakeCall { call_type: FakeCallType::CREATE, - gas: gas.clone(), + gas: *gas, sender_address: None, receive_address: None, - value: Some(value.clone()), + value: Some(*value), data: code.to_vec(), code_address: None }); @@ -115,14 +115,14 @@ impl Ext for FakeExt { self.calls.insert(FakeCall { call_type: FakeCallType::CALL, - gas: gas.clone(), + gas: *gas, sender_address: Some(sender_address.clone()), receive_address: Some(receive_address.clone()), value: value, data: data.to_vec(), code_address: Some(code_address.clone()) }); - MessageCallResult::Success(gas.clone()) + MessageCallResult::Success(*gas) } fn extcode(&self, address: &Address) -> Bytes { @@ -898,7 +898,7 @@ fn test_calls(factory: super::Factory) { let mut ext = FakeExt::new(); ext.balances = { let mut s = HashMap::new(); - s.insert(params.address.clone(), params.gas.clone()); + s.insert(params.address.clone(), params.gas); s }; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index ad2f18f11..11515b80e 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -45,10 +45,9 @@ impl OriginInfo { OriginInfo { address: params.address.clone(), origin: params.origin.clone(), - gas_price: params.gas_price.clone(), + gas_price: params.gas_price, value: match params.value { - ActionValue::Transfer(val) => val, - ActionValue::Apparent(val) => val, + ActionValue::Transfer(val) | ActionValue::Apparent(val) => val } } } @@ -131,8 +130,8 @@ impl<'a> Ext for Externalities<'a> { sender: self.origin_info.address.clone(), origin: self.origin_info.origin.clone(), gas: *gas, - gas_price: self.origin_info.gas_price.clone(), - value: ActionValue::Transfer(value.clone()), + gas_price: self.origin_info.gas_price, + value: ActionValue::Transfer(*value), code: Some(code.to_vec()), data: None, }; @@ -161,12 +160,12 @@ impl<'a> Ext for Externalities<'a> { let mut params = ActionParams { sender: sender_address.clone(), - address: receive_address.clone(), - value: ActionValue::Apparent(self.origin_info.value.clone()), + address: receive_address.clone(), + value: ActionValue::Apparent(self.origin_info.value), code_address: code_address.clone(), origin: self.origin_info.origin.clone(), gas: *gas, - gas_price: self.origin_info.gas_price.clone(), + gas_price: self.origin_info.gas_price, code: self.state.code(code_address), data: Some(data.to_vec()), }; diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 762f47db4..d2690051c 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -43,8 +43,8 @@ impl PodAccount { /// NOTE: This will silently fail unless the account is fully cached. pub fn from_account(acc: &Account) -> PodAccount { PodAccount { - balance: acc.balance().clone(), - nonce: acc.nonce().clone(), + balance: *acc.balance(), + nonce: *acc.nonce(), storage: acc.storage_overlay().iter().fold(BTreeMap::new(), |mut m, (k, &(_, ref v))| {m.insert(k.clone(), v.clone()); m}), code: acc.code().unwrap().to_vec(), } diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index e30f703ae..00886b89c 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -153,12 +153,12 @@ impl State { /// Get the balance of account `a`. pub fn balance(&self, a: &Address) -> U256 { - self.get(a, false).as_ref().map_or(U256::zero(), |account| account.balance().clone()) + self.get(a, false).as_ref().map_or(U256::zero(), |account| *account.balance()) } /// Get the nonce of account `a`. pub fn nonce(&self, a: &Address) -> U256 { - self.get(a, false).as_ref().map_or(U256::zero(), |account| account.nonce().clone()) + self.get(a, false).as_ref().map_or(U256::zero(), |account| *account.nonce()) } /// Mutate storage of account `address` so that it is `value` for `key`. diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 2610fe244..6b819189d 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -11,8 +11,8 @@ authors = ["Ethcore for CryptoError { match e { ::secp256k1::Error::InvalidMessage => CryptoError::InvalidMessage, ::secp256k1::Error::InvalidPublicKey => CryptoError::InvalidPublic, - ::secp256k1::Error::InvalidSignature => CryptoError::InvalidSignature, ::secp256k1::Error::InvalidSecretKey => CryptoError::InvalidSecret, _ => CryptoError::InvalidSignature, } diff --git a/util/src/hash.rs b/util/src/hash.rs index 75c39720e..2e6c565b4 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -296,7 +296,7 @@ macro_rules! impl_hash { try!(write!(f, "{:02x}", i)); } try!(write!(f, "…")); - for i in &self.0[$size - 4..$size] { + for i in &self.0[$size - 2..$size] { try!(write!(f, "{:02x}", i)); } Ok(()) @@ -647,7 +647,7 @@ mod tests { fn hash() { let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h); - assert_eq!(format!("{}", h), "0123…89abcdef"); + assert_eq!(format!("{}", h), "0123…cdef"); assert_eq!(format!("{:?}", h), "0123456789abcdef"); assert_eq!(h.hex(), "0123456789abcdef"); assert!(h == h); diff --git a/util/src/network/discovery.rs b/util/src/network/discovery.rs index 32370b88d..3e914761d 100644 --- a/util/src/network/discovery.rs +++ b/util/src/network/discovery.rs @@ -211,7 +211,7 @@ impl Discovery { } let mut ret:Vec<&NodeId> = Vec::new(); - for (_, nodes) in found { + for nodes in found.values() { for n in nodes { if ret.len() < BUCKET_SIZE as usize /* && n->endpoint && n->endpoint.isAllowed() */ { ret.push(n); diff --git a/util/src/network/session.rs b/util/src/network/session.rs index 8e9a3a9ff..8f8e46a40 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -324,7 +324,7 @@ impl Session { let mut rlp = RlpStream::new(); rlp.append(&(PACKET_DISCONNECT as u32)); rlp.begin_list(1); - rlp.append(&(reason.clone() as u32)); + rlp.append(&(reason as u32)); self.connection.send_packet(&rlp.out()).ok(); NetworkError::Disconnect(reason) } diff --git a/util/src/rlp/untrusted_rlp.rs b/util/src/rlp/untrusted_rlp.rs index 7126e868d..463d5cb2f 100644 --- a/util/src/rlp/untrusted_rlp.rs +++ b/util/src/rlp/untrusted_rlp.rs @@ -408,7 +408,7 @@ impl Decodable for Vec { fn decode(decoder: &D) -> Result where D: Decoder { decoder.read_value(| bytes | { let mut res = vec![]; - res.extend(bytes); + res.extend_from_slice(bytes); Ok(res) }) } diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index b6cc81137..e7884a177 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -293,7 +293,7 @@ impl<'a> Iterator for TrieDBIterator<'a> { fn next(&mut self) -> Option { let b = match self.trail.last_mut() { - Some(ref mut b) => { b.increment(); b.clone() }, + Some(mut b) => { b.increment(); b.clone() }, None => return None }; match (b.status, b.node) { @@ -309,9 +309,8 @@ impl<'a> Iterator for TrieDBIterator<'a> { self.trail.pop(); self.next() }, - (Status::At, Node::Leaf(_, v)) => Some((self.key(), v)), + (Status::At, Node::Leaf(_, v)) | (Status::At, Node::Branch(_, Some(v))) => Some((self.key(), v)), (Status::At, Node::Extension(_, d)) => self.descend_next(d), - (Status::At, Node::Branch(_, Some(v))) => Some((self.key(), v)), (Status::At, Node::Branch(_, _)) => self.next(), (Status::AtChild(i), Node::Branch(children, _)) if children[i].len() > 0 => { match i {