Extract blockchain from ethcore (#10114)

* Split blockchain & db from ethcore.

* Clean up blockchain deps.

* Missing docs.

* Fix blockchain tests.

* Make other crates compile.

* Remove some re-exports.

* Remove types re-export from ethcore.

* Remove EVM dependency from transaction.

* Merge ethcore-transaction with common-types.

* Clean-up ethcore deps a bit.

* remove ethcore from cargo.toml

* Update ethcore/blockchain/src/lib.rs

Co-Authored-By: tomusdrw <tomusdrw@users.noreply.github.com>

* Address review comments.

* Update DB comment.

* Add tracking issue to the TODO and fix typo.

* Common naming for common types.

* Update ethcore/db/src/keys.rs

Co-Authored-By: tomusdrw <tomusdrw@users.noreply.github.com>

* Update ethcore/blockchain/src/generator.rs

Co-Authored-By: tomusdrw <tomusdrw@users.noreply.github.com>

* Try to fix beta tests.
This commit is contained in:
Tomasz Drwięga
2019-01-04 14:05:46 +01:00
committed by Afri Schoedon
parent 3090324366
commit 3650f2d51c
223 changed files with 1428 additions and 1058 deletions

View File

@@ -32,11 +32,11 @@ use ethstore::{
random_string, SecretVaultRef, StoreAccountRef, OpaqueSecret,
};
use parking_lot::RwLock;
use types::transaction::{Action, Transaction};
pub use ethstore::ethkey::Signature;
pub use ethstore::{Derivation, IndexDerivation, KeyFile};
pub use hardware_wallet::{Error as HardwareError, HardwareWalletManager, KeyPath, TransactionInfo};
pub use super::transaction::{Action, Transaction};
/// Type of unlock.
#[derive(Clone, PartialEq)]

View File

@@ -36,59 +36,58 @@ use std::collections::HashSet;
use std::sync::Arc;
use bytes::Bytes;
use ethereum_types::{H256, U256, Address, Bloom};
use engines::EthEngine;
use error::{Error, BlockError};
use ethereum_types::{H256, U256, Address, Bloom};
use factory::Factories;
use hash::keccak;
use header::{Header, ExtendedHeader};
use receipt::{Receipt, TransactionOutcome};
use rlp::{Rlp, RlpStream, Encodable, Decodable, DecoderError, encode_list};
use state_db::StateDB;
use state::State;
use trace::Tracing;
use transaction::{UnverifiedTransaction, SignedTransaction, Error as TransactionError};
use triehash::ordered_trie_root;
use unexpected::{Mismatch, OutOfBounds};
use verification::PreverifiedBlock;
use vm::{EnvInfo, LastHashes};
/// A block, encoded as it is on the block chain.
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Block {
/// The header of this block.
pub header: Header,
/// The transactions in this block.
pub transactions: Vec<UnverifiedTransaction>,
/// The uncles of this block.
pub uncles: Vec<Header>,
use hash::keccak;
use rlp::{RlpStream, Encodable, encode_list};
use types::transaction::{SignedTransaction, Error as TransactionError};
use types::block::Block;
use types::header::{Header, ExtendedHeader};
use types::receipt::{Receipt, TransactionOutcome};
/// Block that is ready for transactions to be added.
///
/// It's a bit like a Vec<Transaction>, except that whenever a transaction is pushed, we execute it and
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
pub struct OpenBlock<'x> {
block: ExecutedBlock,
engine: &'x EthEngine,
}
impl Block {
/// Get the RLP-encoding of the block with the seal.
pub fn rlp_bytes(&self) -> Bytes {
let mut block_rlp = RlpStream::new_list(3);
block_rlp.append(&self.header);
block_rlp.append_list(&self.transactions);
block_rlp.append_list(&self.uncles);
block_rlp.out()
}
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// and collected the uncles.
///
/// There is no function available to push a transaction.
#[derive(Clone)]
pub struct ClosedBlock {
block: ExecutedBlock,
unclosed_state: State<StateDB>,
}
impl Decodable for Block {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
if rlp.as_raw().len() != rlp.payload_info()?.total() {
return Err(DecoderError::RlpIsTooBig);
}
if rlp.item_count()? != 3 {
return Err(DecoderError::RlpIncorrectListLen);
}
Ok(Block {
header: rlp.val_at(0)?,
transactions: rlp.list_at(1)?,
uncles: rlp.list_at(2)?,
})
}
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
///
/// We actually store the post-`Engine::on_close_block` state, unlike in `ClosedBlock` where it's the pre.
#[derive(Clone)]
pub struct LockedBlock {
block: ExecutedBlock,
}
/// A block that has a valid seal.
///
/// The block's header has valid seal arguments. The block cannot be reversed into a `ClosedBlock` or `OpenBlock`.
pub struct SealedBlock {
block: ExecutedBlock,
}
/// An internal type for a block's common elements.
@@ -216,40 +215,6 @@ impl ::parity_machine::Transactions for ExecutedBlock {
}
}
/// Block that is ready for transactions to be added.
///
/// It's a bit like a Vec<Transaction>, except that whenever a transaction is pushed, we execute it and
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
pub struct OpenBlock<'x> {
block: ExecutedBlock,
engine: &'x EthEngine,
}
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
/// and collected the uncles.
///
/// There is no function available to push a transaction.
#[derive(Clone)]
pub struct ClosedBlock {
block: ExecutedBlock,
unclosed_state: State<StateDB>,
}
/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
///
/// We actually store the post-`Engine::on_close_block` state, unlike in `ClosedBlock` where it's the pre.
#[derive(Clone)]
pub struct LockedBlock {
block: ExecutedBlock,
}
/// A block that has a valid seal.
///
/// The block's header has valid seal arguments. The block cannot be reversed into a `ClosedBlock` or `OpenBlock`.
pub struct SealedBlock {
block: ExecutedBlock,
}
impl<'x> OpenBlock<'x> {
/// Create a new `OpenBlock` ready for transaction pushing.
pub fn new<'a>(
@@ -630,14 +595,15 @@ mod tests {
use engines::EthEngine;
use vm::LastHashes;
use error::Error;
use header::Header;
use factory::Factories;
use state_db::StateDB;
use views::BlockView;
use ethereum_types::Address;
use std::sync::Arc;
use transaction::SignedTransaction;
use verification::queue::kind::blocks::Unverified;
use types::transaction::SignedTransaction;
use types::header::Header;
use types::view;
use types::views::BlockView;
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
fn enact_bytes(

View File

@@ -1,44 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H256, U256};
use encoded;
use header::{Header, BlockNumber};
/// Contains information on a best block that is specific to the consensus engine.
///
/// For GHOST fork-choice rule it would typically describe the block with highest
/// combined difficulty (usually the block with the highest block number).
///
/// Sometimes refered as 'latest block'.
pub struct BestBlock {
/// Best block decoded header.
pub header: Header,
/// Best block uncompressed bytes.
pub block: encoded::Block,
/// Best block total difficulty.
pub total_difficulty: U256,
}
/// Best ancient block info. If the blockchain has a gap this keeps track of where it starts.
#[derive(Default)]
pub struct BestAncientBlock {
/// Best block hash.
pub hash: H256,
/// Best block number.
pub number: BlockNumber,
}

View File

@@ -1,54 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::{H256, U256};
use header::BlockNumber;
/// Brief info about inserted block.
#[derive(Clone)]
pub struct BlockInfo {
/// Block hash.
pub hash: H256,
/// Block number.
pub number: BlockNumber,
/// Total block difficulty.
pub total_difficulty: U256,
/// Block location in blockchain.
pub location: BlockLocation
}
/// Describes location of newly inserted block.
#[derive(Debug, Clone, PartialEq)]
pub enum BlockLocation {
/// It's part of the canon chain.
CanonChain,
/// It's not a part of the canon chain.
Branch,
/// It's part of the fork which should become canon chain,
/// because its total difficulty is higher than current
/// canon chain difficulty.
BranchBecomingCanonChain(BranchBecomingCanonChainData),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BranchBecomingCanonChainData {
/// Hash of the newest common ancestor with old canon chain.
pub ancestor: H256,
/// Hashes of the blocks between ancestor and this block.
pub enacted: Vec<H256>,
/// Hashes of the blocks which were invalidated.
pub retracted: Vec<H256>,
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
/// Represents blockchain's in-memory cache size in bytes.
#[derive(Debug)]
pub struct CacheSize {
/// Blocks cache size.
pub blocks: usize,
/// BlockDetails cache size.
pub block_details: usize,
/// Transaction addresses cache size.
pub transaction_addresses: usize,
/// Block receipts size.
pub block_receipts: usize,
}
impl CacheSize {
/// Total amount used by the cache.
pub fn total(&self) -> usize {
self.blocks + self.block_details + self.transaction_addresses + self.block_receipts
}
}

View File

@@ -1,35 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain configuration.
/// Blockchain configuration.
#[derive(Debug, PartialEq, Clone)]
pub struct Config {
/// Preferred cache size in bytes.
pub pref_cache_size: usize,
/// Maximum cache size in bytes.
pub max_cache_size: usize,
}
impl Default for Config {
fn default() -> Self {
Config {
pref_cache_size: 1 << 14,
max_cache_size: 1 << 20,
}
}
}

View File

@@ -1,261 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain DB extras.
use std::io::Write;
use std::ops;
use db::Key;
use engines::epoch::{Transition as EpochTransition};
use ethereum_types::{H256, H264, U256};
use header::BlockNumber;
use heapsize::HeapSizeOf;
use kvdb::PREFIX_LEN as DB_PREFIX_LEN;
use receipt::Receipt;
use rlp;
/// Represents index of extra data in database
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
pub enum ExtrasIndex {
/// Block details index
BlockDetails = 0,
/// Block hash index
BlockHash = 1,
/// Transaction address index
TransactionAddress = 2,
/// Block receipts index
BlockReceipts = 4,
/// Epoch transition data index.
EpochTransitions = 5,
/// Pending epoch transition data index.
PendingEpochTransition = 6,
}
fn with_index(hash: &H256, i: ExtrasIndex) -> H264 {
let mut result = H264::default();
result[0] = i as u8;
(*result)[1..].clone_from_slice(hash);
result
}
pub struct BlockNumberKey([u8; 5]);
impl ops::Deref for BlockNumberKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Key<H256> for BlockNumber {
type Target = BlockNumberKey;
fn key(&self) -> Self::Target {
let mut result = [0u8; 5];
result[0] = ExtrasIndex::BlockHash as u8;
result[1] = (self >> 24) as u8;
result[2] = (self >> 16) as u8;
result[3] = (self >> 8) as u8;
result[4] = *self as u8;
BlockNumberKey(result)
}
}
impl Key<BlockDetails> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::BlockDetails)
}
}
impl Key<TransactionAddress> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::TransactionAddress)
}
}
impl Key<BlockReceipts> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::BlockReceipts)
}
}
impl Key<::engines::epoch::PendingTransition> for H256 {
type Target = H264;
fn key(&self) -> H264 {
with_index(self, ExtrasIndex::PendingEpochTransition)
}
}
/// length of epoch keys.
pub const EPOCH_KEY_LEN: usize = DB_PREFIX_LEN + 16;
/// epoch key prefix.
/// used to iterate over all epoch transitions in order from genesis.
pub const EPOCH_KEY_PREFIX: &'static [u8; DB_PREFIX_LEN] = &[
ExtrasIndex::EpochTransitions as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub struct EpochTransitionsKey([u8; EPOCH_KEY_LEN]);
impl ops::Deref for EpochTransitionsKey {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] }
}
impl Key<EpochTransitions> for u64 {
type Target = EpochTransitionsKey;
fn key(&self) -> Self::Target {
let mut arr = [0u8; EPOCH_KEY_LEN];
arr[..DB_PREFIX_LEN].copy_from_slice(&EPOCH_KEY_PREFIX[..]);
write!(&mut arr[DB_PREFIX_LEN..], "{:016x}", self)
.expect("format arg is valid; no more than 16 chars will be written; qed");
EpochTransitionsKey(arr)
}
}
/// Familial details concerning a block
#[derive(Debug, Clone)]
pub struct BlockDetails {
/// Block number
pub number: BlockNumber,
/// Total difficulty of the block and all its parents
pub total_difficulty: U256,
/// Parent block hash
pub parent: H256,
/// List of children block hashes
pub children: Vec<H256>,
/// Whether the block is considered finalized
pub is_finalized: bool,
}
impl rlp::Encodable for BlockDetails {
fn rlp_append(&self, stream: &mut rlp::RlpStream) {
let use_short_version = !self.is_finalized;
match use_short_version {
true => { stream.begin_list(4); },
false => { stream.begin_list(5); },
}
stream.append(&self.number);
stream.append(&self.total_difficulty);
stream.append(&self.parent);
stream.append_list(&self.children);
if !use_short_version {
stream.append(&self.is_finalized);
}
}
}
impl rlp::Decodable for BlockDetails {
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
let use_short_version = match rlp.item_count()? {
4 => true,
5 => false,
_ => return Err(rlp::DecoderError::RlpIncorrectListLen),
};
Ok(BlockDetails {
number: rlp.val_at(0)?,
total_difficulty: rlp.val_at(1)?,
parent: rlp.val_at(2)?,
children: rlp.list_at(3)?,
is_finalized: if use_short_version {
false
} else {
rlp.val_at(4)?
},
})
}
}
impl HeapSizeOf for BlockDetails {
fn heap_size_of_children(&self) -> usize {
self.children.heap_size_of_children()
}
}
/// Represents address of certain transaction within block
#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct TransactionAddress {
/// Block hash
pub block_hash: H256,
/// Transaction index within the block
pub index: usize
}
impl HeapSizeOf for TransactionAddress {
fn heap_size_of_children(&self) -> usize { 0 }
}
/// Contains all block receipts.
#[derive(Clone, RlpEncodableWrapper, RlpDecodableWrapper)]
pub struct BlockReceipts {
pub receipts: Vec<Receipt>,
}
impl BlockReceipts {
pub fn new(receipts: Vec<Receipt>) -> Self {
BlockReceipts {
receipts: receipts
}
}
}
impl HeapSizeOf for BlockReceipts {
fn heap_size_of_children(&self) -> usize {
self.receipts.heap_size_of_children()
}
}
/// Candidate transitions to an epoch with specific number.
#[derive(Clone, RlpEncodable, RlpDecodable)]
pub struct EpochTransitions {
pub number: u64,
pub candidates: Vec<EpochTransition>,
}
#[cfg(test)]
mod tests {
use rlp::*;
use super::BlockReceipts;
#[test]
fn encode_block_receipts() {
let br = BlockReceipts::new(Vec::new());
let mut s = RlpStream::new_list(2);
s.append(&br);
assert!(!s.is_finished(), "List shouldn't finished yet");
s.append(&br);
assert!(s.is_finished(), "List should be finished now");
s.out();
}
}

View File

@@ -1,223 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain generator for tests.
use std::collections::VecDeque;
use ethereum_types::{U256, H256, Bloom};
use header::Header;
use rlp::encode;
use transaction::SignedTransaction;
use views::BlockView;
use encoded;
/// Helper structure, used for encoding blocks.
#[derive(Default, Clone, RlpEncodable)]
pub struct Block {
pub header: Header,
pub transactions: Vec<SignedTransaction>,
pub uncles: Vec<Header>
}
impl Block {
#[inline]
pub fn header(&self) -> Header {
self.header.clone()
}
#[inline]
pub fn hash(&self) -> H256 {
view!(BlockView, &self.encoded().raw()).header_view().hash()
}
#[inline]
pub fn number(&self) -> u64 {
self.header.number()
}
#[inline]
pub fn encoded(&self) -> encoded::Block {
encoded::Block::new(encode(self))
}
#[inline]
pub fn difficulty(&self) -> U256 {
*self.header.difficulty()
}
}
#[derive(Debug)]
pub struct BlockOptions {
pub difficulty: U256,
pub bloom: Bloom,
pub transactions: Vec<SignedTransaction>,
}
impl Default for BlockOptions {
fn default() -> Self {
BlockOptions {
difficulty: 10.into(),
bloom: Bloom::default(),
transactions: Vec::new(),
}
}
}
#[derive(Clone)]
pub struct BlockBuilder {
blocks: VecDeque<Block>,
}
impl BlockBuilder {
pub fn genesis() -> Self {
let mut blocks = VecDeque::with_capacity(1);
blocks.push_back(Block::default());
BlockBuilder {
blocks,
}
}
#[inline]
pub fn add_block(&self) -> Self {
self.add_block_with(|| BlockOptions::default())
}
#[inline]
pub fn add_blocks(&self, count: usize) -> Self {
self.add_blocks_with(count, || BlockOptions::default())
}
#[inline]
pub fn add_block_with<T>(&self, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
self.add_blocks_with(1, get_metadata)
}
#[inline]
pub fn add_block_with_difficulty<T>(&self, difficulty: T) -> Self where T: Into<U256> {
let difficulty = difficulty.into();
self.add_blocks_with(1, move || BlockOptions {
difficulty,
..Default::default()
})
}
#[inline]
pub fn add_block_with_transactions<T>(&self, transactions: T) -> Self
where T: IntoIterator<Item = SignedTransaction> {
let transactions = transactions.into_iter().collect::<Vec<_>>();
self.add_blocks_with(1, || BlockOptions {
transactions: transactions.clone(),
..Default::default()
})
}
#[inline]
pub fn add_block_with_bloom(&self, bloom: Bloom) -> Self {
self.add_blocks_with(1, move || BlockOptions {
bloom,
..Default::default()
})
}
pub fn add_blocks_with<T>(&self, count: usize, get_metadata: T) -> Self where T: Fn() -> BlockOptions {
assert!(count > 0, "There must be at least 1 block");
let mut parent_hash = self.last().hash();
let mut parent_number = self.last().number();
let mut blocks = VecDeque::with_capacity(count);
for _ in 0..count {
let mut block = Block::default();
let metadata = get_metadata();
let block_number = parent_number + 1;
block.header.set_parent_hash(parent_hash);
block.header.set_number(block_number);
block.header.set_log_bloom(metadata.bloom);
block.header.set_difficulty(metadata.difficulty);
block.transactions = metadata.transactions;
parent_hash = block.hash();
parent_number = block_number;
blocks.push_back(block);
}
BlockBuilder {
blocks,
}
}
#[inline]
pub fn last(&self) -> &Block {
self.blocks.back().expect("There is always at least 1 block")
}
}
#[derive(Clone)]
pub struct BlockGenerator {
builders: VecDeque<BlockBuilder>,
}
impl BlockGenerator {
pub fn new<T>(builders: T) -> Self where T: IntoIterator<Item = BlockBuilder> {
BlockGenerator {
builders: builders.into_iter().collect(),
}
}
}
impl Iterator for BlockGenerator {
type Item = Block;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.builders.front_mut() {
Some(ref mut builder) => {
if let Some(block) = builder.blocks.pop_front() {
return Some(block);
}
},
None => return None,
}
self.builders.pop_front();
}
}
}
#[cfg(test)]
mod tests {
use super::{BlockBuilder, BlockOptions, BlockGenerator};
#[test]
fn test_block_builder() {
let genesis = BlockBuilder::genesis();
let block_1 = genesis.add_block();
let block_1001 = block_1.add_blocks(1000);
let block_1002 = block_1001.add_block_with(|| BlockOptions::default());
let generator = BlockGenerator::new(vec![genesis, block_1, block_1001, block_1002]);
assert_eq!(generator.count(), 1003);
}
#[test]
fn test_block_builder_fork() {
let genesis = BlockBuilder::genesis();
let block_10a = genesis.add_blocks(10);
let block_11b = genesis.add_blocks(11);
assert_eq!(block_10a.last().number(), 10);
assert_eq!(block_11b.last().number(), 11);
}
}

