Merge branch 'ethminer_crate'

This commit is contained in:
Gav Wood
2016-03-13 15:00:47 +01:00
32 changed files with 841 additions and 375 deletions

View File

@@ -24,6 +24,7 @@ extern crate rustc_serialize;
extern crate ethcore_util as util;
extern crate ethcore;
extern crate ethsync;
extern crate ethminer;
#[macro_use]
extern crate log as rlog;
extern crate env_logger;
@@ -50,6 +51,7 @@ use ethcore::client::*;
use ethcore::service::{ClientService, NetSyncMessage};
use ethcore::ethereum;
use ethsync::{EthSync, SyncConfig, SyncProvider};
use ethminer::{Miner, MinerService};
use docopt::Docopt;
use daemonize::Daemonize;
use number_prefix::{binary_prefix, Standalone, Prefixed};
@@ -112,6 +114,7 @@ API and Console Options:
--rpccorsdomain URL Equivalent to --jsonrpc-cors URL (geth-compatible).
Sealing/Mining Options:
--gasprice GAS Minimal gas price a transaction must have to be accepted for mining [default: 20000000000].
--author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards
from sealed blocks [default: 0037a6b811ffeb6e072da21179d11b1406371c63].
--extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters.
@@ -178,6 +181,7 @@ struct Args {
flag_nodekey: Option<String>,
flag_nodiscover: bool,
flag_maxpeers: Option<usize>,
flag_gasprice: String,
flag_author: String,
flag_extra_data: Option<String>,
flag_datadir: Option<String>,
@@ -219,7 +223,15 @@ fn setup_log(init: &Option<String>) {
}
#[cfg(feature = "rpc")]
fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, secret_store: Arc<AccountService>, url: &str, cors_domain: &str, apis: Vec<&str>) -> Option<Arc<PanicHandler>> {
fn setup_rpc_server(
client: Arc<Client>,
sync: Arc<EthSync>,
secret_store: Arc<AccountService>,
miner: Arc<Miner>,
url: &str,
cors_domain: &str,
apis: Vec<&str>
) -> Option<Arc<PanicHandler>> {
use rpc::v1::*;
let server = rpc::RpcServer::new();
@@ -228,8 +240,8 @@ fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, secret_store: Arc<A
"web3" => server.add_delegate(Web3Client::new().to_delegate()),
"net" => server.add_delegate(NetClient::new(&sync).to_delegate()),
"eth" => {
server.add_delegate(EthClient::new(&client, &sync, &secret_store).to_delegate());
server.add_delegate(EthFilterClient::new(&client).to_delegate());
server.add_delegate(EthClient::new(&client, &sync, &secret_store, &miner).to_delegate());
server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate());
}
"personal" => server.add_delegate(PersonalClient::new(&secret_store).to_delegate()),
_ => {
@@ -241,7 +253,15 @@ fn setup_rpc_server(client: Arc<Client>, sync: Arc<EthSync>, secret_store: Arc<A
}
#[cfg(not(feature = "rpc"))]
fn setup_rpc_server(_client: Arc<Client>, _sync: Arc<EthSync>, _url: &str) -> Option<Arc<PanicHandler>> {
fn setup_rpc_server(
_client: Arc<Client>,
_sync: Arc<EthSync>,
_secret_store: Arc<AccountService>,
_miner: Arc<Miner>,
_url: &str,
_cors_domain: &str,
_apis: Vec<&str>
) -> Option<Arc<PanicHandler>> {
None
}
@@ -276,7 +296,15 @@ impl Configuration {
fn author(&self) -> Address {
let d = self.args.flag_etherbase.as_ref().unwrap_or(&self.args.flag_author);
Address::from_str(d).unwrap_or_else(|_| die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", self.args.flag_author))
Address::from_str(d).unwrap_or_else(|_| {
die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", d)
})
}
fn gasprice(&self) -> U256 {
U256::from_dec_str(self.args.flag_gasprice.as_str()).unwrap_or_else(|_| {
die!("{}: Invalid gas price given. Must be a decimal unsigned 256-bit number.", self.args.flag_gasprice)
})
}
fn extra_data(&self) -> Bytes {
@@ -299,7 +327,9 @@ impl Configuration {
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(),
"morden" | "testnet" => ethereum::new_morden(),
"olympic" => ethereum::new_olympic(),
f => Spec::from_json_utf8(contents(f).unwrap_or_else(|_| die!("{}: Couldn't read chain specification file. Sure it exists?", f)).as_ref()),
f => Spec::from_json_utf8(contents(f).unwrap_or_else(|_| {
die!("{}: Couldn't read chain specification file. Sure it exists?", f)
}).as_ref()),
}
}
@@ -314,7 +344,11 @@ impl Configuration {
fn init_nodes(&self, spec: &Spec) -> Vec<String> {
let mut r = if self.args.flag_no_bootstrap { Vec::new() } else { spec.nodes().clone() };
if let Some(ref x) = self.args.flag_bootnodes {
r.extend(x.split(',').map(|s| Self::normalize_enode(s).unwrap_or_else(|| die!("{}: Invalid node address format given for a boot node.", s))));
r.extend(x.split(',').map(|s| {
Self::normalize_enode(s).unwrap_or_else(|| {
die!("{}: Invalid node address format given for a boot node.", s)
})
}));
}
r
}
@@ -348,6 +382,38 @@ impl Configuration {
ret
}
fn client_config(&self) -> ClientConfig {
let mut client_config = ClientConfig::default();
match self.args.flag_cache {
Some(mb) => {
client_config.blockchain.max_cache_size = mb * 1024 * 1024;
client_config.blockchain.pref_cache_size = client_config.blockchain.max_cache_size / 2;
}
None => {
client_config.blockchain.pref_cache_size = self.args.flag_cache_pref_size;
client_config.blockchain.max_cache_size = self.args.flag_cache_max_size;
}
}
client_config.pruning = match self.args.flag_pruning.as_str() {
"archive" => journaldb::Algorithm::Archive,
"pruned" => journaldb::Algorithm::EarlyMerge,
"fast" => journaldb::Algorithm::OverlayRecent,
// "slow" => journaldb::Algorithm::RefCounted, // TODO: @gavofyork uncomment this once ref-count algo is merged.
_ => { die!("Invalid pruning method given."); }
};
client_config.name = self.args.flag_identity.clone();
client_config.queue.max_mem_use = self.args.flag_queue_max_size;
client_config
}
fn sync_config(&self, spec: &Spec) -> SyncConfig {
let mut sync_config = SyncConfig::default();
sync_config.network_id = self.args.flag_networkid.as_ref().map_or(spec.network_id(), |id| {
U256::from_str(id).unwrap_or_else(|_| die!("{}: Invalid index given with --networkid", id))
});
sync_config
}
fn execute(&self) {
if self.args.flag_version {
print_version();
@@ -406,42 +472,21 @@ impl Configuration {
let spec = self.spec();
let net_settings = self.net_settings(&spec);
let mut sync_config = SyncConfig::default();
sync_config.network_id = self.args.flag_networkid.as_ref().map_or(spec.network_id(), |id| {
U256::from_str(id).unwrap_or_else(|_| {
die!("{}: Invalid index given with --networkid", id)
})
});
let sync_config = self.sync_config(&spec);
// Build client
let mut client_config = ClientConfig::default();
match self.args.flag_cache {
Some(mb) => {
client_config.blockchain.max_cache_size = mb * 1024 * 1024;
client_config.blockchain.pref_cache_size = client_config.blockchain.max_cache_size / 2;
}
None => {
client_config.blockchain.pref_cache_size = self.args.flag_cache_pref_size;
client_config.blockchain.max_cache_size = self.args.flag_cache_max_size;
}
}
client_config.pruning = match self.args.flag_pruning.as_str() {
"" | "archive" => journaldb::Algorithm::Archive,
"pruned" => journaldb::Algorithm::EarlyMerge,
"fast" => journaldb::Algorithm::OverlayRecent,
// "slow" => journaldb::Algorithm::RefCounted, // TODO: @gavofyork uncomment this once ref-count algo is merged.
_ => { die!("Invalid pruning method given."); }
};
client_config.name = self.args.flag_identity.clone();
client_config.queue.max_mem_use = self.args.flag_queue_max_size;
let mut service = ClientService::start(client_config, spec, net_settings, &Path::new(&self.path())).unwrap();
let mut service = ClientService::start(self.client_config(), spec, net_settings, &Path::new(&self.path())).unwrap();
panic_handler.forward_from(&service);
let client = service.client().clone();
client.set_author(self.author());
client.set_extra_data(self.extra_data());
let client = service.client();
// Miner
let miner = Miner::new();
miner.set_author(self.author());
miner.set_extra_data(self.extra_data());
miner.set_minimal_gas_price(self.gasprice());
// Sync
let sync = EthSync::register(service.network(), sync_config, client);
let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone());
// Secret Store
let account_service = Arc::new(AccountService::new());
@@ -456,11 +501,18 @@ impl Configuration {
let cors = self.args.flag_rpccorsdomain.as_ref().unwrap_or(&self.args.flag_jsonrpc_cors);
// TODO: use this as the API list.
let apis = self.args.flag_rpcapi.as_ref().unwrap_or(&self.args.flag_jsonrpc_apis);
let server_handler = setup_rpc_server(service.client(), sync.clone(), account_service.clone(), &url, cors, apis.split(',').collect());
let server_handler = setup_rpc_server(
service.client(),
sync.clone(),
account_service.clone(),
miner.clone(),
&url,
cors,
apis.split(',').collect()
);
if let Some(handler) = server_handler {
panic_handler.forward_from(handler.deref());
}
}
// Register IO handler
@@ -530,7 +582,11 @@ impl Informant {
let report = client.report();
let sync_info = sync.status();
if let (_, _, &Some(ref last_report)) = (self.chain_info.read().unwrap().deref(), self.cache_info.read().unwrap().deref(), self.report.read().unwrap().deref()) {
if let (_, _, &Some(ref last_report)) = (
self.chain_info.read().unwrap().deref(),
self.cache_info.read().unwrap().deref(),
self.report.read().unwrap().deref()
) {
println!("[ #{} {} ]---[ {} blk/s | {} tx/s | {} gas/s //··· {}/{} peers, #{}, {}+{} queued ···// mem: {} db, {} chain, {} queue, {} sync ]",
chain_info.best_block_number,
chain_info.best_block_hash,