Merge remote-tracking branch 'parity/master' into bft
Conflicts: ethcore/src/client/client.rs
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
//! DB backend wrapper for Account trie
|
||||
use util::*;
|
||||
use rlp::NULL_RLP;
|
||||
|
||||
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
35
ethcore/src/blockchain/generator/transaction.rs
Normal file
35
ethcore/src/blockchain/generator/transaction.rs
Normal 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()))
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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>> {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(¤t_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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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![]);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Spec seal.
|
||||
|
||||
use util::rlp::*;
|
||||
use rlp::*;
|
||||
use util::hash::{H64, H256};
|
||||
use ethjson;
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -22,6 +22,7 @@ use tests::helpers::*;
|
||||
use common::*;
|
||||
use devtools::*;
|
||||
use miner::Miner;
|
||||
use rlp::{Rlp, View};
|
||||
|
||||
#[test]
|
||||
fn imports_from_empty() {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
99
ethcore/src/types/trace_types/error.rs
Normal file
99
ethcore/src/types/trace_types/error.rs
Normal 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")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
//! Types used in the public api
|
||||
|
||||
pub mod error;
|
||||
pub mod filter;
|
||||
pub mod flat;
|
||||
pub mod trace;
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user