Miner tests (#1597)
* Un-ignoring RPC test * Additional tests for importing transactions
This commit is contained in:
parent
44bc8a08fb
commit
6c205067b1
@ -262,6 +262,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
|||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
self.spec.ensure_db_good(db.as_hashdb_mut());
|
self.spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
|
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
OpenBlock::new(
|
OpenBlock::new(
|
||||||
engine.deref(),
|
engine.deref(),
|
||||||
|
@ -615,7 +615,9 @@ impl MinerService for Miner {
|
|||||||
let imported = {
|
let imported = {
|
||||||
// Be sure to release the lock before we call enable_and_prepare_sealing
|
// Be sure to release the lock before we call enable_and_prepare_sealing
|
||||||
let mut transaction_queue = self.transaction_queue.lock();
|
let mut transaction_queue = self.transaction_queue.lock();
|
||||||
let import = self.add_transactions_to_queue(chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue).pop().unwrap();
|
let import = self.add_transactions_to_queue(
|
||||||
|
chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue
|
||||||
|
).pop().unwrap();
|
||||||
|
|
||||||
match import {
|
match import {
|
||||||
Ok(ref res) => {
|
Ok(ref res) => {
|
||||||
@ -834,10 +836,13 @@ impl MinerService for Miner {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
use super::super::MinerService;
|
use super::super::MinerService;
|
||||||
use super::Miner;
|
use super::*;
|
||||||
use util::*;
|
use util::*;
|
||||||
use client::{TestBlockChainClient, EachBlockWith};
|
use client::{TestBlockChainClient, EachBlockWith};
|
||||||
|
use client::{TransactionImportResult};
|
||||||
|
use types::transaction::{Transaction, Action};
|
||||||
use block::*;
|
use block::*;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
|
|
||||||
@ -872,4 +877,84 @@ mod tests {
|
|||||||
// solution to original work submitted.
|
// solution to original work submitted.
|
||||||
assert!(miner.submit_seal(&client, res.unwrap(), vec![]).is_ok());
|
assert!(miner.submit_seal(&client, res.unwrap(), vec![]).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn miner() -> Miner {
|
||||||
|
Arc::try_unwrap(Miner::new(
|
||||||
|
MinerOptions {
|
||||||
|
new_work_notify: Vec::new(),
|
||||||
|
force_sealing: false,
|
||||||
|
reseal_on_external_tx: false,
|
||||||
|
reseal_on_own_tx: true,
|
||||||
|
reseal_min_period: Duration::from_secs(5),
|
||||||
|
tx_gas_limit: !U256::zero(),
|
||||||
|
tx_queue_size: 1024,
|
||||||
|
pending_set: PendingSet::AlwaysSealing,
|
||||||
|
work_queue_size: 5,
|
||||||
|
enable_resubmission: true,
|
||||||
|
},
|
||||||
|
GasPricer::new_fixed(0u64.into()),
|
||||||
|
Spec::new_test(),
|
||||||
|
None, // accounts provider
|
||||||
|
)).ok().expect("Miner was just created.")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_make_pending_block_when_importing_own_transaction() {
|
||||||
|
// given
|
||||||
|
let client = TestBlockChainClient::default();
|
||||||
|
let miner = miner();
|
||||||
|
let transaction = {
|
||||||
|
let keypair = KeyPair::create().unwrap();
|
||||||
|
Transaction {
|
||||||
|
action: Action::Create,
|
||||||
|
value: U256::zero(),
|
||||||
|
data: "3331600055".from_hex().unwrap(),
|
||||||
|
gas: U256::from(100_000),
|
||||||
|
gas_price: U256::zero(),
|
||||||
|
nonce: U256::zero(),
|
||||||
|
}.sign(keypair.secret())
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = miner.import_own_transaction(&client, transaction);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
|
assert_eq!(miner.all_transactions().len(), 1);
|
||||||
|
assert_eq!(miner.pending_transactions().len(), 1);
|
||||||
|
assert_eq!(miner.pending_transactions_hashes().len(), 1);
|
||||||
|
assert_eq!(miner.pending_receipts().len(), 1);
|
||||||
|
// This method will let us know if pending block was created (before calling that method)
|
||||||
|
assert_eq!(miner.enable_and_prepare_sealing(&client), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_import_external_transaction() {
|
||||||
|
// given
|
||||||
|
let client = TestBlockChainClient::default();
|
||||||
|
let miner = miner();
|
||||||
|
let transaction = {
|
||||||
|
let keypair = KeyPair::create().unwrap();
|
||||||
|
Transaction {
|
||||||
|
action: Action::Create,
|
||||||
|
value: U256::zero(),
|
||||||
|
data: "3331600055".from_hex().unwrap(),
|
||||||
|
gas: U256::from(100_000),
|
||||||
|
gas_price: U256::zero(),
|
||||||
|
nonce: U256::zero(),
|
||||||
|
}.sign(keypair.secret())
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = miner.import_external_transactions(&client, vec![transaction]).pop().unwrap();
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
|
assert_eq!(miner.all_transactions().len(), 1);
|
||||||
|
assert_eq!(miner.pending_transactions_hashes().len(), 0);
|
||||||
|
assert_eq!(miner.pending_transactions().len(), 0);
|
||||||
|
assert_eq!(miner.pending_receipts().len(), 0);
|
||||||
|
// This method will let us know if pending block was created (before calling that method)
|
||||||
|
assert_eq!(miner.enable_and_prepare_sealing(&client), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ impl PriceInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[ignore]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_get_price_info() {
|
fn should_get_price_info() {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -88,6 +87,7 @@ fn should_get_price_info() {
|
|||||||
init_log();
|
init_log();
|
||||||
let done = Arc::new((Mutex::new(PriceInfo { ethusd: 0f32 }), Condvar::new()));
|
let done = Arc::new((Mutex::new(PriceInfo { ethusd: 0f32 }), Condvar::new()));
|
||||||
let rdone = done.clone();
|
let rdone = done.clone();
|
||||||
|
|
||||||
PriceInfo::get(move |price| { let mut p = rdone.0.lock(); *p = price; rdone.1.notify_one(); }).unwrap();
|
PriceInfo::get(move |price| { let mut p = rdone.0.lock(); *p = price; rdone.1.notify_one(); }).unwrap();
|
||||||
let mut p = done.0.lock();
|
let mut p = done.0.lock();
|
||||||
let t = done.1.wait_for(&mut p, Duration::from_millis(10000));
|
let t = done.1.wait_for(&mut p, Duration::from_millis(10000));
|
||||||
|
@ -182,7 +182,7 @@ impl MinerService for TestMinerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn map_sealing_work<F, T>(&self, _chain: &MiningBlockChainClient, _f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
fn map_sealing_work<F, T>(&self, _chain: &MiningBlockChainClient, _f: F) -> Option<T> where F: FnOnce(&ClosedBlock) -> T {
|
||||||
unimplemented!();
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
@ -56,7 +56,7 @@ struct EthTester {
|
|||||||
pub client: Arc<TestBlockChainClient>,
|
pub client: Arc<TestBlockChainClient>,
|
||||||
pub sync: Arc<TestSyncProvider>,
|
pub sync: Arc<TestSyncProvider>,
|
||||||
pub accounts_provider: Arc<AccountProvider>,
|
pub accounts_provider: Arc<AccountProvider>,
|
||||||
miner: Arc<TestMinerService>,
|
pub miner: Arc<TestMinerService>,
|
||||||
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
||||||
pub io: IoHandler,
|
pub io: IoHandler,
|
||||||
}
|
}
|
||||||
@ -742,13 +742,12 @@ fn returns_no_work_if_cant_mine() {
|
|||||||
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ignore]
|
|
||||||
// enable once TestMinerService supports the mining API.
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_error_if_can_mine_and_no_closed_block() {
|
fn returns_error_if_can_mine_and_no_closed_block() {
|
||||||
use ethsync::{SyncState};
|
use ethsync::{SyncState};
|
||||||
|
|
||||||
let eth_tester = EthTester::default();
|
let eth_tester = EthTester::default();
|
||||||
|
eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap());
|
||||||
eth_tester.sync.status.write().state = SyncState::Idle;
|
eth_tester.sync.status.write().state = SyncState::Idle;
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
|
||||||
|
@ -87,7 +87,7 @@ impl Worker {
|
|||||||
if deleting.load(AtomicOrdering::Acquire) {
|
if deleting.load(AtomicOrdering::Acquire) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let _ = wait.wait(&mut lock);
|
wait.wait(&mut lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if deleting.load(AtomicOrdering::Acquire) {
|
if deleting.load(AtomicOrdering::Acquire) {
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
//! A collection associating pair of keys (row and column) with a single value.
|
//! A collection associating pair of keys (row and column) with a single value.
|
||||||
|
|
||||||
use std::default::Default;
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -25,22 +24,13 @@ use std::collections::HashMap;
|
|||||||
/// You can obviously use `HashMap<(Row,Col), Val>`, but this structure gives
|
/// You can obviously use `HashMap<(Row,Col), Val>`, but this structure gives
|
||||||
/// you better access to all `Columns` in Specific `Row`. Namely you can get sub-hashmap
|
/// you better access to all `Columns` in Specific `Row`. Namely you can get sub-hashmap
|
||||||
/// `HashMap<Col, Val>` for specific `Row`
|
/// `HashMap<Col, Val>` for specific `Row`
|
||||||
|
#[derive(Default, Debug, PartialEq)]
|
||||||
pub struct Table<Row, Col, Val>
|
pub struct Table<Row, Col, Val>
|
||||||
where Row: Eq + Hash + Clone,
|
where Row: Eq + Hash + Clone,
|
||||||
Col: Eq + Hash {
|
Col: Eq + Hash {
|
||||||
map: HashMap<Row, HashMap<Col, Val>>,
|
map: HashMap<Row, HashMap<Col, Val>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Row, Col, Val> Default for Table<Row, Col, Val>
|
|
||||||
where Row: Eq + Hash + Clone,
|
|
||||||
Col: Eq + Hash {
|
|
||||||
fn default() -> Self {
|
|
||||||
Table::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is default but clippy does not detect it?
|
|
||||||
#[cfg_attr(feature="dev", allow(new_without_default))]
|
|
||||||
impl<Row, Col, Val> Table<Row, Col, Val>
|
impl<Row, Col, Val> Table<Row, Col, Val>
|
||||||
where Row: Eq + Hash + Clone,
|
where Row: Eq + Hash + Clone,
|
||||||
Col: Eq + Hash {
|
Col: Eq + Hash {
|
||||||
|
Loading…
Reference in New Issue
Block a user