Reorganised ImportError to be a type of Errpr (rather than vice-versa).
Added support for eth_submitWork.
This commit is contained in:
parent
ffc5c2ea7b
commit
394e9c679b
@ -21,7 +21,7 @@
|
|||||||
use common::*;
|
use common::*;
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use state::*;
|
use state::*;
|
||||||
use verification::PreVerifiedBlock;
|
use verification::PreverifiedBlock;
|
||||||
|
|
||||||
/// A block, encoded as it is on the block chain.
|
/// A block, encoded as it is on the block chain.
|
||||||
// TODO: rename to Block
|
// TODO: rename to Block
|
||||||
@ -302,6 +302,18 @@ impl ClosedBlock {
|
|||||||
Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes })
|
Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provide a valid seal in order to turn this into a `SealedBlock`.
|
||||||
|
/// This does check the validity of `seal` with the engine.
|
||||||
|
/// Returns the `ClosedBlock` back again if the seal is no good.
|
||||||
|
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
|
let mut s = self;
|
||||||
|
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() {
|
||||||
|
false => Err(s),
|
||||||
|
true => 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.
|
||||||
pub fn drain(self) -> JournalDB { self.block.state.drop().1 }
|
pub fn drain(self) -> JournalDB { self.block.state.drop().1 }
|
||||||
}
|
}
|
||||||
@ -350,7 +362,7 @@ pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, db: JournalDB, parent: &
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
pub fn enact_verified(block: &PreVerifiedBlock, engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||||
let view = BlockView::new(&block.bytes);
|
let view = BlockView::new(&block.bytes);
|
||||||
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
|
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ use service::*;
|
|||||||
use client::BlockStatus;
|
use client::BlockStatus;
|
||||||
use util::panics::*;
|
use util::panics::*;
|
||||||
|
|
||||||
known_heap_size!(0, UnVerifiedBlock, VerifyingBlock, PreVerifiedBlock);
|
known_heap_size!(0, UnverifiedBlock, VerifyingBlock, PreverifiedBlock);
|
||||||
|
|
||||||
const MIN_MEM_LIMIT: usize = 16384;
|
const MIN_MEM_LIMIT: usize = 16384;
|
||||||
const MIN_QUEUE_LIMIT: usize = 512;
|
const MIN_QUEUE_LIMIT: usize = 512;
|
||||||
@ -105,14 +105,14 @@ pub struct BlockQueue {
|
|||||||
max_mem_use: usize,
|
max_mem_use: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnVerifiedBlock {
|
struct UnverifiedBlock {
|
||||||
header: Header,
|
header: Header,
|
||||||
bytes: Bytes,
|
bytes: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VerifyingBlock {
|
struct VerifyingBlock {
|
||||||
hash: H256,
|
hash: H256,
|
||||||
block: Option<PreVerifiedBlock>,
|
block: Option<PreverifiedBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueueSignal {
|
struct QueueSignal {
|
||||||
@ -134,8 +134,8 @@ impl QueueSignal {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Verification {
|
struct Verification {
|
||||||
unverified: VecDeque<UnVerifiedBlock>,
|
unverified: VecDeque<UnverifiedBlock>,
|
||||||
verified: VecDeque<PreVerifiedBlock>,
|
verified: VecDeque<PreverifiedBlock>,
|
||||||
verifying: VecDeque<VerifyingBlock>,
|
verifying: VecDeque<VerifyingBlock>,
|
||||||
bad: HashSet<H256>,
|
bad: HashSet<H256>,
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ impl BlockQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain_verifying(verifying: &mut VecDeque<VerifyingBlock>, verified: &mut VecDeque<PreVerifiedBlock>, bad: &mut HashSet<H256>) {
|
fn drain_verifying(verifying: &mut VecDeque<VerifyingBlock>, verified: &mut VecDeque<PreverifiedBlock>, bad: &mut HashSet<H256>) {
|
||||||
while !verifying.is_empty() && verifying.front().unwrap().block.is_some() {
|
while !verifying.is_empty() && verifying.front().unwrap().block.is_some() {
|
||||||
let block = verifying.pop_front().unwrap().block.unwrap();
|
let block = verifying.pop_front().unwrap().block.unwrap();
|
||||||
if bad.contains(&block.header.parent_hash) {
|
if bad.contains(&block.header.parent_hash) {
|
||||||
@ -289,31 +289,31 @@ impl BlockQueue {
|
|||||||
let header = BlockView::new(&bytes).header();
|
let header = BlockView::new(&bytes).header();
|
||||||
let h = header.hash();
|
let h = header.hash();
|
||||||
if self.processing.read().unwrap().contains(&h) {
|
if self.processing.read().unwrap().contains(&h) {
|
||||||
return Err(ImportError::AlreadyQueued);
|
return Err(x!(ImportError::AlreadyQueued));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut verification = self.verification.lock().unwrap();
|
let mut verification = self.verification.lock().unwrap();
|
||||||
if verification.bad.contains(&h) {
|
if verification.bad.contains(&h) {
|
||||||
return Err(ImportError::Bad(None));
|
return Err(x!(ImportError::KnownBad));
|
||||||
}
|
}
|
||||||
|
|
||||||
if verification.bad.contains(&header.parent_hash) {
|
if verification.bad.contains(&header.parent_hash) {
|
||||||
verification.bad.insert(h.clone());
|
verification.bad.insert(h.clone());
|
||||||
return Err(ImportError::Bad(None));
|
return Err(x!(ImportError::KnownBad));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match verify_block_basic(&header, &bytes, self.engine.deref().deref()) {
|
match verify_block_basic(&header, &bytes, self.engine.deref().deref()) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
self.processing.write().unwrap().insert(h.clone());
|
self.processing.write().unwrap().insert(h.clone());
|
||||||
self.verification.lock().unwrap().unverified.push_back(UnVerifiedBlock { header: header, bytes: bytes });
|
self.verification.lock().unwrap().unverified.push_back(UnverifiedBlock { header: header, bytes: bytes });
|
||||||
self.more_to_verify.notify_all();
|
self.more_to_verify.notify_all();
|
||||||
Ok(h)
|
Ok(h)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "client", "Stage 1 block verification failed for {}\nError: {:?}", BlockView::new(&bytes).header_view().sha3(), err);
|
warn!(target: "client", "Stage 1 block verification failed for {}\nError: {:?}", BlockView::new(&bytes).header_view().sha3(), err);
|
||||||
self.verification.lock().unwrap().bad.insert(h.clone());
|
self.verification.lock().unwrap().bad.insert(h.clone());
|
||||||
Err(From::from(err))
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ impl BlockQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Removes up to `max` verified blocks from the queue
|
/// Removes up to `max` verified blocks from the queue
|
||||||
pub fn drain(&mut self, max: usize) -> Vec<PreVerifiedBlock> {
|
pub fn drain(&mut self, max: usize) -> Vec<PreverifiedBlock> {
|
||||||
let mut verification = self.verification.lock().unwrap();
|
let mut verification = self.verification.lock().unwrap();
|
||||||
let count = min(max, verification.verified.len());
|
let count = min(max, verification.verified.len());
|
||||||
let mut result = Vec::with_capacity(count);
|
let mut result = Vec::with_capacity(count);
|
||||||
|
@ -176,7 +176,7 @@ pub struct ClientReport {
|
|||||||
|
|
||||||
impl ClientReport {
|
impl ClientReport {
|
||||||
/// Alter internal reporting to reflect the additional `block` has been processed.
|
/// Alter internal reporting to reflect the additional `block` has been processed.
|
||||||
pub fn accrue_block(&mut self, block: &PreVerifiedBlock) {
|
pub fn accrue_block(&mut self, block: &PreverifiedBlock) {
|
||||||
self.blocks_imported += 1;
|
self.blocks_imported += 1;
|
||||||
self.transactions_applied += block.transactions.len();
|
self.transactions_applied += block.transactions.len();
|
||||||
self.gas_processed = self.gas_processed + block.header.gas_used;
|
self.gas_processed = self.gas_processed + block.header.gas_used;
|
||||||
@ -257,7 +257,7 @@ impl Client {
|
|||||||
last_hashes
|
last_hashes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_and_close_block(&self, block: &PreVerifiedBlock) -> Result<ClosedBlock, ()> {
|
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<ClosedBlock, ()> {
|
||||||
let engine = self.engine.deref().deref();
|
let engine = self.engine.deref().deref();
|
||||||
let header = &block.header;
|
let header = &block.header;
|
||||||
|
|
||||||
@ -433,6 +433,28 @@ impl Client {
|
|||||||
|
|
||||||
/// 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>> { &self.sealing_block }
|
||||||
|
|
||||||
|
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
||||||
|
pub fn submit_seal(&self, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error> {
|
||||||
|
let mut maybe_b = self.sealing_block.lock().unwrap();
|
||||||
|
match *maybe_b {
|
||||||
|
Some(ref b) if b.hash() == pow_hash => {}
|
||||||
|
_ => { return Err(Error::PowHashInvalid); }
|
||||||
|
}
|
||||||
|
|
||||||
|
let b = maybe_b.take();
|
||||||
|
match b.unwrap().try_seal(self.engine.deref().deref(), seal) {
|
||||||
|
Err(old) => {
|
||||||
|
*maybe_b = Some(old);
|
||||||
|
Err(Error::PowInvalid)
|
||||||
|
}
|
||||||
|
Ok(sealed) => {
|
||||||
|
// TODO: commit DB from `sealed.drain` and make a VerifiedBlock to skip running the transactions twice.
|
||||||
|
try!(self.import_block(sealed.rlp_bytes()));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need MinerService MinerIoHandler
|
// TODO: need MinerService MinerIoHandler
|
||||||
@ -509,12 +531,14 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn import_block(&self, bytes: Bytes) -> ImportResult {
|
fn import_block(&self, bytes: Bytes) -> ImportResult {
|
||||||
let header = BlockView::new(&bytes).header();
|
{
|
||||||
if self.chain.read().unwrap().is_known(&header.hash()) {
|
let header = BlockView::new(&bytes).header_view();
|
||||||
return Err(ImportError::AlreadyInChain);
|
if self.chain.read().unwrap().is_known(&header.sha3()) {
|
||||||
}
|
return Err(x!(ImportError::AlreadyInChain));
|
||||||
if self.block_status(BlockId::Hash(header.parent_hash)) == BlockStatus::Unknown {
|
}
|
||||||
return Err(ImportError::UnknownParent);
|
if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown {
|
||||||
|
return Err(x!(BlockError::UnknownParent(header.parent_hash())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.block_queue.write().unwrap().import_block(bytes)
|
self.block_queue.write().unwrap().import_block(bytes)
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ pub trait Engine : Sync + Send {
|
|||||||
|
|
||||||
/// The number of additional header fields required for this engine.
|
/// The number of additional header fields required for this engine.
|
||||||
fn seal_fields(&self) -> usize { 0 }
|
fn seal_fields(&self) -> usize { 0 }
|
||||||
/// Default values of the additional fields RLP-encoded in a raw (non-list) harness.
|
|
||||||
fn seal_rlp(&self) -> Bytes { vec![] }
|
|
||||||
|
|
||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||||
|
@ -131,25 +131,14 @@ pub enum BlockError {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Import to the block queue result
|
/// Import to the block queue result
|
||||||
pub enum ImportError {
|
pub enum ImportError {
|
||||||
/// Bad block detected
|
/// Already in the block chain.
|
||||||
Bad(Option<Error>),
|
|
||||||
/// Already in the block chain
|
|
||||||
AlreadyInChain,
|
AlreadyInChain,
|
||||||
/// Already in the block queue
|
/// Already in the block queue.
|
||||||
AlreadyQueued,
|
AlreadyQueued,
|
||||||
/// Unknown parent
|
/// Already marked as bad from a previous import (could mean parent is bad).
|
||||||
UnknownParent,
|
KnownBad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for ImportError {
|
|
||||||
fn from(err: Error) -> ImportError {
|
|
||||||
ImportError::Bad(Some(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of import block operation.
|
|
||||||
pub type ImportResult = Result<H256, ImportError>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// General error type which should be capable of representing all errors in ethcore.
|
/// General error type which should be capable of representing all errors in ethcore.
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -163,14 +152,29 @@ pub enum Error {
|
|||||||
Execution(ExecutionError),
|
Execution(ExecutionError),
|
||||||
/// Error concerning transaction processing.
|
/// Error concerning transaction processing.
|
||||||
Transaction(TransactionError),
|
Transaction(TransactionError),
|
||||||
|
/// Error concerning block import.
|
||||||
|
Import(ImportError),
|
||||||
|
/// PoW hash is invalid or out of date.
|
||||||
|
PowHashInvalid,
|
||||||
|
/// The value of the nonce or mishash is invalid.
|
||||||
|
PowInvalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Result of import block operation.
|
||||||
|
pub type ImportResult = Result<H256, Error>;
|
||||||
|
|
||||||
impl From<TransactionError> for Error {
|
impl From<TransactionError> for Error {
|
||||||
fn from(err: TransactionError) -> Error {
|
fn from(err: TransactionError) -> Error {
|
||||||
Error::Transaction(err)
|
Error::Transaction(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ImportError> for Error {
|
||||||
|
fn from(err: ImportError) -> Error {
|
||||||
|
Error::Import(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<BlockError> for Error {
|
impl From<BlockError> for Error {
|
||||||
fn from(err: BlockError) -> Error {
|
fn from(err: BlockError) -> Error {
|
||||||
Error::Block(err)
|
Error::Block(err)
|
||||||
|
@ -74,8 +74,6 @@ impl Engine for Ethash {
|
|||||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||||
// Two fields - mix
|
// Two fields - mix
|
||||||
fn seal_fields(&self) -> usize { 2 }
|
fn seal_fields(&self) -> usize { 2 }
|
||||||
// Two empty data items in RLP.
|
|
||||||
fn seal_rlp(&self) -> Bytes { encode(&H64::new()).to_vec() }
|
|
||||||
|
|
||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||||
@ -261,12 +259,15 @@ impl Ethash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
fn nonce(&self) -> H64 {
|
pub fn nonce(&self) -> H64 {
|
||||||
decode(&self.seal()[1])
|
decode(&self.seal()[1])
|
||||||
}
|
}
|
||||||
fn mix_hash(&self) -> H256 {
|
pub fn mix_hash(&self) -> H256 {
|
||||||
decode(&self.seal()[0])
|
decode(&self.seal()[0])
|
||||||
}
|
}
|
||||||
|
pub fn set_nonce_and_mix_hash(&mut self, nonce: &H64, mix_hash: &H256) {
|
||||||
|
self.seal = vec![encode(mix_hash).to_vec(), encode(nonce).to_vec()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -26,7 +26,7 @@ use engine::Engine;
|
|||||||
use blockchain::*;
|
use blockchain::*;
|
||||||
|
|
||||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||||
pub struct PreVerifiedBlock {
|
pub struct PreverifiedBlock {
|
||||||
/// Populated block header
|
/// Populated block header
|
||||||
pub header: Header,
|
pub header: Header,
|
||||||
/// Populated block transactions
|
/// Populated block transactions
|
||||||
@ -55,8 +55,8 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Res
|
|||||||
|
|
||||||
/// Phase 2 verification. Perform costly checks such as transaction signatures and block nonce for ethash.
|
/// Phase 2 verification. Perform costly checks such as transaction signatures and block nonce for ethash.
|
||||||
/// Still operates on a individual block
|
/// Still operates on a individual block
|
||||||
/// Returns a PreVerifiedBlock structure populated with transactions
|
/// Returns a PreverifiedBlock structure populated with transactions
|
||||||
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreVerifiedBlock, Error> {
|
pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) -> Result<PreverifiedBlock, Error> {
|
||||||
try!(engine.verify_block_unordered(&header, Some(&bytes)));
|
try!(engine.verify_block_unordered(&header, Some(&bytes)));
|
||||||
for u in Rlp::new(&bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
|
for u in Rlp::new(&bytes).at(2).iter().map(|rlp| rlp.as_val::<Header>()) {
|
||||||
try!(engine.verify_block_unordered(&u, None));
|
try!(engine.verify_block_unordered(&u, None));
|
||||||
@ -70,7 +70,7 @@ pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &Engine) ->
|
|||||||
transactions.push(t);
|
transactions.push(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(PreVerifiedBlock {
|
Ok(PreverifiedBlock {
|
||||||
header: header,
|
header: header,
|
||||||
transactions: transactions,
|
transactions: transactions,
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
|
@ -21,6 +21,7 @@ use jsonrpc_core::*;
|
|||||||
use util::hash::*;
|
use util::hash::*;
|
||||||
use util::uint::*;
|
use util::uint::*;
|
||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
|
use util::rlp::encode;
|
||||||
use ethcore::client::*;
|
use ethcore::client::*;
|
||||||
use ethcore::block::{IsBlock};
|
use ethcore::block::{IsBlock};
|
||||||
use ethcore::views::*;
|
use ethcore::views::*;
|
||||||
@ -221,10 +222,10 @@ impl Eth for EthClient {
|
|||||||
let u = c.sealing_block().lock().unwrap();
|
let u = c.sealing_block().lock().unwrap();
|
||||||
match *u {
|
match *u {
|
||||||
Some(ref b) => {
|
Some(ref b) => {
|
||||||
let current_hash = b.hash();
|
let pow_hash = b.hash();
|
||||||
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
||||||
let seed_hash = get_seedhash(b.block().header().number());
|
let seed_hash = get_seedhash(b.block().header().number());
|
||||||
to_value(&(current_hash, seed_hash, target))
|
to_value(&(pow_hash, seed_hash, target))
|
||||||
}
|
}
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
}
|
}
|
||||||
@ -233,7 +234,13 @@ impl Eth for EthClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn submit_work(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn submit_work(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
from_params::<(H64, H256, H256)>(params).and_then(|(nonce, pow_hash, mix_hash)| {
|
||||||
|
let c = take_weak!(self.client);
|
||||||
|
let seal = vec![encode(&mix_hash).to_vec(), encode(&nonce).to_vec()];
|
||||||
|
to_value(&c.submit_seal(pow_hash, seal).is_ok())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// fn submit_hashrate(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
// fn submit_hashrate(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
}
|
}
|
||||||
|
@ -477,19 +477,19 @@ impl ChainSync {
|
|||||||
// TODO: Decompose block and add to self.headers and self.bodies instead
|
// TODO: Decompose block and add to self.headers and self.bodies instead
|
||||||
if header.number == From::from(self.current_base_block() + 1) {
|
if header.number == From::from(self.current_base_block() + 1) {
|
||||||
match io.chain().import_block(block_rlp.as_raw().to_vec()) {
|
match io.chain().import_block(block_rlp.as_raw().to_vec()) {
|
||||||
Err(ImportError::AlreadyInChain) => {
|
Err(Error::Import(ImportError::AlreadyInChain)) => {
|
||||||
trace!(target: "sync", "New block already in chain {:?}", h);
|
trace!(target: "sync", "New block already in chain {:?}", h);
|
||||||
},
|
},
|
||||||
Err(ImportError::AlreadyQueued) => {
|
Err(Error::Import(ImportError::AlreadyQueued)) => {
|
||||||
trace!(target: "sync", "New block already queued {:?}", h);
|
trace!(target: "sync", "New block already queued {:?}", h);
|
||||||
},
|
},
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
self.last_imported_block = Some(header.number);
|
self.last_imported_block = Some(header.number);
|
||||||
trace!(target: "sync", "New block queued {:?}", h);
|
trace!(target: "sync", "New block queued {:?}", h);
|
||||||
},
|
},
|
||||||
Err(ImportError::UnknownParent) => {
|
Err(Error::Block(BlockError::UnknownParent(p))) => {
|
||||||
unknown = true;
|
unknown = true;
|
||||||
trace!(target: "sync", "New block with unknown parent {:?}", h);
|
trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h);
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!(target: "sync", "Bad new block {:?} : {:?}", h, e);
|
debug!(target: "sync", "Bad new block {:?} : {:?}", h, e);
|
||||||
@ -781,12 +781,12 @@ impl ChainSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match io.chain().import_block(block_rlp.out()) {
|
match io.chain().import_block(block_rlp.out()) {
|
||||||
Err(ImportError::AlreadyInChain) => {
|
Err(Error::Import(ImportError::AlreadyInChain)) => {
|
||||||
trace!(target: "sync", "Block already in chain {:?}", h);
|
trace!(target: "sync", "Block already in chain {:?}", h);
|
||||||
self.last_imported_block = Some(headers.0 + i as BlockNumber);
|
self.last_imported_block = Some(headers.0 + i as BlockNumber);
|
||||||
self.last_imported_hash = Some(h.clone());
|
self.last_imported_hash = Some(h.clone());
|
||||||
},
|
},
|
||||||
Err(ImportError::AlreadyQueued) => {
|
Err(Error::Import(ImportError::AlreadyQueued)) => {
|
||||||
trace!(target: "sync", "Block already queued {:?}", h);
|
trace!(target: "sync", "Block already queued {:?}", h);
|
||||||
self.last_imported_block = Some(headers.0 + i as BlockNumber);
|
self.last_imported_block = Some(headers.0 + i as BlockNumber);
|
||||||
self.last_imported_hash = Some(h.clone());
|
self.last_imported_hash = Some(h.clone());
|
||||||
|
Loading…
Reference in New Issue
Block a user