diff --git a/Cargo.lock b/Cargo.lock index 460fd08c9..edcfc1fd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -439,7 +439,6 @@ name = "common-types" version = "0.1.0" dependencies = [ "ethereum-types 0.4.2", - "ethjson", "ethkey", "heapsize", "keccak-hash", @@ -1375,7 +1374,9 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ + "common-types", "ethereum-types 0.4.2", + "ethkey", "macros", "maplit", "rustc-hex 1.0.0", diff --git a/bin/evmbin/src/main.rs b/bin/evmbin/src/main.rs index a7a63474b..45b28f583 100644 --- a/bin/evmbin/src/main.rs +++ b/bin/evmbin/src/main.rs @@ -204,7 +204,7 @@ fn run_state_test(args: Args) { } for (idx, state) in states.into_iter().enumerate() { let post_root = state.hash.into(); - let transaction = multitransaction.select(&state.indexes).into(); + let transaction = multitransaction.select(&state.indexes); let trie_spec = if args.flag_std_dump_json { TrieSpec::Fat diff --git a/crates/ethcore/res/json_tests b/crates/ethcore/res/json_tests index 1508126ea..31d663076 160000 --- a/crates/ethcore/res/json_tests +++ b/crates/ethcore/res/json_tests @@ -1 +1 @@ -Subproject commit 1508126ea04cd61495b60db2f036ac823de274b1 +Subproject commit 31d663076b6678df18983d6da912d7cad4ad3416 diff --git a/crates/ethcore/src/json_tests/runner.rs b/crates/ethcore/src/json_tests/runner.rs index a82af46cc..1def4f91c 100644 --- a/crates/ethcore/src/json_tests/runner.rs +++ b/crates/ethcore/src/json_tests/runner.rs @@ -184,7 +184,7 @@ impl TestRunner { return Vec::new(); } } - super::state::json_chain_test(&test, &path, &json, &mut |_, _| {}) + super::state::json_state_test(&test, &path, &json, &mut |_, _| {}) }, ) } diff --git a/crates/ethcore/src/json_tests/state.rs b/crates/ethcore/src/json_tests/state.rs index 2b1c89ebc..0070b8710 100644 --- a/crates/ethcore/src/json_tests/state.rs +++ b/crates/ethcore/src/json_tests/state.rs @@ -20,7 +20,6 @@ use ethjson; use pod_state::PodState; use std::path::Path; use trace; -use types::transaction::SignedTransaction; use vm::EnvInfo; fn skip_test( @@ -42,7 +41,7 @@ fn skip_test( }) } -pub fn json_chain_test( +pub fn json_state_test( state_test: ðjson::test::StateTests, path: &Path, json_data: &[u8], @@ -91,8 +90,7 @@ pub fn json_chain_test( } let post_root: H256 = state.hash.into(); - let transaction: SignedTransaction = - multitransaction.select(&state.indexes).into(); + let transaction = multitransaction.select(&state.indexes); let result = || -> Result<_, EvmTestError> { Ok(EvmTestClient::from_pod_state(&spec, pre.clone())?.transact( diff --git a/crates/ethcore/types/Cargo.toml b/crates/ethcore/types/Cargo.toml index d6a18bcd1..9a16ddcb6 100644 --- a/crates/ethcore/types/Cargo.toml +++ b/crates/ethcore/types/Cargo.toml @@ -6,7 +6,6 @@ authors = ["Parity Technologies "] [dependencies] ethereum-types = "0.4" -ethjson = { path = "../../ethjson" } ethkey = { path = "../../accounts/ethkey" } heapsize = "0.4" keccak-hash = "0.1" diff --git a/crates/ethcore/types/src/lib.rs b/crates/ethcore/types/src/lib.rs index 833e5a61c..5c99c105b 100644 --- a/crates/ethcore/types/src/lib.rs +++ b/crates/ethcore/types/src/lib.rs @@ -35,7 +35,6 @@ #![warn(unused_extern_crates)] extern crate ethereum_types; -extern crate ethjson; extern crate ethkey; extern crate heapsize; extern crate keccak_hash as hash; diff --git a/crates/ethcore/types/src/log_entry.rs b/crates/ethcore/types/src/log_entry.rs index 89b56161b..129e78a92 100644 --- a/crates/ethcore/types/src/log_entry.rs +++ b/crates/ethcore/types/src/log_entry.rs @@ -21,7 +21,6 @@ use ethereum_types::{Address, Bloom, BloomInput, H256}; use heapsize::HeapSizeOf; use std::ops::Deref; -use ethjson; use BlockNumber; /// A record of execution for a `LOG` operation. @@ -53,16 +52,6 @@ impl LogEntry { } } -impl From for LogEntry { - fn from(l: ethjson::state::Log) -> Self { - LogEntry { - address: l.address.into(), - topics: l.topics.into_iter().map(Into::into).collect(), - data: l.data.into(), - } - } -} - /// Log localized in a blockchain. #[derive(Default, Debug, PartialEq, Clone)] pub struct LocalizedLogEntry { diff --git a/crates/ethcore/types/src/transaction/transaction.rs b/crates/ethcore/types/src/transaction/transaction.rs index 66f477fd9..892795a6a 100644 --- a/crates/ethcore/types/src/transaction/transaction.rs +++ b/crates/ethcore/types/src/transaction/transaction.rs @@ -17,7 +17,6 @@ //! Transaction data structure. use ethereum_types::{Address, H160, H256, U256}; -use ethjson; use ethkey::{self, public_to_address, recover, Public, Secret, Signature}; use hash::keccak; use heapsize::HeapSizeOf; @@ -606,56 +605,6 @@ impl SignatureComponents { } } -#[cfg(any(test, feature = "test-helpers"))] -impl From for SignedTransaction { - fn from(t: ethjson::state::Transaction) -> Self { - let to: Option = t.to.into(); - let secret = t.secret.map(|s| Secret::from(s.0)); - let tx = TypedTransaction::Legacy(Transaction { - nonce: t.nonce.into(), - gas_price: t.gas_price.into(), - gas: t.gas_limit.into(), - action: match to { - Some(to) => Action::Call(to.into()), - None => Action::Create, - }, - value: t.value.into(), - data: t.data.into(), - }); - match secret { - Some(s) => tx.sign(&s, None), - None => tx.null_sign(1), - } - } -} - -impl From for UnverifiedTransaction { - fn from(t: ethjson::transaction::Transaction) -> Self { - let to: Option = t.to.into(); - UnverifiedTransaction { - unsigned: TypedTransaction::Legacy(Transaction { - nonce: t.nonce.into(), - gas_price: t.gas_price.into(), - gas: t.gas_limit.into(), - action: match to { - Some(to) => Action::Call(to.into()), - None => Action::Create, - }, - value: t.value.into(), - data: t.data.into(), - }), - chain_id: signature::extract_chain_id_from_legacy_v(t.v.into()), - signature: SignatureComponents { - r: t.r.into(), - s: t.s.into(), - standard_v: signature::extract_standard_v(t.v.into()), - }, - hash: 0.into(), - } - .compute_hash() - } -} - /// Signed transaction information without verified signature. #[derive(Debug, Clone, Eq, PartialEq)] pub struct UnverifiedTransaction { diff --git a/crates/ethjson/Cargo.toml b/crates/ethjson/Cargo.toml index 584c04637..b86f34f1d 100644 --- a/crates/ethjson/Cargo.toml +++ b/crates/ethjson/Cargo.toml @@ -5,6 +5,8 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] +common-types = { path = "../ethcore/types", features = ["test-helpers"] } +ethkey = { path = "../accounts/ethkey" } ethereum-types = "0.4" rustc-hex = "1.0" serde = "1.0" diff --git a/crates/ethjson/src/blockchain/transaction.rs b/crates/ethjson/src/blockchain/transaction.rs index 003beb306..277e52001 100644 --- a/crates/ethjson/src/blockchain/transaction.rs +++ b/crates/ethjson/src/blockchain/transaction.rs @@ -41,7 +41,7 @@ pub struct Transaction { pub type AccessList = Vec; -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Debug, PartialEq, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct AccessListItem { pub address: H160, diff --git a/crates/ethjson/src/lib.rs b/crates/ethjson/src/lib.rs index 2f8b67d19..f5a6d5f83 100644 --- a/crates/ethjson/src/lib.rs +++ b/crates/ethjson/src/lib.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with OpenEthereum. If not, see . +extern crate common_types as types; extern crate ethereum_types; +extern crate ethkey; extern crate rustc_hex; extern crate serde; extern crate serde_json; diff --git a/crates/ethjson/src/state/test.rs b/crates/ethjson/src/state/test.rs index 5c2439d3d..4411ff586 100644 --- a/crates/ethjson/src/state/test.rs +++ b/crates/ethjson/src/state/test.rs @@ -17,14 +17,18 @@ //! General test deserialization. use bytes::Bytes; +use ethkey::Secret; use hash::{Address, H256}; use maybe::MaybeEmpty; use serde_json::{self, Error}; use spec::ForkSpec; -use state::{AccountState, Env, Transaction}; +use state::{AccountState, Env}; use std::{collections::BTreeMap, io::Read}; +use types::transaction::{AccessListTx, Action, SignedTransaction, Transaction, TypedTransaction}; use uint::Uint; +use crate::blockchain::transaction::AccessList; + /// State test deserializer. #[derive(Debug, PartialEq, Deserialize)] pub struct Test(BTreeMap); @@ -69,6 +73,8 @@ pub struct State { pub struct MultiTransaction { /// Transaction data set. pub data: Vec, + /// Optional access list + pub access_lists: Option>>, /// Gas limit set. pub gas_limit: Vec, /// Gas price. @@ -84,18 +90,57 @@ pub struct MultiTransaction { pub value: Vec, } +fn sign_with_secret(tx: TypedTransaction, secret: Option) -> SignedTransaction { + match secret { + Some(s) => tx.sign(&s, None), + None => tx.null_sign(1), + } +} + impl MultiTransaction { /// Build transaction with given indexes. - pub fn select(&self, indexes: &PostStateIndexes) -> Transaction { - Transaction { - data: self.data[indexes.data as usize].clone(), - gas_limit: self.gas_limit[indexes.gas as usize].clone(), - gas_price: self.gas_price.clone(), - nonce: self.nonce.clone(), - secret: self.secret.clone(), - to: self.to.clone(), - value: self.value[indexes.value as usize].clone(), + pub fn select(&self, indexes: &PostStateIndexes) -> SignedTransaction { + let secret = self.secret.clone().map(|s| Secret::from(s.0)); + let to: Option
= self.to.clone().into(); + let transaction = Transaction { + nonce: self.nonce.clone().into(), + gas_price: self.gas_price.clone().into(), + gas: self.gas_limit[indexes.gas as usize].clone().into(), + action: match to { + Some(to) => Action::Call(to.into()), + None => Action::Create, + }, + value: self.value[indexes.value as usize].clone().into(), + data: self.data[indexes.data as usize].clone().into(), + }; + + if let Some(access_lists) = self.access_lists.as_ref() { + if access_lists.len() > indexes.data as usize { + if let Some(access_list) = access_lists[indexes.data as usize].clone() { + //access list type of transaction + + let access_list = access_list + .into_iter() + .map(|elem| { + ( + elem.address.into(), + elem.storage_keys.into_iter().map(Into::into).collect(), + ) + }) + .collect(); + + let tx = TypedTransaction::AccessList(AccessListTx { + transaction, + access_list, + }); + + return sign_with_secret(tx, secret); + } + } } + + let tx = TypedTransaction::Legacy(transaction); + sign_with_secret(tx, secret) } } @@ -138,6 +183,39 @@ mod tests { let _deserialized: MultiTransaction = serde_json::from_str(s).unwrap(); } + #[test] + fn multi_transaction_deserialization_with_access_list() { + let s = r#"{ + "data" : [ "" ], + "accessLists" : [ + null, + [ + ], + [ + { + "address" : "0x0000000000000000000000000000000000000102", + "storageKeys" : [ + ] + }, + { + "address" : "0x0000000000000000000000000000000000000101", + "storageKeys" : [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000010" + ] + } + ] + ], + "gasLimit" : [ "0x2dc6c0", "0x222222" ], + "gasPrice" : "0x01", + "nonce" : "0x00", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "1000000000000000000000000000000000000000", + "value" : [ "0x00", "0x01", "0x02" ] + }"#; + let _deserialized: MultiTransaction = serde_json::from_str(s).unwrap(); + } + #[test] fn state_deserialization() { let s = r#"{ diff --git a/crates/ethjson/src/state/transaction.rs b/crates/ethjson/src/state/transaction.rs index 68e639c9c..b770a30a4 100644 --- a/crates/ethjson/src/state/transaction.rs +++ b/crates/ethjson/src/state/transaction.rs @@ -51,6 +51,7 @@ mod tests { fn transaction_deserialization() { let s = r#"{ "data" : "", + "accessLists": null, "gasLimit" : "0x2dc6c0", "gasPrice" : "0x01", "nonce" : "0x00",