Merge remote-tracking branch 'parity/master' into bft

Conflicts:
	ethcore/src/client/client.rs
This commit is contained in:
keorn
2016-09-05 18:16:09 +02:00
204 changed files with 8336 additions and 1513 deletions

View File

@@ -16,6 +16,7 @@
//! DB backend wrapper for Account trie
use util::*;
use rlp::NULL_RLP;
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];

View File

@@ -22,6 +22,7 @@ use state::*;
use verification::PreverifiedBlock;
use trace::FlatTrace;
use factory::Factories;
use rlp::*;
/// A block, encoded as it is on the block chain.
#[derive(Default, Debug, Clone, PartialEq)]
@@ -498,7 +499,7 @@ pub fn enact(
{
if ::log::max_log_level() >= ::log::LogLevel::Trace {
let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(), factories.clone()));
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
trace!(target: "enact", "num={}, root={}, author={}, author_balance={}\n", header.number(), s.root(), header.author(), s.balance(&header.author()));
}
}

View File

@@ -31,7 +31,7 @@ pub struct BlockInfo {
}
/// Describes location of newly inserted block.
#[derive(Clone)]
#[derive(Debug, Clone)]
pub enum BlockLocation {
/// It's part of the canon chain.
CanonChain,
@@ -43,7 +43,7 @@ pub enum BlockLocation {
BranchBecomingCanonChain(BranchBecomingCanonChainData),
}
#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct BranchBecomingCanonChainData {
/// Hash of the newest common ancestor with old canon chain.
pub ancestor: H256,

View File

@@ -18,6 +18,7 @@
use bloomchain as bc;
use util::*;
use rlp::*;
use header::*;
use super::extras::*;
use transaction::*;
@@ -830,7 +831,7 @@ impl BlockChain {
}
}
/// Applt pending insertion updates
/// Apply pending insertion updates
pub fn commit(&self) {
let mut pending_best_block = self.pending_best_block.write();
let mut pending_write_hashes = self.pending_block_hashes.write();
@@ -961,15 +962,45 @@ impl BlockChain {
let block = BlockView::new(block_bytes);
let transaction_hashes = block.transaction_hashes();
transaction_hashes.into_iter()
.enumerate()
.fold(HashMap::new(), |mut acc, (i ,tx_hash)| {
acc.insert(tx_hash, TransactionAddress {
block_hash: info.hash.clone(),
index: i
});
acc
})
match info.location {
BlockLocation::CanonChain => {
transaction_hashes.into_iter()
.enumerate()
.map(|(i ,tx_hash)| {
(tx_hash, TransactionAddress {
block_hash: info.hash.clone(),
index: i
})
})
.collect()
},
BlockLocation::BranchBecomingCanonChain(ref data) => {
let addresses = data.enacted.iter()
.flat_map(|hash| {
let bytes = self.block_body(hash).expect("Enacted block must be in database.");
let hashes = BodyView::new(&bytes).transaction_hashes();
hashes.into_iter()
.enumerate()
.map(|(i, tx_hash)| (tx_hash, TransactionAddress {
block_hash: hash.clone(),
index: i,
}))
.collect::<HashMap<H256, TransactionAddress>>()
});
let current_addresses = transaction_hashes.into_iter()
.enumerate()
.map(|(i ,tx_hash)| {
(tx_hash, TransactionAddress {
block_hash: info.hash.clone(),
index: i
})
});
addresses.chain(current_addresses).collect()
},
BlockLocation::Branch => HashMap::new(),
}
}
/// This functions returns modified blocks blooms.
@@ -1116,7 +1147,6 @@ impl BlockChain {
#[cfg(test)]
mod tests {
#![cfg_attr(feature="dev", allow(similar_names))]
use std::str::FromStr;
use std::sync::Arc;
use rustc_serialize::hex::FromHex;
use util::{Database, DatabaseConfig};
@@ -1127,7 +1157,9 @@ mod tests {
use tests::helpers::*;
use devtools::*;
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
use blockchain::extras::TransactionAddress;
use views::BlockView;
use transaction::{Transaction, Action};
fn new_db(path: &str) -> Arc<Database> {
Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path).unwrap())
@@ -1262,6 +1294,106 @@ mod tests {
// TODO: insert block that already includes one of them as an uncle to check it's not allowed.
}
#[test]
fn test_overwriting_transaction_addresses() {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let genesis = canon_chain.generate(&mut finalizer).unwrap();
let mut fork_chain = canon_chain.fork(1);
let mut fork_finalizer = finalizer.fork();
let t1 = Transaction {
nonce: 0.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(),
}.sign(&"".sha3());
let t2 = Transaction {
nonce: 1.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(),
}.sign(&"".sha3());
let t3 = Transaction {
nonce: 2.into(),
gas_price: 0.into(),
gas: 100_000.into(),
action: Action::Create,
value: 100.into(),
data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(),
}.sign(&"".sha3());
let b1a = canon_chain
.with_transaction(t1.clone())
.with_transaction(t2.clone())
.generate(&mut finalizer).unwrap();
// insert transactions in different order
let b1b = fork_chain
.with_transaction(t2.clone())
.with_transaction(t1.clone())
.generate(&mut fork_finalizer).unwrap();
let b2 = fork_chain
.with_transaction(t3.clone())
.generate(&mut fork_finalizer).unwrap();
let b1a_hash = BlockView::new(&b1a).header_view().sha3();
let b1b_hash = BlockView::new(&b1b).header_view().sha3();
let b2_hash = BlockView::new(&b2).header_view().sha3();
let t1_hash = t1.hash();
let t2_hash = t2.hash();
let t3_hash = t3.hash();
let temp = RandomTempPath::new();
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b1a, vec![]);
bc.commit();
let _ = bc.insert_block(&mut batch, &b1b, vec![]);
bc.commit();
db.write(batch).unwrap();
assert_eq!(bc.best_block_hash(), b1a_hash);
assert_eq!(bc.transaction_address(&t1_hash).unwrap(), TransactionAddress {
block_hash: b1a_hash.clone(),
index: 0,
});
assert_eq!(bc.transaction_address(&t2_hash).unwrap(), TransactionAddress {
block_hash: b1a_hash.clone(),
index: 1,
});
// now let's make forked chain the canon chain
let mut batch = db.transaction();
let _ = bc.insert_block(&mut batch, &b2, vec![]);
bc.commit();
db.write(batch).unwrap();
assert_eq!(bc.best_block_hash(), b2_hash);
assert_eq!(bc.transaction_address(&t1_hash).unwrap(), TransactionAddress {
block_hash: b1b_hash.clone(),
index: 1,
});
assert_eq!(bc.transaction_address(&t2_hash).unwrap(), TransactionAddress {
block_hash: b1b_hash.clone(),
index: 0,
});
assert_eq!(bc.transaction_address(&t3_hash).unwrap(), TransactionAddress {
block_hash: b2_hash.clone(),
index: 0,
});
}
#[test]
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
fn test_small_fork() {
@@ -1286,7 +1418,7 @@ mod tests {
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
let mut batch =db.transaction();
let mut batch = db.transaction();
let ir1 = bc.insert_block(&mut batch, &b1, vec![]);
bc.commit();
let ir2 = bc.insert_block(&mut batch, &b2, vec![]);
@@ -1462,7 +1594,7 @@ mod tests {
fn find_transaction_by_hash() {
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0".from_hex().unwrap();
let b1 = "f904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0".from_hex().unwrap();
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
let b1_hash: H256 = "f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3".into();
let temp = RandomTempPath::new();
let db = new_db(temp.as_str());
@@ -1490,11 +1622,11 @@ mod tests {
#[test]
fn test_bloom_filter_simple() {
// TODO: From here
let bloom_b1 = H2048::from_str("00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000").unwrap();
let bloom_b1: H2048 = "00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000".into();
let bloom_b2 = H2048::from_str("00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_b2: H2048 = "00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let bloom_ba = H2048::from_str("00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
let bloom_ba: H2048 = "00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();

View File

@@ -18,6 +18,7 @@
use bloomchain;
use util::*;
use rlp::*;
use header::BlockNumber;
use receipt::Receipt;
use db::Key;
@@ -176,7 +177,7 @@ impl Encodable for BlockDetails {
}
/// Represents address of certain transaction within block
#[derive(Clone)]
#[derive(Debug, PartialEq, Clone)]
pub struct TransactionAddress {
/// Block hash
pub block_hash: H256,

View File

@@ -14,9 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::rlp::*;
use rlp::*;
use util::{H256, H2048};
use util::U256;
use util::bytes::Bytes;
use header::Header;
use transaction::SignedTransaction;
@@ -24,6 +23,7 @@ use transaction::SignedTransaction;
use super::fork::Forkable;
use super::bloom::WithBloom;
use super::complete::CompleteBlock;
use super::transaction::WithTransaction;
/// Helper structure, used for encoding blocks.
#[derive(Default)]
@@ -44,7 +44,7 @@ impl Encodable for Block {
impl Forkable for Block {
fn fork(mut self, fork_number: usize) -> Self where Self: Sized {
let difficulty = self.header.difficulty().clone() - U256::from(fork_number);
let difficulty = self.header.difficulty().clone() - fork_number.into();
self.header.set_difficulty(difficulty);
self
}
@@ -57,6 +57,13 @@ impl WithBloom for Block {
}
}
impl WithTransaction for Block {
fn with_transaction(mut self, transaction: SignedTransaction) -> Self where Self: Sized {
self.transactions.push(transaction);
self
}
}
impl CompleteBlock for Block {
fn complete(mut self, parent_hash: H256) -> Bytes {
self.header.set_parent_hash(parent_hash);

View File

@@ -16,10 +16,12 @@
use util::{U256, H2048, Bytes};
use header::BlockNumber;
use transaction::SignedTransaction;
use super::fork::Fork;
use super::bloom::Bloom;
use super::complete::{BlockFinalizer, CompleteBlock, Complete};
use super::block::Block;
use super::transaction::Transaction;
/// Chain iterator interface.
pub trait ChainIterator: Iterator + Sized {
@@ -28,6 +30,8 @@ pub trait ChainIterator: Iterator + Sized {
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
/// Should be called to make every consecutive block have given bloom.
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self>;
/// Should be called to make every consecutive block have given transaction.
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self>;
/// Should be called to complete block. Without complete, block may have incorrect hash.
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
/// Completes and generates block.
@@ -49,6 +53,13 @@ impl<I> ChainIterator for I where I: Iterator + Sized {
}
}
fn with_transaction(&mut self, transaction: SignedTransaction) -> Transaction<Self> {
Transaction {
iter: self,
transaction: transaction,
}
}
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self> {
Complete {
iter: self,
@@ -83,7 +94,7 @@ impl Default for ChainGenerator {
fn default() -> Self {
ChainGenerator {
number: 0,
difficulty: U256::from(1000),
difficulty: 1000.into(),
}
}
}

View File

@@ -21,6 +21,7 @@ mod block;
mod complete;
mod fork;
pub mod generator;
mod transaction;
pub use self::complete::BlockFinalizer;
pub use self::generator::{ChainIterator, ChainGenerator};

View File

@@ -0,0 +1,35 @@
// Copyright 2015, 2016 Ethcore (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 transaction::SignedTransaction;
pub trait WithTransaction {
fn with_transaction(self, transaction: SignedTransaction) -> Self where Self: Sized;
}
pub struct Transaction<'a, I> where I: 'a {
pub iter: &'a mut I,
pub transaction: SignedTransaction,
}
impl <'a, I> Iterator for Transaction<'a, I> where I: Iterator, <I as Iterator>::Item: WithTransaction {
type Item = <I as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| item.with_transaction(self.transaction.clone()))
}
}

View File

@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain as bc;
use util::rlp::*;
use rlp::*;
use util::HeapSizeOf;
use basic_types::LogBloom;

View File

@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain::group as bc;
use util::rlp::*;
use rlp::*;
use util::HeapSizeOf;
use super::Bloom;

View File

@@ -127,14 +127,14 @@ impl Impl for EcRecover {
let s = H256::from_slice(&input[96..128]);
let bit = match v[31] {
27 | 28 if &v.as_slice()[..31] == &[0; 31] => v[31] - 27,
27 | 28 if &v.0[..31] == &[0; 31] => v[31] - 27,
_ => return,
};
let s = Signature::from_rsv(&r, &s, bit);
if s.is_valid() {
if let Ok(p) = ec_recover(&s, &hash) {
let r = p.as_slice().sha3();
let r = p.sha3();
let out_len = min(output.len(), 32);

View File

@@ -22,11 +22,11 @@ use std::time::{Instant};
use time::precise_time_ns;
// util
use util::{journaldb, rlp, Bytes, View, PerfTimer, Itertools, Mutex, RwLock};
use util::journaldb::JournalDB;
use util::rlp::{UntrustedRlp};
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
use util::journaldb::{self, JournalDB};
use util::{U256, H256, H520, Address, H2048, Uint};
use util::sha3::*;
use util::TrieFactory;
use util::kvdb::*;
// other
@@ -64,9 +64,10 @@ use trace;
use trace::FlatTransactionTraces;
use evm::Factory as EvmFactory;
use miner::{Miner, MinerService};
use util::TrieFactory;
use snapshot::{self, io as snapshot_io};
use factory::Factories;
use rlp::{View, UntrustedRlp};
// re-export
pub use types::blockchain_info::BlockChainInfo;
@@ -878,7 +879,7 @@ impl BlockChainClient for Client {
}
fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
self.chain.block_receipts(hash).map(|receipts| rlp::encode(&receipts).to_vec())
self.chain.block_receipts(hash).map(|receipts| ::rlp::encode(&receipts).to_vec())
}
fn import_block(&self, bytes: Bytes) -> Result<H256, BlockImportError> {

View File

@@ -18,6 +18,7 @@
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use util::*;
use rlp::*;
use ethkey::{Generator, Random};
use devtools::*;
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
@@ -33,7 +34,7 @@ use receipt::{Receipt, LocalizedReceipt};
use blockchain::extras::BlockReceipts;
use error::{ImportResult};
use evm::{Factory as EvmFactory, VMType};
use miner::{Miner, MinerService};
use miner::{Miner, MinerService, TransactionImportResult};
use spec::Spec;
use block_queue::BlockQueueInfo;
@@ -204,7 +205,7 @@ impl TestBlockChainClient {
txs.append(&signed_tx);
txs.out()
},
_ => rlp::EMPTY_LIST_RLP.to_vec()
_ => ::rlp::EMPTY_LIST_RLP.to_vec()
};
let mut rlp = RlpStream::new_list(3);
@@ -222,8 +223,8 @@ impl TestBlockChainClient {
header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec());
let mut rlp = RlpStream::new_list(3);
rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1);
rlp.append_raw(&rlp::NULL_RLP, 1);
rlp.append_raw(&::rlp::NULL_RLP, 1);
rlp.append_raw(&::rlp::NULL_RLP, 1);
self.blocks.write().insert(hash, rlp.out());
}
@@ -234,8 +235,8 @@ impl TestBlockChainClient {
header.set_parent_hash(H256::from(42));
let mut rlp = RlpStream::new_list(3);
rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1);
rlp.append_raw(&rlp::NULL_RLP, 1);
rlp.append_raw(&::rlp::NULL_RLP, 1);
rlp.append_raw(&::rlp::NULL_RLP, 1);
self.blocks.write().insert(hash, rlp.out());
}
@@ -254,6 +255,24 @@ impl TestBlockChainClient {
BlockID::Latest | BlockID::Pending => self.numbers.read().get(&(self.numbers.read().len() - 1)).cloned()
}
}
/// Inserts a transaction to miners transactions queue.
pub fn insert_transaction_to_queue(&self) {
let keypair = Random.generate().unwrap();
let tx = Transaction {
action: Action::Create,
value: U256::from(100),
data: "3331600055".from_hex().unwrap(),
gas: U256::from(100_000),
gas_price: U256::one(),
nonce: U256::zero()
};
let signed_tx = tx.sign(keypair.secret());
self.set_balance(signed_tx.sender().unwrap(), 10_000_000.into());
let res = self.miner.import_external_transactions(self, vec![signed_tx]);
let res = res.into_iter().next().unwrap().expect("Successful import");
assert_eq!(res, TransactionImportResult::Current);
}
}
pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB>> {

View File

@@ -20,7 +20,8 @@ use std::ops::Deref;
use std::hash::Hash;
use std::collections::HashMap;
use util::{DBTransaction, Database, RwLock};
use util::rlp::{encode, Encodable, decode, Decodable};
use rlp;
// database columns
/// Column for State
@@ -83,12 +84,12 @@ pub trait Key<T> {
/// 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: Encodable, R: Deref<Target = [u8]>;
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) 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: Encodable,
T: rlp::Encodable,
R: Deref<Target = [u8]> {
self.write(col, &key, &value);
match policy {
@@ -104,7 +105,7 @@ pub trait Writable {
/// 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: Encodable,
T: rlp::Encodable,
R: Deref<Target = [u8]> {
match policy {
CacheUpdatePolicy::Overwrite => {
@@ -127,13 +128,13 @@ pub trait Writable {
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: Decodable,
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 + Decodable,
T: Clone + rlp::Decodable,
C: Cache<K, T> {
{
let read = cache.read();
@@ -169,17 +170,17 @@ pub trait Readable {
}
impl Writable for DBTransaction {
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
self.put(col, &key.key(), &encode(value));
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));
}
}
impl Readable for Database {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: Decodable, R: Deref<Target = [u8]> {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
let result = self.get(col, &key.key());
match result {
Ok(option) => option.map(|v| decode(&v)),
Ok(option) => option.map(|v| rlp::decode(&v)),
Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
}

View File

@@ -109,7 +109,7 @@ impl Engine for BasicAuthority {
let message = header.bare_hash();
// account should be pernamently unlocked, otherwise sealing will fail
if let Ok(signature) = ap.sign(*block.header().author(), message) {
return Some(vec![encode(&(&*signature as &[u8])).to_vec()]);
return Some(vec![::rlp::encode(&(&*signature as &[u8])).to_vec()]);
} else {
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
}
@@ -131,6 +131,8 @@ impl Engine for BasicAuthority {
}
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
use rlp::{UntrustedRlp, View};
// check the signature is legit.
let sig = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<H520>());
let signer = public_to_address(&try!(recover(&sig.into(), &header.bare_hash())));
@@ -172,7 +174,7 @@ impl Engine for BasicAuthority {
impl Header {
/// Get the none field of the header.
pub fn signature(&self) -> H520 {
decode(&self.seal()[0])
::rlp::decode(&self.seal()[0])
}
}
@@ -228,7 +230,7 @@ mod tests {
fn can_do_signature_verification_fail() {
let engine = new_test_authority().engine;
let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H520::default()).to_vec()]);
header.set_seal(vec![::rlp::encode(&H520::default()).to_vec()]);
let verify_result = engine.verify_block_unordered(&header, None);
assert!(verify_result.is_err());

View File

@@ -100,7 +100,7 @@ mod tests {
assert!(engine.verify_block_basic(&header, None).is_ok());
header.set_seal(vec![rlp::encode(&H520::default()).to_vec()]);
header.set_seal(vec![::rlp::encode(&H520::default()).to_vec()]);
assert!(engine.verify_block_unordered(&header, None).is_ok());
}

View File

@@ -30,7 +30,8 @@ pub use self::tendermint::Tendermint;
pub use self::signed_vote::SignedVote;
pub use self::propose_collect::ProposeCollect;
use common::{HashMap, SemanticVersion, Header, EnvInfo, Address, Builtin, BTreeMap, U256, Bytes, SignedTransaction, Error, UntrustedRlp, H520};
use common::{HashMap, SemanticVersion, Header, EnvInfo, Address, Builtin, BTreeMap, U256, Bytes, SignedTransaction, Error, H520};
use rlp::UntrustedRlp;
use account_provider::AccountProvider;
use block::ExecutedBlock;
use spec::CommonParams;

View File

@@ -19,6 +19,7 @@
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use std::sync::Weak;
use common::*;
use rlp::{UntrustedRlp, View, encode};
use account_provider::AccountProvider;
use block::*;
use spec::CommonParams;
@@ -392,6 +393,7 @@ mod tests {
use common::*;
use std::thread::sleep;
use std::time::{Duration};
use rlp::{UntrustedRlp, RlpStream, Stream, View};
use block::*;
use tests::helpers::*;
use account_provider::AccountProvider;

View File

@@ -29,7 +29,7 @@ use ethkey::Error as EthkeyError;
pub use types::executed::{ExecutionError, CallError};
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone, Copy)]
/// Errors concerning transaction processing.
pub enum TransactionError {
/// Transaction is already imported to the queue
@@ -88,7 +88,7 @@ impl fmt::Display for TransactionError {
}
}
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Clone, Copy, Eq)]
/// Errors concerning block processing.
pub enum BlockError {
/// Block has too many uncles.
@@ -186,7 +186,7 @@ impl fmt::Display for BlockError {
}
}
#[derive(Debug, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
/// Import to the block queue result
pub enum ImportError {
/// Already in the block chain.
@@ -307,8 +307,8 @@ impl From<ExecutionError> for Error {
}
}
impl From<DecoderError> for Error {
fn from(err: DecoderError) -> Error {
impl From<::rlp::DecoderError> for Error {
fn from(err: ::rlp::DecoderError) -> Error {
Error::Util(UtilError::Decoder(err))
}
}

View File

@@ -21,6 +21,7 @@ use spec::CommonParams;
use engines::Engine;
use evm::Schedule;
use ethjson;
use rlp::{self, UntrustedRlp, View};
/// Ethash params.
#[derive(Debug, PartialEq)]
@@ -328,17 +329,17 @@ impl Ethash {
impl Header {
/// Get the none field of the header.
pub fn nonce(&self) -> H64 {
decode(&self.seal()[1])
rlp::decode(&self.seal()[1])
}
/// Get the mix hash field of the header.
pub fn mix_hash(&self) -> H256 {
decode(&self.seal()[0])
rlp::decode(&self.seal()[0])
}
/// Set the nonce and mix hash fields of the header.
pub fn set_nonce_and_mix_hash(&mut self, nonce: &H64, mix_hash: &H256) {
self.set_seal(vec![encode(mix_hash).to_vec(), encode(nonce).to_vec()]);
self.set_seal(vec![rlp::encode(mix_hash).to_vec(), rlp::encode(nonce).to_vec()]);
}
}
@@ -349,6 +350,7 @@ mod tests {
use tests::helpers::*;
use super::super::new_morden;
use super::Ethash;
use rlp;
#[test]
fn on_close_block() {

View File

@@ -16,11 +16,13 @@
//! Evm interface.
use common::*;
use std::{ops, cmp, fmt};
use util::{U128, U256, U512, Uint};
use action_params::ActionParams;
use evm::Ext;
/// Evm errors.
#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
pub enum Error {
/// `OutOfGas` is returned when transaction execution runs out of gas.
/// The state should be reverted to the state from before the
@@ -63,6 +65,21 @@ pub enum Error {
Internal,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
let message = match *self {
OutOfGas => "Out of gas",
BadJumpDestination { .. } => "Bad jump destination",
BadInstruction { .. } => "Bad instruction",
StackUnderflow { .. } => "Stack underflow",
OutOfStack { .. } => "Out of stack",
Internal => "Internal error",
};
message.fmt(f)
}
}
/// A specialized version of Result over EVM errors.
pub type Result<T> = ::std::result::Result<T, Error>;
@@ -193,53 +210,55 @@ pub trait Evm {
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
}
#[test]
#[cfg(test)]
fn should_calculate_overflow_mul_shr_without_overflow() {
// given
let num = 1048576;
mod tests {
use util::{U256, Uint};
use super::CostType;
// when
let (res1, o1) = U256::from(num).overflow_mul_shr(U256::from(num), 20);
let (res2, o2) = num.overflow_mul_shr(num, 20);
#[test]
fn should_calculate_overflow_mul_shr_without_overflow() {
// given
let num = 1048576;
// then
assert_eq!(res1, U256::from(num));
assert!(!o1);
assert_eq!(res2, num);
assert!(!o2);
}
#[test]
#[cfg(test)]
fn should_calculate_overflow_mul_shr_with_overflow() {
// given
let max = ::std::u64::MAX;
let num1 = U256([max, max, max, max]);
let num2 = ::std::usize::MAX;
// when
let (res1, o1) = num1.overflow_mul_shr(num1, 256);
let (res2, o2) = num2.overflow_mul_shr(num2, 64);
// then
assert_eq!(res2, num2 - 1);
assert!(o2);
assert_eq!(res1, !U256::zero() - U256::one());
assert!(o1);
}
#[test]
#[cfg(test)]
fn should_validate_u256_to_usize_conversion() {
// given
let v = U256::from(::std::usize::MAX) + U256::from(1);
// when
let res = usize::from_u256(v);
// then
assert!(res.is_err());
// when
let (res1, o1) = U256::from(num).overflow_mul_shr(U256::from(num), 20);
let (res2, o2) = num.overflow_mul_shr(num, 20);
// then
assert_eq!(res1, U256::from(num));
assert!(!o1);
assert_eq!(res2, num);
assert!(!o2);
}
#[test]
fn should_calculate_overflow_mul_shr_with_overflow() {
// given
let max = u64::max_value();
let num1 = U256([max, max, max, max]);
let num2 = usize::max_value();
// when
let (res1, o1) = num1.overflow_mul_shr(num1, 256);
let (res2, o2) = num2.overflow_mul_shr(num2, 64);
// then
assert_eq!(res2, num2 - 1);
assert!(o2);
assert_eq!(res1, !U256::zero() - U256::one());
assert!(o1);
}
#[test]
fn should_validate_u256_to_usize_conversion() {
// given
let v = U256::from(usize::max_value()) + U256::from(1);
// when
let res = usize::from_u256(v);
// then
assert!(res.is_err());
}
}

View File

@@ -76,7 +76,7 @@ impl<Gas: CostType> Gasometer<Gas> {
instructions::SSTORE => {
let address = H256::from(stack.peek(0));
let newval = stack.peek(1);
let val = U256::from(ext.storage_at(&address).as_slice());
let val = U256::from(&*ext.storage_at(&address));
let gas = if val.is_zero() && !newval.is_zero() {
schedule.sstore_set_gas

View File

@@ -403,18 +403,18 @@ impl<Cost: CostType> Interpreter<Cost> {
let offset = stack.pop_back();
let size = stack.pop_back();
let sha3 = self.mem.read_slice(offset, size).sha3();
stack.push(U256::from(sha3.as_slice()));
stack.push(U256::from(&*sha3));
},
instructions::SLOAD => {
let key = H256::from(&stack.pop_back());
let word = U256::from(ext.storage_at(&key).as_slice());
let word = U256::from(&*ext.storage_at(&key));
stack.push(word);
},
instructions::SSTORE => {
let address = H256::from(&stack.pop_back());
let val = stack.pop_back();
let current_val = U256::from(ext.storage_at(&address).as_slice());
let current_val = U256::from(&*ext.storage_at(&address));
// Increase refund for clear
if !self.is_zero(&current_val) && self.is_zero(&val) {
ext.inc_sstore_clears();
@@ -491,7 +491,7 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::BLOCKHASH => {
let block_number = stack.pop_back();
let block_hash = ext.blockhash(&block_number);
stack.push(U256::from(block_hash.as_slice()));
stack.push(U256::from(&*block_hash));
},
instructions::COINBASE => {
stack.push(address_to_u256(ext.env_info().author.clone()));
@@ -807,7 +807,7 @@ fn u256_to_address(value: &U256) -> Address {
#[inline]
fn address_to_u256(value: Address) -> U256 {
U256::from(H256::from(value).as_slice())
U256::from(&*H256::from(value))
}
#[test]

View File

@@ -32,6 +32,8 @@ const MAX_VM_DEPTH_FOR_THREAD: usize = 64;
/// Returns new address created from address and given nonce.
pub fn contract_address(address: &Address, nonce: &U256) -> Address {
use rlp::{RlpStream, Stream};
let mut stream = RlpStream::new_list(2);
stream.append(address);
stream.append(nonce);
@@ -284,7 +286,7 @@ impl<'a> Executive<'a> {
// just drain the whole gas
self.state.revert_snapshot();
tracer.trace_failed_call(trace_info, vec![]);
tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into());
Err(evm::Error::OutOfGas)
}
@@ -318,7 +320,7 @@ impl<'a> Executive<'a> {
trace_output,
traces
),
_ => tracer.trace_failed_call(trace_info, traces),
Err(e) => tracer.trace_failed_call(trace_info, traces, e.into()),
};
trace!(target: "executive", "substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate);
@@ -383,7 +385,7 @@ impl<'a> Executive<'a> {
created,
subtracer.traces()
),
_ => tracer.trace_failed_create(trace_info, subtracer.traces())
Err(e) => tracer.trace_failed_create(trace_info, subtracer.traces(), e.into())
};
self.enact_result(&res, substate, unconfirmed_substate);

View File

@@ -19,6 +19,7 @@
use util::*;
use basic_types::*;
use time::get_time;
use rlp::*;
use std::cell::RefCell;
@@ -297,7 +298,7 @@ impl Encodable for Header {
#[cfg(test)]
mod tests {
use rustc_serialize::hex::FromHex;
use util::rlp::{decode, encode};
use rlp;
use super::Header;
#[test]
@@ -307,7 +308,7 @@ mod tests {
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = decode(&header_rlp);
let header: Header = rlp::decode(&header_rlp);
let seal_fields = header.seal;
assert_eq!(seal_fields.len(), 2);
assert_eq!(seal_fields[0], mix_hash);
@@ -319,8 +320,8 @@ mod tests {
// that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = decode(&header_rlp);
let encoded_header = encode(&header).to_vec();
let header: Header = rlp::decode(&header_rlp);
let encoded_header = rlp::encode(&header).to_vec();
assert_eq!(header_rlp, encoded_header);
}

View File

@@ -17,6 +17,7 @@
use super::test_common::*;
use evm;
use ethjson;
use rlp::{UntrustedRlp, View};
fn do_json_test(json_data: &[u8]) -> Vec<String> {
let tests = ethjson::transaction::Test::load(json_data).unwrap();

View File

@@ -79,12 +79,9 @@
//! cargo build --release
//! ```
#[macro_use] extern crate log;
#[macro_use] extern crate ethcore_util as util;
extern crate ethcore_io as io;
#[macro_use] extern crate lazy_static;
extern crate rustc_serialize;
#[macro_use] extern crate heapsize;
extern crate crypto;
extern crate time;
extern crate env_logger;
@@ -92,19 +89,32 @@ extern crate num_cpus;
extern crate crossbeam;
extern crate ethjson;
extern crate bloomchain;
#[macro_use] extern crate ethcore_ipc as ipc;
extern crate rayon;
extern crate hyper;
extern crate ethash;
extern crate ethkey;
pub extern crate ethstore;
extern crate semver;
extern crate ethcore_ipc_nano as nanoipc;
extern crate ethcore_devtools as devtools;
extern crate rand;
extern crate bit_set;
extern crate rlp;
#[cfg(feature = "jit" )] extern crate evmjit;
#[macro_use]
extern crate log;
#[macro_use]
extern crate ethcore_util as util;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate heapsize;
#[macro_use]
extern crate ethcore_ipc as ipc;
#[cfg(feature = "jit" )]
extern crate evmjit;
pub extern crate ethstore;
pub mod account_provider;
pub mod engines;

View File

@@ -17,7 +17,7 @@
//! This migration compresses the state db.
use util::migration::{SimpleMigration, Progress};
use util::rlp::{Compressible, UntrustedRlp, View, RlpType};
use rlp::{Compressible, UntrustedRlp, View, RlpType};
/// Compressing migration.
#[derive(Default)]

View File

@@ -23,9 +23,11 @@ use util::Bytes;
use util::{Address, FixedHash, H256};
use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
use util::rlp::{decode, Rlp, RlpStream, Stream, View};
use util::sha3::Hashable;
use rlp::{decode, Rlp, RlpStream, Stream, View};
// attempt to migrate a key, value pair. None if migration not possible.
fn attempt_migrate(mut key_h: H256, val: &[u8]) -> Option<H256> {
let val_hash = val.sha3();

View File

@@ -17,7 +17,7 @@
//! This migration consolidates all databases into single one using Column Families.
use util::{Rlp, RlpStream, View, Stream};
use rlp::{Rlp, RlpStream, View, Stream};
use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, Progress};

View File

@@ -1229,6 +1229,8 @@ mod test {
#[test]
fn should_reject_incorectly_signed_transaction() {
use rlp::{self, RlpStream, Stream};
// given
let mut txq = TransactionQueue::new();
let tx = new_unsigned_tx(123.into(), 1.into());
@@ -1243,7 +1245,7 @@ mod test {
s.append(&0u64); // v
s.append(&U256::zero()); // r
s.append(&U256::zero()); // s
decode(s.as_raw())
rlp::decode(s.as_raw())
};
// when
let res = txq.add(stx, &default_account_details, TransactionOrigin::External);

View File

@@ -19,6 +19,7 @@ use state::Account;
use account_db::AccountDBMut;
use ethjson;
use types::account_diff::*;
use rlp::{self, RlpStream, Stream};
#[derive(Debug, Clone, PartialEq, Eq)]
/// An account, expressed as Plain-Old-Data (hence the name).
@@ -57,7 +58,7 @@ impl PodAccount {
let mut stream = RlpStream::new_list(4);
stream.append(&self.nonce);
stream.append(&self.balance);
stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), encode(&U256::from(v.as_slice())).to_vec())).collect()));
stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), rlp::encode(&U256::from(&**v)).to_vec())).collect()));
stream.append(&self.code.as_ref().unwrap_or(&vec![]).sha3());
stream.out()
}
@@ -71,7 +72,7 @@ impl PodAccount {
let mut r = H256::new();
let mut t = SecTrieDBMut::new(db, &mut r);
for (k, v) in &self.storage {
if let Err(e) = t.insert(k, &encode(&U256::from(v.as_slice()))) {
if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
warn!("Encountered potential DB corruption: {}", e);
}
}

View File

@@ -17,11 +17,12 @@
//! Account state encoding and decoding
use account_db::{AccountDB, AccountDBMut};
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY};
use util::rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
use util::trie::{TrieDB, Trie};
use snapshot::Error;
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY};
use util::trie::{TrieDB, Trie};
use rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
use std::collections::{HashMap, HashSet};
// whether an encoded account has code and how it is referred to.
@@ -206,9 +207,9 @@ mod tests {
use tests::helpers::get_temp_journal_db;
use snapshot::tests::helpers::fill_storage;
use util::{SHA3_NULL_RLP, SHA3_EMPTY};
use util::sha3::{SHA3_EMPTY, SHA3_NULL_RLP};
use util::{Address, FixedHash, H256, HashDB};
use util::rlp::{UntrustedRlp, View};
use rlp::{UntrustedRlp, View};
use std::collections::{HashSet, HashMap};

View File

@@ -20,8 +20,8 @@ use block::Block;
use header::Header;
use views::BlockView;
use util::rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View};
use util::rlp::{Compressible, RlpType};
use rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View};
use rlp::{Compressible, RlpType};
use util::{Bytes, Hashable, H256};
const HEADER_FIELDS: usize = 10;
@@ -103,7 +103,7 @@ impl AbridgedBlock {
header.set_gas_used(try!(rlp.val_at(7)));
header.set_timestamp(try!(rlp.val_at(8)));
header.set_extra_data(try!(rlp.val_at(9)));
let transactions = try!(rlp.val_at(10));
let uncles: Vec<Header> = try!(rlp.val_at(11));

View File

@@ -22,7 +22,7 @@ use ids::BlockID;
use util::H256;
use util::trie::TrieError;
use util::rlp::DecoderError;
use rlp::DecoderError;
/// Snapshot-related errors.
#[derive(Debug)]

View File

@@ -27,7 +27,7 @@ use std::path::{Path, PathBuf};
use util::Bytes;
use util::hash::H256;
use util::rlp::{self, Encodable, RlpStream, UntrustedRlp, Stream, View};
use rlp::{self, Encodable, RlpStream, UntrustedRlp, Stream, View};
use super::ManifestData;
@@ -340,4 +340,92 @@ impl SnapshotReader for LooseReader {
Ok(buf)
}
}
#[cfg(test)]
mod tests {
use devtools::RandomTempPath;
use util::sha3::Hashable;
use snapshot::ManifestData;
use super::{SnapshotWriter, SnapshotReader, PackedWriter, PackedReader, LooseWriter, LooseReader};
const STATE_CHUNKS: &'static [&'static [u8]] = &[b"dog", b"cat", b"hello world", b"hi", b"notarealchunk"];
const BLOCK_CHUNKS: &'static [&'static [u8]] = &[b"hello!", b"goodbye!", b"abcdefg", b"hijklmnop", b"qrstuvwxy", b"and", b"z"];
#[test]
fn packed_write_and_read() {
let path = RandomTempPath::new();
let mut writer = PackedWriter::new(path.as_path()).unwrap();
let mut state_hashes = Vec::new();
let mut block_hashes = Vec::new();
for chunk in STATE_CHUNKS {
let hash = chunk.sha3();
state_hashes.push(hash.clone());
writer.write_state_chunk(hash, chunk).unwrap();
}
for chunk in BLOCK_CHUNKS {
let hash = chunk.sha3();
block_hashes.push(hash.clone());
writer.write_block_chunk(chunk.sha3(), chunk).unwrap();
}
let manifest = ManifestData {
state_hashes: state_hashes,
block_hashes: block_hashes,
state_root: b"notarealroot".sha3(),
block_number: 12345678987654321,
block_hash: b"notarealblock".sha3(),
};
writer.finish(manifest.clone()).unwrap();
let reader = PackedReader::new(path.as_path()).unwrap().unwrap();
assert_eq!(reader.manifest(), &manifest);
for hash in manifest.state_hashes.iter().chain(&manifest.block_hashes) {
reader.chunk(hash.clone()).unwrap();
}
}
#[test]
fn loose_write_and_read() {
let path = RandomTempPath::new();
let mut writer = LooseWriter::new(path.as_path().into()).unwrap();
let mut state_hashes = Vec::new();
let mut block_hashes = Vec::new();
for chunk in STATE_CHUNKS {
let hash = chunk.sha3();
state_hashes.push(hash.clone());
writer.write_state_chunk(hash, chunk).unwrap();
}
for chunk in BLOCK_CHUNKS {
let hash = chunk.sha3();
block_hashes.push(hash.clone());
writer.write_block_chunk(chunk.sha3(), chunk).unwrap();
}
let manifest = ManifestData {
state_hashes: state_hashes,
block_hashes: block_hashes,
state_root: b"notarealroot".sha3(),
block_number: 12345678987654321,
block_hash: b"notarealblock".sha3(),
};
writer.finish(manifest.clone()).unwrap();
let reader = LooseReader::new(path.as_path().into()).unwrap();
assert_eq!(reader.manifest(), &manifest);
for hash in manifest.state_hashes.iter().chain(&manifest.block_hashes) {
reader.chunk(hash.clone()).unwrap();
}
}
}

View File

@@ -32,9 +32,9 @@ use util::Mutex;
use util::hash::{FixedHash, H256};
use util::journaldb::{self, Algorithm, JournalDB};
use util::kvdb::Database;
use util::rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View, Compressible, RlpType};
use util::rlp::SHA3_NULL_RLP;
use util::sha3::SHA3_NULL_RLP;
use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut};
use rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View, Compressible, RlpType};
use self::account::Account;
use self::block::AbridgedBlock;
@@ -653,4 +653,4 @@ impl BlockRebuilder {
}
}
}
}
}

View File

@@ -40,7 +40,7 @@ use util::kvdb::{Database, DatabaseConfig};
use util::snappy;
/// Statuses for restorations.
#[derive(PartialEq, Clone, Copy, Debug)]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum RestorationStatus {
/// No restoration.
Inactive,
@@ -519,3 +519,50 @@ impl SnapshotService for Service {
.expect("snapshot service and io service are kept alive by client service; qed");
}
}
#[cfg(test)]
mod tests {
use service::ClientIoMessage;
use io::{IoService};
use devtools::RandomTempPath;
use tests::helpers::get_test_spec;
use util::journaldb::Algorithm;
use snapshot::ManifestData;
use super::*;
#[test]
fn sends_async_messages() {
let service = IoService::<ClientIoMessage>::start().unwrap();
let dir = RandomTempPath::new();
let mut dir = dir.as_path().to_owned();
dir.push("pruning");
dir.push("db");
let service = Service::new(
&get_test_spec(),
Algorithm::Archive,
dir,
service.channel()
).unwrap();
assert!(service.manifest().is_none());
assert!(service.chunk(Default::default()).is_none());
assert_eq!(service.status(), RestorationStatus::Inactive);
assert_eq!(service.chunks_done(), (0, 0));
let manifest = ManifestData {
state_hashes: vec![],
block_hashes: vec![],
state_root: Default::default(),
block_number: 0,
block_hash: Default::default(),
};
service.begin_restore(manifest);
service.abort_restore();
service.restore_state_chunk(Default::default(), vec![]);
service.restore_block_chunk(Default::default(), vec![]);
}
}

View File

@@ -25,7 +25,7 @@ use util::hash::{FixedHash, H256};
use util::hashdb::HashDB;
use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
use util::trie::{TrieDB, TrieDBMut, Trie};
use util::rlp::SHA3_NULL_RLP;
use util::sha3::SHA3_NULL_RLP;
// the proportion of accounts we will alter each tick.
const ACCOUNT_CHURN: f32 = 0.01;
@@ -78,7 +78,7 @@ impl StateProducer {
let new_accs = rng.gen::<u32>() % 5;
for _ in 0..new_accs {
let address_hash = H256::random();
let address_hash = H256(rng.gen());
let balance: usize = rng.gen();
let nonce: usize = rng.gen();
let acc = ::state::Account::new_basic(balance.into(), nonce.into()).rlp();

View File

@@ -19,4 +19,19 @@
mod blocks;
mod state;
pub mod helpers;
pub mod helpers;
use super::ManifestData;
#[test]
fn manifest_rlp() {
let manifest = ManifestData {
block_hashes: Vec::new(),
state_hashes: Vec::new(),
block_number: 1234567,
state_root: Default::default(),
block_hash: Default::default(),
};
let raw = manifest.clone().into_rlp();
assert_eq!(ManifestData::from_rlp(&raw).unwrap(), manifest);
}

View File

@@ -20,7 +20,7 @@ use snapshot::{chunk_state, Progress, StateRebuilder};
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
use super::helpers::{compare_dbs, StateProducer};
use rand;
use rand::{XorShiftRng, SeedableRng};
use util::hash::H256;
use util::journaldb::{self, Algorithm};
use util::kvdb::{Database, DatabaseConfig};
@@ -33,7 +33,7 @@ use std::sync::Arc;
#[test]
fn snap_and_restore() {
let mut producer = StateProducer::new();
let mut rng = rand::thread_rng();
let mut rng = XorShiftRng::from_seed([1, 2, 3, 4]);
let mut old_db = MemoryDB::new();
let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS);

View File

@@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::rlp::*;
use util::{Address, H256, Uint, U256};
use util::sha3::SHA3_NULL_RLP;
use ethjson;
use super::seal::Seal;

View File

@@ -16,7 +16,7 @@
//! Spec seal.
use util::rlp::*;
use rlp::*;
use util::hash::{H64, H256};
use ethjson;

View File

@@ -24,6 +24,7 @@ use super::genesis::Genesis;
use super::seal::Generic as GenericSeal;
use ethereum;
use ethjson;
use rlp::{Rlp, RlpStream, View, Stream};
/// Parameters common to all engines.
#[derive(Debug, PartialEq, Clone)]
@@ -232,7 +233,7 @@ impl Spec {
{
let mut t = SecTrieDBMut::new(db, &mut root);
for (address, account) in self.genesis_state.get().iter() {
try!(t.insert(address.as_slice(), &account.rlp()));
try!(t.insert(&**address, &account.rlp()));
}
}
for (address, account) in self.genesis_state.get().iter() {

View File

@@ -19,6 +19,7 @@
use std::collections::hash_map::Entry;
use util::*;
use pod_account::*;
use rlp::*;
use std::cell::{Ref, RefCell, Cell};
@@ -287,7 +288,7 @@ impl Account {
// so we can call overloaded `to_bytes` method
let res = match v.is_zero() {
true => t.remove(k),
false => t.insert(k, &encode(&U256::from(v.as_slice()))),
false => t.insert(k, &encode(&U256::from(&*v))),
};
if let Err(e) = res {
@@ -333,6 +334,7 @@ mod tests {
use util::*;
use super::*;
use account_db::*;
use rlp::*;
#[test]
fn account_compress() {

View File

@@ -444,8 +444,7 @@ use env_info::*;
use spec::*;
use transaction::*;
use util::log::init_log;
use trace::trace;
use trace::FlatTrace;
use trace::{FlatTrace, TraceError, trace};
use types::executed::CallType;
#[test]
@@ -538,7 +537,7 @@ fn should_trace_failed_create_transaction() {
gas: 78792.into(),
init: vec![91, 96, 0, 86],
}),
result: trace::Res::FailedCreate,
result: trace::Res::FailedCreate(TraceError::OutOfGas),
subtraces: 0
}];
@@ -869,7 +868,7 @@ fn should_trace_failed_call_transaction() {
input: vec![],
call_type: CallType::Call,
}),
result: trace::Res::FailedCall,
result: trace::Res::FailedCall(TraceError::OutOfGas),
subtraces: 0,
}];
@@ -1084,7 +1083,7 @@ fn should_trace_failed_subcall_transaction() {
input: vec![],
call_type: CallType::Call,
}),
result: trace::Res::FailedCall,
result: trace::Res::FailedCall(TraceError::OutOfGas),
}];
assert_eq!(result.trace, expected_trace);
@@ -1217,7 +1216,7 @@ fn should_trace_failed_subcall_with_subcall_transaction() {
input: vec![],
call_type: CallType::Call,
}),
result: trace::Res::FailedCall,
result: trace::Res::FailedCall(TraceError::OutOfGas),
}, FlatTrace {
trace_address: vec![0, 0].into_iter().collect(),
subtraces: 0,

View File

@@ -22,6 +22,7 @@ use tests::helpers::*;
use common::*;
use devtools::*;
use miner::Miner;
use rlp::{Rlp, View};
#[test]
fn imports_from_empty() {

View File

@@ -27,6 +27,7 @@ use engines::Engine;
use ethereum;
use devtools::*;
use miner::Miner;
use rlp::{self, RlpStream, Stream};
#[cfg(feature = "json-tests")]
pub enum ChainEra {
@@ -116,7 +117,7 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransa
rlp.append(header);
rlp.begin_list(transactions.len());
for t in transactions {
rlp.append_raw(&encode::<SignedTransaction>(t).to_vec(), 1);
rlp.append_raw(&rlp::encode::<SignedTransaction>(t).to_vec(), 1);
}
rlp.append(&uncles);
rlp.out()

View File

@@ -1,6 +1,6 @@
use bloomchain::Bloom;
use bloomchain::group::{BloomGroup, GroupPosition};
use util::rlp::*;
use rlp::*;
use basic_types::LogBloom;
/// Helper structure representing bloom of the trace.

View File

@@ -420,7 +420,7 @@ mod tests {
use devtools::RandomTempPath;
use header::BlockNumber;
use trace::{Config, Switch, TraceDB, Database as TraceDatabase, DatabaseExtras, ImportRequest};
use trace::{Filter, LocalizedTrace, AddressesFilter};
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
use trace::trace::{Call, Action, Res};
use trace::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
use types::executed::CallType;
@@ -560,7 +560,7 @@ mod tests {
input: vec![],
call_type: CallType::Call,
}),
result: Res::FailedCall,
result: Res::FailedCall(TraceError::OutOfGas),
}])]),
block_hash: block_hash.clone(),
block_number: block_number,
@@ -579,7 +579,7 @@ mod tests {
input: vec![],
call_type: CallType::Call,
}),
result: Res::FailedCall,
result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![],
subtraces: 0,
transaction_number: 0,

View File

@@ -19,7 +19,7 @@
use util::{Bytes, Address, U256};
use action_params::ActionParams;
use trace::trace::{Call, Create, Action, Res, CreateResult, CallResult, VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff, Suicide};
use trace::{Tracer, VMTracer, FlatTrace};
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
/// Simple executive tracer. Traces all calls and creates. Ignores delegatecalls.
#[derive(Default)]
@@ -112,23 +112,23 @@ impl Tracer for ExecutiveTracer {
self.traces.extend(update_trace_address(subs));
}
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<FlatTrace>) {
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<FlatTrace>, error: TraceError) {
let trace = FlatTrace {
trace_address: Default::default(),
subtraces: top_level_subtraces(&subs),
action: Action::Call(call.expect("self.prepare_trace_call().is_some(): so we must be tracing: qed")),
result: Res::FailedCall,
result: Res::FailedCall(error),
};
debug!(target: "trace", "Traced failed call {:?}", trace);
self.traces.push(trace);
self.traces.extend(update_trace_address(subs));
}
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<FlatTrace>) {
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<FlatTrace>, error: TraceError) {
let trace = FlatTrace {
subtraces: top_level_subtraces(&subs),
action: Action::Create(create.expect("self.prepare_trace_create().is_some(): so we must be tracing: qed")),
result: Res::FailedCreate,
result: Res::FailedCreate(error),
trace_address: Default::default(),
};
debug!(target: "trace", "Traced failed create {:?}", trace);

View File

@@ -24,7 +24,8 @@ mod executive_tracer;
mod import;
mod noop_tracer;
pub use types::trace_types::*;
pub use types::trace_types::{filter, flat, localized, trace};
pub use types::trace_types::error::Error as TraceError;
pub use self::config::{Config, Switch};
pub use self::db::TraceDB;
pub use self::error::Error;
@@ -71,10 +72,10 @@ pub trait Tracer: Send {
);
/// Stores failed call trace.
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<FlatTrace>);
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<FlatTrace>, error: TraceError);
/// Stores failed create trace.
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<FlatTrace>);
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<FlatTrace>, error: TraceError);
/// Stores suicide info.
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address);

View File

@@ -18,7 +18,7 @@
use util::{Bytes, Address, U256};
use action_params::ActionParams;
use trace::{Tracer, VMTracer, FlatTrace};
use trace::{Tracer, VMTracer, FlatTrace, TraceError};
use trace::trace::{Call, Create, VMTrace};
/// Nonoperative tracer. Does not trace anything.
@@ -47,11 +47,11 @@ impl Tracer for NoopTracer {
assert!(code.is_none(), "self.prepare_trace_output().is_none(): so we can't be tracing: qed");
}
fn trace_failed_call(&mut self, call: Option<Call>, _: Vec<FlatTrace>) {
fn trace_failed_call(&mut self, call: Option<Call>, _: Vec<FlatTrace>, _: TraceError) {
assert!(call.is_none(), "self.prepare_trace_call().is_none(): so we can't be tracing: qed");
}
fn trace_failed_create(&mut self, create: Option<Create>, _: Vec<FlatTrace>) {
fn trace_failed_create(&mut self, create: Option<Create>, _: Vec<FlatTrace>, _: TraceError) {
assert!(create.is_none(), "self.prepare_trace_create().is_none(): so we can't be tracing: qed");
}

View File

@@ -98,12 +98,10 @@ impl AccountDiff {
// TODO: refactor into something nicer.
fn interpreted_hash(u: &H256) -> String {
use util::bytes::*;
if u <= &H256::from(0xffffffff) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u32(), U256::from(u.as_slice()).low_u32())
format!("{} = 0x{:x}", U256::from(&**u).low_u32(), U256::from(&**u).low_u32())
} else if u <= &H256::from(u64::max_value()) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u64(), U256::from(u.as_slice()).low_u64())
format!("{} = 0x{:x}", U256::from(&**u).low_u64(), U256::from(&**u).low_u64())
// } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") {
// format!("@{}", Address::from(u))
} else {
@@ -113,7 +111,7 @@ fn interpreted_hash(u: &H256) -> String {
impl fmt::Display for AccountDiff {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use util::bytes::*;
use util::bytes::ToPretty;
match self.nonce {
Diff::Born(ref x) => try!(write!(f, " non {}", x)),

View File

@@ -17,7 +17,7 @@
//! Transaction execution format module.
use util::{Bytes, U256, Address, U512};
use util::rlp::*;
use rlp::*;
use trace::{VMTrace, FlatTrace};
use types::log_entry::LogEntry;
use types::state_diff::StateDiff;
@@ -203,7 +203,8 @@ pub type ExecutionResult = Result<Executed, ExecutionError>;
#[test]
fn should_encode_and_decode_call_type() {
use util::rlp;
use rlp;
let original = CallType::Call;
let encoded = rlp::encode(&original);
let decoded = rlp::decode(&encoded);

View File

@@ -18,8 +18,9 @@
use std::ops::Deref;
use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
use util::rlp::*;
use util::bloom::Bloomable;
use rlp::*;
use basic_types::LogBloom;
use header::BlockNumber;
use ethjson;

View File

@@ -17,8 +17,9 @@
//! Receipt
use util::{H256, U256, Address};
use util::rlp::*;
use util::HeapSizeOf;
use rlp::*;
use basic_types::LogBloom;
use header::BlockNumber;
use log_entry::{LogEntry, LocalizedLogEntry};

View File

@@ -0,0 +1,99 @@
// Copyright 2015, 2016 Ethcore (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/>.
//! Trace errors.
use std::fmt;
use rlp::{Encodable, RlpStream, Decodable, Decoder, DecoderError, Stream, View};
use evm::Error as EvmError;
/// Trace evm errors.
#[derive(Debug, PartialEq, Clone, Binary)]
pub enum Error {
/// `OutOfGas` is returned when transaction execution runs out of gas.
OutOfGas,
/// `BadJumpDestination` is returned when execution tried to move
/// to position that wasn't marked with JUMPDEST instruction
BadJumpDestination,
/// `BadInstructions` is returned when given instruction is not supported
BadInstruction,
/// `StackUnderflow` when there is not enough stack elements to execute instruction
StackUnderflow,
/// When execution would exceed defined Stack Limit
OutOfStack,
/// Returned on evm internal error. Should never be ignored during development.
/// Likely to cause consensus issues.
Internal,
}
impl From<EvmError> for Error {
fn from(e: EvmError) -> Self {
match e {
EvmError::OutOfGas => Error::OutOfGas,
EvmError::BadJumpDestination { .. } => Error::BadJumpDestination,
EvmError::BadInstruction { .. } => Error::BadInstruction,
EvmError::StackUnderflow { .. } => Error::StackUnderflow,
EvmError::OutOfStack { .. } => Error::OutOfStack,
EvmError::Internal => Error::Internal,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
let message = match *self {
OutOfGas => "Out of gas",
BadJumpDestination => "Bad jump destination",
BadInstruction => "Bad instruction",
StackUnderflow => "Stack underflow",
OutOfStack => "Out of stack",
Internal => "Internal error",
};
message.fmt(f)
}
}
impl Encodable for Error {
fn rlp_append(&self, s: &mut RlpStream) {
use self::Error::*;
let value = match *self {
OutOfGas => 0u8,
BadJumpDestination => 1,
BadInstruction => 2,
StackUnderflow => 3,
OutOfStack => 4,
Internal => 5,
};
s.append(&value);
}
}
impl Decodable for Error {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
use self::Error::*;
let value: u8 = try!(decoder.as_rlp().as_val());
match value {
0 => Ok(OutOfGas),
1 => Ok(BadJumpDestination),
2 => Ok(BadInstruction),
3 => Ok(StackUnderflow),
4 => Ok(OutOfStack),
5 => Ok(Internal),
_ => Err(DecoderError::Custom("Invalid error type")),
}
}
}

View File

@@ -140,7 +140,7 @@ mod tests {
use util::bloom::Bloomable;
use trace::trace::{Action, Call, Res, Create, CreateResult, Suicide};
use trace::flat::FlatTrace;
use trace::{Filter, AddressesFilter};
use trace::{Filter, AddressesFilter, TraceError};
use types::executed::CallType;
#[test]
@@ -286,7 +286,7 @@ mod tests {
input: vec![0x5],
call_type: CallType::Call,
}),
result: Res::FailedCall,
result: Res::FailedCall(TraceError::OutOfGas),
trace_address: vec![0].into_iter().collect(),
subtraces: 0,
};

View File

@@ -17,7 +17,7 @@
//! Flat trace module
use std::collections::VecDeque;
use util::rlp::*;
use rlp::*;
use util::HeapSizeOf;
use basic_types::LogBloom;
use super::trace::{Action, Res};
@@ -167,7 +167,6 @@ mod tests {
#[test]
fn test_trace_serialization() {
use util::rlp;
// block #51921
let flat_trace = FlatTrace {
@@ -220,8 +219,8 @@ mod tests {
FlatTransactionTraces(vec![flat_trace1, flat_trace2])
]);
let encoded = rlp::encode(&block_traces);
let decoded = rlp::decode(&encoded);
let encoded = ::rlp::encode(&block_traces);
let decoded = ::rlp::decode(&encoded);
assert_eq!(block_traces, decoded);
}
}

View File

@@ -16,6 +16,7 @@
//! Types used in the public api
pub mod error;
pub mod filter;
pub mod flat;
pub mod trace;

View File

@@ -17,12 +17,14 @@
//! Tracing datatypes.
use util::{U256, Bytes, Address};
use util::rlp::*;
use util::sha3::Hashable;
use util::bloom::Bloomable;
use rlp::*;
use action_params::ActionParams;
use basic_types::LogBloom;
use types::executed::CallType;
use super::error::Error;
/// `Call` result.
#[derive(Debug, Clone, PartialEq, Default, Binary)]
@@ -321,9 +323,9 @@ pub enum Res {
/// Successful create action result.
Create(CreateResult),
/// Failed call.
FailedCall,
FailedCall(Error),
/// Failed create.
FailedCreate,
FailedCreate(Error),
/// None
None,
}
@@ -341,13 +343,15 @@ impl Encodable for Res {
s.append(&1u8);
s.append(create);
},
Res::FailedCall => {
s.begin_list(1);
Res::FailedCall(ref err) => {
s.begin_list(2);
s.append(&2u8);
s.append(err);
},
Res::FailedCreate => {
s.begin_list(1);
Res::FailedCreate(ref err) => {
s.begin_list(2);
s.append(&3u8);
s.append(err);
},
Res::None => {
s.begin_list(1);
@@ -364,8 +368,8 @@ impl Decodable for Res {
match action_type {
0 => d.val_at(1).map(Res::Call),
1 => d.val_at(1).map(Res::Create),
2 => Ok(Res::FailedCall),
3 => Ok(Res::FailedCreate),
2 => d.val_at(1).map(Res::FailedCall),
3 => d.val_at(1).map(Res::FailedCreate),
4 => Ok(Res::None),
_ => Err(DecoderError::Custom("Invalid result type.")),
}
@@ -377,7 +381,7 @@ impl Res {
pub fn bloom(&self) -> LogBloom {
match *self {
Res::Create(ref create) => create.bloom(),
Res::Call(_) | Res::FailedCall | Res::FailedCreate | Res::None => Default::default(),
Res::Call(_) | Res::FailedCall(_) | Res::FailedCreate(_) | Res::None => Default::default(),
}
}
}

View File

@@ -18,7 +18,7 @@
use std::ops::Deref;
use std::cell::*;
use util::rlp::*;
use rlp::*;
use util::sha3::Hashable;
use util::{H256, Address, U256, Bytes};
use ethkey::{Signature, sign, Secret, recover, public_to_address, Error as EthkeyError};
@@ -275,7 +275,7 @@ impl SignedTransaction {
match hash {
Some(h) => h,
None => {
let h = self.rlp_sha3();
let h = (&*self.rlp_bytes()).sha3();
self.hash.set(Some(h));
h
}

View File

@@ -18,9 +18,8 @@
use ipc::binary::{BinaryConvertError, BinaryConvertable};
use error::{TransactionError, Error};
use util::Populatable;
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
/// Represents the result of importing transaction.
pub enum TransactionImportResult {
/// Transaction was imported to current queue.

View File

@@ -24,6 +24,7 @@
use common::*;
use engines::Engine;
use blockchain::*;
use rlp::{UntrustedRlp, View};
/// Preprocessed block data gathered in `verify_block_unordered` call
pub struct PreverifiedBlock {
@@ -240,6 +241,7 @@ mod tests {
use spec::*;
use transaction::*;
use tests::helpers::*;
use rlp::View;
fn check_ok(result: Result<(), Error>) {
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
@@ -346,6 +348,8 @@ mod tests {
#[test]
#[cfg_attr(feature="dev", allow(similar_names))]
fn test_verify_block() {
use rlp::{RlpStream, Stream};
// Test against morden
let mut good = Header::new();
let spec = Spec::new_test();
@@ -411,7 +415,7 @@ mod tests {
let mut uncles_rlp = RlpStream::new();
uncles_rlp.append(&good_uncles);
let good_uncles_hash = uncles_rlp.as_raw().sha3();
let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| encode::<SignedTransaction>(t).to_vec()).collect());
let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| ::rlp::encode::<SignedTransaction>(t).to_vec()).collect());
let mut parent = good.clone();
parent.set_number(9);

View File

@@ -20,6 +20,7 @@ use util::*;
use header::*;
use transaction::*;
use super::{TransactionView, HeaderView};
use rlp::{Rlp, View};
/// View onto block rlp.
pub struct BlockView<'a> {

View File

@@ -20,6 +20,7 @@ use util::*;
use header::*;
use transaction::*;
use super::{TransactionView, HeaderView};
use rlp::{Rlp, View};
/// View onto block rlp.
pub struct BodyView<'a> {

View File

@@ -16,7 +16,8 @@
//! View onto block header rlp
use util::{Rlp, U256, Bytes, Hashable, H256, Address, H2048, View};
use util::{U256, Bytes, Hashable, H256, Address, H2048};
use rlp::{Rlp, View};
use header::BlockNumber;
/// View onto block header rlp.

View File

@@ -15,7 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto transaction rlp
use util::{Rlp, U256, Bytes, Hashable, H256, View};
use util::{U256, Bytes, Hashable, H256};
use rlp::{Rlp, View};
/// View onto transaction rlp.
pub struct TransactionView<'a> {