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> {
match params {
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 client = take_weak!(self.client);
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());
to_value(&(pow_hash, seed_hash, target))
}
_ => Err(Error::invalid_params())
_ => Err(Error::internal_error())
}
},
_ => Err(Error::invalid_params())

View File

@ -43,12 +43,12 @@ fn sync_provider() -> Arc<TestSyncProvider> {
}
fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService)
Arc::new(TestMinerService::default())
}
struct EthTester {
client: Arc<TestBlockChainClient>,
_sync: Arc<TestSyncProvider>,
pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>,
_accounts_provider: Arc<TestAccountProvider>,
_miner: Arc<TestMinerService>,
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
@ -68,7 +68,7 @@ impl Default for EthTester {
io.add_delegate(eth);
EthTester {
client: client,
_sync: sync,
sync: sync,
_accounts_provider: ap,
_miner: miner,
io: io,
@ -346,5 +346,25 @@ fn rpc_eth_compile_serpent() {
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 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 {
@ -45,7 +57,9 @@ impl MinerService for TestMinerService {
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.
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`.
/// 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/>.
use ethsync::{SyncProvider, SyncStatus, SyncState};
use std::sync::{RwLock};
pub struct Config {
pub protocol_version: u8,
@ -22,13 +23,13 @@ pub struct Config {
}
pub struct TestSyncProvider {
status: SyncStatus,
pub status: RwLock<SyncStatus>,
}
impl TestSyncProvider {
pub fn new(config: Config) -> Self {
TestSyncProvider {
status: SyncStatus {
status: RwLock::new(SyncStatus {
state: SyncState::NotSynced,
protocol_version: config.protocol_version,
start_block_number: 0,
@ -39,14 +40,14 @@ impl TestSyncProvider {
num_peers: config.num_peers,
num_active_peers: 0,
mem_used: 0,
},
}),
}
}
}
impl SyncProvider for TestSyncProvider {
fn status(&self) -> SyncStatus {
self.status.clone()
self.status.read().unwrap().clone()
}
}