Using miner in rpc instead of sync

This commit is contained in:
Tomasz Drwięga 2016-03-11 14:48:30 +01:00
parent 03da6c991f
commit 197ea7f7d6
5 changed files with 67 additions and 46 deletions

View File

@ -63,5 +63,46 @@ mod miner;
mod transaction_queue; mod transaction_queue;
pub use transaction_queue::TransactionQueue; pub use transaction_queue::TransactionQueue;
pub use miner::{Miner, MinerService}; pub use miner::{Miner};
use std::sync::Mutex;
use util::{H256, U256, Address, Bytes};
use ethcore::client::{BlockChainClient};
use ethcore::block::{ClosedBlock};
use ethcore::error::{Error};
use ethcore::transaction::SignedTransaction;
/// Miner client API
pub trait MinerService : Send + Sync {
/// Returns miner's status.
fn status(&self) -> MinerStatus;
/// Imports transactions to transaction queue.
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_nonce: T) -> Result<(), Error>
where T: Fn(&Address) -> U256;
/// Removes all transactions from the queue and restart mining operation.
fn clear_and_reset(&self, chain: &BlockChainClient);
/// called when blocks are imported to chain, updates transactions queue.
fn chain_new_blocks(&self, chain: &BlockChainClient, good: &[H256], bad: &[H256], retracted: &[H256]);
/// New chain head event. Restart mining operation.
fn prepare_sealing(&self, chain: &BlockChainClient);
/// 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>>;
/// 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.
fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
}
/// Mining status
pub struct MinerStatus {
/// Number of transactions in queue with state `pending` (ready to be included in block)
pub transaction_queue_pending: usize,
/// Number of transactions in queue with state `future` (not yet ready to be included in block)
pub transaction_queue_future: usize,
}

View File

@ -14,50 +14,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::*;
use std::sync::atomic::AtomicBool;
use rayon::prelude::*; use rayon::prelude::*;
use std::sync::{Mutex, RwLock, Arc};
use std::sync::atomic;
use std::sync::atomic::AtomicBool;
use util::{H256, U256, Address, Bytes};
use ethcore::views::{BlockView}; use ethcore::views::{BlockView};
use ethcore::client::{BlockChainClient, BlockId}; use ethcore::client::{BlockChainClient, BlockId};
use ethcore::block::*; use ethcore::block::{ClosedBlock};
use ethcore::error::*; use ethcore::error::{Error};
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use transaction_queue::{TransactionQueue};
/// Miner client API use super::{MinerService, MinerStatus, TransactionQueue};
pub trait MinerService : Send + Sync {
/// Returns miner's status.
fn status(&self) -> MinerStatus;
/// Imports transactions to transaction queue.
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_nonce: T) -> Result<(), Error>
where T: Fn(&Address) -> U256;
/// Removes all transactions from the queue and restart mining operation.
fn clear_and_reset(&self, chain: &BlockChainClient);
/// called when blocks are imported to chain, updates transactions queue.
fn chain_new_blocks(&self, chain: &BlockChainClient, good: &[H256], bad: &[H256], _retracted: &[H256]);
/// New chain head event. Restart mining operation.
fn prepare_sealing(&self, chain: &BlockChainClient);
/// 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>>;
/// 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.
fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
}
/// Mining status
pub struct MinerStatus {
/// Number of transactions in queue with state `pending` (ready to be included in block)
pub transaction_queue_pending: usize,
/// Number of transactions in queue with state `future` (not yet ready to be included in block)
pub transaction_queue_future: usize,
}
/// Keeps track of transactions using priority queue and holds currently mined block. /// Keeps track of transactions using priority queue and holds currently mined block.
pub struct Miner { pub struct Miner {
@ -76,7 +45,7 @@ impl Default for Miner {
transaction_queue: Mutex::new(TransactionQueue::new()), transaction_queue: Mutex::new(TransactionQueue::new()),
sealing_enabled: AtomicBool::new(false), sealing_enabled: AtomicBool::new(false),
sealing_block: Mutex::new(None), sealing_block: Mutex::new(None),
author: RwLock::new(Address::new()), author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
} }
} }

View File

@ -171,6 +171,7 @@ struct Args {
flag_nodekey: Option<String>, flag_nodekey: Option<String>,
flag_nodiscover: bool, flag_nodiscover: bool,
flag_maxpeers: Option<usize>, flag_maxpeers: Option<usize>,
flag_gasprice: String,
flag_author: String, flag_author: String,
flag_extra_data: Option<String>, flag_extra_data: Option<String>,
flag_datadir: Option<String>, flag_datadir: Option<String>,

View File

@ -19,6 +19,8 @@
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))] #![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))] #![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
#[macro_use]
extern crate log;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;

View File

@ -53,7 +53,7 @@ impl<C, S, A, M> EthClient<C, S, A, M>
A: AccountProvider, A: AccountProvider,
M: MinerService { M: MinerService {
/// Creates new EthClient. /// Creates new EthClient.
pub fn new(client: &Arc<C>, sync: &Arc<S>, miner: &Arc<M>) -> Self { pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>) -> Self {
EthClient { EthClient {
client: Arc::downgrade(client), client: Arc::downgrade(client),
sync: Arc::downgrade(sync), sync: Arc::downgrade(sync),
@ -189,7 +189,7 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
fn block_transaction_count_by_number(&self, params: Params) -> Result<Value, Error> { fn block_transaction_count_by_number(&self, params: Params) -> Result<Value, Error> {
from_params::<(BlockNumber,)>(params) from_params::<(BlockNumber,)>(params)
.and_then(|(block_number,)| match block_number { .and_then(|(block_number,)| match block_number {
BlockNumber::Pending => to_value(&take_weak!(self.sync).status().transaction_queue_pending), BlockNumber::Pending => to_value(&take_weak!(self.miner).status().transaction_queue_pending),
_ => match take_weak!(self.client).block(block_number.into()) { _ => match take_weak!(self.client).block(block_number.into()) {
Some(bytes) => to_value(&BlockView::new(&bytes).transactions_count()), Some(bytes) => to_value(&BlockView::new(&bytes).transactions_count()),
None => Ok(Value::Null) None => Ok(Value::Null)
@ -292,12 +292,20 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
let accounts = take_weak!(self.accounts); let accounts = take_weak!(self.accounts);
match accounts.account_secret(&transaction_request.from) { match accounts.account_secret(&transaction_request.from) {
Ok(secret) => { Ok(secret) => {
let sync = take_weak!(self.sync); let miner = take_weak!(self.miner);
let client = take_weak!(self.client);
let (transaction, _) = transaction_request.to_eth(); let (transaction, _) = transaction_request.to_eth();
let signed_transaction = transaction.sign(&secret); let signed_transaction = transaction.sign(&secret);
let hash = signed_transaction.hash(); let hash = signed_transaction.hash();
sync.insert_transaction(signed_transaction);
to_value(&hash) let import = miner.import_transactions(vec![signed_transaction], |a: &Address| client.nonce(a));
match import {
Ok(_) => to_value(&hash),
Err(e) => {
warn!("Error sending transaction: {:?}", e);
to_value(&U256::zero())
}
}
}, },
Err(_) => { to_value(&U256::zero()) } Err(_) => { to_value(&U256::zero()) }
} }