diff --git a/.travis.yml b/.travis.yml
index 7589697af..816e6d883 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,6 +55,7 @@ env:
global:
- secure: 3sUjNi9mhdL5h1GTm8LONnDN/SYvUHT+WSkMl93h3nYiLCQXk8eZaPS98AS7oOaTsfW4UvnwckVFCFl49ttInsv4cd/TkAxmrJHe6kPyS9/4NWUdmP8BjicbBvL/ioSdXMECMEYzPDLV+I3KhtC2LcB6ceDEl/XwMOJlzbGf7RbtcXGVQgMLqSYY1YKjQA4vbT5nFgIS/sZu3Z9yFgN0GafnihKcizqoHhdJjs/zxmX+qJepnC6o3V6KcFnS7QHhM1JOr85twE6S422UlvNaEb5ovwLPqmOl5+fA+6shbx4AxFTY6E9Iors+OVY/JliFhrqOdCt0i2P1FUHN4kbGZQkf0rphN/ZOI2uKNFTOyXiPvppfo/ZemKmcqkwkqP9+lf5QqYmtE6hsAYagxn49xJZILl8tAYbdqxF5gxa+TEVrfsBFtz/Sv3q8QhKQNPAmjEcKyMatyEreLUIFEpFTGIco8jN4eXeSoLRdJ+Z75ihttfQWhNfUDgNL30iQLy0AgFSsh/cyb5M8y9lxrGDzDTogvaiKGwr/V45sPkcXWCkmOgMdINqBB6ZtdL3bGHdyjmYj+y3btjf3aP11k++BL0fXIaKn25aS/p/9iyGb1FyGCM03o4ZRQ3YhTOvfMRfRGf6nWbaMx9upv8o5ShSdysewhrnh3082r7u896ny1Ho=
- secure: 0/FeVvFl3AhBW0TCPoujY9zOAYoUNMlAz3XjC04vlc4Ksfx0lGU3KFi97LlALxMWV0lfwQc7ixSe2vTgQVQuLVSU9XEW40fQgEjJlmLca2RcRx1kfzJDypuWSiCME7MWmLPH0ac4COdTDS1z5WGggv5YB7GQPCzFvcmOOaPYtF29ngCtkyB2HmNkY/W3omHFEk7Si6bsmOSHZiOAhivPl6ixnGpFyTEKPyraMMqPIj5rbEGkzgeLTiXf2ur143n/tnSr8tmP1MfQi9yS8/ONidMqnxUeuLkeNnb82zj9pVJhVXq0xF44WXJ8Za1jm0ByiTakgqpm8Juk822qjvtNulJ1XZW/fyZQZaN1dy3uq5Ud3W8wS9M7VIVl8CoXozzDpIsdPeUAtkAxeHBsZqL1vAH2yC1YJA7HPySMYzCjYqkJ2r62xYk0gXmNXphfU+F/X/rHzHsTMJPONJ54HQwu12m7zVlKIYBGHgEXg/HAM/g4ljUzl6WWR/nHH/tQM8ND/8FpHluJSZJWacq/1QNhVdTq2x6cqws2fs5A7nVpccR9+6RRgYgv6+YS2LxvFzByuZveGGoKif+uMECXN876j40araUqU528Yz9i8bHJlnM3coRBndaLNWByLcUyXCB9r9IUosUu41rr+L2mVzkSDm0GicuNCzqvzYQ9Q6QY4uQ=
+ - secure: DglvLR27MrBKQO/8s7ZfGqfimXk1Iq5MreCTc+ZkWMkZ0sDP76YBUPq5j25hcg0Z09z09O2Q5OUOyYkhVD4AnRjoRLUplHdpDE9CBSz2vUGpMpzhgAqzBc6SDsEmWU2JlAPBraIODXQdP/Qo6tYY4zn3vwd/VFKo27GTb5b60WAkTVvT/0YPWycEXFIa7sNMgjNI0EnT+Se5USDYwb6MM1T9JxJot0q3WtOnsVyroCHJp4QDicpS8eQIu3Tl+SLE4d0EoJ4YYLOI+jWOybipuO1xM1xlHq/gpWfjKqbJh24xtAds524dN7ujfjAhyO2zQbuTOfi7QVOj/Go0tGYxNxobR4pYG783Aiq3Quj0GzSrLEAatkk5tGOcuVJ98EYIg3WPJuC93waTTXcS0xDyy09XHxWxZ/5PiXorRZjpHvnZfRF0X4Mus6jUJ7hqDuOUiF5BI1RHomHvJQQHUrLdmh7OHyrer3YUpKRs65tww6H+VM+lKNa3MnMkB5+or/co14svs7I4pni9S+aZg//bwuxGVXchK6bjLCP1X99Ar4fA5EGsTVdjp3PRqutM/P3RqNGkwTczat/PNZ8fFAD9y7pDs2L6YkqpflTC9d6vKTSl6gORGw6ltLUJs23ON6xRNIBMw1cXp67wN57vF46TPt1i3ZlIQsYn0pAVNKavbZE=
deploy:
provider: releases
@@ -64,3 +65,11 @@ deploy:
file: parity${ARCHIVE_SUFFIX}.tar.gz
on:
tags: true
+
+notifications:
+ webhooks:
+ urls:
+ - https://hooks.slack.com/services/${SLACK_WEBHOOK}
+ on_success: always
+ on_failure: always
+ on_start: never
diff --git a/Cargo.toml b/Cargo.toml
index 6766a5b2c..1eac83ac3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ ethcore-util = { path = "util" }
ethcore = { path = "ethcore" }
ethsync = { path = "sync" }
ethcore-rpc = { path = "rpc", optional = true }
+fdlimit = { path = "util/fdlimit" }
[features]
default = ["rpc"]
diff --git a/README.md b/README.md
index c223921f1..dc0498d26 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,13 @@
# ethcore
-[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url]
+[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url]
[travis-image]: https://travis-ci.com/ethcore/parity.svg?token=DMFvZu71iaTbUYx9UypX&branch=master
[travis-url]: https://travis-ci.com/ethcore/parity
[coveralls-image]: https://coveralls.io/repos/github/ethcore/parity/badge.svg?branch=master&t=Fk0OuQ
[coveralls-url]: https://coveralls.io/r/ethcore/parity?branch=master
+[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
+[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
### Building from source
diff --git a/add_license.sh b/add_license.sh
new file mode 100755
index 000000000..1d916f427
--- /dev/null
+++ b/add_license.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+for f in $(find . -name '*.rs'); do
+ cat license_header $f > $f.new
+ mv $f.new $f
+done
diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs
index 56b120d1d..8dc2456c0 100644
--- a/ethash/src/compute.rs
+++ b/ethash/src/compute.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Ethash implementation
//! See https://github.com/ethereum/wiki/wiki/Ethash
diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs
index 17853c985..4c6b8639f 100644
--- a/ethash/src/lib.rs
+++ b/ethash/src/lib.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Ethash implementation
//! See https://github.com/ethereum/wiki/wiki/Ethash
extern crate sha3;
diff --git a/ethash/src/sizes.rs b/ethash/src/sizes.rs
index 40840eb84..b3a3c0d22 100644
--- a/ethash/src/sizes.rs
+++ b/ethash/src/sizes.rs
@@ -1,3 +1,19 @@
+// 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 .
+
// 2048 Epochs (~20 years) worth of tabulated DAG sizes
// Generated with the following Mathematica Code:
diff --git a/ethcore/res/ethereum/tests b/ethcore/res/ethereum/tests
index c670b1d8c..3116f85a4 160000
--- a/ethcore/res/ethereum/tests
+++ b/ethcore/res/ethereum/tests
@@ -1 +1 @@
-Subproject commit c670b1d8c9f09593a6758ab2c099360e16c7c25b
+Subproject commit 3116f85a499ceaf4dfdc46726060fc056e2d7829
diff --git a/ethcore/src/account.rs b/ethcore/src/account.rs
index 63f86b171..aa5a0c4bd 100644
--- a/ethcore/src/account.rs
+++ b/ethcore/src/account.rs
@@ -1,7 +1,24 @@
+// 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 .
+
//! Single account in the system.
use util::*;
use pod_account::*;
+use account_db::*;
/// Single account in the system.
#[derive(Clone)]
@@ -99,7 +116,7 @@ impl Account {
}
/// Get (and cache) the contents of the trie's storage at `key`.
- pub fn storage_at(&self, db: &HashDB, key: &H256) -> H256 {
+ pub fn storage_at(&self, db: &AccountDB, key: &H256) -> H256 {
self.storage_overlay.borrow_mut().entry(key.clone()).or_insert_with(||{
(Filth::Clean, H256::from(SecTrieDB::new(db, &self.storage_root).get(key.bytes()).map_or(U256::zero(), |v| -> U256 {decode(v)})))
}).1.clone()
@@ -147,7 +164,7 @@ impl Account {
}
/// Provide a database to lookup `code_hash`. Should not be called if it is a contract without code.
- pub fn cache_code(&mut self, db: &HashDB) -> bool {
+ pub fn cache_code(&mut self, db: &AccountDB) -> bool {
// TODO: fill out self.code_cache;
trace!("Account::cache_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty());
self.is_cached() ||
@@ -184,7 +201,7 @@ impl Account {
pub fn sub_balance(&mut self, x: &U256) { self.balance = self.balance - *x; }
/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
- pub fn commit_storage(&mut self, db: &mut HashDB) {
+ pub fn commit_storage(&mut self, db: &mut AccountDBMut) {
let mut t = SecTrieDBMut::from_existing(db, &mut self.storage_root);
for (k, &mut (ref mut f, ref mut v)) in self.storage_overlay.borrow_mut().iter_mut() {
if f == &Filth::Dirty {
@@ -200,7 +217,7 @@ impl Account {
}
/// Commit any unsaved code. `code_hash` will always return the hash of the `code_cache` after this.
- pub fn commit_code(&mut self, db: &mut HashDB) {
+ pub fn commit_code(&mut self, db: &mut AccountDBMut) {
trace!("Commiting code of {:?} - {:?}, {:?}", self, self.code_hash.is_none(), self.code_cache.is_empty());
match (self.code_hash.is_none(), self.code_cache.is_empty()) {
(true, true) => self.code_hash = Some(SHA3_EMPTY),
@@ -233,10 +250,12 @@ mod tests {
use util::*;
use super::*;
+ use account_db::*;
#[test]
fn storage_at() {
let mut db = MemoryDB::new();
+ let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = {
let mut a = Account::new_contract(U256::from(69u8));
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
@@ -248,13 +267,14 @@ mod tests {
let a = Account::from_rlp(&rlp);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
- assert_eq!(a.storage_at(&db, &H256::from(&U256::from(0x00u64))), H256::from(&U256::from(0x1234u64)));
- assert_eq!(a.storage_at(&db, &H256::from(&U256::from(0x01u64))), H256::new());
+ assert_eq!(a.storage_at(&db.immutable(), &H256::from(&U256::from(0x00u64))), H256::from(&U256::from(0x1234u64)));
+ assert_eq!(a.storage_at(&db.immutable(), &H256::from(&U256::from(0x01u64))), H256::new());
}
#[test]
fn note_code() {
let mut db = MemoryDB::new();
+ let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = {
let mut a = Account::new_contract(U256::from(69u8));
@@ -264,7 +284,7 @@ mod tests {
};
let mut a = Account::from_rlp(&rlp);
- assert!(a.cache_code(&db));
+ assert!(a.cache_code(&db.immutable()));
let mut a = Account::from_rlp(&rlp);
assert_eq!(a.note_code(vec![0x55, 0x44, 0xffu8]), Ok(()));
@@ -274,6 +294,7 @@ mod tests {
fn commit_storage() {
let mut a = Account::new_contract(U256::from(69u8));
let mut db = MemoryDB::new();
+ let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(x!(0), x!(0x1234));
assert_eq!(a.storage_root(), None);
a.commit_storage(&mut db);
@@ -284,6 +305,7 @@ mod tests {
fn commit_remove_commit_storage() {
let mut a = Account::new_contract(U256::from(69u8));
let mut db = MemoryDB::new();
+ let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(x!(0), x!(0x1234));
a.commit_storage(&mut db);
a.set_storage(x!(1), x!(0x1234));
@@ -297,6 +319,7 @@ mod tests {
fn commit_code() {
let mut a = Account::new_contract(U256::from(69u8));
let mut db = MemoryDB::new();
+ let mut db = AccountDBMut::new(&mut db, &Address::new());
a.init_code(vec![0x55, 0x44, 0xffu8]);
assert_eq!(a.code_hash(), SHA3_EMPTY);
a.commit_code(&mut db);
diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs
new file mode 100644
index 000000000..e7f1b2bad
--- /dev/null
+++ b/ethcore/src/account_db.rs
@@ -0,0 +1,120 @@
+//! DB backend wrapper for Account trie
+use util::*;
+
+static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];
+
+// TODO: introduce HashDBMut?
+/// DB backend wrapper for Account trie
+/// Transforms trie node keys for the database
+pub struct AccountDB<'db> {
+ db: &'db HashDB,
+ address: H256,
+}
+
+#[inline]
+fn combine_key<'a>(address: &'a H256, key: &'a H256) -> H256 {
+ let mut addr_hash = address.sha3();
+ // preserve 96 bits of original key for db lookup
+ addr_hash[0..12].clone_from_slice(&[0u8; 12]);
+ &addr_hash ^ key
+}
+
+impl<'db> AccountDB<'db> {
+ pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
+ AccountDB {
+ db: db,
+ address: x!(address.clone()),
+ }
+ }
+}
+
+impl<'db> HashDB for AccountDB<'db>{
+ fn keys(&self) -> HashMap {
+ unimplemented!()
+ }
+
+ fn lookup(&self, key: &H256) -> Option<&[u8]> {
+ if key == &SHA3_NULL_RLP {
+ return Some(&NULL_RLP_STATIC);
+ }
+ self.db.lookup(&combine_key(&self.address, key))
+ }
+
+ fn exists(&self, key: &H256) -> bool {
+ if key == &SHA3_NULL_RLP {
+ return true;
+ }
+ self.db.exists(&combine_key(&self.address, key))
+ }
+
+ fn insert(&mut self, _value: &[u8]) -> H256 {
+ unimplemented!()
+ }
+
+ fn emplace(&mut self, _key: H256, _value: Bytes) {
+ unimplemented!()
+ }
+
+ fn kill(&mut self, _key: &H256) {
+ unimplemented!()
+ }
+}
+
+/// DB backend wrapper for Account trie
+pub struct AccountDBMut<'db> {
+ db: &'db mut HashDB,
+ address: H256,
+}
+
+impl<'db> AccountDBMut<'db> {
+ pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> {
+ AccountDBMut {
+ db: db,
+ address: x!(address.clone()),
+ }
+ }
+
+ #[allow(dead_code)]
+ pub fn immutable(&'db self) -> AccountDB<'db> {
+ AccountDB { db: self.db, address: self.address.clone() }
+ }
+}
+
+impl<'db> HashDB for AccountDBMut<'db>{
+ fn keys(&self) -> HashMap {
+ unimplemented!()
+ }
+
+ fn lookup(&self, key: &H256) -> Option<&[u8]> {
+ if key == &SHA3_NULL_RLP {
+ return Some(&NULL_RLP_STATIC);
+ }
+ self.db.lookup(&combine_key(&self.address, key))
+ }
+
+ fn exists(&self, key: &H256) -> bool {
+ if key == &SHA3_NULL_RLP {
+ return true;
+ }
+ self.db.exists(&combine_key(&self.address, key))
+ }
+
+ fn insert(&mut self, value: &[u8]) -> H256 {
+ let k = value.sha3();
+ let ak = combine_key(&self.address, &k);
+ self.db.emplace(ak, value.to_vec());
+ k
+ }
+
+ fn emplace(&mut self, key: H256, value: Bytes) {
+ let key = combine_key(&self.address, &key);
+ self.db.emplace(key, value.to_vec())
+ }
+
+ fn kill(&mut self, key: &H256) {
+ let key = combine_key(&self.address, key);
+ self.db.kill(&key)
+ }
+}
+
+
diff --git a/ethcore/src/account_diff.rs b/ethcore/src/account_diff.rs
index 86faf40de..6c7e6573e 100644
--- a/ethcore/src/account_diff.rs
+++ b/ethcore/src/account_diff.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Diff between two accounts.
use util::*;
diff --git a/ethcore/src/action_params.rs b/ethcore/src/action_params.rs
index a56e64f4d..9e2d72c73 100644
--- a/ethcore/src/action_params.rs
+++ b/ethcore/src/action_params.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Evm input params.
use util::hash::*;
use util::uint::*;
diff --git a/ethcore/src/basic_types.rs b/ethcore/src/basic_types.rs
index 49a5c9556..51e05500c 100644
--- a/ethcore/src/basic_types.rs
+++ b/ethcore/src/basic_types.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Ethcore basic typenames.
use util::*;
diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs
index a2de89d13..c03417dc1 100644
--- a/ethcore/src/block.rs
+++ b/ethcore/src/block.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Blockchain block.
#![allow(ptr_arg)] // Because of &LastHashes -> &Vec<_>
@@ -14,7 +30,7 @@ pub struct Block {
/// The header of this block.
pub header: Header,
/// The transactions in this block.
- pub transactions: Vec,
+ pub transactions: Vec,
/// The uncles of this block.
pub uncles: Vec,
}
@@ -62,7 +78,7 @@ impl Decodable for Block {
/// Internal type for a block's common elements.
// TODO: rename to ExecutedBlock
// TODO: use BareBlock
-#[derive(Debug, Clone)]
+#[derive(Debug)]
pub struct ExecutedBlock {
base: Block,
@@ -76,7 +92,7 @@ pub struct BlockRefMut<'a> {
/// Block header.
pub header: &'a Header,
/// Block transactions.
- pub transactions: &'a Vec,
+ pub transactions: &'a Vec,
/// Block uncles.
pub uncles: &'a Vec,
/// Transaction receipts.
@@ -113,7 +129,7 @@ pub trait IsBlock {
fn state(&self) -> &State { &self.block().state }
/// Get all information on transactions in this block.
- fn transactions(&self) -> &Vec { &self.block().base.transactions }
+ fn transactions(&self) -> &Vec { &self.block().base.transactions }
/// Get all information on receipts in this block.
fn receipts(&self) -> &Vec { &self.block().receipts }
@@ -228,7 +244,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
/// Push a transaction into the block.
///
/// If valid, it will be executed, and archived together with the receipt.
- pub fn push_transaction(&mut self, t: Transaction, h: Option) -> Result<&Receipt, Error> {
+ pub fn push_transaction(&mut self, t: SignedTransaction, h: Option) -> Result<&Receipt, Error> {
let env_info = self.env_info();
// info!("env_info says gas_used={}", env_info.gas_used);
match self.block.state.apply(&env_info, self.engine, &t) {
@@ -316,10 +332,12 @@ impl IsBlock for SealedBlock {
}
/// Enact the block given by block header, transactions and uncles
-pub fn enact<'x, 'y>(header: &Header, transactions: &[Transaction], uncles: &[Header], engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: &'y LastHashes) -> Result, Error> {
+pub fn enact<'x, 'y>(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: &'y LastHashes) -> Result, Error> {
{
- let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce());
- trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
+ if ::log::max_log_level() >= ::log::LogLevel::Trace {
+ let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce());
+ trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
+ }
}
let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), header.extra_data().clone());
@@ -363,10 +381,10 @@ mod tests {
let engine = Spec::new_test().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
- let db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
- let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]);
+ let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let b = b.close();
let _ = b.seal(vec![]);
}
@@ -378,16 +396,16 @@ mod tests {
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
- let db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
- let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(vec![]).unwrap();
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
+ let b = OpenBlock::new(engine.deref(), db, &genesis_header, &vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(vec![]).unwrap();
let orig_bytes = b.rlp_bytes();
let orig_db = b.drain();
let mut db_result = get_temp_journal_db();
- let db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
- let e = enact_and_seal(&orig_bytes, engine.deref(), db.clone(), &genesis_header, &vec![genesis_header.hash()]).unwrap();
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
+ let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, &vec![genesis_header.hash()]).unwrap();
assert_eq!(e.rlp_bytes(), orig_bytes);
diff --git a/ethcore/src/block_queue.rs b/ethcore/src/block_queue.rs
index e14f2a06a..2e3728aee 100644
--- a/ethcore/src/block_queue.rs
+++ b/ethcore/src/block_queue.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! A queue of blocks. Sits between network or other I/O and the BlockChain.
//! Sorts them ready for blockchain insertion.
use std::thread::{JoinHandle, self};
diff --git a/ethcore/src/blockchain.rs b/ethcore/src/blockchain.rs
index e2ed54c19..4c765360e 100644
--- a/ethcore/src/blockchain.rs
+++ b/ethcore/src/blockchain.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Blockchain database.
use util::*;
@@ -93,7 +109,7 @@ pub trait BlockProvider {
/// Get a list of transactions for a given block.
/// Returns None if block deos not exist.
- fn transactions(&self, hash: &H256) -> Option> {
+ fn transactions(&self, hash: &H256) -> Option> {
self.block(hash).map(|bytes| BlockView::new(&bytes).transactions())
}
diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs
index 297f734b5..5589a2525 100644
--- a/ethcore/src/builtin.rs
+++ b/ethcore/src/builtin.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use util::*;
use crypto::sha2::Sha256;
use crypto::ripemd160::Ripemd160;
diff --git a/ethcore/src/client.rs b/ethcore/src/client.rs
index 03c03ab49..3a0309c1c 100644
--- a/ethcore/src/client.rs
+++ b/ethcore/src/client.rs
@@ -1,7 +1,23 @@
+// 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 .
+
//! Blockchain database client.
use util::*;
-use rocksdb::{Options, DB};
+use rocksdb::{Options, DB, DBCompactionStyle};
use blockchain::{BlockChain, BlockProvider, CacheSize};
use views::BlockView;
use error::*;
@@ -139,24 +155,31 @@ impl ClientReport {
pub struct Client {
chain: Arc>,
engine: Arc>,
- state_db: JournalDB,
+ state_db: Arc,
+ state_journal: Mutex,
block_queue: RwLock,
report: RwLock,
- uncommited_states: RwLock>,
import_lock: Mutex<()>
}
const HISTORY: u64 = 1000;
+const CLIENT_DB_VER_STR: &'static str = "1.0";
impl Client {
/// Create a new client with given spec and DB path.
pub fn new(spec: Spec, path: &Path, message_channel: IoChannel ) -> Result, Error> {
+ let mut dir = path.to_path_buf();
+ dir.push(H64::from(spec.genesis_header().hash()).hex());
+ //TODO: sec/fat: pruned/full versioning
+ dir.push(format!("v{}-sec-pruned", CLIENT_DB_VER_STR));
+ let path = dir.as_path();
let gb = spec.genesis_block();
let chain = Arc::new(RwLock::new(BlockChain::new(&gb, path)));
let mut opts = Options::new();
opts.set_max_open_files(256);
opts.create_if_missing(true);
opts.set_use_fsync(false);
+ opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
/*
opts.set_bytes_per_sync(8388608);
opts.set_disable_data_sync(false);
@@ -180,16 +203,16 @@ impl Client {
let engine = Arc::new(try!(spec.to_engine()));
let mut state_db = JournalDB::new_with_arc(db.clone());
- if engine.spec().ensure_db_good(&mut state_db) {
+ if state_db.is_empty() && engine.spec().ensure_db_good(&mut state_db) {
state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
}
Ok(Arc::new(Client {
chain: chain,
engine: engine.clone(),
- state_db: state_db,
+ state_db: db.clone(),
+ state_journal: Mutex::new(JournalDB::new_with_arc(db)),
block_queue: RwLock::new(BlockQueue::new(engine, message_channel)),
report: RwLock::new(Default::default()),
- uncommited_states: RwLock::new(HashMap::new()),
import_lock: Mutex::new(()),
}))
}
@@ -242,7 +265,7 @@ impl Client {
}
}
- let db = self.state_db.clone();
+ let db = self.state_journal.lock().unwrap().clone();
let result = match enact_verified(&block, self.engine.deref().deref(), db, &parent, &last_hashes) {
Ok(b) => b,
Err(e) => {
@@ -277,14 +300,9 @@ impl Client {
ret
}
- /// Clear cached state overlay
- pub fn clear_state(&self, hash: &H256) {
- self.uncommited_states.write().unwrap().remove(hash);
- }
-
/// Get a copy of the best block's state.
pub fn state(&self) -> State {
- State::from_existing(self.state_db.clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
+ State::from_existing(JournalDB::new_with_arc(self.state_db.clone()), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
}
/// Get info on the cache.
diff --git a/ethcore/src/common.rs b/ethcore/src/common.rs
index b699bd4c6..5235e9f58 100644
--- a/ethcore/src/common.rs
+++ b/ethcore/src/common.rs
@@ -1,3 +1,19 @@
+// 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 .
+
pub use util::*;
pub use basic_types::*;
pub use error::*;
diff --git a/ethcore/src/engine.rs b/ethcore/src/engine.rs
index 7017989e7..f86c943ee 100644
--- a/ethcore/src/engine.rs
+++ b/ethcore/src/engine.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use common::*;
use block::ExecutedBlock;
use spec::Spec;
@@ -56,9 +72,9 @@ pub trait Engine : Sync + Send {
/// Additional verification for transactions in blocks.
// TODO: Add flags for which bits of the transaction to check.
// TODO: consider including State in the params.
- fn verify_transaction_basic(&self, _t: &Transaction, _header: &Header) -> Result<(), Error> { Ok(()) }
+ fn verify_transaction_basic(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
/// Verify a particular transaction is valid.
- fn verify_transaction(&self, _t: &Transaction, _header: &Header) -> Result<(), Error> { Ok(()) }
+ fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
/// Don't forget to call Super::populateFromParent when subclassing & overriding.
// TODO: consider including State in the params.
diff --git a/ethcore/src/env_info.rs b/ethcore/src/env_info.rs
index 7c0516d2a..02fc5188c 100644
--- a/ethcore/src/env_info.rs
+++ b/ethcore/src/env_info.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use util::*;
use header::BlockNumber;
diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs
index 2d6753e95..d441929c5 100644
--- a/ethcore/src/error.rs
+++ b/ethcore/src/error.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! General error types for use in ethcore.
use util::*;
diff --git a/ethcore/src/ethereum/denominations.rs b/ethcore/src/ethereum/denominations.rs
index 2ab66431d..a8ac2c44c 100644
--- a/ethcore/src/ethereum/denominations.rs
+++ b/ethcore/src/ethereum/denominations.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use util::*;
#[inline]
diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs
index e9aedc128..43e3720d2 100644
--- a/ethcore/src/ethereum/ethash.rs
+++ b/ethcore/src/ethereum/ethash.rs
@@ -1,3 +1,19 @@
+// 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 .
+
extern crate ethash;
use self::ethash::{quick_get_difficulty, EthashManager, H256 as EH256};
@@ -154,14 +170,14 @@ impl Engine for Ethash {
Ok(())
}
- fn verify_transaction_basic(&self, t: &Transaction, header: &Header) -> result::Result<(), Error> {
+ fn verify_transaction_basic(&self, t: &SignedTransaction, header: &Header) -> result::Result<(), Error> {
if header.number() >= self.u64_param("frontierCompatibilityModeLimit") {
try!(t.check_low_s());
}
Ok(())
}
- fn verify_transaction(&self, t: &Transaction, _header: &Header) -> Result<(), Error> {
+ fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> {
t.sender().map(|_|()) // Perform EC recovery and cache sender
}
}
@@ -232,10 +248,10 @@ fn on_close_block() {
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
- let mut db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
- let b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]);
+ let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
}
@@ -246,10 +262,10 @@ fn on_close_block_with_uncle() {
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
- let mut db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
let last_hashes = vec![genesis_header.hash()];
- let mut b = OpenBlock::new(engine.deref(), db.clone(), &genesis_header, &last_hashes, Address::zero(), vec![]);
+ let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone();
diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs
index ec6cfe103..11c20ddbe 100644
--- a/ethcore/src/ethereum/mod.rs
+++ b/ethcore/src/ethereum/mod.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Ethereum protocol module.
//!
//! Contains all Ethereum network specific stuff, such as denominations and
@@ -44,9 +60,9 @@ mod tests {
let engine = new_morden().to_engine().unwrap();
let genesis_header = engine.spec().genesis_header();
let mut db_result = get_temp_journal_db();
- let mut db = db_result.reference_mut();
- engine.spec().ensure_db_good(db);
- let s = State::from_existing(db.clone(), genesis_header.state_root.clone(), engine.account_start_nonce());
+ let mut db = db_result.take();
+ engine.spec().ensure_db_good(&mut db);
+ let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce());
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64));
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000003")), U256::from(1u64));
diff --git a/ethcore/src/evm/evm.rs b/ethcore/src/evm/evm.rs
index f011f67a4..28eb96f44 100644
--- a/ethcore/src/evm/evm.rs
+++ b/ethcore/src/evm/evm.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Evm interface.
use common::*;
diff --git a/ethcore/src/evm/ext.rs b/ethcore/src/evm/ext.rs
index 83f093bcf..ae4cff3be 100644
--- a/ethcore/src/evm/ext.rs
+++ b/ethcore/src/evm/ext.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Interface for Evm externalities.
use common::Bytes;
diff --git a/ethcore/src/evm/factory.rs b/ethcore/src/evm/factory.rs
index bd9315e7f..f1be0e427 100644
--- a/ethcore/src/evm/factory.rs
+++ b/ethcore/src/evm/factory.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Evm factory.
//!
//! TODO: consider spliting it into two separate files.
diff --git a/ethcore/src/evm/instructions.rs b/ethcore/src/evm/instructions.rs
index 976c3c603..623868618 100644
--- a/ethcore/src/evm/instructions.rs
+++ b/ethcore/src/evm/instructions.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! VM Instructions list and utility functions
pub type Instruction = u8;
diff --git a/ethcore/src/evm/interpreter.rs b/ethcore/src/evm/interpreter.rs
index 6516d9946..8b8197526 100644
--- a/ethcore/src/evm/interpreter.rs
+++ b/ethcore/src/evm/interpreter.rs
@@ -1,3 +1,19 @@
+// 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 .
+
///! Rust VM implementation
use common::*;
@@ -263,7 +279,7 @@ pub struct Interpreter;
impl evm::Evm for Interpreter {
fn exec(&self, params: ActionParams, ext: &mut evm::Ext) -> evm::Result {
- let code = ¶ms.code.clone().unwrap();
+ let code = ¶ms.code.as_ref().unwrap();
let valid_jump_destinations = self.find_jump_destinations(&code);
let mut current_gas = params.gas.clone();
@@ -728,12 +744,15 @@ impl Interpreter {
let big_id = stack.pop_back();
let id = big_id.low_u64() as usize;
let max = id.wrapping_add(32);
- let data = params.data.clone().unwrap_or_else(|| vec![]);
- let bound = cmp::min(data.len(), max);
- if id < bound && big_id < U256::from(data.len()) {
- let mut v = data[id..bound].to_vec();
- v.resize(32, 0);
- stack.push(U256::from(&v[..]))
+ if let Some(data) = params.data.as_ref() {
+ let bound = cmp::min(data.len(), max);
+ if id < bound && big_id < U256::from(data.len()) {
+ let mut v = [0u8; 32];
+ v[0..bound-id].clone_from_slice(&data[id..bound]);
+ stack.push(U256::from(&v[..]))
+ } else {
+ stack.push(U256::zero())
+ }
} else {
stack.push(U256::zero())
}
diff --git a/ethcore/src/evm/jit.rs b/ethcore/src/evm/jit.rs
index 6a6d7e5ff..dc407d0c1 100644
--- a/ethcore/src/evm/jit.rs
+++ b/ethcore/src/evm/jit.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Just in time compiler execution environment.
use common::*;
use evmjit;
diff --git a/ethcore/src/evm/mod.rs b/ethcore/src/evm/mod.rs
index 2ed9a1146..3e1dc5ed7 100644
--- a/ethcore/src/evm/mod.rs
+++ b/ethcore/src/evm/mod.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Ethereum virtual machine.
pub mod ext;
diff --git a/ethcore/src/evm/schedule.rs b/ethcore/src/evm/schedule.rs
index d46b7ff11..f82157239 100644
--- a/ethcore/src/evm/schedule.rs
+++ b/ethcore/src/evm/schedule.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Cost schedule and other parameterisations for the EVM.
/// Definition of the cost schedule and other parameterisations for the EVM.
diff --git a/ethcore/src/evm/tests.rs b/ethcore/src/evm/tests.rs
index 7b8e29d23..d0daf33e7 100644
--- a/ethcore/src/evm/tests.rs
+++ b/ethcore/src/evm/tests.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use common::*;
use evm;
use evm::{Ext, Schedule, Factory, VMType, ContractCreateResult, MessageCallResult};
diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs
index b67b71306..2d6039953 100644
--- a/ethcore/src/executive.rs
+++ b/ethcore/src/executive.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Transaction Execution environment.
use common::*;
use state::*;
@@ -86,7 +102,7 @@ impl<'a> Executive<'a> {
}
/// This funtion should be used to execute transaction.
- pub fn transact(&'a mut self, t: &Transaction) -> Result {
+ pub fn transact(&'a mut self, t: &SignedTransaction) -> Result {
let sender = try!(t.sender());
let nonce = self.state.nonce(&sender);
@@ -194,7 +210,7 @@ impl<'a> Executive<'a> {
/// Returns either gas_left or `evm::Error`.
pub fn call(&mut self, params: ActionParams, substate: &mut Substate, mut output: BytesRef) -> evm::Result {
// backup used in case of running out of gas
- let backup = self.state.clone();
+ self.state.snapshot();
// at first, transfer value to destination
if let ActionValue::Transfer(val) = params.value {
@@ -212,11 +228,12 @@ impl<'a> Executive<'a> {
match cost <= params.gas {
true => {
self.engine.execute_builtin(¶ms.code_address, data, &mut output);
+ self.state.clear_snapshot();
Ok(params.gas - cost)
},
// just drain the whole gas
false => {
- self.state.revert(backup);
+ self.state.revert_snapshot();
Err(evm::Error::OutOfGas)
}
}
@@ -232,11 +249,12 @@ impl<'a> Executive<'a> {
trace!("exec: sstore-clears={}\n", unconfirmed_substate.sstore_clears_count);
trace!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate);
- self.enact_result(&res, substate, unconfirmed_substate, backup);
+ self.enact_result(&res, substate, unconfirmed_substate);
trace!("exec: new substate={:?}\n", substate);
res
} else {
// otherwise, nothing
+ self.state.clear_snapshot();
Ok(params.gas)
}
}
@@ -246,7 +264,7 @@ impl<'a> Executive<'a> {
/// Modifies the substate.
pub fn create(&mut self, params: ActionParams, substate: &mut Substate) -> evm::Result {
// backup used in case of running out of gas
- let backup = self.state.clone();
+ self.state.snapshot();
// part of substate that may be reverted
let mut unconfirmed_substate = Substate::new();
@@ -263,12 +281,12 @@ impl<'a> Executive<'a> {
let res = {
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract)
};
- self.enact_result(&res, substate, unconfirmed_substate, backup);
+ self.enact_result(&res, substate, unconfirmed_substate);
res
}
/// Finalizes the transaction (does refunds and suicides).
- fn finalize(&mut self, t: &Transaction, substate: Substate, result: evm::Result) -> ExecutionResult {
+ fn finalize(&mut self, t: &SignedTransaction, substate: Substate, result: evm::Result) -> ExecutionResult {
let schedule = self.engine.schedule(self.info);
// refunds from SSTORE nonzero -> zero
@@ -324,16 +342,19 @@ impl<'a> Executive<'a> {
}
}
- fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate, backup: State) {
+ fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate) {
match *result {
Err(evm::Error::OutOfGas)
| Err(evm::Error::BadJumpDestination {..})
| Err(evm::Error::BadInstruction {.. })
| Err(evm::Error::StackUnderflow {..})
| Err(evm::Error::OutOfStack {..}) => {
- self.state.revert(backup);
+ self.state.revert_snapshot();
},
- Ok(_) | Err(evm::Error::Internal) => substate.accrue(un_substate)
+ Ok(_) | Err(evm::Error::Internal) => {
+ self.state.clear_snapshot();
+ substate.accrue(un_substate)
+ }
}
}
}
@@ -685,9 +706,15 @@ mod tests {
// test is incorrect, mk
evm_test_ignore!{test_transact_simple: test_transact_simple_jit, test_transact_simple_int}
fn test_transact_simple(factory: Factory) {
- let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero());
let keypair = KeyPair::create().unwrap();
- t.sign(&keypair.secret());
+ let t = Transaction {
+ action: Action::Create,
+ value: U256::from(17),
+ data: "3331600055".from_hex().unwrap(),
+ gas: U256::from(100_000),
+ gas_price: U256::zero(),
+ nonce: U256::zero()
+ }.sign(&keypair.secret());
let sender = t.sender().unwrap();
let contract = contract_address(&sender, &U256::zero());
@@ -717,8 +744,14 @@ mod tests {
evm_test!{test_transact_invalid_sender: test_transact_invalid_sender_jit, test_transact_invalid_sender_int}
fn test_transact_invalid_sender(factory: Factory) {
- let t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::zero());
-
+ let t = Transaction {
+ action: Action::Create,
+ value: U256::from(17),
+ data: "3331600055".from_hex().unwrap(),
+ gas: U256::from(100_000),
+ gas_price: U256::zero(),
+ nonce: U256::zero()
+ }.fake_sign();
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
let mut info = EnvInfo::default();
@@ -738,11 +771,17 @@ mod tests {
evm_test!{test_transact_invalid_nonce: test_transact_invalid_nonce_jit, test_transact_invalid_nonce_int}
fn test_transact_invalid_nonce(factory: Factory) {
- let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::zero(), U256::one());
let keypair = KeyPair::create().unwrap();
- t.sign(&keypair.secret());
+ let t = Transaction {
+ action: Action::Create,
+ value: U256::from(17),
+ data: "3331600055".from_hex().unwrap(),
+ gas: U256::from(100_000),
+ gas_price: U256::zero(),
+ nonce: U256::one()
+ }.sign(&keypair.secret());
let sender = t.sender().unwrap();
-
+
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(17));
@@ -764,9 +803,15 @@ mod tests {
evm_test!{test_transact_gas_limit_reached: test_transact_gas_limit_reached_jit, test_transact_gas_limit_reached_int}
fn test_transact_gas_limit_reached(factory: Factory) {
- let mut t = Transaction::new_create(U256::from(17), "3331600055".from_hex().unwrap(), U256::from(80_001), U256::zero(), U256::zero());
let keypair = KeyPair::create().unwrap();
- t.sign(&keypair.secret());
+ let t = Transaction {
+ action: Action::Create,
+ value: U256::from(17),
+ data: "3331600055".from_hex().unwrap(),
+ gas: U256::from(80_001),
+ gas_price: U256::zero(),
+ nonce: U256::zero()
+ }.sign(&keypair.secret());
let sender = t.sender().unwrap();
let mut state_result = get_temp_state();
@@ -791,9 +836,16 @@ mod tests {
evm_test!{test_not_enough_cash: test_not_enough_cash_jit, test_not_enough_cash_int}
fn test_not_enough_cash(factory: Factory) {
- let mut t = Transaction::new_create(U256::from(18), "3331600055".from_hex().unwrap(), U256::from(100_000), U256::one(), U256::zero());
+
let keypair = KeyPair::create().unwrap();
- t.sign(&keypair.secret());
+ let t = Transaction {
+ action: Action::Create,
+ value: U256::from(18),
+ data: "3331600055".from_hex().unwrap(),
+ gas: U256::from(100_000),
+ gas_price: U256::one(),
+ nonce: U256::zero()
+ }.sign(&keypair.secret());
let sender = t.sender().unwrap();
let mut state_result = get_temp_state();
diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs
index 6a874330c..ad2f18f11 100644
--- a/ethcore/src/externalities.rs
+++ b/ethcore/src/externalities.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Transaction Execution environment.
use common::*;
use state::*;
diff --git a/ethcore/src/extras.rs b/ethcore/src/extras.rs
index 4c54c6b27..f29925483 100644
--- a/ethcore/src/extras.rs
+++ b/ethcore/src/extras.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Blockchain DB extras.
use util::*;
diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs
index b188a6bcf..6ee682544 100644
--- a/ethcore/src/header.rs
+++ b/ethcore/src/header.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Block header.
use util::*;
diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs
index 6ee7e9f9e..6a9f84073 100644
--- a/ethcore/src/json_tests/chain.rs
+++ b/ethcore/src/json_tests/chain.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use client::{BlockChainClient,Client};
use pod_state::*;
diff --git a/ethcore/src/json_tests/client.rs b/ethcore/src/json_tests/client.rs
index 1d09ed079..2d3166c74 100644
--- a/ethcore/src/json_tests/client.rs
+++ b/ethcore/src/json_tests/client.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use client::{BlockChainClient,Client};
use super::test_common::*;
use tests::helpers::*;
diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs
index 4a56007ad..7ac60e6b4 100644
--- a/ethcore/src/json_tests/executive.rs
+++ b/ethcore/src/json_tests/executive.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use state::*;
use executive::*;
diff --git a/ethcore/src/json_tests/homestead_chain.rs b/ethcore/src/json_tests/homestead_chain.rs
index 1962da1bc..7756840bc 100644
--- a/ethcore/src/json_tests/homestead_chain.rs
+++ b/ethcore/src/json_tests/homestead_chain.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use super::chain::json_chain_test;
use tests::helpers::*;
diff --git a/ethcore/src/json_tests/homestead_state.rs b/ethcore/src/json_tests/homestead_state.rs
index 474d56f8a..0b611dad7 100644
--- a/ethcore/src/json_tests/homestead_state.rs
+++ b/ethcore/src/json_tests/homestead_state.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use tests::helpers::*;
use super::state::json_chain_test;
diff --git a/ethcore/src/json_tests/mod.rs b/ethcore/src/json_tests/mod.rs
index b5d6779bc..1cae0fa1d 100644
--- a/ethcore/src/json_tests/mod.rs
+++ b/ethcore/src/json_tests/mod.rs
@@ -1,3 +1,19 @@
+// 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 .
+
#[macro_use]
mod test_common;
diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs
index fa8da9329..f6b5751a7 100644
--- a/ethcore/src/json_tests/state.rs
+++ b/ethcore/src/json_tests/state.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use tests::helpers::*;
use pod_state::*;
@@ -33,7 +49,7 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec {
flush!(" - {}...", name);
- let t = Transaction::from_json(&test["transaction"]);
+ let t = SignedTransaction::from_json(&test["transaction"]);
let env = EnvInfo::from_json(&test["env"]);
let _out = Bytes::from_json(&test["out"]);
let post_state_root = xjson!(&test["postStateRoot"]);
diff --git a/ethcore/src/json_tests/test_common.rs b/ethcore/src/json_tests/test_common.rs
index 87e7b979e..7f7051bf0 100644
--- a/ethcore/src/json_tests/test_common.rs
+++ b/ethcore/src/json_tests/test_common.rs
@@ -1,3 +1,19 @@
+// 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 .
+
pub use common::*;
macro_rules! test {
diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs
index 91f7d96e5..51888413d 100644
--- a/ethcore/src/json_tests/transaction.rs
+++ b/ethcore/src/json_tests/transaction.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use super::test_common::*;
use evm;
@@ -6,7 +22,7 @@ fn do_json_test(json_data: &[u8]) -> Vec {
let mut failed = Vec::new();
let old_schedule = evm::Schedule::new_frontier();
let new_schedule = evm::Schedule::new_homestead();
- let ot = RefCell::new(Transaction::new());
+ let ot = RefCell::new(None);
for (name, test) in json.as_object().unwrap() {
let mut fail = false;
let mut fail_unless = |cond: bool| if !cond && !fail { failed.push(name.clone()); println!("Transaction: {:?}", ot.borrow()); fail = true };
@@ -15,7 +31,7 @@ fn do_json_test(json_data: &[u8]) -> Vec {
.and_then(|s| BlockNumber::from_str(s).ok())
.unwrap_or(0) { x if x < 1_000_000 => &old_schedule, _ => &new_schedule };
let rlp = Bytes::from_json(&test["rlp"]);
- let res = UntrustedRlp::new(&rlp).as_val().map_err(From::from).and_then(|t: Transaction| t.validate(schedule, schedule.have_delegate_call));
+ let res = UntrustedRlp::new(&rlp).as_val().map_err(From::from).and_then(|t: SignedTransaction| t.validate(schedule, schedule.have_delegate_call));
fail_unless(test.find("transaction").is_none() == res.is_err());
if let (Some(&Json::Object(ref tx)), Some(&Json::String(ref expect_sender))) = (test.find("transaction"), test.find("sender")) {
let t = res.unwrap();
@@ -26,10 +42,10 @@ fn do_json_test(json_data: &[u8]) -> Vec {
fail_unless(t.nonce == xjson!(&tx["nonce"]));
fail_unless(t.value == xjson!(&tx["value"]));
if let Action::Call(ref to) = t.action {
- *ot.borrow_mut() = t.clone();
+ *ot.borrow_mut() = Some(t.clone());
fail_unless(to == &xjson!(&tx["to"]));
} else {
- *ot.borrow_mut() = t.clone();
+ *ot.borrow_mut() = Some(t.clone());
fail_unless(Bytes::from_json(&tx["to"]).is_empty());
}
}
diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs
index 540b5ea40..9537c8862 100644
--- a/ethcore/src/lib.rs
+++ b/ethcore/src/lib.rs
@@ -1,3 +1,19 @@
+// 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 .
+
#![warn(missing_docs)]
#![feature(cell_extras)]
#![feature(augmented_assignments)]
@@ -97,6 +113,7 @@ mod state_diff;
mod engine;
mod state;
mod account;
+mod account_db;
mod action_params;
mod transaction;
mod null_engine;
diff --git a/ethcore/src/log_entry.rs b/ethcore/src/log_entry.rs
index 46faad797..ee73b1ad1 100644
--- a/ethcore/src/log_entry.rs
+++ b/ethcore/src/log_entry.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use util::*;
use basic_types::LogBloom;
diff --git a/ethcore/src/null_engine.rs b/ethcore/src/null_engine.rs
index 3c829606c..af7255617 100644
--- a/ethcore/src/null_engine.rs
+++ b/ethcore/src/null_engine.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use engine::Engine;
use spec::Spec;
use evm::Schedule;
diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs
index 7bc886617..762f47db4 100644
--- a/ethcore/src/pod_account.rs
+++ b/ethcore/src/pod_account.rs
@@ -1,5 +1,22 @@
+// 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 .
+
use util::*;
use account::*;
+use account_db::*;
#[derive(Debug,Clone,PartialEq,Eq)]
/// An account, expressed as Plain-Old-Data (hence the name).
@@ -44,7 +61,7 @@ impl PodAccount {
}
/// Place additional data into given hash DB.
- pub fn insert_additional(&self, db: &mut HashDB) {
+ pub fn insert_additional(&self, db: &mut AccountDBMut) {
if !self.code.is_empty() {
db.insert(&self.code);
}
diff --git a/ethcore/src/pod_state.rs b/ethcore/src/pod_state.rs
index 69eca17b6..b873249ac 100644
--- a/ethcore/src/pod_state.rs
+++ b/ethcore/src/pod_state.rs
@@ -1,3 +1,19 @@
+// 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 .
+
use util::*;
use pod_account::*;
diff --git a/ethcore/src/receipt.rs b/ethcore/src/receipt.rs
index 3888a6abc..5fc1a318b 100644
--- a/ethcore/src/receipt.rs
+++ b/ethcore/src/receipt.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Receipt
use util::*;
diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs
index fa530df70..92f483507 100644
--- a/ethcore/src/service.rs
+++ b/ethcore/src/service.rs
@@ -1,3 +1,19 @@
+// 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 .
+
//! Creates and registers client and network services.
use util::*;
@@ -32,7 +48,6 @@ impl ClientService {
info!("Configured for {} using {} engine", spec.name, spec.engine_name);
let mut dir = env::home_dir().unwrap();
dir.push(".parity");
- dir.push(H64::from(spec.genesis_header().hash()).hex());
let client = try!(Client::new(spec, &dir, net_service.io().channel()));
let client_io = Arc::new(ClientIoHandler {
client: client.clone()
diff --git a/ethcore/src/spec.rs b/ethcore/src/spec.rs
index 50bbbb633..67269d334 100644
--- a/ethcore/src/spec.rs
+++ b/ethcore/src/spec.rs
@@ -1,9 +1,26 @@
+// 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 .
+
//! Parameters for a block chain.
use common::*;
use engine::*;
use pod_state::*;
use null_engine::*;
+use account_db::*;
/// Convert JSON value to equivalent RLP representation.
// TODO: handle container types.
@@ -262,8 +279,8 @@ impl Spec {
t.insert(address.as_slice(), &account.rlp());
}
}
- for (_, account) in self.genesis_state.get().iter() {
- account.insert_additional(db);
+ for (address, account) in self.genesis_state.get().iter() {
+ account.insert_additional(&mut AccountDBMut::new(db, address));
}
assert!(db.contains(&self.state_root()));
true
diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs
index ed7d29813..e30f703ae 100644
--- a/ethcore/src/state.rs
+++ b/ethcore/src/state.rs
@@ -1,6 +1,23 @@
+// 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 .
+
use common::*;
use engine::Engine;
use executive::Executive;
+use account_db::*;
#[cfg(test)]
#[cfg(feature = "json-tests")]
use pod_account::*;
@@ -13,12 +30,11 @@ use pod_state::PodState;
pub type ApplyResult = Result;
/// Representation of the entire state of all accounts in the system.
-#[derive(Clone)]
pub struct State {
db: JournalDB,
root: H256,
cache: RefCell>>,
-
+ snapshots: RefCell>>>>,
account_start_nonce: U256,
}
@@ -36,6 +52,7 @@ impl State {
db: db,
root: root,
cache: RefCell::new(HashMap::new()),
+ snapshots: RefCell::new(Vec::new()),
account_start_nonce: account_start_nonce,
}
}
@@ -51,10 +68,63 @@ impl State {
db: db,
root: root,
cache: RefCell::new(HashMap::new()),
+ snapshots: RefCell::new(Vec::new()),
account_start_nonce: account_start_nonce,
}
}
+ /// Create a recoverable snaphot of this state
+ pub fn snapshot(&mut self) {
+ self.snapshots.borrow_mut().push(HashMap::new());
+ }
+
+ /// Merge last snapshot with previous
+ pub fn clear_snapshot(&mut self) {
+ // merge with previous snapshot
+ let last = self.snapshots.borrow_mut().pop();
+ if let Some(mut snapshot) = last {
+ if let Some(ref mut prev) = self.snapshots.borrow_mut().last_mut() {
+ for (k, v) in snapshot.drain() {
+ prev.entry(k).or_insert(v);
+ }
+ }
+ }
+ }
+
+ /// Revert to snapshot
+ pub fn revert_snapshot(&mut self) {
+ if let Some(mut snapshot) = self.snapshots.borrow_mut().pop() {
+ for (k, v) in snapshot.drain() {
+ match v {
+ Some(v) => {
+ self.cache.borrow_mut().insert(k, v);
+ },
+ None => {
+ self.cache.borrow_mut().remove(&k);
+ }
+ }
+ }
+ }
+ }
+
+ fn insert_cache(&self, address: &Address, account: Option) {
+ if let Some(ref mut snapshot) = self.snapshots.borrow_mut().last_mut() {
+ if !snapshot.contains_key(&address) {
+ snapshot.insert(address.clone(), self.cache.borrow_mut().insert(address.clone(), account));
+ return;
+ }
+ }
+ self.cache.borrow_mut().insert(address.clone(), account);
+ }
+
+ fn note_cache(&self, address: &Address) {
+ if let Some(ref mut snapshot) = self.snapshots.borrow_mut().last_mut() {
+ if !snapshot.contains_key(&address) {
+ snapshot.insert(address.clone(), self.cache.borrow().get(address).cloned());
+ }
+ }
+ }
+
/// Destroy the current object and return root and database.
pub fn drop(self) -> (H256, JournalDB) {
(self.root, self.db)
@@ -68,12 +138,12 @@ impl State {
/// Create a new contract at address `contract`. If there is already an account at the address
/// it will have its code reset, ready for `init_code()`.
pub fn new_contract(&mut self, contract: &Address, balance: U256) {
- self.cache.borrow_mut().insert(contract.clone(), Some(Account::new_contract(balance)));
+ self.insert_cache(&contract, Some(Account::new_contract(balance)));
}
/// Remove an existing account.
pub fn kill_account(&mut self, account: &Address) {
- self.cache.borrow_mut().insert(account.clone(), None);
+ self.insert_cache(account, None);
}
/// Determine whether an account exists.
@@ -91,9 +161,9 @@ impl State {
self.get(a, false).as_ref().map_or(U256::zero(), |account| account.nonce().clone())
}
- /// Mutate storage of account `a` so that it is `value` for `key`.
- pub fn storage_at(&self, a: &Address, key: &H256) -> H256 {
- self.get(a, false).as_ref().map_or(H256::new(), |a|a.storage_at(&self.db, key))
+ /// Mutate storage of account `address` so that it is `value` for `key`.
+ pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
+ self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(&self.db, address), key))
}
/// Mutate storage of account `a` so that it is `value` for `key`.
@@ -139,7 +209,7 @@ impl State {
/// Execute a given transaction.
/// This will change the state accordingly.
- pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
+ pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &SignedTransaction) -> ApplyResult {
// let old = self.to_pod();
let e = try!(Executive::new(self, env_info, engine).transact(t));
@@ -152,22 +222,18 @@ impl State {
Ok(receipt)
}
- /// Reverts uncommited changed.
- pub fn revert(&mut self, backup: State) {
- self.cache = backup.cache;
- }
-
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
/// `accounts` is mutable because we may need to commit the code or storage and record that.
#[allow(match_ref_pats)]
pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap>) {
// first, commit the sub trees.
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
- for (_, ref mut a) in accounts.iter_mut() {
+ for (address, ref mut a) in accounts.iter_mut() {
match a {
&mut&mut Some(ref mut account) => {
- account.commit_storage(db);
- account.commit_code(db);
+ let mut account_db = AccountDBMut::new(db, address);
+ account.commit_storage(&mut account_db);
+ account.commit_code(&mut account_db);
}
&mut&mut None => {}
}
@@ -186,6 +252,7 @@ impl State {
/// Commits our cached account changes into the trie.
pub fn commit(&mut self) {
+ assert!(self.snapshots.borrow().is_empty());
Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
}
@@ -193,6 +260,7 @@ impl State {
#[cfg(feature = "json-tests")]
/// Populate the state from `accounts`.
pub fn populate_from(&mut self, accounts: PodState) {
+ assert!(self.snapshots.borrow().is_empty());
for (add, acc) in accounts.drain().into_iter() {
self.cache.borrow_mut().insert(add, Some(Account::from_pod(acc)));
}
@@ -202,6 +270,7 @@ impl State {
#[cfg(feature = "json-tests")]
/// Populate a PodAccount map from this state.
pub fn to_pod(&self) -> PodState {
+ assert!(self.snapshots.borrow().is_empty());
// TODO: handle database rather than just the cache.
PodState::from(self.cache.borrow().iter().fold(BTreeMap::new(), |mut m, (add, opt)| {
if let Some(ref acc) = *opt {
@@ -214,12 +283,13 @@ impl State {
/// Pull account `a` in our cache from the trie DB and return it.
/// `require_code` requires that the code be cached, too.
fn get(&self, a: &Address, require_code: bool) -> Ref