--author and --extra-data options. Fixed null parent-hash.
This commit is contained in:
parent
1eca9acffb
commit
48df869202
@ -182,6 +182,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
r.block.base.header.set_author(author);
|
r.block.base.header.set_author(author);
|
||||||
r.block.base.header.set_extra_data(extra_data);
|
r.block.base.header.set_extra_data(extra_data);
|
||||||
r.block.base.header.set_timestamp_now(parent.timestamp());
|
r.block.base.header.set_timestamp_now(parent.timestamp());
|
||||||
|
r.block.base.header.set_parent_hash(parent.hash());
|
||||||
|
|
||||||
engine.populate_from_parent(&mut r.block.base.header, parent);
|
engine.populate_from_parent(&mut r.block.base.header, parent);
|
||||||
engine.on_new_block(&mut r.block);
|
engine.on_new_block(&mut r.block);
|
||||||
@ -308,10 +309,15 @@ impl ClosedBlock {
|
|||||||
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
s.block.base.header.set_seal(seal);
|
s.block.base.header.set_seal(seal);
|
||||||
match engine.verify_block_basic(&s.block.base.header, None).is_err() || engine.verify_block_unordered(&s.block.base.header, None).is_err() {
|
if let Err(e) = engine.verify_block_basic(&s.block.base.header, None) {
|
||||||
false => Err(s),
|
debug!("Failed to try_seal: {:?}", e);
|
||||||
true => Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }),
|
return Err(s);
|
||||||
}
|
}
|
||||||
|
if let Err(e) = engine.verify_block_unordered(&s.block.base.header, None) {
|
||||||
|
debug!("Failed to try_seal: {:?}", e);
|
||||||
|
return Err(s);
|
||||||
|
}
|
||||||
|
Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drop this object and return the underlieing database.
|
/// Drop this object and return the underlieing database.
|
||||||
|
@ -196,6 +196,8 @@ pub struct Client {
|
|||||||
|
|
||||||
// for sealing...
|
// for sealing...
|
||||||
sealing_block: Mutex<Option<ClosedBlock>>,
|
sealing_block: Mutex<Option<ClosedBlock>>,
|
||||||
|
author: RwLock<Address>,
|
||||||
|
extra_data: RwLock<Bytes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const HISTORY: u64 = 1000;
|
const HISTORY: u64 = 1000;
|
||||||
@ -233,6 +235,8 @@ impl Client {
|
|||||||
import_lock: Mutex::new(()),
|
import_lock: Mutex::new(()),
|
||||||
panic_handler: panic_handler,
|
panic_handler: panic_handler,
|
||||||
sealing_block: Mutex::new(None),
|
sealing_block: Mutex::new(None),
|
||||||
|
author: RwLock::new(Address::new()),
|
||||||
|
extra_data: RwLock::new(Vec::new()),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +368,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.chain_info().best_block_hash != original_best {
|
if self.chain_info().best_block_hash != original_best {
|
||||||
self.new_chain_head();
|
self.prepare_sealing();
|
||||||
}
|
}
|
||||||
|
|
||||||
imported
|
imported
|
||||||
@ -414,27 +418,55 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// New chain head event.
|
/// Set the author that we will seal blocks as.
|
||||||
pub fn new_chain_head(&self) {
|
pub fn author(&self) -> Address {
|
||||||
|
self.author.read().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the author that we will seal blocks as.
|
||||||
|
pub fn set_author(&self, author: Address) {
|
||||||
|
*self.author.write().unwrap() = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the extra_data that we will seal blocks wuth.
|
||||||
|
pub fn extra_data(&self) -> Bytes {
|
||||||
|
self.extra_data.read().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the extra_data that we will seal blocks with.
|
||||||
|
pub fn set_extra_data(&self, extra_data: Bytes) {
|
||||||
|
*self.extra_data.write().unwrap() = extra_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// New chain head event. Restart mining operation.
|
||||||
|
pub fn prepare_sealing(&self) {
|
||||||
let h = self.chain.read().unwrap().best_block_hash();
|
let h = self.chain.read().unwrap().best_block_hash();
|
||||||
debug!("New best block: #{}: {}", self.chain.read().unwrap().best_block_number(), h);
|
|
||||||
let b = OpenBlock::new(
|
let b = OpenBlock::new(
|
||||||
self.engine.deref().deref(),
|
self.engine.deref().deref(),
|
||||||
self.state_db.lock().unwrap().clone(),
|
self.state_db.lock().unwrap().clone(),
|
||||||
match self.chain.read().unwrap().block_header(&h) { Some(ref x) => x, None => {return;} },
|
match self.chain.read().unwrap().block_header(&h) { Some(ref x) => x, None => {return;} },
|
||||||
self.build_last_hashes(h.clone()),
|
self.build_last_hashes(h),
|
||||||
x!("0037a6b811ffeb6e072da21179d11b1406371c63"),
|
self.author(),
|
||||||
b"Parity".to_vec()
|
self.extra_data()
|
||||||
);
|
);
|
||||||
|
// TODO: push uncles.
|
||||||
|
// TODO: push transactions.
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
debug!("Sealing: hash={}, diff={}, number={}", b.hash(), b.block().header().difficulty(), b.block().header().number());
|
trace!("Sealing: number={}, hash={}, diff={}", b.hash(), b.block().header().difficulty(), b.block().header().number());
|
||||||
|
debug!("Header: {:?}", b.block().header());
|
||||||
*self.sealing_block.lock().unwrap() = Some(b);
|
*self.sealing_block.lock().unwrap() = Some(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
pub fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> { &self.sealing_block }
|
pub fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
|
||||||
|
if self.sealing_block.lock().unwrap().is_none() {
|
||||||
|
self.prepare_sealing();
|
||||||
|
}
|
||||||
|
&self.sealing_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.
|
||||||
pub fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error> {
|
pub fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error> {
|
||||||
let mut maybe_b = self.sealing_block.lock().unwrap();
|
let mut maybe_b = self.sealing_block.lock().unwrap();
|
||||||
match *maybe_b {
|
match *maybe_b {
|
||||||
|
@ -102,10 +102,12 @@ impl Header {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number field of the header.
|
/// Get the parent_hash field of the header.
|
||||||
pub fn number(&self) -> BlockNumber { self.number }
|
pub fn parent_hash(&self) -> &H256 { &self.parent_hash }
|
||||||
/// Get the timestamp field of the header.
|
/// Get the timestamp field of the header.
|
||||||
pub fn timestamp(&self) -> u64 { self.timestamp }
|
pub fn timestamp(&self) -> u64 { self.timestamp }
|
||||||
|
/// Get the number field of the header.
|
||||||
|
pub fn number(&self) -> BlockNumber { self.number }
|
||||||
/// Get the author field of the header.
|
/// Get the author field of the header.
|
||||||
pub fn author(&self) -> &Address { &self.author }
|
pub fn author(&self) -> &Address { &self.author }
|
||||||
|
|
||||||
@ -127,11 +129,13 @@ impl Header {
|
|||||||
// TODO: seal_at, set_seal_at &c.
|
// TODO: seal_at, set_seal_at &c.
|
||||||
|
|
||||||
/// Set the number field of the header.
|
/// Set the number field of the header.
|
||||||
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
|
pub fn set_parent_hash(&mut self, a: H256) { self.parent_hash = a; self.note_dirty(); }
|
||||||
/// Set the timestamp field of the header.
|
/// Set the timestamp field of the header.
|
||||||
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
|
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
|
||||||
/// Set the timestamp field of the header to the current time.
|
/// Set the timestamp field of the header to the current time.
|
||||||
pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(now_utc().to_timespec().sec as u64, but_later_than + 1); self.note_dirty(); }
|
pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(now_utc().to_timespec().sec as u64, but_later_than + 1); self.note_dirty(); }
|
||||||
|
/// Set the number field of the header.
|
||||||
|
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
|
||||||
/// Set the author field of the header.
|
/// Set the author field of the header.
|
||||||
pub fn set_author(&mut self, a: Address) { if a != self.author { self.author = a; self.note_dirty(); } }
|
pub fn set_author(&mut self, a: Address) { if a != self.author { self.author = a; self.note_dirty(); } }
|
||||||
|
|
||||||
|
@ -85,6 +85,10 @@ Options:
|
|||||||
--jsonrpc-url URL Specify URL for JSON-RPC API server [default: 127.0.0.1:8545].
|
--jsonrpc-url URL Specify URL for JSON-RPC API server [default: 127.0.0.1:8545].
|
||||||
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null].
|
--jsonrpc-cors URL Specify CORS header for JSON-RPC API responses [default: null].
|
||||||
|
|
||||||
|
--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.
|
||||||
|
|
||||||
-l --logging LOGGING Specify the logging level.
|
-l --logging LOGGING Specify the logging level.
|
||||||
-v --version Show information about version.
|
-v --version Show information about version.
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
@ -114,6 +118,8 @@ struct Args {
|
|||||||
flag_jsonrpc_cors: String,
|
flag_jsonrpc_cors: String,
|
||||||
flag_logging: Option<String>,
|
flag_logging: Option<String>,
|
||||||
flag_version: bool,
|
flag_version: bool,
|
||||||
|
flag_author: String,
|
||||||
|
flag_extra_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_log(init: &Option<String>) {
|
fn setup_log(init: &Option<String>) {
|
||||||
@ -196,6 +202,18 @@ impl Configuration {
|
|||||||
self.args.flag_db_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
|
self.args.flag_db_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn author(&self) -> Address {
|
||||||
|
Address::from_str(&self.args.flag_author).unwrap_or_else(|_| die!("{}: Invalid address for --author. Must be 40 hex characters, without the 0x at the beginning.", self.args.flag_author))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extra_data(&self) -> Bytes {
|
||||||
|
match self.args.flag_extra_data {
|
||||||
|
Some(ref x) if x.len() <= 32 => x.as_bytes().to_owned(),
|
||||||
|
None => version_data(),
|
||||||
|
Some(ref x) => { die!("{}: Extra data must be at most 32 characters.", x); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn _keys_path(&self) -> String {
|
fn _keys_path(&self) -> String {
|
||||||
self.args.flag_keys_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
|
self.args.flag_keys_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
|
||||||
}
|
}
|
||||||
@ -296,6 +314,8 @@ impl Configuration {
|
|||||||
client_config.queue.max_mem_use = self.args.flag_queue_max_size;
|
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(client_config, spec, net_settings, &Path::new(&self.path())).unwrap();
|
||||||
let client = service.client().clone();
|
let client = service.client().clone();
|
||||||
|
client.set_author(self.author());
|
||||||
|
client.set_extra_data(self.extra_data());
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
let sync = EthSync::register(service.network(), sync_config, client);
|
let sync = EthSync::register(service.network(), sync_config, client);
|
||||||
|
@ -236,12 +236,12 @@ impl Eth for EthClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn submit_work(&self, params: Params) -> Result<Value, Error> {
|
fn submit_work(&self, params: Params) -> Result<Value, Error> {
|
||||||
// TODO: println! should be debug!
|
|
||||||
println!("Work submission: {:?}", params);
|
|
||||||
from_params::<(H64, H256, H256)>(params).and_then(|(nonce, pow_hash, mix_hash)| {
|
from_params::<(H64, H256, H256)>(params).and_then(|(nonce, pow_hash, mix_hash)| {
|
||||||
|
// trace!("Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
|
||||||
let c = take_weak!(self.client);
|
let c = take_weak!(self.client);
|
||||||
let seal = vec![encode(&mix_hash).to_vec(), encode(&nonce).to_vec()];
|
let seal = vec![encode(&mix_hash).to_vec(), encode(&nonce).to_vec()];
|
||||||
to_value(&c.submit_seal(pow_hash, seal).is_ok())
|
let r = c.submit_seal(pow_hash, seal);
|
||||||
|
to_value(&r.is_ok())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use common::*;
|
use common::*;
|
||||||
|
use rlp::{Stream, RlpStream};
|
||||||
use target_info::Target;
|
use target_info::Target;
|
||||||
use rustc_version;
|
use rustc_version;
|
||||||
|
|
||||||
@ -70,4 +71,18 @@ pub fn contents(name: &str) -> Result<Bytes, UtilError> {
|
|||||||
/// Get the standard version string for this software.
|
/// Get the standard version string for this software.
|
||||||
pub fn version() -> String {
|
pub fn version() -> String {
|
||||||
format!("Parity//v{}-{}-{}/{}-{}-{}/rustc{}", env!("CARGO_PKG_VERSION"), short_sha(), commit_date().replace("-", ""), Target::arch(), Target::os(), Target::env(), rustc_version::version())
|
format!("Parity//v{}-{}-{}/{}-{}-{}/rustc{}", env!("CARGO_PKG_VERSION"), short_sha(), commit_date().replace("-", ""), Target::arch(), Target::os(), Target::env(), rustc_version::version())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the standard version data for this software.
|
||||||
|
pub fn version_data() -> Bytes {
|
||||||
|
let mut s = RlpStream::new_list(4);
|
||||||
|
let v =
|
||||||
|
(u32::from_str(env!("CARGO_PKG_VERSION_MAJOR")).unwrap() << 16) +
|
||||||
|
(u32::from_str(env!("CARGO_PKG_VERSION_MINOR")).unwrap() << 8) +
|
||||||
|
u32::from_str(env!("CARGO_PKG_VERSION_PATCH")).unwrap();
|
||||||
|
s.append(&v);
|
||||||
|
s.append(&"Parity");
|
||||||
|
s.append(&format!("rustc{}", rustc_version::version()));
|
||||||
|
s.append(&Target::os());
|
||||||
|
s.out()
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user