From 0de73609d2c0fa94067712ef229e72d4dd2541ee Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 14 Mar 2016 14:18:29 +0100 Subject: [PATCH 1/5] eth_hashrate && eth_submitHashrate tests --- ethcore/src/client/test_client.rs | 8 +-- rpc/src/v1/helpers/external_miner.rs | 59 ++++++++++++++++++ rpc/src/v1/helpers/mod.rs | 2 + rpc/src/v1/impls/eth.rs | 48 ++++++++++----- rpc/src/v1/tests/eth.rs | 72 +++++++++++++++++----- rpc/src/v1/tests/helpers/external_miner.rs | 48 +++++++++++++++ rpc/src/v1/tests/helpers/mod.rs | 2 + 7 files changed, 203 insertions(+), 36 deletions(-) create mode 100644 rpc/src/v1/helpers/external_miner.rs create mode 100644 rpc/src/v1/tests/helpers/external_miner.rs diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 140b8d91f..55c473d1e 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -87,22 +87,22 @@ impl TestBlockChainClient { } /// Set the balance of account `address` to `balance`. - pub fn set_balance(&mut self, address: Address, balance: U256) { + pub fn set_balance(&self, address: Address, balance: U256) { self.balances.write().unwrap().insert(address, balance); } /// Set `code` at `address`. - pub fn set_code(&mut self, address: Address, code: Bytes) { + pub fn set_code(&self, address: Address, code: Bytes) { self.code.write().unwrap().insert(address, code); } /// Set storage `position` to `value` for account `address`. - pub fn set_storage(&mut self, address: Address, position: H256, value: H256) { + pub fn set_storage(&self, address: Address, position: H256, value: H256) { self.storage.write().unwrap().insert((address, position), value); } /// Add blocks to test client. - pub fn add_blocks(&mut self, count: usize, with: EachBlockWith) { + pub fn add_blocks(&self, count: usize, with: EachBlockWith) { let len = self.numbers.read().unwrap().len(); for n in len..(len + count) { let mut header = BlockHeader::new(); diff --git a/rpc/src/v1/helpers/external_miner.rs b/rpc/src/v1/helpers/external_miner.rs new file mode 100644 index 000000000..4cbda8928 --- /dev/null +++ b/rpc/src/v1/helpers/external_miner.rs @@ -0,0 +1,59 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::HashMap; +use std::sync::RwLock; +use util::numbers::U256; +use util::hash::H256; + +/// External miner interface. +pub trait ExternalMinerService: Send + Sync { + /// Submit hashrate for given miner. + fn submit_hashrate(&self, hashrate: U256, id: H256); + + /// Total hashrate. + fn hashrate(&self) -> U256; + + /// Returns true if external miner is mining. + fn is_mining(&self) -> bool; +} + +/// External Miner. +pub struct ExternalMiner { + hashrates: RwLock>, +} + +impl Default for ExternalMiner { + fn default() -> Self { + ExternalMiner { + hashrates: RwLock::new(HashMap::new()), + } + } +} + +impl ExternalMinerService for ExternalMiner { + fn submit_hashrate(&self, hashrate: U256, id: H256) { + self.hashrates.write().unwrap().insert(id, hashrate); + } + + fn hashrate(&self) -> U256 { + self.hashrates.read().unwrap().iter().fold(U256::from(0), |sum, (_, v)| sum + *v) + } + + fn is_mining(&self) -> bool { + !self.hashrates.read().unwrap().is_empty() + } +} diff --git a/rpc/src/v1/helpers/mod.rs b/rpc/src/v1/helpers/mod.rs index b1a5c05ba..8c574cff6 100644 --- a/rpc/src/v1/helpers/mod.rs +++ b/rpc/src/v1/helpers/mod.rs @@ -16,6 +16,8 @@ mod poll_manager; mod poll_filter; +pub mod external_miner; pub use self::poll_manager::PollManager; pub use self::poll_filter::PollFilter; +pub use self::external_miner::{ExternalMinerService, ExternalMiner}; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 0e8b8d863..9ceea2e25 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -15,8 +15,8 @@ // along with Parity. If not, see . //! Eth rpc implementation. -use std::collections::{HashMap, HashSet}; -use std::sync::{Arc, Weak, Mutex, RwLock}; +use std::collections::HashSet; +use std::sync::{Arc, Weak, Mutex}; use std::ops::Deref; use ethsync::{SyncProvider, SyncState}; use ethminer::{MinerService}; @@ -25,42 +25,59 @@ use util::numbers::*; use util::sha3::*; use util::rlp::encode; use ethcore::client::*; -use ethcore::block::{IsBlock}; +use ethcore::block::IsBlock; use ethcore::views::*; use ethcore::ethereum::Ethash; use ethcore::ethereum::denominations::shannon; use ethcore::transaction::Transaction as EthTransaction; use v1::traits::{Eth, EthFilter}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log}; -use v1::helpers::{PollFilter, PollManager}; +use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner}; use util::keys::store::AccountProvider; /// Eth rpc implementation. -pub struct EthClient +pub struct EthClient where C: BlockChainClient, S: SyncProvider, A: AccountProvider, - M: MinerService { + M: MinerService, + EM: ExternalMinerService { client: Weak, sync: Weak, accounts: Weak, miner: Weak, - hashrates: RwLock>, + external_miner: EM, } -impl EthClient +impl EthClient where C: BlockChainClient, S: SyncProvider, A: AccountProvider, M: MinerService { + /// Creates new EthClient. pub fn new(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc) -> Self { + EthClient::new_with_external_miner(client, sync, accounts, miner, ExternalMiner::default()) + } +} + + +impl EthClient + where C: BlockChainClient, + S: SyncProvider, + A: AccountProvider, + M: MinerService, + EM: ExternalMinerService { + + /// Creates new EthClient with custom external miner. + pub fn new_with_external_miner(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc, em: EM) + -> EthClient { EthClient { client: Arc::downgrade(client), sync: Arc::downgrade(sync), miner: Arc::downgrade(miner), accounts: Arc::downgrade(accounts), - hashrates: RwLock::new(HashMap::new()), + external_miner: em, } } @@ -110,11 +127,12 @@ impl EthClient } } -impl Eth for EthClient +impl Eth for EthClient where C: BlockChainClient + 'static, S: SyncProvider + 'static, A: AccountProvider + 'static, - M: MinerService + 'static { + M: MinerService + 'static, + EM: ExternalMinerService + 'static { fn protocol_version(&self, params: Params) -> Result { match params { @@ -152,7 +170,7 @@ impl Eth for EthClient // TODO: return real value of mining once it's implemented. fn is_mining(&self, params: Params) -> Result { match params { - Params::None => to_value(&!self.hashrates.read().unwrap().is_empty()), + Params::None => to_value(&self.external_miner.is_mining()), _ => Err(Error::invalid_params()) } } @@ -160,7 +178,7 @@ impl Eth for EthClient // TODO: return real hashrate once we have mining fn hashrate(&self, params: Params) -> Result { match params { - Params::None => to_value(&self.hashrates.read().unwrap().iter().fold(0u64, |sum, (_, v)| sum + v)), + Params::None => to_value(&self.external_miner.hashrate()), _ => Err(Error::invalid_params()) } } @@ -318,8 +336,8 @@ impl Eth for EthClient fn submit_hashrate(&self, params: Params) -> Result { // TODO: Index should be U256. - from_params::<(Index, H256)>(params).and_then(|(rate, id)| { - self.hashrates.write().unwrap().insert(id, rate.value() as u64); + from_params::<(U256, H256)>(params).and_then(|(rate, id)| { + self.external_miner.submit_hashrate(rate, id); to_value(&true) }) } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 35c227e40..e07390165 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -15,20 +15,16 @@ // along with Parity. If not, see . use std::collections::HashMap; -use std::sync::Arc; +use std::sync::{Arc, RwLock}; use jsonrpc_core::IoHandler; use util::hash::{Address, H256}; use util::numbers::U256; use ethcore::client::{TestBlockChainClient, EachBlockWith}; use v1::{Eth, EthClient}; -use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService}; +use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService, TestExternalMiner}; fn blockchain_client() -> Arc { - let mut client = TestBlockChainClient::new(); - client.add_blocks(10, EachBlockWith::Nothing); - client.set_balance(Address::from(1), U256::from(5)); - client.set_storage(Address::from(1), H256::from(4), H256::from(7)); - client.set_code(Address::from(1), vec![0xff, 0x21]); + let client = TestBlockChainClient::new(); Arc::new(client) } @@ -51,10 +47,11 @@ fn miner_service() -> Arc { } struct EthTester { - _client: Arc, + client: Arc, _sync: Arc, _accounts_provider: Arc, _miner: Arc, + hashrates: Arc>>, pub io: IoHandler, } @@ -64,15 +61,18 @@ impl Default for EthTester { let sync = sync_provider(); let ap = accounts_provider(); let miner = miner_service(); - let eth = EthClient::new(&client, &sync, &ap, &miner).to_delegate(); + let hashrates = Arc::new(RwLock::new(HashMap::new())); + let external_miner = TestExternalMiner::new(hashrates.clone()); + let eth = EthClient::new_with_external_miner(&client, &sync, &ap, &miner, external_miner).to_delegate(); let io = IoHandler::new(); io.add_delegate(eth); EthTester { - _client: client, + client: client, _sync: sync, _accounts_provider: ap, _miner: miner, - io: io + io: io, + hashrates: hashrates, } } } @@ -92,9 +92,35 @@ fn rpc_eth_syncing() { } #[test] -#[ignore] fn rpc_eth_hashrate() { - unimplemented!() + let tester = EthTester::default(); + tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffa)); + tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffb)); + tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1)); + + let request = r#"{"jsonrpc": "2.0", "method": "eth_hashrate", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":"0xfffc","id":1}"#; + + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_eth_submit_hashrate() { + let tester = EthTester::default(); + + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_submitHashrate", + "params": [ + "0x0000000000000000000000000000000000000000000000000000000000500000", + "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); + assert_eq!(tester.hashrates.read().unwrap().get(&H256::from("0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c")).cloned(), + Some(U256::from(0x500_000))); } #[test] @@ -127,14 +153,20 @@ fn rpc_eth_accounts() { #[test] fn rpc_eth_block_number() { + let tester = EthTester::default(); + tester.client.add_blocks(10, EachBlockWith::Nothing); + let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#; - assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] fn rpc_eth_balance() { + let tester = EthTester::default(); + tester.client.set_balance(Address::from(1), U256::from(5)); + let request = r#"{ "jsonrpc": "2.0", "method": "eth_getBalance", @@ -143,11 +175,14 @@ fn rpc_eth_balance() { }"#; let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#; - assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] fn rpc_eth_storage_at() { + let tester = EthTester::default(); + tester.client.set_storage(Address::from(1), H256::from(4), H256::from(7)); + let request = r#"{ "jsonrpc": "2.0", "method": "eth_getStorageAt", @@ -156,7 +191,7 @@ fn rpc_eth_storage_at() { }"#; let response = r#"{"jsonrpc":"2.0","result":"0x07","id":1}"#; - assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] @@ -226,6 +261,9 @@ fn rpc_eth_uncle_count_by_block_number() { #[test] fn rpc_eth_code() { + let tester = EthTester::default(); + tester.client.set_code(Address::from(1), vec![0xff, 0x21]); + let request = r#"{ "jsonrpc": "2.0", "method": "eth_getCode", @@ -234,7 +272,7 @@ fn rpc_eth_code() { }"#; let response = r#"{"jsonrpc":"2.0","result":"0xff21","id":1}"#; - assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] diff --git a/rpc/src/v1/tests/helpers/external_miner.rs b/rpc/src/v1/tests/helpers/external_miner.rs new file mode 100644 index 000000000..a5111b302 --- /dev/null +++ b/rpc/src/v1/tests/helpers/external_miner.rs @@ -0,0 +1,48 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +use std::collections::HashMap; +use std::sync::{Arc, RwLock}; +use util::numbers::U256; +use util::hash::H256; +use v1::helpers::ExternalMinerService; + +/// Test ExternalMinerService; +pub struct TestExternalMiner { + pub hashrates: Arc>> +} + +impl TestExternalMiner { + pub fn new(hashrates: Arc>>) -> Self { + TestExternalMiner { + hashrates: hashrates, + } + } +} + +impl ExternalMinerService for TestExternalMiner { + fn submit_hashrate(&self, hashrate: U256, id: H256) { + self.hashrates.write().unwrap().insert(id, hashrate); + } + + fn hashrate(&self) -> U256 { + self.hashrates.read().unwrap().iter().fold(U256::from(0), |sum, (_, v)| sum + *v) + } + + fn is_mining(&self) -> bool { + !self.hashrates.read().unwrap().is_empty() + } +} diff --git a/rpc/src/v1/tests/helpers/mod.rs b/rpc/src/v1/tests/helpers/mod.rs index fc429982e..fc652e7d6 100644 --- a/rpc/src/v1/tests/helpers/mod.rs +++ b/rpc/src/v1/tests/helpers/mod.rs @@ -17,7 +17,9 @@ mod account_provider; mod sync_provider; mod miner_service; +mod external_miner; pub use self::account_provider::{TestAccount, TestAccountProvider}; pub use self::sync_provider::{Config, TestSyncProvider}; pub use self::miner_service::{TestMinerService}; +pub use self::external_miner::TestExternalMiner; From 47ca84041b8c4b0ed346f4c10b75d015369f1266 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 14 Mar 2016 14:59:09 +0100 Subject: [PATCH 2/5] tests for eth_mining, eth_compileLLL, eth_compileSolidity, eth_compileSerpent --- rpc/src/v1/tests/eth.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index e07390165..6bc929709 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -130,9 +130,18 @@ fn rpc_eth_author() { } #[test] -#[ignore] fn rpc_eth_mining() { - unimplemented!() + let tester = EthTester::default(); + + let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#; + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); + + tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1)); + + let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] @@ -313,5 +322,29 @@ fn rpc_eth_compilers() { assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); } +#[test] +fn rpc_eth_compile_lll() { + let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#; + + assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_eth_compile_solidity() { + let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#; + + assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_eth_compile_serpent() { + let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#; + + assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); +} + From 9b241faf010303da6c2245ba2529e439bded5034 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 14 Mar 2016 17:01:10 +0100 Subject: [PATCH 3/5] uncle method mock --- ethcore/src/views.rs | 7 ++++++- rpc/src/v1/impls/eth.rs | 15 +++++++++++++++ rpc/src/v1/traits/eth.rs | 9 ++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/ethcore/src/views.rs b/ethcore/src/views.rs index 4a7ff054d..745cbff2c 100644 --- a/ethcore/src/views.rs +++ b/ethcore/src/views.rs @@ -223,6 +223,11 @@ impl<'a> BlockView<'a> { pub fn uncle_hashes(&self) -> Vec { self.rlp.at(2).iter().map(|rlp| rlp.as_raw().sha3()).collect() } + + /// Return nth uncle. + pub fn uncle_at(&self, index: usize) -> Option
{ + self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) + } } impl<'a> Hashable for BlockView<'a> { @@ -280,7 +285,7 @@ impl<'a> HeaderView<'a> { /// Returns block number. pub fn number(&self) -> BlockNumber { self.rlp.val_at(8) } - + /// Returns block gas limit. pub fn gas_limit(&self) -> U256 { self.rlp.val_at(9) } diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 9ceea2e25..fda391304 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -125,6 +125,11 @@ impl EthClient None => Ok(Value::Null) } } + + fn uncle(&self, _block: BlockId, _index: usize) -> Result { + // TODO: implement! + Ok(Value::Null) + } } impl Eth for EthClient @@ -285,6 +290,16 @@ impl Eth for EthClient .and_then(|(number, index)| self.transaction(TransactionId::Location(number.into(), index.value()))) } + fn uncle_by_block_hash_and_index(&self, params: Params) -> Result { + from_params::<(H256, Index)>(params) + .and_then(|(hash, index)| self.uncle(BlockId::Hash(hash), index.value())) + } + + fn uncle_by_block_number_and_index(&self, params: Params) -> Result { + from_params::<(BlockNumber, Index)>(params) + .and_then(|(number, index)| self.uncle(number.into(), index.value())) + } + fn compilers(&self, params: Params) -> Result { match params { Params::None => to_value(&vec![] as &Vec), diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index bcd7e7cfe..8a48e0dfe 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -102,7 +102,10 @@ pub trait Eth: Sized + Send + Sync + 'static { fn transaction_receipt(&self, _: Params) -> Result { rpc_unimplemented!() } /// Returns an uncles at given block and index. - fn uncle_at(&self, _: Params) -> Result { rpc_unimplemented!() } + fn uncle_by_block_hash_and_index(&self, _: Params) -> Result { rpc_unimplemented!() } + + /// Returns an uncles at given block and index. + fn uncle_by_block_number_and_index(&self, _: Params) -> Result { rpc_unimplemented!() } /// Returns available compilers. fn compilers(&self, _: Params) -> Result { rpc_unimplemented!() } @@ -158,8 +161,8 @@ pub trait Eth: Sized + Send + Sync + 'static { delegate.add_method("eth_getTransactionByBlockHashAndIndex", Eth::transaction_by_block_hash_and_index); delegate.add_method("eth_getTransactionByBlockNumberAndIndex", Eth::transaction_by_block_number_and_index); delegate.add_method("eth_getTransactionReceipt", Eth::transaction_receipt); - delegate.add_method("eth_getUncleByBlockHashAndIndex", Eth::uncle_at); - delegate.add_method("eth_getUncleByBlockNumberAndIndex", Eth::uncle_at); + delegate.add_method("eth_getUncleByBlockHashAndIndex", Eth::uncle_by_block_hash_and_index); + delegate.add_method("eth_getUncleByBlockNumberAndIndex", Eth::uncle_by_block_number_and_index); delegate.add_method("eth_getCompilers", Eth::compilers); delegate.add_method("eth_compileLLL", Eth::compile_lll); delegate.add_method("eth_compileSolidity", Eth::compile_solidity); From 85833d228a4843438b23d332c1fba2b2558669bd Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 15 Mar 2016 01:22:58 +0100 Subject: [PATCH 4/5] Ignore new blocks while seeking --- sync/src/chain.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 57f53f459..363597d40 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -479,6 +479,9 @@ impl ChainSync { let header_rlp = try!(block_rlp.at(0)); let h = header_rlp.as_raw().sha3(); trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); + if !self.have_common_block { + trace!(target: "sync", "NewBlock ignored while seeking"); + } let header: BlockHeader = try!(header_rlp.as_val()); let mut unknown = false; { @@ -498,9 +501,10 @@ impl ChainSync { Ok(_) => { if self.current_base_block() < header.number { self.last_imported_block = Some(header.number); + self.last_imported_hash = Some(header.hash()); self.remove_downloaded_blocks(header.number); } - trace!(target: "sync", "New block queued {:?}", h); + trace!(target: "sync", "New block queued {:?} ({})", h, header.number); }, Err(Error::Block(BlockError::UnknownParent(p))) => { unknown = true; @@ -779,7 +783,7 @@ impl ChainSync { { let headers = self.headers.range_iter().next().unwrap(); let bodies = self.bodies.range_iter().next().unwrap(); - if headers.0 != bodies.0 || headers.0 != self.current_base_block() + 1 { + if headers.0 != bodies.0 || headers.0 > self.current_base_block() + 1 { return; } From b9b0444662e651df8f30416d0f27eed5fd166fe7 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 15 Mar 2016 11:20:19 +0100 Subject: [PATCH 5/5] Trace sending to unconfirmed session --- util/src/network/session.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/src/network/session.rs b/util/src/network/session.rs index 84c063c92..2f30d7376 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -213,6 +213,10 @@ impl Session { /// Send a protocol packet to peer. pub fn send_packet(&mut self, protocol: &str, packet_id: u8, data: &[u8]) -> Result<(), UtilError> { + if self.info.capabilities.is_empty() || !self.had_hello { + debug!(target: "network", "Sending to unconfirmed session {}, protocol: {}, packet: {}", self.token(), protocol, packet_id); + return Err(From::from(NetworkError::BadProtocol)); + } if self.expired() { return Err(From::from(NetworkError::Expired)); }