View File

@@ -1,134 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Import route.
use ethereum_types::H256;
use blockchain::block_info::{BlockInfo, BlockLocation};
/// Import route for newly inserted block.
#[derive(Debug, PartialEq, Clone)]
pub struct ImportRoute {
/// Blocks that were invalidated by new block.
pub retracted: Vec<H256>,
/// Blocks that were validated by new block.
pub enacted: Vec<H256>,
/// Blocks which are neither retracted nor enacted.
pub omitted: Vec<H256>,
}
impl ImportRoute {
pub fn none() -> Self {
ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![],
}
}
}
impl From<BlockInfo> for ImportRoute {
fn from(info: BlockInfo) -> ImportRoute {
match info.location {
BlockLocation::CanonChain => ImportRoute {
retracted: vec![],
enacted: vec![info.hash],
omitted: vec![],
},
BlockLocation::Branch => ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![info.hash],
},
BlockLocation::BranchBecomingCanonChain(mut data) => {
data.enacted.push(info.hash);
ImportRoute {
retracted: data.retracted,
enacted: data.enacted,
omitted: vec![],
}
}
}
}
}
#[cfg(test)]
mod tests {
use ethereum_types::{H256, U256};
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
use blockchain::ImportRoute;
#[test]
fn import_route_none() {
assert_eq!(ImportRoute::none(), ImportRoute {
enacted: vec![],
retracted: vec![],
omitted: vec![],
});
}
#[test]
fn import_route_branch() {
let info = BlockInfo {
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::Branch,
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![],
omitted: vec![H256::from(U256::from(1))],
});
}
#[test]
fn import_route_canon_chain() {
let info = BlockInfo {
hash: H256::from(U256::from(1)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::CanonChain,
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![],
enacted: vec![H256::from(U256::from(1))],
omitted: vec![],
});
}
#[test]
fn import_route_branch_becoming_canon_chain() {
let info = BlockInfo {
hash: H256::from(U256::from(2)),
number: 0,
total_difficulty: U256::from(0),
location: BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
ancestor: H256::from(U256::from(0)),
enacted: vec![H256::from(U256::from(1))],
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
})
};
assert_eq!(ImportRoute::from(info), ImportRoute {
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
enacted: vec![H256::from(U256::from(1)), H256::from(U256::from(2))],
omitted: vec![],
});
}
}

View File

@@ -1,37 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Blockchain database.
mod best_block;
mod block_info;
mod blockchain;
mod cache;
mod config;
mod extras;
mod import_route;
mod update;
#[cfg(test)]
pub mod generator;
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainDB, BlockChainDBHandler};
pub use self::cache::CacheSize;
pub use self::config::Config;
pub use self::extras::{BlockReceipts, BlockDetails, TransactionAddress};
pub use self::import_route::ImportRoute;
pub use self::update::ExtrasInsert;
pub use types::tree_route::TreeRoute;

View File

@@ -1,48 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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::collections::HashMap;
use ethereum_types::{H256, Bloom};
use header::BlockNumber;
use blockchain::block_info::BlockInfo;
use blockchain::extras::{BlockDetails, BlockReceipts, TransactionAddress};
use encoded::Block;
/// Block extras update info.
pub struct ExtrasUpdate {
/// Block info.
pub info: BlockInfo,
/// Current block uncompressed rlp bytes
pub block: Block,
/// Modified block hashes.
pub block_hashes: HashMap<BlockNumber, H256>,
/// Modified block details.
pub block_details: HashMap<H256, BlockDetails>,
/// Modified block receipts.
pub block_receipts: HashMap<H256, BlockReceipts>,
/// Modified blocks blooms.
pub blocks_blooms: Option<(u64, Vec<Bloom>)>,
/// Modified transaction addresses (None signifies removed transactions).
pub transactions_addresses: HashMap<H256, Option<TransactionAddress>>,
}
/// Extra information in block insertion.
pub struct ExtrasInsert {
/// The primitive fork choice before applying finalization rules.
pub fork_choice: ::engines::ForkChoice,
/// Is the inserted block considered finalized.
pub is_finalized: bool,
}

View File

@@ -1,77 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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::collections::{VecDeque, HashSet};
use std::hash::Hash;
const COLLECTION_QUEUE_SIZE: usize = 8;
pub struct CacheManager<T> {
pref_cache_size: usize,
max_cache_size: usize,
bytes_per_cache_entry: usize,
cache_usage: VecDeque<HashSet<T>>
}
impl<T> CacheManager<T> where T: Eq + Hash {
pub fn new(pref_cache_size: usize, max_cache_size: usize, bytes_per_cache_entry: usize) -> Self {
CacheManager {
pref_cache_size: pref_cache_size,
max_cache_size: max_cache_size,
bytes_per_cache_entry: bytes_per_cache_entry,
cache_usage: (0..COLLECTION_QUEUE_SIZE).into_iter().map(|_| Default::default()).collect(),
}
}
pub fn note_used(&mut self, id: T) {
if !self.cache_usage[0].contains(&id) {
if let Some(c) = self.cache_usage.iter_mut().skip(1).find(|e| e.contains(&id)) {
c.remove(&id);
}
self.cache_usage[0].insert(id);
}
}
/// Collects unused objects from cache.
/// First params is the current size of the cache.
/// Second one is an with objects to remove. It should also return new size of the cache.
pub fn collect_garbage<F>(&mut self, current_size: usize, mut notify_unused: F) where F: FnMut(HashSet<T>) -> usize {
if current_size < self.pref_cache_size {
self.rotate_cache_if_needed();
return;
}
for _ in 0..COLLECTION_QUEUE_SIZE {
if let Some(back) = self.cache_usage.pop_back() {
let current_size = notify_unused(back);
self.cache_usage.push_front(Default::default());
if current_size < self.max_cache_size {
break
}
}
}
}
fn rotate_cache_if_needed(&mut self) {
if self.cache_usage.is_empty() { return }
if self.cache_usage[0].len() * self.bytes_per_cache_entry > self.pref_cache_size / COLLECTION_QUEUE_SIZE {
if let Some(cache) = self.cache_usage.pop_back() {
self.cache_usage.push_front(cache);
}
}
}
}

View File

@@ -18,13 +18,13 @@
use std::sync::Arc;
use blockchain::BlockChain;
use engines::{EthEngine, EpochVerifier};
use header::Header;
use machine::EthereumMachine;
use rand::Rng;
use blockchain::BlockChain;
use parking_lot::RwLock;
use rand::Rng;
use types::header::Header;
// do "heavy" verification on ~1/50 blocks, randomly sampled.
const HEAVY_VERIFY_RATE: f32 = 0.02;

View File

@@ -16,7 +16,7 @@
use bytes::Bytes;
use ethereum_types::{H256, U256};
use transaction::UnverifiedTransaction;
use types::transaction::UnverifiedTransaction;
use blockchain::ImportRoute;
use std::time::Duration;
use std::collections::HashMap;

View File

