Merge branch 'master' of github.com:ethcore/parity into client_submodules
This commit is contained in:
@@ -283,7 +283,8 @@ impl<V> Client<V> where V: Verifier {
|
||||
.commit(header.number(), &header.hash(), ancient)
|
||||
.expect("State DB commit failed.");
|
||||
|
||||
// And update the chain
|
||||
// And update the chain after commit to prevent race conditions
|
||||
// (when something is in chain but you are not able to fetch details)
|
||||
self.chain.write().unwrap()
|
||||
.insert_block(&block.bytes, receipts);
|
||||
|
||||
@@ -409,39 +410,6 @@ impl<V> Client<V> where V: Verifier {
|
||||
trace!("Sealing: number={}, hash={}, diff={}", b.hash(), b.block().header().difficulty(), b.block().header().number());
|
||||
*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.
|
||||
pub fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
|
||||
if self.sealing_block.lock().unwrap().is_none() {
|
||||
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
|
||||
// TODO: Above should be on a timer that resets after two blocks have arrived without being asked for.
|
||||
self.prepare_sealing();
|
||||
}
|
||||
&self.sealing_block
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
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
|
||||
@@ -606,6 +574,39 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
|
||||
fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
|
||||
if self.sealing_block.lock().unwrap().is_none() {
|
||||
self.sealing_enabled.store(true, atomic::Ordering::Relaxed);
|
||||
// TODO: Above should be on a timer that resets after two blocks have arrived without being asked for.
|
||||
self.prepare_sealing();
|
||||
}
|
||||
&self.sealing_block
|
||||
}
|
||||
|
||||
/// 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, 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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MayPanic for Client {
|
||||
|
||||
@@ -26,16 +26,18 @@ pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
|
||||
pub use self::ids::{BlockId, TransactionId};
|
||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||
|
||||
use std::sync::Mutex;
|
||||
use util::bytes::Bytes;
|
||||
use util::hash::{Address, H256, H2048};
|
||||
use util::numbers::U256;
|
||||
use blockchain::TreeRoute;
|
||||
use block_queue::BlockQueueInfo;
|
||||
use block::ClosedBlock;
|
||||
use header::BlockNumber;
|
||||
use transaction::LocalizedTransaction;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use filter::Filter;
|
||||
use error::ImportResult;
|
||||
use error::{ImportResult, Error};
|
||||
|
||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||
pub trait BlockChainClient : Sync + Send {
|
||||
@@ -100,5 +102,12 @@ pub trait BlockChainClient : Sync + Send {
|
||||
|
||||
/// Returns logs matching given filter.
|
||||
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>;
|
||||
|
||||
/// Grab the `ClosedBlock` that we want to be sealed. Comes as a mutex that you have to lock.
|
||||
fn sealing_block(&self) -> &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, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,19 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//use std::mem;
|
||||
//use std::ops::{Deref, DerefMut};
|
||||
//use std::collections::HashMap;
|
||||
//use rustc_serialize::hex::FromHex;
|
||||
//use util::rlp;
|
||||
//use util::rlp::*;
|
||||
//use util::bytes::Bytes;
|
||||
//use util::hash::{FixedHash, Address, H256, H2048};
|
||||
//use util::numbers::{Uint, U256};
|
||||
//use util::crypto::KeyPair;
|
||||
//use util::sha3::Hashable;
|
||||
//! Test client.
|
||||
|
||||
use util::*;
|
||||
//use std::sync::RwLock;
|
||||
use transaction::{Transaction, LocalizedTransaction, Action};
|
||||
use blockchain::TreeRoute;
|
||||
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId};
|
||||
@@ -34,26 +24,39 @@ use header::{Header as BlockHeader, BlockNumber};
|
||||
use filter::Filter;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use receipt::Receipt;
|
||||
use error::ImportResult;
|
||||
use error::{ImportResult, Error};
|
||||
use block_queue::BlockQueueInfo;
|
||||
use block::ClosedBlock;
|
||||
|
||||
/// Test client.
|
||||
pub struct TestBlockChainClient {
|
||||
/// Blocks.
|
||||
pub blocks: RwLock<HashMap<H256, Bytes>>,
|
||||
/// Mapping of numbers to hashes.
|
||||
pub numbers: RwLock<HashMap<usize, H256>>,
|
||||
/// Genesis block hash.
|
||||
pub genesis_hash: H256,
|
||||
/// Last block hash.
|
||||
pub last_hash: RwLock<H256>,
|
||||
/// Difficulty.
|
||||
pub difficulty: RwLock<U256>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
/// Used for generating test client blocks.
|
||||
pub enum EachBlockWith {
|
||||
/// Plain block.
|
||||
Nothing,
|
||||
/// Block with an uncle.
|
||||
Uncle,
|
||||
/// Block with a transaction.
|
||||
Transaction,
|
||||
/// Block with an uncle and transaction.
|
||||
UncleAndTransaction
|
||||
}
|
||||
|
||||
impl TestBlockChainClient {
|
||||
/// Creates new test client.
|
||||
pub fn new() -> TestBlockChainClient {
|
||||
|
||||
let mut client = TestBlockChainClient {
|
||||
@@ -68,6 +71,7 @@ impl TestBlockChainClient {
|
||||
client
|
||||
}
|
||||
|
||||
/// Add blocks to test client.
|
||||
pub fn add_blocks(&mut self, count: usize, with: EachBlockWith) {
|
||||
let len = self.numbers.read().unwrap().len();
|
||||
for n in len..(len + count) {
|
||||
@@ -115,6 +119,7 @@ impl TestBlockChainClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO:
|
||||
pub fn corrupt_block(&mut self, n: BlockNumber) {
|
||||
let hash = self.block_hash(BlockId::Number(n)).unwrap();
|
||||
let mut header: BlockHeader = decode(&self.block_header(BlockId::Number(n)).unwrap());
|
||||
@@ -126,6 +131,7 @@ impl TestBlockChainClient {
|
||||
self.blocks.write().unwrap().insert(hash, rlp.out());
|
||||
}
|
||||
|
||||
/// TODO:
|
||||
pub fn block_hash_delta_minus(&mut self, delta: usize) -> H256 {
|
||||
let blocks_read = self.numbers.read().unwrap();
|
||||
let index = blocks_read.len() - delta;
|
||||
@@ -171,6 +177,14 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sealing_block(&self) -> &Mutex<Option<ClosedBlock>> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn submit_seal(&self, _pow_hash: H256, _seal: Vec<Bytes>) -> Result<(), Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user