diff --git a/Cargo.lock b/Cargo.lock index af8a0171c..beafce255 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "parity" -version = "1.2.3" +version = "1.2.4" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", @@ -16,7 +16,7 @@ dependencies = [ "ethcore-ipc-nano 1.2.0", "ethcore-rpc 1.2.0", "ethcore-signer 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "ethsync 1.2.0", "fdlimit 0.1.0", "hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -257,7 +257,7 @@ dependencies = [ "ethcore-devtools 1.2.0", "ethcore-ipc 1.2.0", "ethcore-ipc-codegen 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "ethjson 0.1.0", "ethstore 0.1.0", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -278,7 +278,7 @@ version = "1.2.0" dependencies = [ "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", @@ -308,7 +308,7 @@ name = "ethcore-ipc" version = "1.2.0" dependencies = [ "ethcore-devtools 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -342,7 +342,7 @@ dependencies = [ "ethash 1.2.0", "ethcore 1.2.0", "ethcore-devtools 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "ethjson 0.1.0", "ethsync 1.2.0", "json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)", @@ -364,7 +364,7 @@ dependencies = [ "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-signer 0.6.0 (git+https://github.com/ethcore/parity-ui.git)", @@ -375,7 +375,7 @@ dependencies = [ [[package]] name = "ethcore-util" -version = "1.2.3" +version = "1.2.4" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -414,7 +414,7 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -456,7 +456,7 @@ dependencies = [ "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.2.0", - "ethcore-util 1.2.3", + "ethcore-util 1.2.4", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -597,7 +597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "json-ipc-server" version = "0.2.4" -source = "git+https://github.com/ethcore/json-ipc-server.git#7a02a0f8b249fda100b9bab5f90b2081d410d8cf" +source = "git+https://github.com/ethcore/json-ipc-server.git#56b6307130710ebc73cb9be087b6ed0b6c400bcf" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index c77393e08..d8fbd3e8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore client." name = "parity" -version = "1.2.3" +version = "1.2.4" license = "GPL-3.0" authors = ["Ethcore "] build = "build.rs" diff --git a/ethcore/res/null_morden.json b/ethcore/res/null_morden.json index c820579d0..9b792934a 100644 --- a/ethcore/res/null_morden.json +++ b/ethcore/res/null_morden.json @@ -4,7 +4,7 @@ "Null": null }, "params": { - "accountStartNonce": "0x0100000", + "accountStartNonce": "0x0", "maximumExtraDataSize": "0x20", "minGasLimit": "0x1388", "networkID" : "0x2" diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index d59c3f5ec..99206af67 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -66,6 +66,8 @@ pub struct TestBlockChainClient { pub queue_size: AtomicUsize, /// Miner pub miner: Arc, + /// Test spec + spec: Spec, } #[derive(Clone)] @@ -105,6 +107,7 @@ impl TestBlockChainClient { receipts: RwLock::new(HashMap::new()), queue_size: AtomicUsize::new(0), miner: Arc::new(Miner::with_spec(Spec::new_test())), + spec: Spec::new_test(), }; client.add_blocks(1, EachBlockWith::Nothing); // add genesis block client.genesis_hash = client.last_hash.read().unwrap().clone(); @@ -267,7 +270,7 @@ impl BlockChainClient for TestBlockChainClient { fn nonce(&self, address: &Address, id: BlockID) -> Option { match id { - BlockID::Latest => Some(self.nonces.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)), + BlockID::Latest => Some(self.nonces.read().unwrap().get(address).cloned().unwrap_or(self.spec.params.account_start_nonce)), _ => None, } } diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 8ca95b97e..442940295 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -98,11 +98,11 @@ impl<'a> Executive<'a> { let check = options.check_nonce; match options.tracing { true => match options.vm_tracing { - true => self.transact_with_tracer(t, check, ExecutiveTracer::default(), ExecutiveVMTracer::default()), + true => self.transact_with_tracer(t, check, ExecutiveTracer::default(), ExecutiveVMTracer::toplevel()), false => self.transact_with_tracer(t, check, ExecutiveTracer::default(), NoopVMTracer), }, false => match options.vm_tracing { - true => self.transact_with_tracer(t, check, NoopTracer, ExecutiveVMTracer::default()), + true => self.transact_with_tracer(t, check, NoopTracer, ExecutiveVMTracer::toplevel()), false => self.transact_with_tracer(t, check, NoopTracer, NoopVMTracer), }, } @@ -633,7 +633,7 @@ mod tests { let engine = TestEngine::new(5); let mut substate = Substate::new(); let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); let gas_left = { let mut ex = Executive::new(&mut state, &info, &engine, &factory); @@ -692,7 +692,7 @@ mod tests { ], subs: vec![ VMTrace { - parent_step: 7, + parent_step: 6, code: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], operations: vec![ VMOperation { pc: 0, instruction: 96, gas_cost: 3.into(), executed: Some(VMExecutedOperation { gas_used: 67976.into(), stack_push: vec_into![16], mem_diff: None, store_diff: None }) }, @@ -742,7 +742,7 @@ mod tests { let engine = TestEngine::new(5); let mut substate = Substate::new(); let mut tracer = ExecutiveTracer::default(); - let mut vm_tracer = ExecutiveVMTracer::default(); + let mut vm_tracer = ExecutiveVMTracer::toplevel(); let gas_left = { let mut ex = Executive::new(&mut state, &info, &engine, &factory); diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 0cf8a8f08..61a4b2e48 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -167,7 +167,7 @@ impl State { /// Get the nonce of account `a`. pub fn nonce(&self, a: &Address) -> U256 { - self.get(a, false).as_ref().map_or(U256::zero(), |account| *account.nonce()) + self.get(a, false).as_ref().map_or(self.account_start_nonce, |account| *account.nonce()) } /// Mutate storage of account `address` so that it is `value` for `key`. diff --git a/ethcore/src/trace/executive_tracer.rs b/ethcore/src/trace/executive_tracer.rs index 1ada91c48..f56d80f58 100644 --- a/ethcore/src/trace/executive_tracer.rs +++ b/ethcore/src/trace/executive_tracer.rs @@ -155,11 +155,24 @@ impl Tracer for ExecutiveTracer { } /// Simple VM tracer. Traces all operations. -#[derive(Default)] pub struct ExecutiveVMTracer { data: VMTrace, } +impl ExecutiveVMTracer { + /// Create a new top-level instance. + pub fn toplevel() -> Self { + ExecutiveVMTracer { + data: VMTrace { + parent_step: 0, + code: vec![], + operations: vec![Default::default()], // prefill with a single entry so that prepare_subtrace can get the parent_step + subs: vec![], + } + } + } +} + impl VMTracer for ExecutiveVMTracer { fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool { self.data.operations.push(VMOperation { @@ -183,7 +196,7 @@ impl VMTracer for ExecutiveVMTracer { fn prepare_subtrace(&self, code: &[u8]) -> Self { ExecutiveVMTracer { data: VMTrace { - parent_step: self.data.operations.len(), + parent_step: self.data.operations.len() - 1, // won't overflow since we must already have pushed an operation in trace_prepare_execute. code: code.to_vec(), operations: vec![], subs: vec![], diff --git a/ethcore/src/types/trace_types/trace.rs b/ethcore/src/types/trace_types/trace.rs index 346b99c06..8d251032c 100644 --- a/ethcore/src/types/trace_types/trace.rs +++ b/ethcore/src/types/trace_types/trace.rs @@ -473,7 +473,7 @@ impl Decodable for VMExecutedOperation { } } -#[derive(Debug, Clone, PartialEq, Binary)] +#[derive(Debug, Clone, PartialEq, Binary, Default)] /// A record of the execution of a single VM operation. pub struct VMOperation { /// The program counter. diff --git a/nsis/installer.nsi b/nsis/installer.nsi index 15a747169..b7c174bb9 100644 --- a/nsis/installer.nsi +++ b/nsis/installer.nsi @@ -4,7 +4,7 @@ !define DESCRIPTION "Fast, light, robust Ethereum implementation" !define VERSIONMAJOR 1 !define VERSIONMINOR 2 -!define VERSIONBUILD 3 +!define VERSIONBUILD 4 !addplugindir .\ diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 734ce2807..bbc640dcc 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -236,6 +236,54 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ } "#; +const POSITIVE_NONCE_SPEC: &'static [u8] = br#"{ + "name": "Frontier (Test)", + "engine": { + "Ethash": { + "params": { + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "frontierCompatibilityModeLimit": "0xffffffffffffffff", + "daoHardforkTransition": "0xffffffffffffffff", + "daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000", + "daoHardforkAccounts": [] + } + } + }, + "params": { + "accountStartNonce": "0x0100", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x50000", + "networkID" : "0x1" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x50000" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "faa34835af5c2ea724333018a515fbb7d5bc0b33": { "balance": "10000000000000", "nonce": "0" } + } +} +"#; + #[test] fn eth_transaction_count() { use util::crypto::Secret; @@ -365,6 +413,24 @@ fn verify_transaction_counts(name: String, chain: BlockChain) { } } +#[test] +fn starting_nonce_test() { + let tester = EthTester::from_spec_provider(|| Spec::load(POSITIVE_NONCE_SPEC)); + let address = ::util::hash::Address::from(10); + + let sample = tester.handler.handle_request(&(r#" + { + "jsonrpc": "2.0", + "method": "eth_getTransactionCount", + "params": [""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"", "latest"], + "id": 15 + } + "#) + ).unwrap(); + + assert_eq!(r#"{"jsonrpc":"2.0","result":"0x0100","id":15}"#, &sample); +} + register_test!(eth_transaction_count_1, verify_transaction_counts, "BlockchainTests/bcWalletTest"); register_test!(eth_transaction_count_2, verify_transaction_counts, "BlockchainTests/bcTotalDifficultyTest"); register_test!(eth_transaction_count_3, verify_transaction_counts, "BlockchainTests/bcGasPricerTest"); diff --git a/sync/src/chain.rs b/sync/src/chain.rs index ac11744db..5cfc97af7 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -580,6 +580,10 @@ impl ChainSync { /// Called by peer once it has new block bodies #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) { + trace!(target: "sync", "Ignoring new block from unconfirmed peer {}", peer_id); + return Ok(()); + } let block_rlp = try!(r.at(0)); let header_rlp = try!(block_rlp.at(0)); let h = header_rlp.as_raw().sha3(); @@ -644,6 +648,10 @@ impl ChainSync { /// Handles `NewHashes` packet. Initiates headers download for any unknown hashes. fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) { + trace!(target: "sync", "Ignoring new hashes from unconfirmed peer {}", peer_id); + return Ok(()); + } if self.state != SyncState::Idle { trace!(target: "sync", "Ignoring new hashes since we're already downloading."); let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, max); @@ -1023,7 +1031,7 @@ impl ChainSync { if !io.is_chain_queue_empty() { return Ok(()); } - if self.peers.get(&peer_id).map_or(false, |p| p.confirmed) { + if !self.peers.get(&peer_id).map_or(false, |p| p.confirmed) { trace!(target: "sync", "{} Ignoring transactions from unconfirmed/unknown peer", peer_id); } @@ -1679,7 +1687,7 @@ mod tests { asking_hash: None, ask_time: 0f64, expired: false, - confirmed: false, + confirmed: true, }); sync } diff --git a/util/Cargo.toml b/util/Cargo.toml index eb338aa42..04e439dca 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore utility library" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-util" -version = "1.2.3" +version = "1.2.4" authors = ["Ethcore "] build = "build.rs" diff --git a/util/src/misc.rs b/util/src/misc.rs index b7259f037..987cdb6d4 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -49,7 +49,7 @@ pub fn version() -> String { let date_dash = if commit_date.is_empty() { "" } else { "-" }; let env = Target::env(); let env_dash = if env.is_empty() { "" } else { "-" }; - format!("Parity/v{}-beta{}{}{}{}/{}-{}{}{}/rustc{}", env!("CARGO_PKG_VERSION"), sha3_dash, sha3, date_dash, commit_date, Target::arch(), Target::os(), env_dash, env, rustc_version()) + format!("Parity/v{}-stable{}{}{}{}/{}-{}{}{}/rustc{}", env!("CARGO_PKG_VERSION"), sha3_dash, sha3, date_dash, commit_date, Target::arch(), Target::os(), env_dash, env, rustc_version()) } /// Get the standard version data for this software.