@@ -14,25 +14,36 @@
// 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::collections::{HashSet, BTreeMap, VecDeque};
use std::cmp;
use std::collections::{HashSet, BTreeMap, VecDeque};
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::sync::{Arc, Weak};
use std::time::{Instant, Duration};
// util
use hash::keccak;
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use bytes::Bytes;
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, Address, U256};
use evm::Schedule;
use hash::keccak;
use io::IoChannel;
use itertools::Itertools;
use journaldb;
use trie::{TrieSpec, TrieFactory, Trie};
use kvdb::{DBValue, KeyValueDB, DBTransaction};
use parking_lot::{Mutex, RwLock};
use rand::OsRng;
use types::transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Action};
use trie::{TrieSpec, TrieFactory, Trie};
use types::ancestry_action::AncestryAction;
use types::encoded;
use types::filter::Filter;
use types::log_entry::LocalizedLogEntry;
use types::receipt::{Receipt, LocalizedReceipt};
use types::{BlockNumber, header::{Header, ExtendedHeader}};
use vm::{EnvInfo, LastHashes};
// other
use ethereum_types::{H256, Address, U256};
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, ImportRoute, TransactionAddress, ExtrasInsert};
use client::ancient_import::AncientVerifier;
use client::{
Nonce, Balance, ChainInfo, BlockInfo, CallContract, TransactionInfo,
@@ -48,37 +59,24 @@ use client::{
IoClient, BadBlocks,
};
use client::bad_blocks;
use encoded;
use engines::{EthEngine, EpochTransition, ForkChoice};
use error::{
ImportErrorKind, ExecutionError, CallError, BlockError,
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult, ErrorKind as EthcoreErrorKind
};
use vm::{EnvInfo, LastHashes};
use evm::Schedule;
use executive::{Executive, Executed, TransactOptions, contract_address};
use factory::{Factories, VmFactory};
use header::{BlockNumber, Header, ExtendedHeader};
use io::IoChannel;
use log_entry::LocalizedLogEntry;
use miner::{Miner, MinerService};
use ethcore_miner::pool::VerifiedTransaction;
use parking_lot::{Mutex, RwLock};
use rand::OsRng;
use receipt::{Receipt, LocalizedReceipt};
use snapshot::{self, io as snapshot_io, SnapshotClient};
use spec::Spec;
use state_db::StateDB;
use state::{self, State};
use trace;
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
use transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Transaction, Action};
use types::filter::Filter;
use types::ancestry_action::AncestryAction;
use verification;
use verification::{PreverifiedBlock, Verifier, BlockQueue};
use verification::queue::kind::blocks::Unverified;
use state_db::StateDB;
use trace::{self, TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
use transaction_ext::Transaction;
use verification::queue::kind::BlockLike;
use verification::queue::kind::blocks::Unverified;
use verification::{PreverifiedBlock, Verifier, BlockQueue};
use verification;
// re-export
pub use types::blockchain_info::BlockChainInfo;
@@ -1231,7 +1229,7 @@ impl Client {
// from the null sender, with 50M gas.
fn contract_call_tx(&self, block_id: BlockId, address: Address, data: Bytes) -> SignedTransaction {
let from = Address::default();
Transaction {
transaction::Transaction {
nonce: self.nonce(&from, block_id).unwrap_or_else(|| self.engine.account_start_nonce(0)),
action: Action::Call(address),
gas: U256::from(50_000_000),
@@ -2112,7 +2110,7 @@ impl BlockChainClient for Client {
fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error> {
let authoring_params = self.importer.miner.authoring_params();
let transaction = Transaction {
let transaction = transaction::Transaction {
nonce: self.latest_nonce(&authoring_params.author),
action: Action::Call(address),
gas: self.importer.miner.sensible_gas_limit(),
@@ -2411,7 +2409,7 @@ impl super::traits::EngineClient for Client {
BlockChainClient::block_number(self, id)
}
fn block_header(&self, id: BlockId) -> Option<::encoded::Header> {
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
BlockChainClient::block_header(self, id)
}
}
@@ -2520,7 +2518,7 @@ mod tests {
use std::sync::atomic::{AtomicBool, Ordering};
use kvdb::DBTransaction;
use blockchain::ExtrasInsert;
use encoded;
use types::encoded;
let client = generate_dummy_client(0);
let genesis = client.chain_info().best_block_hash;
@@ -2579,9 +2577,9 @@ mod tests {
use hash::keccak;
use super::transaction_receipt;
use ethkey::KeyPair;
use log_entry::{LogEntry, LocalizedLogEntry};
use receipt::{Receipt, LocalizedReceipt, TransactionOutcome};
use transaction::{Transaction, LocalizedTransaction, Action};
use types::log_entry::{LogEntry, LocalizedLogEntry};
use types::receipt::{Receipt, LocalizedReceipt, TransactionOutcome};
use types::transaction::{Transaction, LocalizedTransaction, Action};
// given
let key = KeyPair::from_secret_slice(&keccak("test")).unwrap();

View File

@@ -21,7 +21,8 @@ use std::sync::Arc;
use ethereum_types::{H256, U256, H160};
use {factory, journaldb, trie, kvdb_memorydb};
use kvdb::{self, KeyValueDB};
use {state, state_db, client, executive, trace, transaction, db, spec, pod_state, log_entry, receipt};
use {state, state_db, client, executive, trace, db, spec, pod_state};
use types::{log_entry, receipt, transaction};
use factory::Factories;
use evm::{VMType, FinalizationResult};
use vm::{self, ActionParams};

View File

@@ -20,20 +20,35 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrder};
use std::sync::Arc;
use std::collections::{HashMap, BTreeMap};
use std::mem;
use itertools::Itertools;
use rustc_hex::FromHex;
use hash::keccak;
use blockchain::{TreeRoute, BlockReceipts};
use bytes::Bytes;
use db::{NUM_COLUMNS, COL_STATE};
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, U256, Address};
use parking_lot::RwLock;
use journaldb;
use ethkey::{Generator, Random};
use ethtrie;
use hash::keccak;
use itertools::Itertools;
use kvdb::DBValue;
use kvdb_memorydb;
use bytes::Bytes;
use parking_lot::RwLock;
use rlp::{Rlp, RlpStream};
use ethkey::{Generator, Random};
use ethcore_miner::pool::VerifiedTransaction;
use transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action};
use blockchain::{TreeRoute, BlockReceipts};
use rustc_hex::FromHex;
use types::transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action};
use types::BlockNumber;
use types::basic_account::BasicAccount;
use types::encoded;
use types::filter::Filter;
use types::header::Header;
use types::log_entry::LocalizedLogEntry;
use types::pruning_info::PruningInfo;
use types::receipt::{Receipt, LocalizedReceipt, TransactionOutcome};
use types::view;
use types::views::BlockView;
use vm::Schedule;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use client::{
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, CallContract, TransactionInfo, RegistryInfo,
PrepareOpenBlock, BlockChainClient, BlockChainInfo, BlockStatus, BlockId, Mode,
@@ -42,30 +57,18 @@ use client::{
Call, StateClient, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter, IoClient,
BadBlocks,
};
use db::{NUM_COLUMNS, COL_STATE};
use header::{Header as BlockHeader, BlockNumber};
use filter::Filter;
use log_entry::LocalizedLogEntry;
use receipt::{Receipt, LocalizedReceipt, TransactionOutcome};
use engines::EthEngine;
use error::{Error, EthcoreResult};
use vm::Schedule;
use executed::CallError;
use executive::Executed;
use journaldb;
use miner::{self, Miner, MinerService};
use spec::Spec;
use types::basic_account::BasicAccount;
use types::pruning_info::PruningInfo;
use state::StateInfo;
use state_db::StateDB;
use trace::LocalizedTrace;
use verification::queue::QueueInfo;
use verification::queue::kind::blocks::Unverified;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use executive::Executed;
use error::CallError;
use trace::LocalizedTrace;
use state_db::StateDB;
use header::Header;
use encoded;
use engines::EthEngine;
use ethtrie;
use state::StateInfo;
use views::BlockView;
/// Test client.
pub struct TestBlockChainClient {
@@ -244,11 +247,11 @@ impl TestBlockChainClient {
/// Add a block to test client.
pub fn add_block<F>(&self, with: EachBlockWith, hook: F)
where F: Fn(BlockHeader) -> BlockHeader
where F: Fn(Header) -> Header
{
let n = self.numbers.read().len();
let mut header = BlockHeader::new();
let mut header = Header::new();
header.set_difficulty(From::from(n));
header.set_parent_hash(self.last_hash.read().clone());
header.set_number(n as BlockNumber);
@@ -260,7 +263,7 @@ impl TestBlockChainClient {
let uncles = match with {
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
let mut uncles = RlpStream::new_list(1);
let mut uncle_header = BlockHeader::new();
let mut uncle_header = Header::new();
uncle_header.set_difficulty(From::from(n));
uncle_header.set_parent_hash(self.last_hash.read().clone());
uncle_header.set_number(n as BlockNumber);
@@ -309,7 +312,7 @@ impl TestBlockChainClient {
/// Make a bad block by setting invalid parent hash.
pub fn corrupt_block_parent(&self, n: BlockNumber) {
let hash = self.block_hash(BlockId::Number(n)).unwrap();
let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed");
let mut header: Header = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed");
header.set_parent_hash(H256::from(42));
let mut rlp = RlpStream::new_list(3);
rlp.append(&header);
@@ -935,7 +938,7 @@ impl super::traits::EngineClient for TestBlockChainClient {
BlockChainClient::block_number(self, id)
}
fn block_header(&self, id: BlockId) -> Option<::encoded::Header> {
fn block_header(&self, id: BlockId) -> Option<encoded::Header> {
BlockChainClient::block_header(self, id)
}
}

View File

@@ -16,11 +16,10 @@
//! Bridge between Tracedb and Blockchain.
use ethereum_types::H256;
use header::BlockNumber;
use trace::DatabaseExtras as TraceDatabaseExtras;
use blockchain::{BlockChain, BlockProvider, TransactionAddress};
pub use types::trace_filter::Filter;
use ethereum_types::H256;
use trace::DatabaseExtras as TraceDatabaseExtras;
use types::BlockNumber;
impl TraceDatabaseExtras for BlockChain {
fn block_hash(&self, block_number: BlockNumber) -> Option<H256> {

View File

@@ -17,40 +17,39 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use blockchain::{BlockReceipts, TreeRoute};
use bytes::Bytes;
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{H256, U256, Address};
use evm::Schedule;
use itertools::Itertools;
use kvdb::DBValue;
use types::transaction::{self, LocalizedTransaction, SignedTransaction};
use types::BlockNumber;
use types::basic_account::BasicAccount;
use types::block_status::BlockStatus;
use types::blockchain_info::BlockChainInfo;
use types::call_analytics::CallAnalytics;
use types::encoded;
use types::filter::Filter;
use types::header::Header;
use types::ids::*;
use types::log_entry::LocalizedLogEntry;
use types::pruning_info::PruningInfo;
use types::receipt::LocalizedReceipt;
use types::trace_filter::Filter as TraceFilter;
use vm::LastHashes;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use blockchain::{BlockReceipts, TreeRoute};
use client::Mode;
use encoded;
use vm::LastHashes;
use error::{Error, CallError, EthcoreResult};
use evm::Schedule;
use engines::EthEngine;
use error::{Error, EthcoreResult};
use executed::CallError;
use executive::Executed;
use filter::Filter;
use header::{BlockNumber};
use log_entry::LocalizedLogEntry;
use receipt::LocalizedReceipt;
use state::StateInfo;
use trace::LocalizedTrace;
use transaction::{self, LocalizedTransaction, SignedTransaction};
use verification::queue::QueueInfo as BlockQueueInfo;
use verification::queue::kind::blocks::Unverified;
use state::StateInfo;
use header::Header;
use engines::EthEngine;
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool::VerifiedTransaction;
use bytes::Bytes;
use kvdb::DBValue;
use types::ids::*;
use types::basic_account::BasicAccount;
use types::trace_filter::Filter as TraceFilter;
use types::call_analytics::CallAnalytics;
use types::blockchain_info::BlockChainInfo;
use types::block_status::BlockStatus;
use types::pruning_info::PruningInfo;
/// State information to be used during client query
pub enum StateOrBlock {

View File

@@ -1,239 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Database utilities and definitions.
use std::ops::Deref;
use std::hash::Hash;
use std::collections::HashMap;
use parking_lot::RwLock;
use kvdb::{DBTransaction, KeyValueDB};
use rlp;
// database columns
/// Column for State
pub const COL_STATE: Option<u32> = Some(0);
/// Column for Block headers
pub const COL_HEADERS: Option<u32> = Some(1);
/// Column for Block bodies
pub const COL_BODIES: Option<u32> = Some(2);
/// Column for Extras
pub const COL_EXTRA: Option<u32> = Some(3);
/// Column for Traces
pub const COL_TRACE: Option<u32> = Some(4);
/// Column for the empty accounts bloom filter.
pub const COL_ACCOUNT_BLOOM: Option<u32> = Some(5);
/// Column for general information from the local node which can persist.
pub const COL_NODE_INFO: Option<u32> = Some(6);
/// Column for the light client chain.
pub const COL_LIGHT_CHAIN: Option<u32> = Some(7);
/// Number of columns in DB
pub const NUM_COLUMNS: Option<u32> = Some(8);
/// Modes for updating caches.
#[derive(Clone, Copy)]
pub enum CacheUpdatePolicy {
/// Overwrite entries.
Overwrite,
/// Remove entries.
Remove,
}
/// A cache for arbitrary key-value pairs.
pub trait Cache<K, V> {
/// Insert an entry into the cache and get the old value.
fn insert(&mut self, k: K, v: V) -> Option<V>;
/// Remove an entry from the cache, getting the old value if it existed.
fn remove(&mut self, k: &K) -> Option<V>;
/// Query the cache for a key's associated value.
fn get(&self, k: &K) -> Option<&V>;
}
impl<K, V> Cache<K, V> for HashMap<K, V> where K: Hash + Eq {
fn insert(&mut self, k: K, v: V) -> Option<V> {
HashMap::insert(self, k, v)
}
fn remove(&mut self, k: &K) -> Option<V> {
HashMap::remove(self, k)
}
fn get(&self, k: &K) -> Option<&V> {
HashMap::get(self, k)
}
}
/// Should be used to get database key associated with given value.
pub trait Key<T> {
/// The db key associated with this value.
type Target: Deref<Target = [u8]>;
/// Returns db key.
fn key(&self) -> Self::Target;
}
/// Should be used to write value into database.
pub trait Writable {
/// Writes the value into the database.
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]>;
/// Deletes key from the databse.
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: Deref<Target = [u8]>;
/// Writes the value into the database and updates the cache.
fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: Deref<Target = [u8]> {
self.write(col, &key, &value);
match policy {
CacheUpdatePolicy::Overwrite => {
cache.insert(key, value);
},
CacheUpdatePolicy::Remove => {
cache.remove(&key);
}
}
}
/// Writes the values into the database and updates the cache.
fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values {
self.write(col, &key, &value);
cache.insert(key, value);
}
},
CacheUpdatePolicy::Remove => {
for (key, value) in &values {
self.write(col, key, value);
cache.remove(key);
}
},
}
}
/// Writes and removes the values into the database and updates the cache.
fn extend_with_option_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, Option<T>>, values: HashMap<K, Option<T>>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: rlp::Encodable,
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
for (key, value) in values {
match value {
Some(ref v) => self.write(col, &key, v),
None => self.delete(col, &key),
}
cache.insert(key, value);
}
},
CacheUpdatePolicy::Remove => {
for (key, value) in values {
match value {
Some(v) => self.write(col, &key, &v),
None => self.delete(col, &key),
}
cache.remove(&key);
}
},
}
}
}
/// Should be used to read values from database.
pub trait Readable {
/// Returns value for given key.
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where
T: rlp::Decodable,
R: Deref<Target = [u8]>;
/// Returns value for given key either in cache or in database.
fn read_with_cache<K, T, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> Option<T> where
K: Key<T> + Eq + Hash + Clone,
T: Clone + rlp::Decodable,
C: Cache<K, T> {
{
let read = cache.read();
if let Some(v) = read.get(key) {
return Some(v.clone());
}
}
self.read(col, key).map(|value: T|{
let mut write = cache.write();
write.insert(key.clone(), value.clone());
value
})
}
/// Returns true if given value exists.
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target= [u8]>;
/// Returns true if given value exists either in cache or in database.
fn exists_with_cache<K, T, R, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> bool where
K: Eq + Hash + Key<T, Target = R>,
R: Deref<Target = [u8]>,
C: Cache<K, T> {
{
let read = cache.read();
if read.get(key).is_some() {
return true;
}
}
self.exists::<T, R>(col, key)
}
}
impl Writable for DBTransaction {
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]> {
self.put(col, &key.key(), &rlp::encode(value));
}
fn delete<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>) where T: rlp::Encodable, R: Deref<Target = [u8]> {
self.delete(col, &key.key());
}
}
impl<KVDB: KeyValueDB + ?Sized> Readable for KVDB {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T>
where T: rlp::Decodable, R: Deref<Target = [u8]> {
self.get(col, &key.key())
.expect(&format!("db get failed, key: {:?}", &key.key() as &[u8]))
.map(|v| rlp::decode(&v).expect("decode db value failed") )
}
fn exists<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> bool where R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
match result {
Ok(v) => v.is_some(),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}
}
}
}

View File

@@ -1,305 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Lazily-decoded owning views of RLP-encoded blockchain objects.
//! These views are meant to contain _trusted_ data -- without encoding
//! errors or inconsistencies.
//!
//! In general these views are useful when only a few fields of an object
//! are relevant. In these cases it's more efficient to decode the object piecemeal.
//! When the entirety of the object is needed, it's better to upgrade it to a fully
//! decoded object where parts like the hash can be saved.
use block::Block as FullBlock;
use ethereum_types::{H256, Bloom, U256, Address};
use hash::keccak;
use header::{BlockNumber, Header as FullHeader};
use heapsize::HeapSizeOf;
use rlp::{self, Rlp, RlpStream};
use transaction::UnverifiedTransaction;
use views::{self, BlockView, HeaderView, BodyView};
/// Owning header view.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Header(Vec<u8>);
impl HeapSizeOf for Header {
fn heap_size_of_children(&self) -> usize { self.0.heap_size_of_children() }
}
impl Header {
/// Create a new owning header view.
/// Expects the data to be an RLP-encoded header -- any other case will likely lead to
/// panics further down the line.
pub fn new(encoded: Vec<u8>) -> Self { Header(encoded) }
/// Upgrade this encoded view to a fully owned `Header` object.
pub fn decode(&self) -> Result<FullHeader, rlp::DecoderError> {
rlp::decode(&self.0)
}
/// Get a borrowed header view onto the data.
#[inline]
pub fn view(&self) -> HeaderView { view!(HeaderView, &self.0) }
/// Get the rlp of the header.
#[inline]
pub fn rlp(&self) -> Rlp { Rlp::new(&self.0) }
/// Consume the view and return the raw bytes.
pub fn into_inner(self) -> Vec<u8> { self.0 }
}
// forwarders to borrowed view.
impl Header {
/// Returns the header hash.
pub fn hash(&self) -> H256 { keccak(&self.0) }
/// Returns the parent hash.
pub fn parent_hash(&self) -> H256 { self.view().parent_hash() }
/// Returns the uncles hash.
pub fn uncles_hash(&self) -> H256 { self.view().uncles_hash() }
/// Returns the author.
pub fn author(&self) -> Address { self.view().author() }
/// Returns the state root.
pub fn state_root(&self) -> H256 { self.view().state_root() }
/// Returns the transaction trie root.
pub fn transactions_root(&self) -> H256 { self.view().transactions_root() }
/// Returns the receipts trie root
pub fn receipts_root(&self) -> H256 { self.view().receipts_root() }
/// Returns the block log bloom
pub fn log_bloom(&self) -> Bloom { self.view().log_bloom() }
/// Difficulty of this block
pub fn difficulty(&self) -> U256 { self.view().difficulty() }
/// Number of this block.
pub fn number(&self) -> BlockNumber { self.view().number() }
/// Time this block was produced.
pub fn timestamp(&self) -> u64 { self.view().timestamp() }
/// Gas limit of this block.
pub fn gas_limit(&self) -> U256 { self.view().gas_limit() }
/// Total gas used in this block.
pub fn gas_used(&self) -> U256 { self.view().gas_used() }
/// Block extra data.
pub fn extra_data(&self) -> Vec<u8> { self.view().extra_data() }
/// Engine-specific seal fields.
pub fn seal(&self) -> Vec<Vec<u8>> { self.view().seal() }
}
/// Owning block body view.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Body(Vec<u8>);
impl HeapSizeOf for Body {
fn heap_size_of_children(&self) -> usize { self.0.heap_size_of_children() }
}
impl Body {
/// Create a new owning block body view. The raw bytes passed in must be an rlp-encoded block
/// body.
pub fn new(raw: Vec<u8>) -> Self { Body(raw) }
/// Get a borrowed view of the data within.
#[inline]
pub fn view(&self) -> BodyView { view!(BodyView, &self.0) }
/// Fully decode this block body.
pub fn decode(&self) -> (Vec<UnverifiedTransaction>, Vec<FullHeader>) {
(self.view().transactions(), self.view().uncles())
}
/// Get the RLP of this block body.
#[inline]
pub fn rlp(&self) -> Rlp {
Rlp::new(&self.0)
}
/// Consume the view and return the raw bytes.
pub fn into_inner(self) -> Vec<u8> { self.0 }
}
// forwarders to borrowed view.
impl Body {
/// Get raw rlp of transactions
pub fn transactions_rlp(&self) -> Rlp { self.view().transactions_rlp().rlp }
/// Get a vector of all transactions.
pub fn transactions(&self) -> Vec<UnverifiedTransaction> { self.view().transactions() }
/// Number of transactions in the block.
pub fn transactions_count(&self) -> usize { self.view().transactions_count() }
/// A view over each transaction in the block.
pub fn transaction_views(&self) -> Vec<views::TransactionView> { self.view().transaction_views() }
/// The hash of each transaction in the block.
pub fn transaction_hashes(&self) -> Vec<H256> { self.view().transaction_hashes() }
/// Get raw rlp of uncle headers
pub fn uncles_rlp(&self) -> Rlp { self.view().uncles_rlp().rlp }
/// Decode uncle headers.
pub fn uncles(&self) -> Vec<FullHeader> { self.view().uncles() }
/// Number of uncles.
pub fn uncles_count(&self) -> usize { self.view().uncles_count() }
/// Borrowed view over each uncle.
pub fn uncle_views(&self) -> Vec<views::HeaderView> { self.view().uncle_views() }
/// Hash of each uncle.
pub fn uncle_hashes(&self) -> Vec<H256> { self.view().uncle_hashes() }
}
/// Owning block view.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Block(Vec<u8>);
impl HeapSizeOf for Block {
fn heap_size_of_children(&self) -> usize { self.0.heap_size_of_children() }
}
impl Block {
/// Create a new owning block view. The raw bytes passed in must be an rlp-encoded block.
pub fn new(raw: Vec<u8>) -> Self { Block(raw) }
/// Create a new owning block view by concatenating the encoded header and body
pub fn new_from_header_and_body(header: &views::HeaderView, body: &views::BodyView) -> Self {
let mut stream = RlpStream::new_list(3);
stream.append_raw(header.rlp().as_raw(), 1);
stream.append_raw(body.transactions_rlp().as_raw(), 1);
stream.append_raw(body.uncles_rlp().as_raw(), 1);
Block::new(stream.out())
}
/// Get a borrowed view of the whole block.
#[inline]
pub fn view(&self) -> BlockView { view!(BlockView, &self.0) }
/// Get a borrowed view of the block header.
#[inline]
pub fn header_view(&self) -> HeaderView { self.view().header_view() }
/// Decode to a full block.
pub fn decode(&self) -> Result<FullBlock, rlp::DecoderError> { rlp::decode(&self.0) }
/// Decode the header.
pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) }
/// Clone the encoded header.
pub fn header(&self) -> Header { Header(self.view().rlp().at(0).as_raw().to_vec()) }
/// Get the rlp of this block.
#[inline]
pub fn rlp(&self) -> Rlp {
Rlp::new(&self.0)
}
/// Consume the view and return the raw bytes.
pub fn into_inner(self) -> Vec<u8> { self.0 }
/// Returns the reference to slice of bytes
pub fn raw(&self) -> &[u8] {
&self.0
}
}
// forwarders to borrowed header view.
impl Block {
/// Returns the header hash.
pub fn hash(&self) -> H256 { self.header_view().hash() }
/// Returns the parent hash.
pub fn parent_hash(&self) -> H256 { self.header_view().parent_hash() }
/// Returns the uncles hash.
pub fn uncles_hash(&self) -> H256 { self.header_view().uncles_hash() }
/// Returns the author.
pub fn author(&self) -> Address { self.header_view().author() }
/// Returns the state root.
pub fn state_root(&self) -> H256 { self.header_view().state_root() }
/// Returns the transaction trie root.
pub fn transactions_root(&self) -> H256 { self.header_view().transactions_root() }
/// Returns the receipts trie root
pub fn receipts_root(&self) -> H256 { self.header_view().receipts_root() }
/// Returns the block log bloom
pub fn log_bloom(&self) -> Bloom { self.header_view().log_bloom() }
/// Difficulty of this block
pub fn difficulty(&self) -> U256 { self.header_view().difficulty() }
/// Number of this block.
pub fn number(&self) -> BlockNumber { self.header_view().number() }
/// Time this block was produced.
pub fn timestamp(&self) -> u64 { self.header_view().timestamp() }
/// Gas limit of this block.
pub fn gas_limit(&self) -> U256 { self.header_view().gas_limit() }
/// Total gas used in this block.
pub fn gas_used(&self) -> U256 { self.header_view().gas_used() }
/// Block extra data.
pub fn extra_data(&self) -> Vec<u8> { self.header_view().extra_data() }
/// Engine-specific seal fields.
pub fn seal(&self) -> Vec<Vec<u8>> { self.header_view().seal() }
}
// forwarders to body view.
impl Block {
/// Get a vector of all transactions.
pub fn transactions(&self) -> Vec<UnverifiedTransaction> { self.view().transactions() }
/// Number of transactions in the block.
pub fn transactions_count(&self) -> usize { self.view().transactions_count() }
/// A view over each transaction in the block.
pub fn transaction_views(&self) -> Vec<views::TransactionView> { self.view().transaction_views() }
/// The hash of each transaction in the block.
pub fn transaction_hashes(&self) -> Vec<H256> { self.view().transaction_hashes() }
/// Decode uncle headers.
pub fn uncles(&self) -> Vec<FullHeader> { self.view().uncles() }
/// Number of uncles.
pub fn uncles_count(&self) -> usize { self.view().uncles_count() }
/// Borrowed view over each uncle.
pub fn uncle_views(&self) -> Vec<views::HeaderView> { self.view().uncle_views() }
/// Hash of each uncle.
pub fn uncle_hashes(&self) -> Vec<H256> { self.view().uncle_hashes() }
}

View File

@@ -34,7 +34,6 @@ use error::{Error, ErrorKind, BlockError};
use ethjson;
use machine::{AuxiliaryData, Call, EthereumMachine};
use hash::keccak;
use header::{Header, BlockNumber, ExtendedHeader};
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
use self::finality::RollingFinality;
@@ -44,6 +43,8 @@ use itertools::{self, Itertools};
use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp};
use ethereum_types::{H256, H520, Address, U128, U256};
use parking_lot::{Mutex, RwLock};
use types::BlockNumber;
use types::header::{Header, ExtendedHeader};
use types::ancestry_action::AncestryAction;
use unexpected::{Mismatch, OutOfBounds};
@@ -1528,7 +1529,7 @@ mod tests {
use hash::keccak;
use ethereum_types::{Address, H520, H256, U256};
use ethkey::Signature;
use header::Header;
use types::header::Header;
use rlp::encode;
use block::*;
use test_helpers::{
@@ -1537,7 +1538,7 @@ mod tests {
};
use account_provider::AccountProvider;
use spec::Spec;
use transaction::{Action, Transaction};
use types::transaction::{Action, Transaction};
use engines::{Seal, Engine, EngineError, EthEngine};
use engines::validator_set::{TestSet, SimpleList};
use error::{Error, ErrorKind};

View File

@@ -25,9 +25,9 @@ use block::*;
use engines::{Engine, Seal, ConstructedVerifier, EngineError};
use error::{BlockError, Error};
use ethjson;
use header::{Header, ExtendedHeader};
use client::EngineClient;
use machine::{AuxiliaryData, Call, EthereumMachine};
use types::header::{Header, ExtendedHeader};
use super::signer::EngineSigner;
use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
@@ -215,7 +215,7 @@ mod tests {
use block::*;
use test_helpers::get_temp_state_db;
use account_provider::AccountProvider;
use header::Header;
use types::header::Header;
use spec::Spec;
use engines::Seal;
use tempdir::TempDir;

View File

@@ -1,98 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Epoch verifiers and transitions.
use ethereum_types::H256;
use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp};
/// A full epoch transition.
#[derive(Debug, Clone)]
pub struct Transition {
/// Block hash at which the transition occurred.
pub block_hash: H256,
/// Block number at which the transition occurred.
pub block_number: u64,
/// "transition/epoch" proof from the engine combined with a finality proof.
pub proof: Vec<u8>,
}
impl Encodable for Transition {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(3)
.append(&self.block_hash)
.append(&self.block_number)
.append(&self.proof);
}
}
impl Decodable for Transition {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
Ok(Transition {
block_hash: rlp.val_at(0)?,
block_number: rlp.val_at(1)?,
proof: rlp.val_at(2)?,
})
}
}
/// An epoch transition pending a finality proof.
/// Not all transitions need one.
pub struct PendingTransition {
/// "transition/epoch" proof from the engine.
pub proof: Vec<u8>,
}
impl Encodable for PendingTransition {
fn rlp_append(&self, s: &mut RlpStream) {
s.append(&self.proof);
}
}
impl Decodable for PendingTransition {
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
Ok(PendingTransition {
proof: rlp.as_val()?,
})
}
}
/// Verifier for all blocks within an epoch with self-contained state.
pub trait EpochVerifier<M: ::parity_machine::Machine>: Send + Sync {
/// Lightly verify the next block header.
/// This may not be a header belonging to a different epoch.
fn verify_light(&self, header: &M::Header) -> Result<(), M::Error>;
/// Perform potentially heavier checks on the next block header.
fn verify_heavy(&self, header: &M::Header) -> Result<(), M::Error> {
self.verify_light(header)
}
/// Check a finality proof against this epoch verifier.
/// Returns `Some(hashes)` if the proof proves finality of these hashes.
/// Returns `None` if the proof doesn't prove anything.
fn check_finality_proof(&self, _proof: &[u8]) -> Option<Vec<H256>> {
None
}
}
/// Special "no-op" verifier for stateless, epoch-less engines.
pub struct NoOp;
impl<M: ::parity_machine::Machine> EpochVerifier<M> for NoOp {
fn verify_light(&self, _header: &M::Header) -> Result<(), M::Error> { Ok(()) }
}

View File

@@ -95,7 +95,7 @@ mod tests {
use ethereum_types::{H520, Address};
use test_helpers::get_temp_state_db;
use spec::Spec;
use header::Header;
use types::header::Header;
use block::*;
use engines::Seal;

View File

@@ -24,7 +24,6 @@ mod signer;
mod validator_set;
pub mod block_reward;
pub mod epoch;
pub use self::authority_round::AuthorityRound;
pub use self::basic_authority::BasicAuthority;
@@ -32,20 +31,23 @@ pub use self::epoch::{EpochVerifier, Transition as EpochTransition};
pub use self::instant_seal::{InstantSeal, InstantSealParams};
pub use self::null_engine::NullEngine;
// TODO [ToDr] Remove re-export (#10130)
pub use types::engines::ForkChoice;
pub use types::engines::epoch;
use std::sync::{Weak, Arc};
use std::collections::{BTreeMap, HashMap};
use std::{fmt, error};
use self::epoch::PendingTransition;
use account_provider::AccountProvider;
use builtin::Builtin;
use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue};
use error::Error;
use header::{Header, BlockNumber};
use types::BlockNumber;
use types::header::Header;
use snapshot::SnapshotComponents;
use spec::CommonParams;
use transaction::{self, UnverifiedTransaction, SignedTransaction};
use types::transaction::{self, UnverifiedTransaction, SignedTransaction};
use ethkey::{Password, Signature};
use parity_machine::{Machine, LocalizedMachine as Localized, TotalScoredHeader};
@@ -58,15 +60,6 @@ use types::ancestry_action::AncestryAction;
/// As defined in https://github.com/ethereum/EIPs/pull/210
pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b";
/// Fork choice.
#[derive(Debug, PartialEq, Eq)]
pub enum ForkChoice {
/// Choose the new block.
New,
/// Choose the current best block.
Old,
}
/// Voting errors.
#[derive(Debug)]
pub enum EngineError {
@@ -175,7 +168,7 @@ pub fn default_system_or_code_call<'a>(machine: &'a ::machine::EthereumMachine,
pub type Headers<'a, H> = Fn(H256) -> Option<H> + 'a;
/// Type alias for a function we can query pending transitions by block hash through.
pub type PendingTransitionStore<'a> = Fn(H256) -> Option<PendingTransition> + 'a;
pub type PendingTransitionStore<'a> = Fn(H256) -> Option<epoch::PendingTransition> + 'a;
/// Proof dependent on state.
pub trait StateDependentProof<M: Machine>: Send + Sync {

View File

@@ -14,12 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethereum_types::U256;
use engines::Engine;
use engines::block_reward::{self, RewardKind};
use header::BlockNumber;
use ethereum_types::U256;
use machine::WithRewards;
use parity_machine::{Header, LiveBlock, WithBalances, TotalScoredHeader};
use types::BlockNumber;
/// Params for a null engine.
#[derive(Clone, Default)]

View File

@@ -21,11 +21,12 @@ use std::sync::Weak;
use bytes::Bytes;
use ethereum_types::{H256, Address};
use machine::{AuxiliaryData, Call, EthereumMachine};
use parking_lot::RwLock;
use types::BlockNumber;
use types::header::Header;
use client::EngineClient;
use header::{Header, BlockNumber};
use machine::{AuxiliaryData, Call, EthereumMachine};
use super::{ValidatorSet, SimpleList, SystemCall};
use super::safe_contract::ValidatorSafeContract;
@@ -67,7 +68,7 @@ impl ValidatorContract {
}
impl ValidatorSet for ValidatorContract {
fn default_caller(&self, id: ::ids::BlockId) -> Box<Call> {
fn default_caller(&self, id: ::types::ids::BlockId) -> Box<Call> {
self.validators.default_caller(id)
}
@@ -139,7 +140,7 @@ mod tests {
use bytes::ToPretty;
use rlp::encode;
use spec::Spec;
use header::Header;
use types::header::Header;
use account_provider::AccountProvider;
use miner::MinerService;
use types::ids::BlockId;

View File

@@ -24,13 +24,16 @@ mod contract;
mod multi;
use std::sync::Weak;
use ids::BlockId;
use ethereum_types::{H256, Address};
use bytes::Bytes;
use ethereum_types::{H256, Address};
use ethjson::spec::ValidatorSet as ValidatorSpec;
use client::EngineClient;
use header::{Header, BlockNumber};
use machine::{AuxiliaryData, Call, EthereumMachine};
use types::BlockNumber;
use types::header::Header;
use types::ids::BlockId;
use client::EngineClient;
#[cfg(test)]
pub use self::test::TestSet;

View File

@@ -18,11 +18,14 @@
use std::collections::BTreeMap;
use std::sync::Weak;
use bytes::Bytes;
use ethereum_types::{H256, Address};
use parking_lot::RwLock;
use bytes::Bytes;
use ids::BlockId;
use header::{BlockNumber, Header};
use types::BlockNumber;
use types::header::Header;
use types::ids::BlockId;
use client::EngineClient;
use machine::{AuxiliaryData, Call, EthereumMachine};
use super::{SystemCall, ValidatorSet};
@@ -152,7 +155,7 @@ mod tests {
use engines::EpochChange;
use engines::validator_set::ValidatorSet;
use ethkey::Secret;
use header::Header;
use types::header::Header;
use miner::MinerService;
use spec::Spec;
use test_helpers::{generate_dummy_client_with_spec_and_accounts, generate_dummy_client_with_spec_and_data};

View File

@@ -16,24 +16,26 @@
/// Validator set maintained in a contract, updated using `getValidators` method.
use std::sync::{Weak, Arc};
use bytes::Bytes;
use client::EngineClient;
use ethabi::FunctionOutputDecoder;
use ethereum_types::{H256, U256, Address, Bloom};
use hash::keccak;
use header::Header;
use ids::BlockId;
use kvdb::DBValue;
use log_entry::LogEntry;
use machine::{AuxiliaryData, Call, EthereumMachine, AuxiliaryRequest};
use memory_cache::MemoryLruCache;
use parking_lot::RwLock;
use receipt::Receipt;
use rlp::{Rlp, RlpStream};
use std::sync::{Weak, Arc};
use types::header::Header;
use types::ids::BlockId;
use types::log_entry::LogEntry;
use types::receipt::Receipt;
use unexpected::Mismatch;
use client::EngineClient;
use machine::{AuxiliaryData, Call, EthereumMachine, AuxiliaryRequest};
use super::{SystemCall, ValidatorSet};
use super::simple_list::SimpleList;
use unexpected::Mismatch;
use ethabi::FunctionOutputDecoder;
use_contract!(validator_set, "res/contracts/validator_set.json");
@@ -91,7 +93,7 @@ fn encode_first_proof(header: &Header, state_items: &[Vec<u8>]) -> Bytes {
fn check_first_proof(machine: &EthereumMachine, contract_address: Address, old_header: Header, state_items: &[DBValue])
-> Result<Vec<Address>, String>
{
use transaction::{Action, Transaction};
use types::transaction::{Action, Transaction};
// TODO: match client contract_call_tx more cleanly without duplication.
const PROVIDED_GAS: u64 = 50_000_000;
@@ -343,7 +345,7 @@ impl ValidatorSet for ValidatorSafeContract {
}
}
fn epoch_set(&self, first: bool, machine: &EthereumMachine, _number: ::header::BlockNumber, proof: &[u8])
fn epoch_set(&self, first: bool, machine: &EthereumMachine, _number: ::types::BlockNumber, proof: &[u8])
-> Result<(SimpleList, Option<H256>), ::error::Error>
{
let rlp = Rlp::new(proof);
@@ -444,7 +446,7 @@ mod tests {
use types::ids::BlockId;
use spec::Spec;
use account_provider::AccountProvider;
use transaction::{Transaction, Action};
use types::transaction::{Transaction, Action};
use client::{ChainInfo, BlockInfo, ImportBlock};
use ethkey::Secret;
use miner::MinerService;
@@ -532,10 +534,10 @@ mod tests {
#[test]
fn detects_bloom() {
use header::Header;
use engines::EpochChange;
use machine::AuxiliaryRequest;
use log_entry::LogEntry;
use types::header::Header;
use types::log_entry::LogEntry;
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);
let engine = client.engine().clone();
@@ -571,7 +573,7 @@ mod tests {
#[test]
fn initial_contract_is_signal() {
use header::Header;
use types::header::Header;
use engines::{EpochChange, Proof};
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, None);

View File

@@ -20,7 +20,8 @@ use heapsize::HeapSizeOf;
use ethereum_types::{H256, Address};
use machine::{AuxiliaryData, Call, EthereumMachine};
use header::{BlockNumber, Header};
use types::BlockNumber;
use types::header::Header;
use super::ValidatorSet;
/// Validator set containing a known set of addresses.
@@ -64,7 +65,7 @@ impl HeapSizeOf for SimpleList {
}
impl ValidatorSet for SimpleList {
fn default_caller(&self, _block_id: ::ids::BlockId) -> Box<Call> {
fn default_caller(&self, _block_id: ::types::ids::BlockId) -> Box<Call> {
Box::new(|_, _| Err("Simple list doesn't require calls.".into()))
}

View File

@@ -19,12 +19,14 @@
use std::str::FromStr;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use heapsize::HeapSizeOf;
use ethereum_types::{H256, Address};
use bytes::Bytes;
use ethereum_types::{H256, Address};
use heapsize::HeapSizeOf;
use types::BlockNumber;
use types::header::Header;
use machine::{AuxiliaryData, Call, EthereumMachine};
use header::{Header, BlockNumber};
use super::{ValidatorSet, SimpleList};
/// Set used for testing with a single validator.
@@ -57,7 +59,7 @@ impl HeapSizeOf for TestSet {
}
impl ValidatorSet for TestSet {
fn default_caller(&self, _block_id: ::ids::BlockId) -> Box<Call> {
fn default_caller(&self, _block_id: ::types::ids::BlockId) -> Box<Call> {
Box::new(|_, _| Err("Test set doesn't require calls.".into()))
}

View File

@@ -18,18 +18,19 @@
use std::{fmt, error};
use std::time::SystemTime;
use ethereum_types::{H256, U256, Address, Bloom};
use snappy::InvalidInput;
use unexpected::{Mismatch, OutOfBounds};
use ethtrie::TrieError;
use io::*;
use header::BlockNumber;
use snapshot::Error as SnapshotError;
use engines::EngineError;
use ethkey::Error as EthkeyError;
use account_provider::SignError as AccountsError;
use transaction::Error as TransactionError;
use ethtrie::TrieError;
use rlp;
use snappy::InvalidInput;
use snapshot::Error as SnapshotError;
use types::transaction::Error as TransactionError;
use types::BlockNumber;
use unexpected::{Mismatch, OutOfBounds};
use account_provider::SignError as AccountsError;
use engines::EngineError;
pub use executed::{ExecutionError, CallError};
@@ -165,7 +166,7 @@ error_chain! {
}
foreign_links {
Channel(IoError) #[doc = "Io channel error"];
Channel(::io::IoError) #[doc = "Io channel error"];
}
}
@@ -224,7 +225,7 @@ error_chain! {
}
foreign_links {
Io(IoError) #[doc = "Io create error"];
Io(::io::IoError) #[doc = "Io create error"];
StdIo(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."];
Trie(TrieError) #[doc = "Error concerning TrieDBs."];
Execution(ExecutionError) #[doc = "Error concerning EVM code execution."];

View File

@@ -14,21 +14,24 @@
// 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::path::Path;
use std::cmp;
use std::collections::BTreeMap;
use std::path::Path;
use std::sync::Arc;
use hash::{KECCAK_EMPTY_LIST_RLP};
use engines::block_reward::{self, BlockRewardContract, RewardKind};
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
use ethereum_types::{H256, H64, U256};
use unexpected::{OutOfBounds, Mismatch};
use block::*;
use error::{BlockError, Error};
use header::{Header, BlockNumber, ExtendedHeader};
use engines::{self, Engine};
use ethjson;
use hash::{KECCAK_EMPTY_LIST_RLP};
use rlp::Rlp;
use types::header::{Header, ExtendedHeader};
use types::BlockNumber;
use unexpected::{OutOfBounds, Mismatch};
use block::ExecutedBlock;
use engines::block_reward::{self, BlockRewardContract, RewardKind};
use engines::{self, Engine};
use error::{BlockError, Error};
use ethash::{self, quick_get_difficulty, slow_hash_block_number, EthashManager, OptimizeFor};
use machine::EthereumMachine;
/// Number of blocks in an ethash snapshot.
@@ -482,7 +485,7 @@ mod tests {
use block::*;
use test_helpers::get_temp_state_db;
use error::{BlockError, Error, ErrorKind};
use header::Header;
use types::header::Header;
use spec::Spec;
use engines::Engine;
use super::super::{new_morden, new_mcip3_test, new_homestead_test_machine};

View File

@@ -180,7 +180,8 @@ mod tests {
use state::*;
use super::*;
use test_helpers::get_temp_state_db;
use views::BlockView;
use types::view;
use types::views::BlockView;
#[test]
fn ensure_db_good() {

View File

@@ -21,8 +21,8 @@ use bytes::Bytes;
use ethtrie;
use vm;
use trace::{VMTrace, FlatTrace};
use log_entry::LogEntry;
use state_diff::StateDiff;
use types::state_diff::StateDiff;
use types::log_entry::LogEntry;
use std::{fmt, error};

View File

@@ -21,7 +21,7 @@ use hash::keccak;
use ethereum_types::{H256, U256, U512, Address};
use bytes::{Bytes, BytesRef};
use state::{Backend as StateBackend, State, Substate, CleanupMode};
use error::ExecutionError;
use executed::ExecutionError;
use machine::EthereumMachine as Machine;
use evm::{CallType, Finalize, FinalizationResult};
use vm::{
@@ -31,7 +31,8 @@ use vm::{
use factory::VmFactory;
use externalities::*;
use trace::{self, Tracer, VMTracer};
use transaction::{Action, SignedTransaction};
use types::transaction::{Action, SignedTransaction};
use transaction_ext::Transaction;
use crossbeam;
pub use executed::{Executed, ExecutionResult};
@@ -1179,7 +1180,7 @@ mod tests {
use trace::trace;
use trace::{FlatTrace, Tracer, NoopTracer, ExecutiveTracer};
use trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, VMTracer, NoopVMTracer, ExecutiveVMTracer};
use transaction::{Action, Transaction};
use types::transaction::{Action, Transaction};
fn make_frontier_machine(max_depth: usize) -> EthereumMachine {
let mut machine = ::ethereum::new_frontier_test_machine();

View File

@@ -27,7 +27,7 @@ use vm::{
Ext, ContractCreateResult, MessageCallResult, CreateContractAddress,
ReturnData, TrapKind
};
use transaction::UNSIGNED_SENDER;
use types::transaction::UNSIGNED_SENDER;
use trace::{Tracer, VMTracer};
/// Policy for handling output data on `RETURN` opcode.
@@ -340,7 +340,7 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> vm::Result<()> {
use log_entry::LogEntry;
use types::log_entry::LogEntry;
if self.static_flag {
return Err(vm::Error::MutableCallInStaticContext);

View File

@@ -1,456 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Block header.
use std::cmp;
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP, keccak};
use heapsize::HeapSizeOf;
use ethereum_types::{H256, U256, Address, Bloom};
use bytes::Bytes;
use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable};
pub use types::BlockNumber;
/// Semantic boolean for when a seal/signature is included.
#[derive(Debug, Clone, Copy)]
enum Seal {
/// The seal/signature is included.
With,
/// The seal/signature is not included.
Without,
}
/// Extended block header, wrapping `Header` with finalized and total difficulty information.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendedHeader {
/// The actual header.
pub header: Header,
/// Whether the block underlying this header is considered finalized.
pub is_finalized: bool,
/// The parent block difficulty.
pub parent_total_difficulty: U256,
}
/// A block header.
///
/// Reflects the specific RLP fields of a block in the chain with additional room for the seal
/// which is non-specific.
///
/// Doesn't do all that much on its own.
#[derive(Debug, Clone, Eq)]
pub struct Header {
/// Parent hash.
parent_hash: H256,
/// Block timestamp.
timestamp: u64,
/// Block number.
number: BlockNumber,
/// Block author.
author: Address,
/// Transactions root.
transactions_root: H256,
/// Block uncles hash.
uncles_hash: H256,
/// Block extra data.
extra_data: Bytes,
/// State root.
state_root: H256,
/// Block receipts root.
receipts_root: H256,
/// Block bloom.
log_bloom: Bloom,
/// Gas used for contracts execution.
gas_used: U256,
/// Block gas limit.
gas_limit: U256,
/// Block difficulty.
difficulty: U256,
/// Vector of post-RLP-encoded fields.
seal: Vec<Bytes>,
/// Memoized hash of that header and the seal.
hash: Option<H256>,
}
impl PartialEq for Header {
fn eq(&self, c: &Header) -> bool {
if let (&Some(ref h1), &Some(ref h2)) = (&self.hash, &c.hash) {
if h1 == h2 {
return true
}
}
self.parent_hash == c.parent_hash &&
self.timestamp == c.timestamp &&
self.number == c.number &&
self.author == c.author &&
self.transactions_root == c.transactions_root &&
self.uncles_hash == c.uncles_hash &&
self.extra_data == c.extra_data &&
self.state_root == c.state_root &&
self.receipts_root == c.receipts_root &&
self.log_bloom == c.log_bloom &&
self.gas_used == c.gas_used &&
self.gas_limit == c.gas_limit &&
self.difficulty == c.difficulty &&
self.seal == c.seal
}
}
impl Default for Header {
fn default() -> Self {
Header {
parent_hash: H256::default(),
timestamp: 0,
number: 0,
author: Address::default(),
transactions_root: KECCAK_NULL_RLP,
uncles_hash: KECCAK_EMPTY_LIST_RLP,
extra_data: vec![],
state_root: KECCAK_NULL_RLP,
receipts_root: KECCAK_NULL_RLP,
log_bloom: Bloom::default(),
gas_used: U256::default(),
gas_limit: U256::default(),
difficulty: U256::default(),
seal: vec![],
hash: None,
}
}
}
impl Header {
/// Create a new, default-valued, header.
pub fn new() -> Self { Self::default() }
/// Get the parent_hash field of the header.
pub fn parent_hash(&self) -> &H256 { &self.parent_hash }
/// Get the timestamp field of the header.
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.
pub fn author(&self) -> &Address { &self.author }
/// Get the extra data field of the header.
pub fn extra_data(&self) -> &Bytes { &self.extra_data }
/// Get the state root field of the header.
pub fn state_root(&self) -> &H256 { &self.state_root }
/// Get the receipts root field of the header.
pub fn receipts_root(&self) -> &H256 { &self.receipts_root }
/// Get the log bloom field of the header.
pub fn log_bloom(&self) -> &Bloom { &self.log_bloom }
/// Get the transactions root field of the header.
pub fn transactions_root(&self) -> &H256 { &self.transactions_root }
/// Get the uncles hash field of the header.
pub fn uncles_hash(&self) -> &H256 { &self.uncles_hash }
/// Get the gas used field of the header.
pub fn gas_used(&self) -> &U256 { &self.gas_used }
/// Get the gas limit field of the header.
pub fn gas_limit(&self) -> &U256 { &self.gas_limit }
/// Get the difficulty field of the header.
pub fn difficulty(&self) -> &U256 { &self.difficulty }
/// Get the seal field of the header.
pub fn seal(&self) -> &[Bytes] { &self.seal }
/// Get the seal field with RLP-decoded values as bytes.
pub fn decode_seal<'a, T: ::std::iter::FromIterator<&'a [u8]>>(&'a self) -> Result<T, DecoderError> {
self.seal.iter().map(|rlp| {
Rlp::new(rlp).data()
}).collect()
}
/// Get a mutable reference to extra_data
#[cfg(test)]
pub fn extra_data_mut(&mut self) -> &mut Bytes {
self.hash = None;
&mut self.extra_data
}
/// Set the number field of the header.
pub fn set_parent_hash(&mut self, a: H256) {
change_field(&mut self.hash, &mut self.parent_hash, a);
}
/// Set the uncles hash field of the header.
pub fn set_uncles_hash(&mut self, a: H256) {
change_field(&mut self.hash, &mut self.uncles_hash, a);
}
/// Set the state root field of the header.
pub fn set_state_root(&mut self, a: H256) {
change_field(&mut self.hash, &mut self.state_root, a);
}
/// Set the transactions root field of the header.
pub fn set_transactions_root(&mut self, a: H256) {
change_field(&mut self.hash, &mut self.transactions_root, a);
}
/// Set the receipts root field of the header.
pub fn set_receipts_root(&mut self, a: H256) {
change_field(&mut self.hash, &mut self.receipts_root, a);
}
/// Set the log bloom field of the header.
pub fn set_log_bloom(&mut self, a: Bloom) {
change_field(&mut self.hash, &mut self.log_bloom, a);
}
/// Set the timestamp field of the header.
pub fn set_timestamp(&mut self, a: u64) {
change_field(&mut self.hash, &mut self.timestamp, a);
}
/// Set the number field of the header.
pub fn set_number(&mut self, a: BlockNumber) {
change_field(&mut self.hash, &mut self.number, a);
}
/// Set the author field of the header.
pub fn set_author(&mut self, a: Address) {
change_field(&mut self.hash, &mut self.author, a);
}
/// Set the extra data field of the header.
pub fn set_extra_data(&mut self, a: Bytes) {
change_field(&mut self.hash, &mut self.extra_data, a);
}
/// Set the gas used field of the header.
pub fn set_gas_used(&mut self, a: U256) {
change_field(&mut self.hash, &mut self.gas_used, a);
}
/// Set the gas limit field of the header.
pub fn set_gas_limit(&mut self, a: U256) {
change_field(&mut self.hash, &mut self.gas_limit, a);
}
/// Set the difficulty field of the header.
pub fn set_difficulty(&mut self, a: U256) {
change_field(&mut self.hash, &mut self.difficulty, a);
}
/// Set the seal field of the header.
pub fn set_seal(&mut self, a: Vec<Bytes>) {
change_field(&mut self.hash, &mut self.seal, a)
}
/// Get & memoize the hash of this header (keccak of the RLP with seal).
pub fn compute_hash(&mut self) -> H256 {
let hash = self.hash();
self.hash = Some(hash);
hash
}
/// Get the hash of this header (keccak of the RLP with seal).
pub fn hash(&self) -> H256 {
self.hash.unwrap_or_else(|| keccak(self.rlp(Seal::With)))
}
/// Get the hash of the header excluding the seal
pub fn bare_hash(&self) -> H256 {
keccak(self.rlp(Seal::Without))
}
/// Encode the header, getting a type-safe wrapper around the RLP.
pub fn encoded(&self) -> ::encoded::Header {
::encoded::Header::new(self.rlp(Seal::With))
}
/// Get the RLP representation of this Header.
fn rlp(&self, with_seal: Seal) -> Bytes {
let mut s = RlpStream::new();
self.stream_rlp(&mut s, with_seal);
s.out()
}
/// Place this header into an RLP stream `s`, optionally `with_seal`.
fn stream_rlp(&self, s: &mut RlpStream, with_seal: Seal) {
if let Seal::With = with_seal {
s.begin_list(13 + self.seal.len());
} else {
s.begin_list(13);
}
s.append(&self.parent_hash);
s.append(&self.uncles_hash);
s.append(&self.author);
s.append(&self.state_root);
s.append(&self.transactions_root);
s.append(&self.receipts_root);
s.append(&self.log_bloom);
s.append(&self.difficulty);
s.append(&self.number);
s.append(&self.gas_limit);
s.append(&self.gas_used);
s.append(&self.timestamp);
s.append(&self.extra_data);
if let Seal::With = with_seal {
for b in &self.seal {
s.append_raw(b, 1);
}
}
}
}
/// Alter value of given field, reset memoised hash if changed.
fn change_field<T>(hash: &mut Option<H256>, field: &mut T, value: T) where T: PartialEq<T> {
if field != &value {
*field = value;
*hash = None;
}
}
impl Decodable for Header {
fn decode(r: &Rlp) -> Result<Self, DecoderError> {
let mut blockheader = Header {
parent_hash: r.val_at(0)?,
uncles_hash: r.val_at(1)?,
author: r.val_at(2)?,
state_root: r.val_at(3)?,
transactions_root: r.val_at(4)?,
receipts_root: r.val_at(5)?,
log_bloom: r.val_at(6)?,
difficulty: r.val_at(7)?,
number: r.val_at(8)?,
gas_limit: r.val_at(9)?,
gas_used: r.val_at(10)?,
timestamp: cmp::min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(),
extra_data: r.val_at(12)?,
seal: vec![],
hash: keccak(r.as_raw()).into(),
};
for i in 13..r.item_count()? {
blockheader.seal.push(r.at(i)?.as_raw().to_vec())
}
Ok(blockheader)
}
}
impl Encodable for Header {
fn rlp_append(&self, s: &mut RlpStream) {
self.stream_rlp(s, Seal::With);
}
}
impl HeapSizeOf for Header {
fn heap_size_of_children(&self) -> usize {
self.extra_data.heap_size_of_children() + self.seal.heap_size_of_children()
}
}
impl ::parity_machine::Header for Header {
fn bare_hash(&self) -> H256 { Header::bare_hash(self) }
fn hash(&self) -> H256 { Header::hash(self) }
fn seal(&self) -> &[Vec<u8>] { Header::seal(self) }
fn author(&self) -> &Address { Header::author(self) }
fn number(&self) -> BlockNumber { Header::number(self) }
}
impl ::parity_machine::ScoredHeader for Header {
type Value = U256;
fn score(&self) -> &U256 { self.difficulty() }
fn set_score(&mut self, score: U256) { self.set_difficulty(score) }
}
impl ::parity_machine::Header for ExtendedHeader {
fn bare_hash(&self) -> H256 { self.header.bare_hash() }
fn hash(&self) -> H256 { self.header.hash() }
fn seal(&self) -> &[Vec<u8>] { self.header.seal() }
fn author(&self) -> &Address { self.header.author() }
fn number(&self) -> BlockNumber { self.header.number() }
}
impl ::parity_machine::ScoredHeader for ExtendedHeader {
type Value = U256;
fn score(&self) -> &U256 { self.header.difficulty() }
fn set_score(&mut self, score: U256) { self.header.set_difficulty(score) }
}
impl ::parity_machine::TotalScoredHeader for ExtendedHeader {
type Value = U256;
fn total_score(&self) -> U256 { self.parent_total_difficulty + *self.header.difficulty() }
}
impl ::parity_machine::FinalizableHeader for ExtendedHeader {
fn is_finalized(&self) -> bool { self.is_finalized }
}
#[cfg(test)]
mod tests {
use rustc_hex::FromHex;
use rlp;
use super::Header;
#[test]
fn test_header_seal_fields() {
// that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let mix_hash_decoded = "a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
let nonce_decoded = "ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let seal_fields = header.seal.clone();
assert_eq!(seal_fields.len(), 2);
assert_eq!(seal_fields[0], mix_hash);
assert_eq!(seal_fields[1], nonce);
let decoded_seal = header.decode_seal::<Vec<_>>().unwrap();
assert_eq!(decoded_seal.len(), 2);
assert_eq!(decoded_seal[0], &*mix_hash_decoded);
assert_eq!(decoded_seal[1], &*nonce_decoded);
}
#[test]
fn decode_and_encode_header() {
// that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = rlp::decode(&header_rlp).expect("error decoding header");
let encoded_header = rlp::encode(&header);
assert_eq!(header_rlp, encoded_header);
}
}

View File

@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use ethjson;
use header::Header;
use types::header::Header;
use ethereum_types::U256;
use spec::Spec;

View File

@@ -20,7 +20,7 @@ use pod_state::PodState;
use trace;
use client::{EvmTestClient, EvmTestError, TransactResult};
use ethjson;
use transaction::SignedTransaction;
use types::transaction::SignedTransaction;
use vm::EnvInfo;
use super::SKIP_TEST_STATE;
use super::HookType;

View File

@@ -17,10 +17,11 @@
use std::path::Path;
use super::test_common::*;
use client::EvmTestClient;
use header::Header;
use ethjson;
use rlp::Rlp;
use transaction::UnverifiedTransaction;
use types::header::Header;
use types::transaction::UnverifiedTransaction;
use transaction_ext::Transaction;
/// Run transaction jsontests on a given folder.
pub fn run_test_path<H: FnMut(&str, HookType)>(p: &Path, skip: &[&'static str], h: &mut H) {
@@ -67,7 +68,7 @@ fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mu
let minimal = t.gas_required(&spec.engine.schedule(header.number())).into();
if t.gas < minimal {
return Err(::transaction::Error::InsufficientGas {
return Err(::types::transaction::Error::InsufficientGas {
minimal, got: t.gas,
}.into());
}

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)]
#![warn(missing_docs, unused_extern_crates)]
//! Ethcore library
//!
@@ -57,61 +57,65 @@
// error_chain foreign_links.
#![recursion_limit="128"]
extern crate blooms_db;
extern crate ansi_term;
extern crate bn;
extern crate byteorder;
extern crate crossbeam;
extern crate common_types as types;
extern crate crossbeam;
extern crate ethabi;
extern crate ethash;
extern crate ethcore_blockchain as blockchain;
extern crate ethcore_bloom_journal as bloom_journal;
extern crate parity_crypto;
extern crate ethcore_db as db;
extern crate ethcore_io as io;
extern crate parity_bytes as bytes;
extern crate ethcore_logger;
extern crate ethcore_miner;
#[cfg(feature = "stratum")]
extern crate ethcore_stratum;
extern crate ethcore_transaction as transaction;
extern crate ethereum_types;
extern crate ethjson;
extern crate ethkey;
extern crate ethstore;
extern crate hashdb;
extern crate heapsize;
extern crate itertools;
extern crate journaldb;
extern crate keccak_hash as hash;
extern crate keccak_hasher;
extern crate kvdb;
extern crate kvdb_memorydb;
extern crate kvdb_rocksdb;
extern crate len_caching_lock;
extern crate lru_cache;
extern crate num_cpus;
extern crate memory_cache;
extern crate memorydb;
extern crate num;
extern crate num_cpus;
extern crate parity_bytes as bytes;
extern crate parity_crypto;
extern crate parity_machine;
extern crate parity_snappy as snappy;
extern crate parking_lot;
extern crate patricia_trie as trie;
extern crate patricia_trie_ethereum as ethtrie;
extern crate rand;
extern crate rayon;
extern crate rlp;
extern crate rlp_compress;
extern crate keccak_hash as hash;
extern crate keccak_hasher;
extern crate heapsize;
extern crate memorydb;
extern crate patricia_trie as trie;
extern crate patricia_trie_ethereum as ethtrie;
extern crate triehash_ethereum as triehash;
extern crate ansi_term;
extern crate unexpected;
extern crate parity_snappy as snappy;
extern crate ethabi;
extern crate rustc_hex;
extern crate serde;
extern crate stats;
extern crate triehash_ethereum as triehash;
extern crate unexpected;
extern crate using_queue;
extern crate vm;
extern crate wasm;
extern crate memory_cache;
extern crate journaldb;
extern crate serde;
#[cfg(feature = "stratum")]
extern crate ethcore_stratum;
#[cfg(any(test, feature = "json-tests", feature = "test-helpers"))]
extern crate tempdir;
extern crate len_caching_lock;
#[cfg(any(test, feature = "json-tests"))]
extern crate ethcore_logger;
#[cfg(any(test, feature = "test-helpers"))]
extern crate kvdb_rocksdb;
#[cfg(any(test, feature = "test-helpers"))]
extern crate blooms_db;
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "android"))]
extern crate hardware_wallet;
@@ -143,24 +147,18 @@ extern crate evm;
#[cfg(test)]
extern crate env_logger;
pub extern crate ethstore;
#[macro_use]
pub mod views;
#[cfg(test)]
extern crate rlp_compress;
pub mod account_provider;
pub mod block;
pub mod builtin;
pub mod client;
pub mod db;
pub mod encoded;
pub mod engines;
pub mod error;
pub mod ethereum;
pub mod executed;
pub mod executive;
pub mod header;
pub mod machine;
pub mod miner;
pub mod pod_state;
@@ -170,12 +168,11 @@ pub mod spec;
pub mod state;
pub mod state_db;
pub mod trace;
pub mod transaction_ext;
pub mod verification;
mod cache_manager;
mod account_db;
mod externalities;
mod blockchain;
mod factory;
mod tx_filter;
@@ -186,8 +183,6 @@ pub mod json_tests;
#[cfg(any(test, feature = "test-helpers"))]
pub mod test_helpers;
pub use types::*;
pub use executive::contract_address;
pub use evm::CreateContractAddress;
pub use blockchain::{BlockChainDB, BlockChainDBHandler};
pub use trie::TrieSpec;

View File

@@ -20,23 +20,24 @@ use std::collections::{BTreeMap, HashMap};
use std::cmp;
use std::sync::Arc;
use ethereum_types::{U256, H256, Address};
use rlp::Rlp;
use types::transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction};
use types::BlockNumber;
use types::header::{Header, ExtendedHeader};
use vm::{CallType, ActionParams, ActionValue, ParamsType};
use vm::{EnvInfo, Schedule, CreateContractAddress};
use block::{ExecutedBlock, IsBlock};
use builtin::Builtin;
use client::{BlockInfo, CallContract};
use error::Error;
use executive::Executive;
use header::{BlockNumber, Header, ExtendedHeader};
use spec::CommonParams;
use state::{CleanupMode, Substate};
use trace::{NoopTracer, NoopVMTracer, Tracer, ExecutiveTracer, RewardType, Tracing};
use transaction::{self, SYSTEM_ADDRESS, UNSIGNED_SENDER, UnverifiedTransaction, SignedTransaction};
use tx_filter::TransactionFilter;
use ethereum_types::{U256, H256, Address};
use rlp::Rlp;
use vm::{CallType, ActionParams, ActionValue, ParamsType};
use vm::{EnvInfo, Schedule, CreateContractAddress};
/// Parity tries to round block.gas_limit to multiple of this constant
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
@@ -408,7 +409,7 @@ pub struct AuxiliaryData<'a> {
/// The full block bytes, including the header.
pub bytes: Option<&'a [u8]>,
/// The block receipts.
pub receipts: Option<&'a [::receipt::Receipt]>,
pub receipts: Option<&'a [::types::receipt::Receipt]>,
}
/// Type alias for a function we can make calls through synchronously.
@@ -526,7 +527,7 @@ mod tests {
Default::default(),
ethparams,
);
let mut header = ::header::Header::new();
let mut header = ::types::header::Header::new();
header.set_number(15);
let res = machine.verify_transaction_basic(&transaction, &header);
@@ -546,8 +547,8 @@ mod tests {
ethparams,
);
let mut parent = ::header::Header::new();
let mut header = ::header::Header::new();
let mut parent = ::types::header::Header::new();
let mut header = ::types::header::Header::new();
header.set_number(1);
// this test will work for this constant only

View File

@@ -21,39 +21,42 @@ use std::sync::Arc;
use ansi_term::Colour;
use bytes::Bytes;
use engines::{EthEngine, Seal};
use error::{Error, ErrorKind, ExecutionError};
use ethcore_miner::gas_pricer::GasPricer;
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
#[cfg(feature = "work-notify")]
use ethcore_miner::work_notify::NotifyWork;
use ethereum_types::{H256, U256, Address};
use ethkey::Password;
use io::IoChannel;
use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
use miner;
use parking_lot::{Mutex, RwLock};
use rayon::prelude::*;
use transaction::{
use types::transaction::{
self,
Action,
UnverifiedTransaction,
SignedTransaction,
PendingTransaction,
};
use types::BlockNumber;
use types::block::Block;
use types::header::Header;
use types::receipt::RichReceipt;
use using_queue::{UsingQueue, GetAction};
use account_provider::{AccountProvider, SignError as AccountError};
use block::{ClosedBlock, IsBlock, Block, SealedBlock};
use block::{ClosedBlock, IsBlock, SealedBlock};
use client::{
BlockChain, ChainInfo, CallContract, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
};
use client::{BlockId, ClientIoMessage};
use engines::{EthEngine, Seal};
use error::{Error, ErrorKind};
use executed::ExecutionError;
use executive::contract_address;
use header::{Header, BlockNumber};
use miner;
use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
use receipt::RichReceipt;
use spec::Spec;
use state::State;
use ethkey::Password;
/// Different possible definitions for pending transaction set.
#[derive(Debug, PartialEq)]
@@ -1284,13 +1287,13 @@ mod tests {
use super::*;
use ethkey::{Generator, Random};
use hash::keccak;
use header::BlockNumber;
use rustc_hex::FromHex;
use types::BlockNumber;
use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock};
use miner::{MinerService, PendingOrdering};
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
use transaction::{Transaction};
use types::transaction::{Transaction};
#[test]
fn should_prepare_block_to_seal() {

View File

@@ -33,21 +33,23 @@ use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap};
use bytes::Bytes;
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool::{VerifiedTransaction, QueueStatus, local_transactions};
use ethereum_types::{H256, U256, Address};
use ethkey::Password;
use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
use types::BlockNumber;
use types::block::Block;
use types::header::Header;
use types::receipt::RichReceipt;
use block::{Block, SealedBlock};
use block::SealedBlock;
use client::{
CallContract, RegistryInfo, ScheduleInfo,
BlockChain, BlockProducer, SealedBlockImporter, ChainInfo,
AccountData, Nonce,
};
use error::Error;
use header::{BlockNumber, Header};
use receipt::RichReceipt;
use transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
use state::StateInfo;
use ethkey::Password;
/// Provides methods to verify incoming external transactions
pub trait TransactionVerifierClient: Send + Sync

View File

@@ -25,19 +25,20 @@ use std::{
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool;
use ethcore_miner::pool::client::NonceClient;
use transaction::{
use types::transaction::{
self,
UnverifiedTransaction,
SignedTransaction,
};
use types::header::Header;
use parking_lot::RwLock;
use account_provider::AccountProvider;
use client::{TransactionId, BlockInfo, CallContract, Nonce};
use engines::EthEngine;
use header::Header;
use miner;
use miner::service_transaction_checker::ServiceTransactionChecker;
use transaction_ext::Transaction;
/// Cache for state nonces.
#[derive(Debug, Clone)]

View File

@@ -17,7 +17,7 @@
//! A service transactions contract checker.
use client::{RegistryInfo, CallContract, BlockId};
use transaction::SignedTransaction;
use types::transaction::SignedTransaction;
use ethabi::FunctionOutputDecoder;
use_contract!(service_transaction, "res/contracts/service_transaction.json");

View File

@@ -17,7 +17,7 @@
//! Account state encoding and decoding
use account_db::{AccountDB, AccountDBMut};
use basic_account::BasicAccount;
use types::basic_account::BasicAccount;
use bytes::Bytes;
use ethereum_types::{H256, U256};
use ethtrie::{TrieDB, TrieDBMut};
@@ -207,7 +207,7 @@ pub fn from_fat_rlp(
#[cfg(test)]
mod tests {
use account_db::{AccountDB, AccountDBMut};
use basic_account::BasicAccount;
use types::basic_account::BasicAccount;
use test_helpers::get_temp_state_db;
use snapshot::tests::helpers::fill_storage;

View File

@@ -16,14 +16,14 @@
//! Block RLP compression.
use block::Block;
use header::Header;
use hash::keccak;
use views::BlockView;
use rlp::{DecoderError, RlpStream, Rlp};
use ethereum_types::H256;
use bytes::Bytes;
use ethereum_types::H256;
use hash::keccak;
use rlp::{DecoderError, RlpStream, Rlp};
use triehash::ordered_trie_root;
use types::block::Block;
use types::header::Header;
use types::views::BlockView;
const HEADER_FIELDS: usize = 8;
const BLOCK_FIELDS: usize = 2;
@@ -132,13 +132,14 @@ impl AbridgedBlock {
#[cfg(test)]
mod tests {
use views::BlockView;
use block::Block;
use super::AbridgedBlock;
use transaction::{Action, Transaction};
use ethereum_types::{H256, U256, Address};
use bytes::Bytes;
use ethereum_types::{H256, U256, Address};
use types::transaction::{Action, Transaction};
use types::block::Block;
use types::view;
use types::views::BlockView;
fn encode_block(b: &Block) -> Bytes {
b.rlp_bytes()

View File

@@ -24,21 +24,20 @@ use super::{SnapshotComponents, Rebuilder, ChunkSink};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
use engines::{EthEngine, EpochVerifier, EpochTransition};
use machine::EthereumMachine;
use ids::BlockId;
use header::Header;
use receipt::Receipt;
use snapshot::{Error, ManifestData, Progress};
use itertools::{Position, Itertools};
use rlp::{RlpStream, Rlp};
use ethereum_types::{H256, U256};
use kvdb::KeyValueDB;
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
use bytes::Bytes;
use encoded;
use ethereum_types::{H256, U256};
use itertools::{Position, Itertools};
use kvdb::KeyValueDB;
use rlp::{RlpStream, Rlp};
use types::encoded;
use types::header::Header;
use types::ids::BlockId;
use types::receipt::Receipt;
/// Snapshot creation and restoration for PoA chains.
/// Chunk format:
@@ -319,7 +318,7 @@ impl Rebuilder for ChunkRebuilder {
}
if is_last_chunk {
use block::Block;
use types::block::Block;
let last_rlp = rlp.at(num_items - 1)?;
let block = Block {

View File

@@ -35,7 +35,7 @@ use kvdb::KeyValueDB;
use bytes::Bytes;
use rlp::{RlpStream, Rlp};
use rand::OsRng;
use encoded;
use types::encoded;
/// Snapshot creation and restoration for PoW chains.
/// This includes blocks from the head of the chain as a
@@ -250,7 +250,7 @@ impl Rebuilder for PowRebuilder {
let pair = rlp.at(idx)?;
let abridged_rlp = pair.at(0)?.as_raw().to_owned();
let abridged_block = AbridgedBlock::from_raw(abridged_rlp);
let receipts: Vec<::receipt::Receipt> = pair.list_at(1)?;
let receipts: Vec<::types::receipt::Receipt> = pair.list_at(1)?;
let receipts_root = ordered_trie_root(pair.at(1)?.iter().map(|r| r.as_raw()));
let block = abridged_block.to_block(parent_hash, cur_number, receipts_root)?;

View File

@@ -18,7 +18,7 @@
use std::fmt;
use ids::BlockId;
use types::ids::BlockId;
use ethereum_types::H256;
use ethtrie::TrieError;

View File

@@ -28,8 +28,8 @@ use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY};
use account_db::{AccountDB, AccountDBMut};
use blockchain::{BlockChain, BlockProvider};
use engines::EthEngine;
use header::Header;
use ids::BlockId;
use types::header::Header;
use types::ids::BlockId;
use ethereum_types::{H256, U256};
use hashdb::HashDB;

View File

@@ -33,7 +33,7 @@ use engines::EthEngine;
use error::{Error, ErrorKind as SnapshotErrorKind};
use snapshot::{Error as SnapshotError};
use hash::keccak;
use ids::BlockId;
use types::ids::BlockId;
use io::IoChannel;

View File

@@ -23,7 +23,7 @@ use std::sync::Arc;
use hash::{KECCAK_NULL_RLP};
use account_db::AccountDBMut;
use basic_account::BasicAccount;
use types::basic_account::BasicAccount;
use blockchain::{BlockChain, BlockChainDB};
use client::{Client, ChainInfo};
use engines::EthEngine;
@@ -142,7 +142,7 @@ pub fn compare_dbs(one: &HashDB<KeccakHasher, DBValue>, two: &HashDB<KeccakHashe
/// Take a snapshot from the given client into a temporary file.
/// Return a snapshot reader for it.
pub fn snap(client: &Client) -> (Box<SnapshotReader>, TempDir) {
use ids::BlockId;
use types::ids::BlockId;
let tempdir = TempDir::new("").unwrap();
let path = tempdir.path().join("file");

View File

@@ -26,7 +26,7 @@ use ethkey::Secret;
use snapshot::tests::helpers as snapshot_helpers;
use spec::Spec;
use test_helpers::generate_dummy_client_with_spec_and_accounts;
use transaction::{Transaction, Action, SignedTransaction};
use types::transaction::{Transaction, Action, SignedTransaction};
use tempdir::TempDir;
use ethereum_types::Address;

View File

@@ -22,7 +22,7 @@ use std::sync::Arc;
use tempdir::TempDir;
use blockchain::BlockProvider;
use client::{Client, ClientConfig, ImportBlock, BlockInfo};
use ids::BlockId;
use types::ids::BlockId;
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
use snapshot::service::{Service, ServiceParams};
use snapshot::{chunk_state, chunk_secondary, ManifestData, Progress, SnapshotService, RestorationStatus};
@@ -153,7 +153,7 @@ fn guards_delete_folders() {
#[test]
fn keep_ancient_blocks() {
::env_logger::init().ok();
::env_logger::try_init().ok();
// Test variables
const NUM_BLOCKS: u64 = 500;
@@ -272,7 +272,7 @@ fn keep_ancient_blocks() {
#[test]
fn recover_aborted_recovery() {
::env_logger::init().ok();
::env_logger::try_init().ok();
const NUM_BLOCKS: u32 = 400;
let gas_prices = vec![1.into(), 2.into(), 3.into(), 999.into()];

View File

@@ -20,7 +20,7 @@ use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use hash::{KECCAK_NULL_RLP, keccak};
use basic_account::BasicAccount;
use types::basic_account::BasicAccount;
use snapshot::account;
use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS};
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};

View File

@@ -18,7 +18,7 @@
use parking_lot::Mutex;
use client::{BlockInfo, Client, ChainNotify, NewBlocks, ClientIoMessage};
use ids::BlockId;
use types::ids::BlockId;
use io::IoChannel;
use ethereum_types::H256;

View File

@@ -29,10 +29,12 @@ use memorydb::MemoryDB;
use parking_lot::RwLock;
use rlp::{Rlp, RlpStream};
use rustc_hex::{FromHex, ToHex};
use types::BlockNumber;
use types::encoded;
use types::header::Header;
use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
use builtin::Builtin;
use encoded;
use engines::{
EthEngine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority,
AuthorityRound, DEFAULT_BLOCKHASH_CONTRACT
@@ -40,7 +42,6 @@ use engines::{
use error::Error;
use executive::Executive;
use factory::Factories;
use header::{BlockNumber, Header};
use machine::EthereumMachine;
use pod_state::PodState;
use spec::Genesis;
@@ -840,7 +841,7 @@ impl Spec {
/// initialize genesis epoch data, using in-memory database for
/// constructor.
pub fn genesis_epoch_data(&self) -> Result<Vec<u8>, String> {
use transaction::{Action, Transaction};
use types::transaction::{Action, Transaction};
use journaldb;
use kvdb_memorydb;
@@ -989,8 +990,9 @@ mod tests {
use super::*;
use state::State;
use test_helpers::get_temp_state_db;
use views::BlockView;
use tempdir::TempDir;
use types::view;
use types::views::BlockView;
// https://github.com/paritytech/parity-ethereum/issues/1840
#[test]

View File

@@ -31,7 +31,7 @@ use ethtrie::{TrieFactory, TrieDB, SecTrieDB, Result as TrieResult};
use pod_account::*;
use rlp::{RlpStream, encode};
use lru_cache::LruCache;
use basic_account::BasicAccount;
use types::basic_account::BasicAccount;
use std::cell::{RefCell, Cell};

View File

@@ -26,7 +26,7 @@ use std::fmt;
use std::sync::Arc;
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY};
use receipt::{Receipt, TransactionOutcome};
use types::receipt::{Receipt, TransactionOutcome};
use machine::EthereumMachine as Machine;
use vm::EnvInfo;
use error::Error;
@@ -38,7 +38,7 @@ use pod_state::{self, PodState};
use types::basic_account::BasicAccount;
use executed::{Executed, ExecutionError};
use types::state_diff::StateDiff;
use transaction::SignedTransaction;
use types::transaction::SignedTransaction;
use state_db::StateDB;
use factory::VmFactory;
@@ -1316,7 +1316,7 @@ mod tests {
use machine::EthereumMachine;
use vm::EnvInfo;
use spec::*;
use transaction::*;
use types::transaction::*;
use ethcore_logger::init_log;
use trace::{FlatTrace, TraceError, trace};
use evm::CallType;

View File

@@ -17,7 +17,7 @@
//! Execution environment substate.
use std::collections::HashSet;
use ethereum_types::Address;
use log_entry::LogEntry;
use types::log_entry::LogEntry;
use evm::{Schedule, CleanDustMode};
use super::CleanupMode;
@@ -69,7 +69,7 @@ impl Substate {
#[cfg(test)]
mod tests {
use super::Substate;
use log_entry::LogEntry;
use types::log_entry::LogEntry;
#[test]
fn created() {

View File

@@ -26,13 +26,14 @@ use db::COL_ACCOUNT_BLOOM;
use ethereum_types::{H256, Address};
use hash::keccak;
use hashdb::HashDB;
use keccak_hasher::KeccakHasher;
use header::BlockNumber;
use journaldb::JournalDB;
use keccak_hasher::KeccakHasher;
use kvdb::{KeyValueDB, DBTransaction, DBValue};
use lru_cache::LruCache;
use memory_cache::MemoryLruCache;
use parking_lot::Mutex;
use types::BlockNumber;
use state::{self, Account};
/// Value used to initialize bloom bitmap size.

View File

@@ -19,32 +19,35 @@
use std::path::Path;
use std::sync::Arc;
use std::{fs, io};
use account_provider::AccountProvider;
use ethereum_types::{H256, U256, Address};
use block::{OpenBlock, Drain};
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler, Config as BlockChainConfig, ExtrasInsert};
use blooms_db;
use bytes::Bytes;
use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock};
use ethereum_types::{H256, U256, Address};
use ethkey::KeyPair;
use evm::Factory as EvmFactory;
use factory::Factories;
use hash::keccak;
use header::Header;
use io::*;
use miner::Miner;
use parking_lot::RwLock;
use rlp::{self, RlpStream};
use spec::Spec;
use state_db::StateDB;
use state::*;
use transaction::{Action, Transaction, SignedTransaction};
use views::BlockView;
use blooms_db;
use io::IoChannel;
use kvdb::KeyValueDB;
use kvdb_rocksdb::{self, Database, DatabaseConfig};
use parking_lot::RwLock;
use rlp::{self, RlpStream};
use tempdir::TempDir;
use types::transaction::{Action, Transaction, SignedTransaction};
use types::encoded;
use types::header::Header;
use types::view;
use types::views::BlockView;
use account_provider::AccountProvider;
use block::{OpenBlock, Drain};
use client::{Client, ClientConfig, ChainInfo, ImportBlock, ChainNotify, ChainMessageType, PrepareOpenBlock};
use factory::Factories;
use miner::Miner;
use spec::Spec;
use state::*;
use state_db::StateDB;
use verification::queue::kind::blocks::Unverified;
use encoded;
/// Creates test block with corresponding header
pub fn create_test_block(header: &Header) -> Bytes {

View File

@@ -0,0 +1,61 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use blockchain::BlockProvider;
use test_helpers::{
generate_dummy_blockchain,
generate_dummy_blockchain_with_extra,
generate_dummy_empty_blockchain,
};
#[test]
fn can_contain_arbitrary_block_sequence() {
let bc = generate_dummy_blockchain(50);
assert_eq!(bc.best_block_number(), 49);
}
#[test]
fn can_collect_garbage() {
let bc = generate_dummy_blockchain(3000);
assert_eq!(bc.best_block_number(), 2999);
let best_hash = bc.best_block_hash();
let mut block_header = bc.block_header_data(&best_hash);
while !block_header.is_none() {
block_header = bc.block_header_data(&block_header.unwrap().parent_hash());
}
assert!(bc.cache_size().blocks > 1024 * 1024);
for _ in 0..2 {
bc.collect_garbage();
}
assert!(bc.cache_size().blocks < 1024 * 1024);
}
#[test]
fn can_contain_arbitrary_block_sequence_with_extra() {
let bc = generate_dummy_blockchain_with_extra(25);
assert_eq!(bc.best_block_number(), 24);
}
#[test]
fn can_contain_only_genesis_block() {
let bc = generate_dummy_empty_blockchain();
assert_eq!(bc.best_block_number(), 0);
}

View File

@@ -16,27 +16,29 @@
use std::str::FromStr;
use std::sync::Arc;
use ethereum_types::{U256, Address};
use ethkey::KeyPair;
use hash::keccak;
use io::IoChannel;
use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock};
use state::{self, State, CleanupMode};
use executive::{Executive, TransactOptions};
use ethereum;
use tempdir::TempDir;
use types::transaction::{PendingTransaction, Transaction, Action, Condition};
use types::filter::Filter;
use types::view;
use types::views::BlockView;
use block::IsBlock;
use client::{BlockChainClient, Client, ClientConfig, BlockId, ChainInfo, BlockInfo, PrepareOpenBlock, ImportSealedBlock, ImportBlock};
use ethereum;
use executive::{Executive, TransactOptions};
use miner::{Miner, PendingOrdering, MinerService};
use spec::Spec;
use state::{self, State, CleanupMode};
use test_helpers::{
self,
generate_dummy_client, push_blocks_to_client, get_test_client_with_blocks, get_good_dummy_block_seq,
generate_dummy_client_with_data, get_good_dummy_block, get_bad_state_dummy_block
};
use types::filter::Filter;
use ethereum_types::{U256, Address};
use miner::{Miner, PendingOrdering};
use spec::Spec;
use views::BlockView;
use ethkey::KeyPair;
use transaction::{PendingTransaction, Transaction, Action, Condition};
use miner::MinerService;
use tempdir::TempDir;
use test_helpers;
use verification::queue::kind::blocks::Unverified;
#[test]

View File

@@ -24,7 +24,7 @@ use executive::Executive;
use state::Substate;
use test_helpers::get_temp_state_with_factory;
use trace::{NoopVMTracer, NoopTracer};
use transaction::SYSTEM_ADDRESS;
use types::transaction::SYSTEM_ADDRESS;
use rustc_hex::FromHex;

View File

@@ -15,5 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
mod client;
mod blockchain;
mod evm;
mod trace;

View File

@@ -26,14 +26,15 @@ use client::*;
use test_helpers::get_temp_state_db;
use client::{BlockChainClient, Client, ClientConfig};
use std::sync::Arc;
use header::Header;
use miner::Miner;
use transaction::{Action, Transaction};
use views::BlockView;
use types::transaction::{Action, Transaction};
use trace::{RewardType, LocalizedTrace};
use trace::trace::Action::Reward;
use test_helpers;
use verification::queue::kind::blocks::Unverified;
use types::header::Header;
use types::view;
use types::views::BlockView;
#[test]
fn can_trace_block_and_uncle_reward() {

View File

@@ -17,16 +17,19 @@
//! Trace database.
use std::collections::HashMap;
use std::sync::Arc;
use blockchain::{BlockChainDB};
use heapsize::HeapSizeOf;
use blockchain::BlockChainDB;
use db::cache_manager::CacheManager;
use db::{self, Key, Writable, Readable, CacheUpdatePolicy};
use ethereum_types::{H256, H264};
use heapsize::HeapSizeOf;
use kvdb::{DBTransaction};
use parking_lot::RwLock;
use header::BlockNumber;
use types::BlockNumber;
use trace::{LocalizedTrace, Config, Filter, Database as TraceDatabase, ImportRequest, DatabaseExtras};
use db::{self, Key, Writable, Readable, CacheUpdatePolicy};
use super::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
use cache_manager::CacheManager;
use trace::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
const TRACE_DB_VER: &'static [u8] = b"1.0";
@@ -333,7 +336,7 @@ mod tests {
use std::sync::Arc;
use ethereum_types::{H256, U256, Address};
use kvdb::{DBTransaction};
use header::BlockNumber;
use types::BlockNumber;
use trace::{Config, TraceDB, Database as TraceDatabase, DatabaseExtras, ImportRequest};
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
use trace::trace::{Call, Action, Res};

View File

@@ -16,7 +16,8 @@
//! Traces import request.
use ethereum_types::H256;
use header::BlockNumber;
use types::BlockNumber;
use trace::FlatBlockTraces;
/// Traces import request.

View File

@@ -39,7 +39,7 @@ pub use self::types::filter::{Filter, AddressesFilter};
use ethereum_types::{H256, U256, Address};
use kvdb::DBTransaction;
use vm::{Error as VmError, ActionParams};
use header::BlockNumber;
use types::BlockNumber;
/// This trait is used by executive to build traces.
pub trait Tracer: Send {

View File

@@ -18,7 +18,7 @@
use ethereum_types::H256;
use super::trace::{Action, Res};
use header::BlockNumber;
use types::BlockNumber;
/// Localized trace.
#[derive(Debug, PartialEq, Clone)]

View File

@@ -0,0 +1,44 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethereum transaction
use evm::Schedule;
use types::transaction::{self, Action};
/// Extends transaction with gas verification method.
pub trait Transaction {
/// Get the transaction cost in gas for this transaction.
fn gas_required(&self, schedule: &Schedule) -> u64;
}
impl Transaction for transaction::Transaction {
fn gas_required(&self, schedule: &Schedule) -> u64 {
gas_required_for(match self.action {
Action::Create => true,
Action::Call(_) => false
}, &self.data, schedule)
}
}
/// Get the transaction cost in gas for the given params.
fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> u64 {
data.iter().fold(
(if is_create {schedule.tx_create_gas} else {schedule.tx_gas}) as u64,
|g, b| g + (match *b { 0 => schedule.tx_data_zero_gas, _ => schedule.tx_data_non_zero_gas }) as u64
)
}

View File

@@ -23,7 +23,7 @@ use ethabi::FunctionOutputDecoder;
use client::{BlockInfo, CallContract, BlockId};
use parking_lot::Mutex;
use spec::CommonParams;
use transaction::{Action, SignedTransaction};
use types::transaction::{Action, SignedTransaction};
use types::BlockNumber;
use hash::KECCAK_EMPTY;
@@ -149,7 +149,7 @@ mod test {
use io::IoChannel;
use ethkey::{Secret, KeyPair};
use super::TransactionFilter;
use transaction::{Transaction, Action};
use types::transaction::{Transaction, Action};
use tempdir::TempDir;
use test_helpers;

View File

@@ -19,7 +19,7 @@
use client::{BlockInfo, CallContract};
use engines::EthEngine;
use error::Error;
use header::Header;
use types::header::Header;
use super::Verifier;
use super::verification;

View File

@@ -19,7 +19,7 @@
use client::{BlockInfo, CallContract};
use engines::EthEngine;
use error::Error;
use header::Header;
use types::header::Header;
use super::{verification, Verifier};
/// A no-op verifier -- this will verify everything it's given immediately.

View File

@@ -70,9 +70,9 @@ pub mod blocks {
use engines::EthEngine;
use error::{Error, ErrorKind, BlockError};
use header::Header;
use types::header::Header;
use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered};
use transaction::UnverifiedTransaction;
use types::transaction::UnverifiedTransaction;
use heapsize::HeapSizeOf;
use ethereum_types::{H256, U256};
@@ -190,7 +190,7 @@ pub mod headers {
use engines::EthEngine;
use error::Error;
use header::Header;
use types::header::Header;
use verification::verify_header_params;
use ethereum_types::{H256, U256};

View File

@@ -117,9 +117,9 @@ pub enum Status {
Unknown,
}
impl Into<::block_status::BlockStatus> for Status {
fn into(self) -> ::block_status::BlockStatus {
use ::block_status::BlockStatus;
impl Into<::types::block_status::BlockStatus> for Status {
fn into(self) -> ::types::block_status::BlockStatus {
use ::types::block_status::BlockStatus;
match self {
Status::Queued => BlockStatus::Queued,
Status::Bad => BlockStatus::Bad,
@@ -744,8 +744,9 @@ mod tests {
use super::kind::blocks::Unverified;
use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block};
use error::*;
use views::BlockView;
use bytes::Bytes;
use types::view;
use types::views::BlockView;
// create a test block queue.
// auto_scaling enables verifier adjustment.

View File

@@ -35,8 +35,8 @@ use blockchain::*;
use client::{BlockInfo, CallContract};
use engines::EthEngine;
use error::{BlockError, Error};
use header::{BlockNumber, Header};
use transaction::SignedTransaction;
use types::{BlockNumber, header::Header};
use types::transaction::SignedTransaction;
use verification::queue::kind::blocks::Unverified;
/// Preprocessed block data gathered in `verify_block_unordered` call
@@ -378,7 +378,7 @@ mod tests {
use std::time::{SystemTime, UNIX_EPOCH};
use ethereum_types::{H256, BloomRef, U256};
use blockchain::{BlockDetails, TransactionAddress, BlockReceipts};
use encoded;
use types::encoded;
use hash::keccak;
use engines::EthEngine;
use error::BlockError::*;
@@ -386,7 +386,7 @@ mod tests {
use ethkey::{Random, Generator};
use spec::{CommonParams, Spec};
use test_helpers::{create_test_block_with_data, create_test_block};
use transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action};
use types::transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action};
use types::log_entry::{LogEntry, LocalizedLogEntry};
use rlp;
use triehash::ordered_trie_root;
@@ -638,14 +638,18 @@ mod tests {
good_uncle1.set_parent_hash(parent8.hash());
good_uncle1.set_difficulty(parent8.difficulty().clone() + diff_inc);
good_uncle1.set_timestamp(parent8.timestamp() + 10);
good_uncle1.extra_data_mut().push(1u8);
let mut ex = good_uncle1.extra_data().to_vec();
ex.push(1u8);
good_uncle1.set_extra_data(ex);
let mut good_uncle2 = good.clone();
good_uncle2.set_number(8);
good_uncle2.set_parent_hash(parent7.hash());
good_uncle2.set_difficulty(parent7.difficulty().clone() + diff_inc);
good_uncle2.set_timestamp(parent7.timestamp() + 10);
good_uncle2.extra_data_mut().push(2u8);
let mut ex = good_uncle2.extra_data().to_vec();
ex.push(2u8);
good_uncle2.set_extra_data(ex);
let good_uncles = vec![ good_uncle1.clone(), good_uncle2.clone() ];
let mut uncles_rlp = RlpStream::new();
@@ -702,12 +706,16 @@ mod tests {
TooMuchGasUsed(OutOfBounds { max: Some(header.gas_limit().clone()), min: None, found: header.gas_used().clone() }));
header = good.clone();
header.extra_data_mut().resize(engine.maximum_extra_data_size() + 1, 0u8);
let mut ex = header.extra_data().to_vec();
ex.resize(engine.maximum_extra_data_size() + 1, 0u8);
header.set_extra_data(ex);
check_fail(basic_test(&create_test_block(&header), engine),
ExtraDataOutOfBounds(OutOfBounds { max: Some(engine.maximum_extra_data_size()), min: None, found: header.extra_data().len() }));
header = good.clone();
header.extra_data_mut().resize(engine.maximum_extra_data_size() + 1, 0u8);
let mut ex = header.extra_data().to_vec();
ex.resize(engine.maximum_extra_data_size() + 1, 0u8);
header.set_extra_data(ex);
check_fail(basic_test(&create_test_block(&header), engine),
ExtraDataOutOfBounds(OutOfBounds { max: Some(engine.maximum_extra_data_size()), min: None, found: header.extra_data().len() }));
@@ -778,7 +786,7 @@ mod tests {
#[test]
fn dust_protection() {
use ethkey::{Generator, Random};
use transaction::{Transaction, Action};
use types::transaction::{Transaction, Action};
use machine::EthereumMachine;
use engines::NullEngine;

View File

@@ -19,7 +19,7 @@
use client::{BlockInfo, CallContract};
use engines::EthEngine;
use error::Error;
use header::Header;
use types::header::Header;
use super::verification;
/// Should be used to verify blocks.

View File

@@ -1,192 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto block rlp.
use bytes::Bytes;
use ethereum_types::H256;
use hash::keccak;
use header::Header;
use transaction::{UnverifiedTransaction, LocalizedTransaction};
use views::{TransactionView, HeaderView};
use super::ViewRlp;
/// View onto block rlp.
pub struct BlockView<'a> {
rlp: ViewRlp<'a>
}
impl<'a> BlockView<'a> {
/// Creates new view onto block from rlp.
/// Use the `view!` macro to create this view in order to capture debugging info.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate ethcore;
///
/// use ethcore::views::{BlockView};
///
/// fn main() {
/// let bytes : &[u8] = &[];
/// let block_view = view!(BlockView, bytes);
/// }
/// ```
pub fn new(rlp: ViewRlp<'a>) -> BlockView<'a> {
BlockView {
rlp: rlp
}
}
/// Block header hash.
pub fn hash(&self) -> H256 {
self.header_view().hash()
}
/// Return reference to underlaying rlp.
pub fn rlp(&self) -> &ViewRlp<'a> {
&self.rlp
}
/// Create new Header object from header rlp.
pub fn header(&self) -> Header {
self.rlp.val_at(0)
}
/// Return header rlp.
pub fn header_rlp(&self) -> ViewRlp<'a> {
self.rlp.at(0)
}
/// Create new header view obto block head rlp.
pub fn header_view(&self) -> HeaderView<'a> {
HeaderView::new(self.header_rlp())
}
/// Return List of transactions in given block.
pub fn transactions(&self) -> Vec<UnverifiedTransaction> {
self.rlp.list_at(1)
}
/// Return List of transactions with additional localization info.
pub fn localized_transactions(&self) -> Vec<LocalizedTransaction> {
let header = self.header_view();
let block_hash = header.hash();
let block_number = header.number();
self.transactions()
.into_iter()
.enumerate()
.map(|(i, t)| LocalizedTransaction {
signed: t,
block_hash: block_hash.clone(),
block_number: block_number,
transaction_index: i,
cached_sender: None,
}).collect()
}
/// Return the raw rlp for the transactions in the given block.
pub fn transactions_rlp(&self) -> ViewRlp<'a> {
self.rlp.at(1)
}
/// Return number of transactions in given block, without deserializing them.
pub fn transactions_count(&self) -> usize {
self.transactions_rlp().iter().count()
}
/// Return List of transactions in given block.
pub fn transaction_views(&self) -> Vec<TransactionView<'a>> {
self.transactions_rlp().iter().map(TransactionView::new).collect()
}
/// Return transaction hashes.
pub fn transaction_hashes(&self) -> Vec<H256> {
self.transactions_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect()
}
/// Returns transaction at given index without deserializing unnecessary data.
pub fn transaction_at(&self, index: usize) -> Option<UnverifiedTransaction> {
self.transactions_rlp().iter().nth(index).map(|rlp| rlp.as_val())
}
/// Returns localized transaction at given index.
pub fn localized_transaction_at(&self, index: usize) -> Option<LocalizedTransaction> {
let header = self.header_view();
let block_hash = header.hash();
let block_number = header.number();
self.transaction_at(index).map(|t| LocalizedTransaction {
signed: t,
block_hash: block_hash,
block_number: block_number,
transaction_index: index,
cached_sender: None,
})
}
/// Returns raw rlp for the uncles in the given block
pub fn uncles_rlp(&self) -> ViewRlp<'a> {
self.rlp.at(2)
}
/// Return list of uncles of given block.
pub fn uncles(&self) -> Vec<Header> {
self.rlp.list_at(2)
}
/// Return number of uncles in given block, without deserializing them.
pub fn uncles_count(&self) -> usize {
self.uncles_rlp().iter().count()
}
/// Return List of transactions in given block.
pub fn uncle_views(&self) -> Vec<HeaderView<'a>> {
self.uncles_rlp().iter().map(HeaderView::new).collect()
}
/// Return list of uncle hashes of given block.
pub fn uncle_hashes(&self) -> Vec<H256> {
self.uncles_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect()
}
/// Return nth uncle.
pub fn uncle_at(&self, index: usize) -> Option<Header> {
self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_val())
}
/// Return nth uncle rlp.
pub fn uncle_rlp_at(&self, index: usize) -> Option<Bytes> {
self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_raw().to_vec())
}
}
#[cfg(test)]
mod tests {
use rustc_hex::FromHex;
use super::BlockView;
#[test]
fn test_block_view() {
// that's rlp of block created with ethash engine.
let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap();
let view = view!(BlockView, &rlp);
assert_eq!(view.hash(), "2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259".into());
assert_eq!(view.transactions_count(), 1);
assert_eq!(view.uncles_count(), 0);
}
}

View File

@@ -1,165 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto block body rlp.
use bytes::Bytes;
use ethereum_types::H256;
use hash::keccak;
use header::{Header, BlockNumber};
use transaction::{LocalizedTransaction, UnverifiedTransaction};
use views::{TransactionView, HeaderView};
use super::ViewRlp;
/// View onto block rlp.
pub struct BodyView<'a> {
rlp: ViewRlp<'a>
}
impl<'a> BodyView<'a> {
/// Creates new view onto block body from rlp.
/// Use the `view!` macro to create this view in order to capture debugging info.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate ethcore;
///
/// use ethcore::views::{BodyView};
///
/// fn main() {
/// let bytes : &[u8] = &[];
/// let body_view = view!(BodyView, bytes);
/// }
/// ```
pub fn new(rlp: ViewRlp<'a>) -> BodyView<'a> {
BodyView {
rlp: rlp
}
}
/// Return reference to underlaying rlp.
pub fn rlp(&self) -> &ViewRlp<'a> {
&self.rlp
}
/// Return List of transactions in given block.
pub fn transactions(&self) -> Vec<UnverifiedTransaction> {
self.rlp.list_at(0)
}
/// Return List of transactions with additional localization info.
pub fn localized_transactions(&self, block_hash: &H256, block_number: BlockNumber) -> Vec<LocalizedTransaction> {
self.transactions()
.into_iter()
.enumerate()
.map(|(i, t)| LocalizedTransaction {
signed: t,
block_hash: block_hash.clone(),
block_number: block_number,
transaction_index: i,
cached_sender: None,
}).collect()
}
/// Return the raw rlp for the transactions in the given block.
pub fn transactions_rlp(&self) -> ViewRlp<'a> {
self.rlp.at(0)
}
/// Return number of transactions in given block, without deserializing them.
pub fn transactions_count(&self) -> usize {
self.transactions_rlp().item_count()
}
/// Return List of transactions in given block.
pub fn transaction_views(&self) -> Vec<TransactionView<'a>> {
self.transactions_rlp().iter().map(TransactionView::new).collect()
}
/// Return transaction hashes.
pub fn transaction_hashes(&self) -> Vec<H256> {
self.transactions_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect()
}
/// Returns transaction at given index without deserializing unnecessary data.
pub fn transaction_at(&self, index: usize) -> Option<UnverifiedTransaction> {
self.transactions_rlp().iter().nth(index).map(|rlp| rlp.as_val())
}
/// Returns localized transaction at given index.
pub fn localized_transaction_at(&self, block_hash: &H256, block_number: BlockNumber, index: usize) -> Option<LocalizedTransaction> {
self.transaction_at(index).map(|t| LocalizedTransaction {
signed: t,
block_hash: block_hash.clone(),
block_number: block_number,
transaction_index: index,
cached_sender: None,
})
}
/// Returns raw rlp for the uncles in the given block
pub fn uncles_rlp(&self) -> ViewRlp<'a> {
self.rlp.at(1)
}
/// Return list of uncles of given block.
pub fn uncles(&self) -> Vec<Header> {
self.rlp.list_at(1)
}
/// Return number of uncles in given block, without deserializing them.
pub fn uncles_count(&self) -> usize {
self.uncles_rlp().item_count()
}
/// Return List of transactions in given block.
pub fn uncle_views(&self) -> Vec<HeaderView<'a>> {
self.uncles_rlp().iter().map(HeaderView::new).collect()
}
/// Return list of uncle hashes of given block.
pub fn uncle_hashes(&self) -> Vec<H256> {
self.uncles_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect()
}
/// Return nth uncle.
pub fn uncle_at(&self, index: usize) -> Option<Header> {
self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_val())
}
/// Return nth uncle rlp.
pub fn uncle_rlp_at(&self, index: usize) -> Option<Bytes> {
self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_raw().to_vec())
}
}
#[cfg(test)]
mod tests {
use rustc_hex::FromHex;
use super::BodyView;
use blockchain::BlockChain;
#[test]
fn test_block_view() {
// that's rlp of block created with ethash engine.
let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap();
let body = BlockChain::block_to_body(&rlp);
let view = view!(BodyView, &body);
assert_eq!(view.transactions_count(), 1);
assert_eq!(view.uncles_count(), 0);
}
}

View File

@@ -1,150 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto block header rlp
use bytes::Bytes;
use ethereum_types::{H256, Bloom, U256, Address};
use hash::keccak;
use header::BlockNumber;
use rlp::{self};
use super::ViewRlp;
/// View onto block header rlp.
pub struct HeaderView<'a> {
rlp: ViewRlp<'a>
}
impl<'a> HeaderView<'a> {
/// Creates a new Header view from valid ViewRlp
/// Use the `view!` macro to create this view in order to capture debugging info.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate ethcore;
///
/// use ethcore::views::{HeaderView};
///
/// fn main() {
/// let bytes : &[u8] = &[];
/// let tx_view = view!(HeaderView, bytes);
/// }
/// ```
pub fn new(rlp: ViewRlp<'a>) -> HeaderView<'a> {
HeaderView {
rlp
}
}
/// Returns header hash.
pub fn hash(&self) -> H256 {
keccak(self.rlp.rlp.as_raw())
}
/// Returns raw rlp.
pub fn rlp(&self) -> &ViewRlp<'a> { &self.rlp }
/// Returns parent hash.
pub fn parent_hash(&self) -> H256 { self.rlp.val_at(0) }
/// Returns uncles hash.
pub fn uncles_hash(&self) -> H256 { self.rlp.val_at(1) }
/// Returns author.
pub fn author(&self) -> Address { self.rlp.val_at(2) }
/// Returns state root.
pub fn state_root(&self) -> H256 { self.rlp.val_at(3) }
/// Returns transactions root.
pub fn transactions_root(&self) -> H256 { self.rlp.val_at(4) }
/// Returns block receipts root.
pub fn receipts_root(&self) -> H256 { self.rlp.val_at(5) }
/// Returns block log bloom.
pub fn log_bloom(&self) -> Bloom { self.rlp.val_at(6) }
/// Returns block difficulty.
pub fn difficulty(&self) -> U256 { self.rlp.val_at(7) }
/// Returns block number.
pub fn number(&self) -> BlockNumber { self.rlp.val_at(8) }
/// Returns block gas limit.
pub fn gas_limit(&self) -> U256 { self.rlp.val_at(9) }
/// Returns block gas used.
pub fn gas_used(&self) -> U256 { self.rlp.val_at(10) }
/// Returns timestamp.
pub fn timestamp(&self) -> u64 { self.rlp.val_at(11) }
/// Returns block extra data.
pub fn extra_data(&self) -> Bytes { self.rlp.val_at(12) }
/// Returns a vector of post-RLP-encoded seal fields.
pub fn seal(&self) -> Vec<Bytes> {
let mut seal = vec![];
for i in 13..self.rlp.item_count() {
seal.push(self.rlp.at(i).as_raw().to_vec());
}
seal
}
/// Returns a vector of seal fields (RLP-decoded).
pub fn decode_seal(&self) -> Result<Vec<Bytes>, rlp::DecoderError> {
let seal = self.seal();
seal.into_iter()
.map(|s| rlp::Rlp::new(&s).data().map(|x| x.to_vec()))
.collect()
}
}
#[cfg(test)]
mod tests {
use rustc_hex::FromHex;
use ethereum_types::Bloom;
use super::HeaderView;
#[test]
fn test_header_view() {
// that's rlp of block header created with ethash engine.
let rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
let view = view!(HeaderView, &rlp);
assert_eq!(view.hash(), "2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259".into());
assert_eq!(view.parent_hash(), "d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7".into());
assert_eq!(view.uncles_hash(), "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347".into());
assert_eq!(view.author(), "8888f1f195afa192cfee860698584c030f4c9db1".into());
assert_eq!(view.state_root(), "5fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25".into());
assert_eq!(view.transactions_root(), "88d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158".into());
assert_eq!(view.receipts_root(), "07c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1".into());
assert_eq!(view.log_bloom(), Bloom::default());
assert_eq!(view.difficulty(), 0x020080.into());
assert_eq!(view.number(), 3);
assert_eq!(view.gas_limit(), 0x2fefba.into());
assert_eq!(view.gas_used(), 0x524d.into());
assert_eq!(view.timestamp(), 0x56_8e_93_2a);
assert_eq!(view.extra_data(), vec![] as Vec<u8>);
assert_eq!(view.seal(), vec![mix_hash, nonce]);
}
}

View File

@@ -1,41 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Block oriented views onto rlp.
#[macro_use]
mod view_rlp;
mod block;
mod body;
mod header;
mod transaction;
pub use self::view_rlp::ViewRlp;
pub use self::block::BlockView;
pub use self::body::BodyView;
pub use self::header::HeaderView;
pub use self::transaction::TransactionView;
#[cfg(test)]
mod tests {
use super::HeaderView;
#[test]
#[should_panic]
fn should_include_file_line_number_in_panic_for_invalid_rlp() {
let _ = view!(HeaderView, &[]).parent_hash();
}
}

View File

@@ -1,106 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto transaction rlp
use bytes::Bytes;
use ethereum_types::{H256, U256};
use hash::keccak;
// use rlp::{Rlp, Decodable};
use super::ViewRlp;
/// View onto transaction rlp.
pub struct TransactionView<'a> {
rlp: ViewRlp<'a>
}
impl<'a> TransactionView<'a> {
/// Creates new view onto valid transaction rlp.
/// Use the `view!` macro to create this view in order to capture debugging info.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate ethcore;
///
/// use ethcore::views::{TransactionView};
///
/// fn main() {
/// let bytes : &[u8] = &[];
/// let tx_view = view!(TransactionView, bytes);
/// }
/// ```
pub fn new(rlp: ViewRlp<'a>) -> TransactionView<'a> {
TransactionView {
rlp: rlp
}
}
/// Return reference to underlaying rlp.
pub fn rlp(&self) -> &ViewRlp<'a> {
&self.rlp
}
/// Returns transaction hash.
pub fn hash(&self) -> H256 {
keccak(self.rlp.as_raw())
}
/// Get the nonce field of the transaction.
pub fn nonce(&self) -> U256 { self.rlp.val_at(0) }
/// Get the gas_price field of the transaction.
pub fn gas_price(&self) -> U256 { self.rlp.val_at(1) }
/// Get the gas field of the transaction.
pub fn gas(&self) -> U256 { self.rlp.val_at(2) }
/// Get the value field of the transaction.
pub fn value(&self) -> U256 { self.rlp.val_at(4) }
/// Get the data field of the transaction.
pub fn data(&self) -> Bytes { self.rlp.val_at(5) }
/// Get the v field of the transaction.
pub fn v(&self) -> u8 { let r: u16 = self.rlp.val_at(6); r as u8 }
/// Get the r field of the transaction.
pub fn r(&self) -> U256 { self.rlp.val_at(7) }
/// Get the s field of the transaction.
pub fn s(&self) -> U256 { self.rlp.val_at(8) }
}
#[cfg(test)]
mod tests {
use rustc_hex::FromHex;
use super::TransactionView;
#[test]
fn test_transaction_view() {
let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap();
let view = view!(TransactionView, &rlp);
assert_eq!(view.nonce(), 0.into());
assert_eq!(view.gas_price(), 1.into());
assert_eq!(view.gas(), 0x61a8.into());
assert_eq!(view.value(), 0xa.into());
assert_eq!(view.data(), "0000000000000000000000000000000000000000000000000000000000".from_hex().unwrap());
assert_eq!(view.r(), "48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353".into());
assert_eq!(view.s(), "efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".into());
assert_eq!(view.v(), 0x1b);
}
}

View File

@@ -1,135 +0,0 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Wrapper for view rlp expected to be valid with debug info
use rlp::{Rlp, Decodable, DecoderError};
/// Wrapper for trusted rlp, which is expected to be valid, for use in views
/// When created with view!, records the file and line where it was created for debugging
pub struct ViewRlp<'a> {
/// Wrapped Rlp, expected to be valid
pub rlp: Rlp<'a>,
file: &'a str,
line: u32,
}
impl<'a, 'view> ViewRlp<'a> where 'a : 'view {
#[doc(hidden)]
pub fn new(bytes: &'a [u8], file: &'a str, line: u32) -> Self {
ViewRlp {
rlp: Rlp::new(bytes),
file,
line
}
}
/// Returns a new instance replacing existing rlp with new rlp, maintaining debug info
fn new_from_rlp(&self, rlp: Rlp<'a>) -> Self {
ViewRlp {
rlp,
file: self.file,
line: self.line
}
}
fn maybe_at(&self, index: usize) -> Option<ViewRlp<'a>> {
self.rlp.at(index)
.map(|rlp| self.new_from_rlp(rlp))
.ok()
}
fn expect_valid_rlp<T>(&self, r: Result<T, DecoderError>) -> T {
r.unwrap_or_else(|e| panic!(
"View rlp is trusted and should be valid. Constructed in {} on line {}: {}",
self.file,
self.line,
e
))
}
/// Returns rlp at the given index, panics if no rlp at that index
pub fn at(&self, index: usize) -> ViewRlp<'a> {
let rlp = self.expect_valid_rlp(self.rlp.at(index));
self.new_from_rlp(rlp)
}
/// Returns an iterator over all rlp values
pub fn iter(&'view self) -> ViewRlpIterator<'a, 'view> {
self.into_iter()
}
/// Returns decoded value of this rlp, panics if rlp not valid
pub fn as_val<T>(&self) -> T where T: Decodable {
self.expect_valid_rlp(self.rlp.as_val())
}
/// Returns decoded value at the given index, panics not present or valid at that index
pub fn val_at<T>(&self, index: usize) -> T where T : Decodable {
self.expect_valid_rlp(self.rlp.val_at(index))
}
/// Returns decoded list of values, panics if rlp is invalid
pub fn list_at<T>(&self, index: usize) -> Vec<T> where T: Decodable {
self.expect_valid_rlp(self.rlp.list_at(index))
}
/// Returns the number of items in the rlp, panics if it is not a list of rlp values
pub fn item_count(&self) -> usize {
self.expect_valid_rlp(self.rlp.item_count())
}
/// Returns raw rlp bytes
pub fn as_raw(&'view self) -> &'a [u8] {
self.rlp.as_raw()
}
}
/// Iterator over rlp-slice list elements.
pub struct ViewRlpIterator<'a, 'view> where 'a: 'view {
rlp: &'view ViewRlp<'a>,
index: usize,
}
impl<'a, 'view> IntoIterator for &'view ViewRlp<'a> where 'a: 'view {
type Item = ViewRlp<'a>;
type IntoIter = ViewRlpIterator<'a, 'view>;
fn into_iter(self) -> Self::IntoIter {
ViewRlpIterator {
rlp: self,
index: 0,
}
}
}
impl<'a, 'view> Iterator for ViewRlpIterator<'a, 'view> {
type Item = ViewRlp<'a>;
fn next(&mut self) -> Option<ViewRlp<'a>> {
let index = self.index;
let result = self.rlp.maybe_at(index);
self.index += 1;
result
}
}
#[macro_export]
macro_rules! view {
($view: ident, $bytes: expr) => {
$view::new($crate::views::ViewRlp::new($bytes, file!(), line!()))
};
}