Merge pull request #742 from ethcore/mining-stop-sync

adding check for a sync when giving work to miner
This commit is contained in:
Arkadiy Paronyan 2016-03-17 12:23:43 +01:00
commit de484b2495
4 changed files with 56 additions and 12 deletions

View File

@ -321,6 +321,15 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
fn work(&self, params: Params) -> Result<Value, Error> { fn work(&self, params: Params) -> Result<Value, Error> {
match params { match params {
Params::None => { Params::None => {
let client = take_weak!(self.client);
// check if we're still syncing and return empty strings int that case
{
let sync = take_weak!(self.sync);
if sync.status().state != SyncState::Idle && client.queue_info().is_empty() {
return to_value(&(String::new(), String::new(), String::new()));
}
}
let miner = take_weak!(self.miner); let miner = take_weak!(self.miner);
let client = take_weak!(self.client); let client = take_weak!(self.client);
let u = miner.sealing_block(client.deref()).lock().unwrap(); let u = miner.sealing_block(client.deref()).lock().unwrap();
@ -331,7 +340,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
let seed_hash = Ethash::get_seedhash(b.block().header().number()); let seed_hash = Ethash::get_seedhash(b.block().header().number());
to_value(&(pow_hash, seed_hash, target)) to_value(&(pow_hash, seed_hash, target))
} }
_ => Err(Error::invalid_params()) _ => Err(Error::internal_error())
} }
}, },
_ => Err(Error::invalid_params()) _ => Err(Error::invalid_params())

View File

@ -43,12 +43,12 @@ fn sync_provider() -> Arc<TestSyncProvider> {
} }
fn miner_service() -> Arc<TestMinerService> { fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService) Arc::new(TestMinerService::default())
} }
struct EthTester { struct EthTester {
client: Arc<TestBlockChainClient>, pub client: Arc<TestBlockChainClient>,
_sync: Arc<TestSyncProvider>, pub sync: Arc<TestSyncProvider>,
_accounts_provider: Arc<TestAccountProvider>, _accounts_provider: Arc<TestAccountProvider>,
_miner: Arc<TestMinerService>, _miner: Arc<TestMinerService>,
hashrates: Arc<RwLock<HashMap<H256, U256>>>, hashrates: Arc<RwLock<HashMap<H256, U256>>>,
@ -68,7 +68,7 @@ impl Default for EthTester {
io.add_delegate(eth); io.add_delegate(eth);
EthTester { EthTester {
client: client, client: client,
_sync: sync, sync: sync,
_accounts_provider: ap, _accounts_provider: ap,
_miner: miner, _miner: miner,
io: io, io: io,
@ -346,5 +346,25 @@ fn rpc_eth_compile_serpent() {
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
} }
#[test]
fn returns_no_work_if_cant_mine() {
let eth_tester = EthTester::default();
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":["","",""],"id":1}"#;
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
}
#[test]
fn returns_error_if_can_mine_and_no_closed_block() {
use ethsync::{SyncState};
let eth_tester = EthTester::default();
eth_tester.sync.status.write().unwrap().state = SyncState::Idle;
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
}

View File

@ -22,7 +22,19 @@ use ethcore::block::ClosedBlock;
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use ethminer::{MinerService, MinerStatus}; use ethminer::{MinerService, MinerStatus};
pub struct TestMinerService; pub struct TestMinerService {
pub imported_transactions: RwLock<Vec<H256>>,
pub latest_closed_block: Mutex<Option<ClosedBlock>>,
}
impl Default for TestMinerService {
fn default() -> TestMinerService {
TestMinerService {
imported_transactions: RwLock::new(Vec::new()),
latest_closed_block: Mutex::new(None),
}
}
}
impl MinerService for TestMinerService { impl MinerService for TestMinerService {
@ -45,7 +57,9 @@ impl MinerService for TestMinerService {
fn prepare_sealing(&self, _chain: &BlockChainClient) { unimplemented!(); } fn prepare_sealing(&self, _chain: &BlockChainClient) { unimplemented!(); }
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock. /// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
fn sealing_block(&self, _chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> { unimplemented!(); } fn sealing_block(&self, _chain: &BlockChainClient) -> &Mutex<Option<ClosedBlock>> {
&self.latest_closed_block
}
/// Submit `seal` as a valid solution for the header of `pow_hash`. /// Submit `seal` as a valid solution for the header of `pow_hash`.
/// Will check the seal, but not actually insert the block into the chain. /// Will check the seal, but not actually insert the block into the chain.

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethsync::{SyncProvider, SyncStatus, SyncState}; use ethsync::{SyncProvider, SyncStatus, SyncState};
use std::sync::{RwLock};
pub struct Config { pub struct Config {
pub protocol_version: u8, pub protocol_version: u8,
@ -22,13 +23,13 @@ pub struct Config {
} }
pub struct TestSyncProvider { pub struct TestSyncProvider {
status: SyncStatus, pub status: RwLock<SyncStatus>,
} }
impl TestSyncProvider { impl TestSyncProvider {
pub fn new(config: Config) -> Self { pub fn new(config: Config) -> Self {
TestSyncProvider { TestSyncProvider {
status: SyncStatus { status: RwLock::new(SyncStatus {
state: SyncState::NotSynced, state: SyncState::NotSynced,
protocol_version: config.protocol_version, protocol_version: config.protocol_version,
start_block_number: 0, start_block_number: 0,
@ -39,14 +40,14 @@ impl TestSyncProvider {
num_peers: config.num_peers, num_peers: config.num_peers,
num_active_peers: 0, num_active_peers: 0,
mem_used: 0, mem_used: 0,
}, }),
} }
} }
} }
impl SyncProvider for TestSyncProvider { impl SyncProvider for TestSyncProvider {
fn status(&self) -> SyncStatus { fn status(&self) -> SyncStatus {
self.status.clone() self.status.read().unwrap().clone()
} }
} }