From 083b69ffb1552f528141b9a1f948dcd55ed5b960 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 21 Sep 2017 11:42:58 +0200 Subject: [PATCH] [beta] Backports (#6563) * Sync progress and error handling fixes (#6560) * Fixed receipt serialization and RPC (#6555) * v1.7.3 --- Cargo.lock | 50 +++++------ Cargo.toml | 2 +- ethcore/light/src/on_demand/request.rs | 5 +- ethcore/light/src/types/request/mod.rs | 7 +- ethcore/src/block.rs | 4 +- ethcore/src/blockchain/blockchain.rs | 11 +-- ethcore/src/client/client.rs | 14 ++- ethcore/src/client/test_client.rs | 5 +- ethcore/src/miner/miner.rs | 2 +- ethcore/src/state/mod.rs | 20 ++--- ethcore/types/src/receipt.rs | 103 ++++++++++++++-------- mac/Parity.pkgproj | 2 +- nsis/installer.nsi | 2 +- parity/informant.rs | 5 +- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- rpc/src/v1/tests/mocked/eth.rs | 6 +- rpc/src/v1/types/receipt.rs | 33 +++++-- sync/src/chain.rs | 8 +- util/Cargo.toml | 2 +- 19 files changed, 164 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd35e0345..13c75a5ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,7 +277,7 @@ dependencies = [ name = "common-types" version = "0.1.0" dependencies = [ - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethjson 0.1.0", "rlp 0.2.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -476,7 +476,7 @@ dependencies = [ "ethcore-ipc-nano 1.7.0", "ethcore-logger 1.7.0", "ethcore-stratum 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethjson 0.1.0", "ethkey 0.2.0", "ethstore 0.1.0", @@ -545,7 +545,7 @@ name = "ethcore-ipc" version = "1.7.0" dependencies = [ "ethcore-devtools 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -594,7 +594,7 @@ dependencies = [ "ethcore-ipc 1.7.0", "ethcore-ipc-codegen 1.7.0", "ethcore-ipc-nano 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -611,7 +611,7 @@ dependencies = [ "ethcore-ipc 1.7.0", "ethcore-ipc-codegen 1.7.0", "ethcore-network 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "evm 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -650,7 +650,7 @@ dependencies = [ "ethcore-devtools 1.7.0", "ethcore-io 1.7.0", "ethcore-logger 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethcrypto 0.1.0", "ethkey 0.2.0", "igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -681,7 +681,7 @@ dependencies = [ "ethcore-ipc-codegen 1.7.0", "ethcore-ipc-nano 1.7.0", "ethcore-logger 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethcrypto 0.1.0", "ethkey 0.2.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -711,7 +711,7 @@ dependencies = [ "ethcore-ipc-codegen 1.7.0", "ethcore-ipc-nano 1.7.0", "ethcore-logger 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-macros 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -724,7 +724,7 @@ dependencies = [ [[package]] name = "ethcore-util" -version = "1.7.2" +version = "1.7.3" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", @@ -774,7 +774,7 @@ name = "ethjson" version = "0.1.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -855,7 +855,7 @@ dependencies = [ "ethcore-ipc-nano 1.7.0", "ethcore-light 1.7.0", "ethcore-network 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethkey 0.2.0", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -874,7 +874,7 @@ dependencies = [ "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethjson 0.1.0", "evmjit 1.7.0", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -891,7 +891,7 @@ version = "0.1.0" dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethjson 0.1.0", "evm 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1136,7 +1136,7 @@ version = "1.7.0" dependencies = [ "ethcore-ipc 1.7.0", "ethcore-ipc-codegen 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1530,7 +1530,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "native-contract-generator 0.1.0", ] @@ -1735,7 +1735,7 @@ dependencies = [ [[package]] name = "parity" -version = "1.7.2" +version = "1.7.3" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1755,7 +1755,7 @@ dependencies = [ "ethcore-logger 1.7.0", "ethcore-secretstore 1.0.0", "ethcore-stratum 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethkey 0.2.0", "ethsync 1.7.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1801,7 +1801,7 @@ dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-devtools 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "fetch 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -1845,7 +1845,7 @@ name = "parity-hash-fetch" version = "1.7.0" dependencies = [ "ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "fetch 0.1.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1863,7 +1863,7 @@ version = "1.7.0" dependencies = [ "cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "jsonrpc-http-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1876,7 +1876,7 @@ version = "0.1.0" dependencies = [ "ethcore 1.7.0", "ethcore-io 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethkey 0.2.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.0", @@ -1906,7 +1906,7 @@ dependencies = [ "ethcore-ipc 1.7.0", "ethcore-light 1.7.0", "ethcore-logger 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethcrypto 0.1.0", "ethjson 0.1.0", "ethkey 0.2.0", @@ -1948,7 +1948,7 @@ dependencies = [ name = "parity-rpc-client" version = "1.4.0" dependencies = [ - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", "jsonrpc-ws-server 7.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.7)", @@ -2011,7 +2011,7 @@ dependencies = [ "ethcore 1.7.0", "ethcore-ipc 1.7.0", "ethcore-ipc-codegen 1.7.0", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "ethsync 1.7.0", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-common-types 1.7.0", @@ -2367,7 +2367,7 @@ name = "rpc-cli" version = "1.4.0" dependencies = [ "bigint 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-util 1.7.2", + "ethcore-util 1.7.3", "futures 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-rpc 1.7.0", "parity-rpc-client 1.4.0", diff --git a/Cargo.toml b/Cargo.toml index 984e0649d..a5f504fc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Parity Ethereum client" name = "parity" -version = "1.7.2" +version = "1.7.3" license = "GPL-3.0" authors = ["Parity Technologies "] build = "build.rs" diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index a2b9ab3ac..155be37de 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use ethcore::basic_account::BasicAccount; use ethcore::encoded; use ethcore::engines::Engine; -use ethcore::receipt::Receipt; +use ethcore::receipt::{Receipt, TransactionOutcome}; use ethcore::state::{self, ProvedExecution}; use ethcore::transaction::SignedTransaction; use evm::env_info::EnvInfo; @@ -926,8 +926,7 @@ mod tests { #[test] fn check_receipts() { let receipts = (0..5).map(|_| Receipt { - state_root: Some(H256::random()), - status_code: None, + outcome: TransactionOutcome::StateRoot(H256::random()), gas_used: 21_000u64.into(), log_bloom: Default::default(), logs: Vec::new(), diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index ff4a32535..eca989938 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -1859,13 +1859,15 @@ mod tests { #[test] fn receipts_roundtrip() { + use ethcore::receipt::{Receipt, TransactionOutcome}; let req = IncompleteReceiptsRequest { hash: Field::Scalar(Default::default()), }; let full_req = Request::Receipts(req.clone()); + let receipt = Receipt::new(TransactionOutcome::Unknown, Default::default(), Vec::new()); let res = ReceiptsResponse { - receipts: vec![Default::default(), Default::default()], + receipts: vec![receipt.clone(), receipt], }; let full_res = Response::Receipts(res.clone()); @@ -2020,6 +2022,7 @@ mod tests { #[test] fn responses_vec() { + use ethcore::receipt::{Receipt, TransactionOutcome}; let mut stream = RlpStream::new_list(2); stream.begin_list(0).begin_list(0); @@ -2027,7 +2030,7 @@ mod tests { let reqs = vec![ Response::Headers(HeadersResponse { headers: vec![] }), Response::HeaderProof(HeaderProofResponse { proof: vec![], hash: Default::default(), td: 100.into()}), - Response::Receipts(ReceiptsResponse { receipts: vec![Default::default()] }), + Response::Receipts(ReceiptsResponse { receipts: vec![Receipt::new(TransactionOutcome::Unknown, Default::default(), Vec::new())] }), Response::Body(BodyResponse { body: body }), Response::Account(AccountResponse { proof: vec![], diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 8cd1e22b6..6d3e406fc 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -30,7 +30,7 @@ use engines::Engine; use error::{Error, BlockError, TransactionError}; use factory::Factories; use header::Header; -use receipt::Receipt; +use receipt::{Receipt, TransactionOutcome}; use state::State; use state_db::StateDB; use trace::FlatTrace; @@ -524,7 +524,7 @@ impl LockedBlock { pub fn strip_receipts(self) -> LockedBlock { let mut block = self; for receipt in &mut block.block.receipts { - receipt.state_root = None; + receipt.outcome = TransactionOutcome::Unknown; } block.block.header.set_receipts_root(ordered_trie_root(block.block.receipts.iter().map(|r| r.rlp_bytes().into_vec()))); block diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 69b6b7255..77a6a1640 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -1471,7 +1471,7 @@ mod tests { use util::kvdb::KeyValueDB; use util::hash::*; use util::sha3::Hashable; - use receipt::Receipt; + use receipt::{Receipt, TransactionOutcome}; use blockchain::{BlockProvider, BlockChain, Config, ImportRoute}; use tests::helpers::*; use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer}; @@ -2038,8 +2038,7 @@ mod tests { let db = new_db(); let bc = new_chain(&genesis, db.clone()); insert_block(&db, &bc, &b1, vec![Receipt { - state_root: Some(H256::default()), - status_code: None, + outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), log_bloom: Default::default(), logs: vec![ @@ -2048,8 +2047,7 @@ mod tests { ], }, Receipt { - state_root: Some(H256::default()), - status_code: None, + outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), log_bloom: Default::default(), logs: vec![ @@ -2058,8 +2056,7 @@ mod tests { }]); insert_block(&db, &bc, &b2, vec![ Receipt { - state_root: Some(H256::default()), - status_code: None, + outcome: TransactionOutcome::StateRoot(H256::default()), gas_used: 10_000.into(), log_bloom: Default::default(), logs: vec![ diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 285778ffc..06d034897 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1978,7 +1978,7 @@ fn transaction_receipt(engine: &Engine, mut tx: LocalizedTransaction, mut receip log_index: no_of_logs + i, }).collect(), log_bloom: receipt.log_bloom, - state_root: receipt.state_root, + outcome: receipt.outcome, } } @@ -2023,7 +2023,7 @@ mod tests { use super::transaction_receipt; use ethkey::KeyPair; use log_entry::{LogEntry, LocalizedLogEntry}; - use receipt::{Receipt, LocalizedReceipt}; + use receipt::{Receipt, LocalizedReceipt, TransactionOutcome}; use transaction::{Transaction, LocalizedTransaction, Action}; use util::Hashable; use tests::helpers::TestEngine; @@ -2035,7 +2035,7 @@ mod tests { let block_number = 1; let block_hash = 5.into(); - let state_root = Some(99.into()); + let state_root = 99.into(); let gas_used = 10.into(); let raw_tx = Transaction { nonce: 0.into(), @@ -2063,14 +2063,12 @@ mod tests { data: vec![], }]; let receipts = vec![Receipt { - state_root: state_root, - status_code: None, + outcome: TransactionOutcome::StateRoot(state_root), gas_used: 5.into(), log_bloom: Default::default(), logs: vec![logs[0].clone()], }, Receipt { - state_root: state_root, - status_code: None, + outcome: TransactionOutcome::StateRoot(state_root), gas_used: gas_used, log_bloom: Default::default(), logs: logs.clone(), @@ -2106,7 +2104,7 @@ mod tests { log_index: 2, }], log_bloom: Default::default(), - state_root: state_root, + outcome: TransactionOutcome::StateRoot(state_root), }); } } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 9b5bd754f..5d4f7d517 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -33,7 +33,7 @@ use db::{NUM_COLUMNS, COL_STATE}; use header::{Header as BlockHeader, BlockNumber}; use filter::Filter; use log_entry::LocalizedLogEntry; -use receipt::{Receipt, LocalizedReceipt}; +use receipt::{Receipt, LocalizedReceipt, TransactionOutcome}; use blockchain::extras::BlockReceipts; use error::{ImportResult, Error as EthcoreError}; use evm::{Factory as EvmFactory, VMType, Schedule}; @@ -594,8 +594,7 @@ impl BlockChainClient for TestBlockChainClient { // starts with 'f' ? if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") { let receipt = BlockReceipts::new(vec![Receipt::new( - Some(H256::zero()), - None, + TransactionOutcome::StateRoot(H256::zero()), U256::zero(), vec![])]); let mut rlp = RlpStream::new(); diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index f8decef1b..af173ec70 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1078,7 +1078,7 @@ impl MinerService for Miner { }, logs: receipt.logs.clone(), log_bloom: receipt.log_bloom, - state_root: receipt.state_root, + outcome: receipt.outcome.clone(), } }) } diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index eda9de6da..6a7aecfeb 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -22,7 +22,7 @@ use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry; -use receipt::Receipt; +use receipt::{Receipt, TransactionOutcome}; use engines::Engine; use evm::env_info::EnvInfo; use error::Error; @@ -655,21 +655,19 @@ impl State { eip658 || (env_info.number >= engine.params().eip98_transition && env_info.number >= engine.params().validate_receipts_transition); - let state_root = if no_intermediate_commits { - None + let outcome = if no_intermediate_commits { + if eip658 { + TransactionOutcome::StatusCode(if e.exception.is_some() { 0 } else { 1 }) + } else { + TransactionOutcome::Unknown + } } else { self.commit()?; - Some(self.root().clone()) - }; - - let status_byte = if eip658 { - Some(if e.exception.is_some() { 0 } else { 1 }) - } else { - None + TransactionOutcome::StateRoot(self.root().clone()) }; let output = e.output; - let receipt = Receipt::new(state_root, status_byte, e.cumulative_gas_used, e.logs); + let receipt = Receipt::new(outcome, e.cumulative_gas_used, e.logs); trace!(target: "state", "Transaction receipt: {:?}", receipt); Ok(ApplyOutcome { diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index 2489958cb..d71cf85e1 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -23,44 +23,56 @@ use rlp::*; use {BlockNumber}; use log_entry::{LogBloom, LogEntry, LocalizedLogEntry}; +/// Transaction outcome store in the receipt. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum TransactionOutcome { + /// Status and state root are unknown under EIP-98 rules. + Unknown, + /// State root is known. Pre EIP-98 and EIP-658 rules. + StateRoot(H256), + /// Status code is known. EIP-658 rules. + StatusCode(u8), +} + /// Information describing execution of a transaction. -#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Receipt { - /// The state root after executing the transaction. Optional since EIP98 - pub state_root: Option, /// The total gas used in the block following execution of the transaction. pub gas_used: U256, /// The OR-wide combination of all logs' blooms for this transaction. pub log_bloom: LogBloom, /// The logs stemming from this transaction. pub logs: Vec, - /// Status byte. Optional before EIP-658. - pub status_code: Option, + /// Transaction outcome. + pub outcome: TransactionOutcome, } impl Receipt { /// Create a new receipt. - pub fn new(state_root: Option, status_code: Option, gas_used: U256, logs: Vec) -> Receipt { + pub fn new(outcome: TransactionOutcome, gas_used: U256, logs: Vec) -> Receipt { Receipt { - state_root: state_root, gas_used: gas_used, log_bloom: logs.iter().fold(LogBloom::default(), |mut b, l| { b = &b | &l.bloom(); b }), //TODO: use |= operator logs: logs, - status_code: status_code, + outcome: outcome, } } } impl Encodable for Receipt { fn rlp_append(&self, s: &mut RlpStream) { - if let Some(ref status) = self.status_code { - s.begin_list(4); - s.append(status); - } else if let Some(ref root) = self.state_root { - s.begin_list(4); - s.append(root); - } else { - s.begin_list(3); + match self.outcome { + TransactionOutcome::Unknown => { + s.begin_list(3); + }, + TransactionOutcome::StateRoot(ref root) => { + s.begin_list(4); + s.append(root); + }, + TransactionOutcome::StatusCode(ref status_code) => { + s.begin_list(4); + s.append(status_code); + }, } s.append(&self.gas_used); s.append(&self.log_bloom); @@ -72,28 +84,25 @@ impl Decodable for Receipt { fn decode(rlp: &UntrustedRlp) -> Result { if rlp.item_count()? == 3 { Ok(Receipt { - state_root: None, - status_code: None, + outcome: TransactionOutcome::Unknown, gas_used: rlp.val_at(0)?, log_bloom: rlp.val_at(1)?, logs: rlp.list_at(2)?, }) } else { - let mut receipt = Receipt { + Ok(Receipt { gas_used: rlp.val_at(1)?, log_bloom: rlp.val_at(2)?, logs: rlp.list_at(3)?, - state_root: None, - status_code: None, - }; - - let first = rlp.at(0)?; - if first.is_data() && first.data()?.len() == 1 { - receipt.status_code = Some(first.as_val()?); - } else { - receipt.state_root = Some(first.as_val()?); - } - Ok(receipt) + outcome: { + let first = rlp.at(0)?; + if first.is_data() && first.data()?.len() <= 1 { + TransactionOutcome::StatusCode(first.as_val()?) + } else { + TransactionOutcome::StateRoot(first.as_val()?) + } + } + }) } } } @@ -121,8 +130,8 @@ pub struct RichReceipt { pub logs: Vec, /// Logs bloom pub log_bloom: LogBloom, - /// State root - pub state_root: Option, + /// Transaction outcome. + pub outcome: TransactionOutcome, } /// Receipt with additional info. @@ -146,21 +155,20 @@ pub struct LocalizedReceipt { pub logs: Vec, /// Logs bloom pub log_bloom: LogBloom, - /// State root - pub state_root: Option, + /// Transaction outcome. + pub outcome: TransactionOutcome, } #[cfg(test)] mod tests { - use super::Receipt; + use super::{Receipt, TransactionOutcome}; use log_entry::LogEntry; #[test] fn test_no_state_root() { let expected = ::rustc_hex::FromHex::from_hex("f9014183040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let r = Receipt::new( - None, - None, + TransactionOutcome::Unknown, 0x40cae.into(), vec![LogEntry { address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), @@ -175,8 +183,25 @@ mod tests { fn test_basic() { let expected = ::rustc_hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let r = Receipt::new( - Some("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()), - None, + TransactionOutcome::StateRoot("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into()), + 0x40cae.into(), + vec![LogEntry { + address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), + topics: vec![], + data: vec![0u8; 32] + }] + ); + let encoded = ::rlp::encode(&r); + assert_eq!(&encoded[..], &expected[..]); + let decoded: Receipt = ::rlp::decode(&encoded); + assert_eq!(decoded, r); + } + + #[test] + fn test_status_code() { + let expected = ::rustc_hex::FromHex::from_hex("f901428083040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let r = Receipt::new( + TransactionOutcome::StatusCode(0), 0x40cae.into(), vec![LogEntry { address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(), diff --git a/mac/Parity.pkgproj b/mac/Parity.pkgproj index d0e0c5d11..2546e7a0f 100755 --- a/mac/Parity.pkgproj +++ b/mac/Parity.pkgproj @@ -462,7 +462,7 @@ OVERWRITE_PERMISSIONS VERSION - 1.7.2 + 1.7.3 UUID 2DCD5B81-7BAF-4DA1-9251-6274B089FD36 diff --git a/nsis/installer.nsi b/nsis/installer.nsi index 2f081ab04..905ca763a 100644 --- a/nsis/installer.nsi +++ b/nsis/installer.nsi @@ -10,7 +10,7 @@ !define DESCRIPTION "Fast, light, robust Ethereum implementation" !define VERSIONMAJOR 1 !define VERSIONMINOR 7 -!define VERSIONBUILD 2 +!define VERSIONBUILD 3 !define ARGS "--warp" !define FIRST_START_ARGS "ui --warp --mode=passive" diff --git a/parity/informant.rs b/parity/informant.rs index 1935ec9b6..4e62ca356 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -88,6 +88,7 @@ pub struct SyncInfo { last_imported_old_block_number: Option, num_peers: usize, max_peers: u32, + snapshot_sync: bool, } pub struct Report { @@ -150,6 +151,7 @@ impl InformantData for FullNodeInformantData { last_imported_old_block_number: status.last_imported_old_block_number, num_peers: status.num_peers, max_peers: status.current_max_peers(net_config.min_peers, net_config.max_peers), + snapshot_sync: status.is_snapshot_syncing(), })) } _ => (is_major_importing(self.sync.as_ref().map(|s| s.status().state), queue_info.clone()), None), @@ -194,6 +196,7 @@ impl InformantData for LightNodeInformantData { last_imported_old_block_number: None, num_peers: peer_numbers.connected, max_peers: peer_numbers.max as u32, + snapshot_sync: false, }); Report { @@ -280,7 +283,7 @@ impl Informant { _ => (false, 0, 0), } ); - + let snapshot_sync = snapshot_sync && sync_info.as_ref().map_or(false, |s| s.snapshot_sync); if !importing && !snapshot_sync && elapsed < Duration::from_secs(30) { return; } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index c5bc0a259..3b75607f8 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -257,7 +257,7 @@ impl MinerService for TestMinerService { contract_address: None, logs: r.logs.clone(), log_bloom: r.log_bloom, - state_root: r.state_root, + outcome: r.outcome.clone(), } ) } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index eb5a7d4e9..43c251bb9 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -27,7 +27,7 @@ use ethkey::Secret; use ethcore::account_provider::AccountProvider; use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionId}; use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; -use ethcore::receipt::LocalizedReceipt; +use ethcore::receipt::{LocalizedReceipt, TransactionOutcome}; use ethcore::transaction::{Transaction, Action}; use ethcore::miner::{ExternalMiner, MinerService}; use ethsync::SyncState; @@ -1006,7 +1006,7 @@ fn rpc_eth_transaction_receipt() { log_index: 1, }], log_bloom: 0.into(), - state_root: Some(0.into()), + outcome: TransactionOutcome::StateRoot(0.into()), }; let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap(); @@ -1019,7 +1019,7 @@ fn rpc_eth_transaction_receipt() { "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","statusCode":null,"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index 29e0f277c..ca313a440 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use v1::types::{Log, H160, H256, H2048, U256}; -use ethcore::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt}; +use ethcore::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt, TransactionOutcome}; /// Receipt #[derive(Debug, Serialize)] @@ -49,6 +49,25 @@ pub struct Receipt { /// Logs bloom #[serde(rename="logsBloom")] pub logs_bloom: H2048, + /// Status code + #[serde(rename="statusCode")] + pub status_code: Option, +} + +impl Receipt { + fn outcome_to_state_root(outcome: TransactionOutcome) -> Option { + match outcome { + TransactionOutcome::Unknown | TransactionOutcome::StatusCode(_) => None, + TransactionOutcome::StateRoot(root) => Some(root.into()), + } + } + + fn outcome_to_status_code(outcome: &TransactionOutcome) -> Option { + match *outcome { + TransactionOutcome::Unknown | TransactionOutcome::StateRoot(_) => None, + TransactionOutcome::StatusCode(ref code) => Some(*code), + } + } } impl From for Receipt { @@ -62,7 +81,8 @@ impl From for Receipt { gas_used: Some(r.gas_used.into()), contract_address: r.contract_address.map(Into::into), logs: r.logs.into_iter().map(Into::into).collect(), - state_root: r.state_root.map(Into::into), + status_code: Self::outcome_to_status_code(&r.outcome), + state_root: Self::outcome_to_state_root(r.outcome), logs_bloom: r.log_bloom.into(), } } @@ -79,7 +99,8 @@ impl From for Receipt { gas_used: Some(r.gas_used.into()), contract_address: r.contract_address.map(Into::into), logs: r.logs.into_iter().map(Into::into).collect(), - state_root: r.state_root.map(Into::into), + status_code: Self::outcome_to_status_code(&r.outcome), + state_root: Self::outcome_to_state_root(r.outcome), logs_bloom: r.log_bloom.into(), } } @@ -96,7 +117,8 @@ impl From for Receipt { gas_used: None, contract_address: None, logs: r.logs.into_iter().map(Into::into).collect(), - state_root: r.state_root.map(Into::into), + status_code: Self::outcome_to_status_code(&r.outcome), + state_root: Self::outcome_to_state_root(r.outcome), logs_bloom: r.log_bloom.into(), } } @@ -109,7 +131,7 @@ mod tests { #[test] fn receipt_serialization() { - let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":null,"type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f"}"#; + let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":null,"type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f","statusCode":null}"#; let receipt = Receipt { transaction_hash: Some(0.into()), @@ -136,6 +158,7 @@ mod tests { }], logs_bloom: 15.into(), state_root: Some(10.into()), + status_code: None, }; let serialized = serde_json::to_string(&receipt).unwrap(); diff --git a/sync/src/chain.rs b/sync/src/chain.rs index bc4985d09..f0c26306e 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -688,7 +688,7 @@ impl ChainSync { } } else { trace!(target: "sync", "{}: Fork mismatch", peer_id); - io.disconnect_peer(peer_id); + io.disable_peer(peer_id); return Ok(()); } } @@ -1146,7 +1146,7 @@ impl ChainSync { trace!(target: "sync", "== Connected {}: {}", peer, io.peer_info(peer)); if let Err(e) = self.send_status(io, peer) { debug!(target:"sync", "Error sending status request: {:?}", e); - io.disable_peer(peer); + io.disconnect_peer(peer); } else { self.handshaking_peers.insert(peer, time::precise_time_ns()); } @@ -1447,7 +1447,7 @@ impl ChainSync { }; if let Err(e) = result { debug!(target:"sync", "Error sending request: {:?}", e); - sync.disable_peer(peer_id); + sync.disconnect_peer(peer_id); } } } @@ -1456,7 +1456,7 @@ impl ChainSync { fn send_packet(&mut self, sync: &mut SyncIo, peer_id: PeerId, packet_id: PacketId, packet: Bytes) { if let Err(e) = sync.send(peer_id, packet_id, packet) { debug!(target:"sync", "Error sending packet: {:?}", e); - sync.disable_peer(peer_id); + sync.disconnect_peer(peer_id); } } diff --git a/util/Cargo.toml b/util/Cargo.toml index 8c4a15b09..466073863 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore utility library" homepage = "http://parity.io" license = "GPL-3.0" name = "ethcore-util" -version = "1.7.2" +version = "1.7.3" authors = ["Parity Technologies "] build = "build.rs"