diff --git a/.gitignore b/.gitignore index 2cdc945d3..90750f379 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,8 @@ # Executables *.exe -Cargo.lock +# Cargo lock in subs +**/Cargo.lock # Generated by Cargo **/target/ @@ -24,4 +25,4 @@ Cargo.lock /json-tests/target/ # jetbrains ide stuff -.idea \ No newline at end of file +.idea diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..c451a6477 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,808 @@ +[root] +name = "parity" +version = "0.9.0" +dependencies = [ + "clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "ctrlc 1.0.1 (git+https://github.com/tomusdrw/rust-ctrlc.git)", + "docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)", + "docopt_macros 0.6.81 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 0.9.0", + "ethcore-rpc 0.9.0", + "ethcore-util 0.9.0", + "ethsync 0.1.0", + "fdlimit 0.1.0", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayvec" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aster" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clippy" +version = "0.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cookie" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cookie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crossbeam" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ctrlc" +version = "1.0.1" +source = "git+https://github.com/tomusdrw/rust-ctrlc.git#d8751b66b31d9698cbb11f8ef37155a8211a0683" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "docopt" +version = "0.6.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "docopt_macros" +version = "0.6.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "elastic-array" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "env_logger" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "eth-secp256k1" +version = "0.5.4" +source = "git+https://github.com/arkpar/rust-secp256k1.git#321e6c22a83606d1875f89cb61c9cb37c7d249ae" +dependencies = [ + "arrayvec 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethash" +version = "0.1.0" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sha3 0.1.0", +] + +[[package]] +name = "ethcore" +version = "0.9.0" +dependencies = [ + "clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethash 0.1.0", + "ethcore-util 0.9.0", + "heapsize 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rocksdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcore-rpc" +version = "0.9.0" +dependencies = [ + "clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 0.9.0", + "ethcore-util 0.9.0", + "ethsync 0.1.0", + "jsonrpc-core 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_macros 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethcore-util" +version = "0.9.0" +dependencies = [ + "arrayvec 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "eth-secp256k1 0.5.4 (git+https://github.com/arkpar/rust-secp256k1.git)", + "heapsize 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "igd 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "json-tests 0.1.0", + "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rocksdb 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "sha3 0.1.0", + "slab 0.1.4 (git+https://github.com/arkpar/slab.git)", + "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethsync" +version = "0.1.0" +dependencies = [ + "clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 0.9.0", + "ethcore-util 0.9.0", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fdlimit" +version = "0.1.0" +dependencies = [ + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "glob" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "heapsize" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hpack" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "httparse" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hyper" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cookie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "igd" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hyper 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.48 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", + "xmltree 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itertools" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "json-tests" +version = "0.1.0" +dependencies = [ + "glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-core" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_macros 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-http-server" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hyper 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "language-tags" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "linked-hash-map" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lru-cache" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nom" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "odds" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quasi" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quasi_codegen" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aster 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quasi_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quasi_codegen 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.1.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rocksdb" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rust-crypto" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_codegen" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aster 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_macros 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_macros" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_codegen 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha3" +version = "0.1.0" +dependencies = [ + "gcc 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.1.4" +source = "git+https://github.com/arkpar/slab.git#3c9284e1f010e394c9d0359b27464e8fb5c87bf0" + +[[package]] +name = "solicit" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "target_info" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "time" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tiny-keccak" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "traitobject" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicase" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-bidi" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "url" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "url" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "uuid" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xml-rs" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xml-rs" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xmltree" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "xml-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + diff --git a/Cargo.toml b/Cargo.toml index fb52d14d5..ca2ad9c6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ rustc-serialize = "0.3" docopt = "0.6" docopt_macros = "0.6" ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" } -clippy = "0.0.37" +clippy = "0.0.41" ethcore-util = { path = "util" } ethcore = { path = "ethcore" } ethsync = { path = "sync" } diff --git a/README.md b/README.md index 8ef5dce19..2ffb28f45 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ # install rocksdb add-apt-repository ppa:ethcore/ethcore apt-get update -apt-get install -y --force-yes librocksdb +apt-get install -y --force-yes librocksdb-dev # install multirust curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index be7652e17..90d147a02 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -18,7 +18,7 @@ ethcore-util = { path = "../util" } evmjit = { path = "../evmjit", optional = true } ethash = { path = "../ethash" } num_cpus = "0.2" -clippy = "0.0.37" +clippy = "0.0.41" crossbeam = "0.1.5" lazy_static = "0.1" diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index 84a6200fd..553bb8018 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -3,7 +3,7 @@ "engineName": "Ethash", "params": { "accountStartNonce": "0x00", - "frontierCompatibilityModeLimit": "0xf4240", + "frontierCompatibilityModeLimit": "0x10c8e0", "maximumExtraDataSize": "0x20", "tieBreakingGas": false, "minGasLimit": "0x1388", diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index cdcf8c7dc..0d0c2489d 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -3,7 +3,7 @@ "engineName": "Ethash", "params": { "accountStartNonce": "0x0100000", - "frontierCompatibilityModeLimit": "0xdbba0", + "frontierCompatibilityModeLimit": "0x10c8e0", "maximumExtraDataSize": "0x20", "tieBreakingGas": false, "minGasLimit": "0x1388", diff --git a/ethcore/src/account_diff.rs b/ethcore/src/account_diff.rs index 6c7e6573e..c02b7ec7b 100644 --- a/ethcore/src/account_diff.rs +++ b/ethcore/src/account_diff.rs @@ -72,14 +72,14 @@ impl AccountDiff { pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option { match (pre, post) { (None, Some(x)) => Some(AccountDiff { - balance: Diff::Born(x.balance.clone()), - nonce: Diff::Born(x.nonce.clone()), + balance: Diff::Born(x.balance), + nonce: Diff::Born(x.nonce), code: Diff::Born(x.code.clone()), storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Born(v.clone()))).collect(), }), (Some(x), None) => Some(AccountDiff { - balance: Diff::Died(x.balance.clone()), - nonce: Diff::Died(x.nonce.clone()), + balance: Diff::Died(x.balance), + nonce: Diff::Died(x.nonce), code: Diff::Died(x.code.clone()), storage: x.storage.iter().map(|(k, v)| (k.clone(), Diff::Died(v.clone()))).collect(), }), @@ -88,8 +88,8 @@ impl AccountDiff { .filter(|k| pre.storage.get(k).unwrap_or(&H256::new()) != post.storage.get(k).unwrap_or(&H256::new())) .collect(); let r = AccountDiff { - balance: Diff::new(pre.balance.clone(), post.balance.clone()), - nonce: Diff::new(pre.nonce.clone(), post.nonce.clone()), + balance: Diff::new(pre.balance, post.balance), + nonce: Diff::new(pre.nonce, post.nonce), code: Diff::new(pre.code.clone(), post.code.clone()), storage: storage.into_iter().map(|k| (k.clone(), Diff::new( diff --git a/ethcore/src/basic_types.rs b/ethcore/src/basic_types.rs index 51e05500c..2e9c5d7b9 100644 --- a/ethcore/src/basic_types.rs +++ b/ethcore/src/basic_types.rs @@ -24,6 +24,7 @@ pub type LogBloom = H2048; /// Constant 2048-bit datum for 0. Often used as a default. pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); +#[allow(enum_variant_names)] /// Semantic boolean for when a seal/signature is included. pub enum Seal { /// The seal/signature is included. diff --git a/ethcore/src/block_queue.rs b/ethcore/src/block_queue.rs index dcfcec1e4..1a1dee48e 100644 --- a/ethcore/src/block_queue.rs +++ b/ethcore/src/block_queue.rs @@ -87,6 +87,7 @@ struct QueueSignal { } impl QueueSignal { + #[allow(bool_comparison)] fn set(&self) { if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false { self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message"); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index e931080b2..c45b22102 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -274,7 +274,7 @@ mod tests { use block::*; use engine::*; use tests::helpers::*; - use super::*; + use super::{Ethash}; use super::super::new_morden; #[test] diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 11c20ddbe..0d1dcd8d5 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -24,7 +24,7 @@ pub mod ethash; /// Export the denominations module. pub mod denominations; -pub use self::ethash::*; +pub use self::ethash::{Ethash}; pub use self::denominations::*; use super::spec::*; diff --git a/ethcore/src/evm/interpreter.rs b/ethcore/src/evm/interpreter.rs index 8b8197526..50c0377ac 100644 --- a/ethcore/src/evm/interpreter.rs +++ b/ethcore/src/evm/interpreter.rs @@ -212,7 +212,7 @@ impl Memory for Vec { fn write(&mut self, offset: U256, value: U256) { let off = offset.low_u64() as usize; let mut val = value; - + let end = off + 32; for pos in 0..32 { self[end - pos - 1] = val.low_u64() as u8; @@ -229,7 +229,7 @@ impl Memory for Vec { fn resize(&mut self, new_size: usize) { self.resize(new_size, 0); } - + fn expand(&mut self, size: usize) { if size > self.len() { Memory::resize(self, size) @@ -258,6 +258,7 @@ impl<'a> CodeReader<'a> { } } +#[allow(enum_variant_names)] enum InstructionCost { Gas(U256), GasMem(U256, U256), @@ -282,7 +283,7 @@ impl evm::Evm for Interpreter { let code = ¶ms.code.as_ref().unwrap(); let valid_jump_destinations = self.find_jump_destinations(&code); - let mut current_gas = params.gas.clone(); + let mut current_gas = params.gas; let mut stack = VecStack::with_capacity(ext.schedule().stack_limit, U256::zero()); let mut mem = vec![]; let mut reader = CodeReader { @@ -331,7 +332,7 @@ impl evm::Evm for Interpreter { let pos = try!(self.verify_jump(position, &valid_jump_destinations)); reader.position = pos; }, - InstructionResult::StopExecutionWithGasLeft(gas_left) => { + InstructionResult::StopExecutionWithGasLeft(gas_left) => { current_gas = gas_left; reader.position = code.len(); }, @@ -380,10 +381,9 @@ impl Interpreter { let gas = if self.is_zero(&val) && !self.is_zero(newval) { schedule.sstore_set_gas - } else if !self.is_zero(&val) && self.is_zero(newval) { - // Refund is added when actually executing sstore - schedule.sstore_reset_gas } else { + // Refund for below case is added when actually executing sstore + // !self.is_zero(&val) && self.is_zero(newval) schedule.sstore_reset_gas }; InstructionCost::Gas(U256::from(gas)) @@ -391,10 +391,7 @@ impl Interpreter { instructions::SLOAD => { InstructionCost::Gas(U256::from(schedule.sload_gas)) }, - instructions::MSTORE => { - InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32))) - }, - instructions::MLOAD => { + instructions::MSTORE | instructions::MLOAD => { InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32))) }, instructions::MSTORE8 => { @@ -409,10 +406,7 @@ impl Interpreter { let gas = U256::from(schedule.sha3_gas) + (U256::from(schedule.sha3_word_gas) * words); InstructionCost::GasMem(gas, try!(self.mem_needed(stack.peek(0), stack.peek(1)))) }, - instructions::CALLDATACOPY => { - InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(0), stack.peek(2))), stack.peek(2).clone()) - }, - instructions::CODECOPY => { + instructions::CALLDATACOPY | instructions::CODECOPY => { InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(0), stack.peek(2))), stack.peek(2).clone()) }, instructions::EXTCODECOPY => { @@ -435,7 +429,7 @@ impl Interpreter { try!(self.mem_needed(stack.peek(5), stack.peek(6))), try!(self.mem_needed(stack.peek(3), stack.peek(4))) ); - + let address = u256_to_address(stack.peek(1)); if instruction == instructions::CALL && !ext.exists(&address) { @@ -532,8 +526,8 @@ impl Interpreter { params: &ActionParams, ext: &mut evm::Ext, instruction: Instruction, - code: &mut CodeReader, - mem: &mut Memory, + code: &mut CodeReader, + mem: &mut Memory, stack: &mut Stack ) -> Result { match instruction { @@ -562,7 +556,7 @@ impl Interpreter { let contract_code = mem.read_slice(init_off, init_size); let can_create = ext.balance(¶ms.address) >= endowment && ext.depth() < ext.schedule().max_depth; - + if !can_create { stack.push(U256::zero()); return Ok(InstructionResult::Ok); @@ -641,7 +635,7 @@ impl Interpreter { Ok(InstructionResult::Ok) } }; - }, + }, instructions::RETURN => { let init_off = stack.pop_back(); let init_size = stack.pop_back(); @@ -736,8 +730,7 @@ impl Interpreter { }, instructions::CALLVALUE => { stack.push(match params.value { - ActionValue::Transfer(val) => val, - ActionValue::Apparent(val) => val, + ActionValue::Transfer(val) | ActionValue::Apparent(val) => val }); }, instructions::CALLDATALOAD => { @@ -836,20 +829,20 @@ impl Interpreter { } } - fn verify_instructions_requirements(&self, - info: &instructions::InstructionInfo, - stack_limit: usize, + fn verify_instructions_requirements(&self, + info: &instructions::InstructionInfo, + stack_limit: usize, stack: &Stack) -> Result<(), evm::Error> { if !stack.has(info.args) { Err(evm::Error::StackUnderflow { instruction: info.name, - wanted: info.args, + wanted: info.args, on_stack: stack.size() }) } else if stack.size() - info.args + info.ret > stack_limit { Err(evm::Error::OutOfStack { instruction: info.name, - wanted: info.ret - info.args, + wanted: info.ret - info.args, limit: stack_limit }) } else { @@ -923,7 +916,7 @@ impl Interpreter { stack.push(if !self.is_zero(&b) { a.overflowing_div(b).0 } else { - U256::zero() + U256::zero() }); }, instructions::MOD => { @@ -982,9 +975,9 @@ impl Interpreter { let (a, neg_a) = get_and_reset_sign(stack.pop_back()); let (b, neg_b) = get_and_reset_sign(stack.pop_back()); - let is_positive_lt = a < b && (neg_a | neg_b) == false; - let is_negative_lt = a > b && (neg_a & neg_b) == true; - let has_different_signs = neg_a == true && neg_b == false; + let is_positive_lt = a < b && !(neg_a | neg_b); + let is_negative_lt = a > b && (neg_a & neg_b); + let has_different_signs = neg_a && !neg_b; stack.push(self.bool_to_u256(is_positive_lt | is_negative_lt | has_different_signs)); }, @@ -997,9 +990,9 @@ impl Interpreter { let (a, neg_a) = get_and_reset_sign(stack.pop_back()); let (b, neg_b) = get_and_reset_sign(stack.pop_back()); - let is_positive_gt = a > b && (neg_a | neg_b) == false; - let is_negative_gt = a < b && (neg_a & neg_b) == true; - let has_different_signs = neg_a == false && neg_b == true; + let is_positive_gt = a > b && !(neg_a | neg_b); + let is_negative_gt = a < b && (neg_a & neg_b); + let has_different_signs = !neg_a && neg_b; stack.push(self.bool_to_u256(is_positive_gt | is_negative_gt | has_different_signs)); }, @@ -1179,7 +1172,7 @@ mod tests { let schedule = evm::Schedule::default(); let current_mem_size = 0; let mem_size = U256::from(5); - + // when let (mem_cost, mem_size) = interpreter.mem_gas_cost(&schedule, current_mem_size, &mem_size).unwrap(); diff --git a/ethcore/src/evm/tests.rs b/ethcore/src/evm/tests.rs index d0daf33e7..02f929192 100644 --- a/ethcore/src/evm/tests.rs +++ b/ethcore/src/evm/tests.rs @@ -25,6 +25,7 @@ struct FakeLogEntry { } #[derive(PartialEq, Eq, Hash, Debug)] +#[allow(enum_variant_names)] // Common prefix is C ;) enum FakeCallType { CALL, CREATE } @@ -59,7 +60,7 @@ struct FakeExt { } impl FakeExt { - fn new() -> Self { + fn new() -> Self { FakeExt::default() } } @@ -84,7 +85,7 @@ impl Ext for FakeExt { } fn balance(&self, address: &Address) -> U256 { - self.balances.get(address).unwrap().clone() + *self.balances.get(address).unwrap() } fn blockhash(&self, number: &U256) -> H256 { @@ -94,35 +95,35 @@ impl Ext for FakeExt { fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { self.calls.insert(FakeCall { call_type: FakeCallType::CREATE, - gas: gas.clone(), + gas: *gas, sender_address: None, receive_address: None, - value: Some(value.clone()), + value: Some(*value), data: code.to_vec(), code_address: None }); ContractCreateResult::Failed } - fn call(&mut self, - gas: &U256, - sender_address: &Address, - receive_address: &Address, + fn call(&mut self, + gas: &U256, + sender_address: &Address, + receive_address: &Address, value: Option, - data: &[u8], - code_address: &Address, + data: &[u8], + code_address: &Address, _output: &mut [u8]) -> MessageCallResult { self.calls.insert(FakeCall { call_type: FakeCallType::CALL, - gas: gas.clone(), + gas: *gas, sender_address: Some(sender_address.clone()), receive_address: Some(receive_address.clone()), value: value, data: data.to_vec(), code_address: Some(code_address.clone()) }); - MessageCallResult::Success(gas.clone()) + MessageCallResult::Success(*gas) } fn extcode(&self, address: &Address) -> Bytes { @@ -176,7 +177,7 @@ fn test_stack_underflow() { let vm : Box = Box::new(super::interpreter::Interpreter); vm.exec(params, &mut ext).unwrap_err() }; - + match err { evm::Error::StackUnderflow {wanted, on_stack, ..} => { assert_eq!(wanted, 2); @@ -353,7 +354,7 @@ evm_test!{test_log_sender: test_log_sender_jit, test_log_sender_int} fn test_log_sender(factory: super::Factory) { // 60 ff - push ff // 60 00 - push 00 - // 53 - mstore + // 53 - mstore // 33 - sender // 60 20 - push 20 // 60 00 - push 0 @@ -449,7 +450,7 @@ fn test_author(factory: super::Factory) { evm_test!{test_timestamp: test_timestamp_jit, test_timestamp_int} fn test_timestamp(factory: super::Factory) { - let timestamp = 0x1234; + let timestamp = 0x1234; let code = "42600055".from_hex().unwrap(); let mut params = ActionParams::default(); @@ -469,7 +470,7 @@ fn test_timestamp(factory: super::Factory) { evm_test!{test_number: test_number_jit, test_number_int} fn test_number(factory: super::Factory) { - let number = 0x1234; + let number = 0x1234; let code = "43600055".from_hex().unwrap(); let mut params = ActionParams::default(); @@ -898,7 +899,7 @@ fn test_calls(factory: super::Factory) { let mut ext = FakeExt::new(); ext.balances = { let mut s = HashMap::new(); - s.insert(params.address.clone(), params.gas.clone()); + s.insert(params.address.clone(), params.gas); s }; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 558e477c7..360bd9738 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -45,10 +45,9 @@ impl OriginInfo { OriginInfo { address: params.address.clone(), origin: params.origin.clone(), - gas_price: params.gas_price.clone(), + gas_price: params.gas_price, value: match params.value { - ActionValue::Transfer(val) => val, - ActionValue::Apparent(val) => val, + ActionValue::Transfer(val) | ActionValue::Apparent(val) => val } } } @@ -133,8 +132,8 @@ impl<'a> Ext for Externalities<'a> { sender: self.origin_info.address.clone(), origin: self.origin_info.origin.clone(), gas: *gas, - gas_price: self.origin_info.gas_price.clone(), - value: ActionValue::Transfer(value.clone()), + gas_price: self.origin_info.gas_price, + value: ActionValue::Transfer(*value), code: Some(code.to_vec()), data: None, }; @@ -164,11 +163,11 @@ impl<'a> Ext for Externalities<'a> { let mut params = ActionParams { sender: sender_address.clone(), address: receive_address.clone(), - value: ActionValue::Apparent(self.origin_info.value.clone()), + value: ActionValue::Apparent(self.origin_info.value), code_address: code_address.clone(), origin: self.origin_info.origin.clone(), gas: *gas, - gas_price: self.origin_info.gas_price.clone(), + gas_price: self.origin_info.gas_price, code: self.state.code(code_address), data: Some(data.to_vec()), }; @@ -364,7 +363,7 @@ mod tests { &Address::new(), &Address::new(), Some(U256::from_str("0000000000000000000000000000000000000000000000000000000000150000").unwrap()), - &vec![], + &[], &Address::new(), &mut output); } diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index f6b5751a7..b5f28444a 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -115,7 +115,7 @@ declare_test!{StateTests_stSolidityTest, "StateTests/stSolidityTest"} declare_test!{StateTests_stSpecialTest, "StateTests/stSpecialTest"} declare_test!{StateTests_stSystemOperationsTest, "StateTests/stSystemOperationsTest"} declare_test!{StateTests_stTransactionTest, "StateTests/stTransactionTest"} -declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"} +//declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"} declare_test!{StateTests_stWalletTest, "StateTests/stWalletTest"} diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 6c4535339..4cca74319 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -18,8 +18,15 @@ #![feature(cell_extras)] #![feature(augmented_assignments)] #![feature(plugin)] +// Clippy #![plugin(clippy)] -#![allow(needless_range_loop, match_bool)] +// TODO [todr] not really sure +#![allow(needless_range_loop)] +// Shorter than if-else +#![allow(match_bool)] +// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. +#![allow(clone_on_copy)] + //! Ethcore library //! @@ -54,7 +61,7 @@ //! cd parity //! cargo build --release //! ``` -//! +//! //! - OSX: //! //! ```bash @@ -124,8 +131,8 @@ mod executive; mod externalities; mod verification; -#[cfg(test)] +#[cfg(test)] mod tests; #[cfg(test)] -#[cfg(feature="json-tests")] +#[cfg(feature="json-tests")] mod json_tests; diff --git a/ethcore/src/pod_account.rs b/ethcore/src/pod_account.rs index 762f47db4..d2690051c 100644 --- a/ethcore/src/pod_account.rs +++ b/ethcore/src/pod_account.rs @@ -43,8 +43,8 @@ impl PodAccount { /// NOTE: This will silently fail unless the account is fully cached. pub fn from_account(acc: &Account) -> PodAccount { PodAccount { - balance: acc.balance().clone(), - nonce: acc.nonce().clone(), + balance: *acc.balance(), + nonce: *acc.nonce(), storage: acc.storage_overlay().iter().fold(BTreeMap::new(), |mut m, (k, &(_, ref v))| {m.insert(k.clone(), v.clone()); m}), code: acc.code().unwrap().to_vec(), } diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index e30f703ae..00886b89c 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -153,12 +153,12 @@ impl State { /// Get the balance of account `a`. pub fn balance(&self, a: &Address) -> U256 { - self.get(a, false).as_ref().map_or(U256::zero(), |account| account.balance().clone()) + self.get(a, false).as_ref().map_or(U256::zero(), |account| *account.balance()) } /// 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().clone()) + self.get(a, false).as_ref().map_or(U256::zero(), |account| *account.nonce()) } /// Mutate storage of account `address` so that it is `value` for `key`. diff --git a/evmjit/.gitignore b/evmjit/.gitignore deleted file mode 100644 index d4f917d3d..000000000 --- a/evmjit/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target -Cargo.lock -*.swp diff --git a/parity/main.rs b/parity/main.rs index 62b73ca47..903b471c5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -36,6 +36,7 @@ extern crate ethcore_rpc as rpc; use std::net::{SocketAddr}; use std::env; +use std::path::PathBuf; use rlog::{LogLevelFilter}; use env_logger::LogBuilder; use ctrlc::CtrlC; @@ -165,7 +166,7 @@ impl Configuration { } Some(ref a) => { public_address = SocketAddr::from_str(a.as_ref()).expect("Invalid listen/public address given with --address"); - listen_address = public_address.clone(); + listen_address = public_address; } }; @@ -207,6 +208,9 @@ fn main() { net_settings.listen_address = listen; net_settings.public_address = public; net_settings.use_secret = conf.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).expect("Invalid key string")); + let mut net_path = PathBuf::from(&conf.path()); + net_path.push("network"); + net_settings.config_path = Some(net_path.to_str().unwrap().to_owned()); // Build client let mut service = ClientService::start(spec, net_settings, &Path::new(&conf.path())).unwrap(); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 66688466c..0bb255d98 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -9,13 +9,13 @@ authors = ["Ethcore for BlockNumber { + #[allow(match_same_arms)] fn into(self) -> BlockId { match self { BlockNumber::Num(n) => BlockId::Number(n), diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 75853e0ab..8eb6a1bee 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Ethcore . -/// +/// /// BlockChain synchronization strategy. -/// Syncs to peers and keeps up to date. +/// Syncs to peers and keeps up to date. /// This implementation uses ethereum protocol v63 /// /// Syncing strategy. /// /// 1. A peer arrives with a total difficulty better than ours -/// 2. Find a common best block between our an peer chain. +/// 2. Find a common best block between our an peer chain. /// Start with out best block and request headers from peer backwards until a common block is found -/// 3. Download headers and block bodies from peers in parallel. +/// 3. Download headers and block bodies from peers in parallel. /// As soon as a set of the blocks is fully downloaded at the head of the queue it is fed to the blockchain /// 4. Maintain sync by handling NewBlocks/NewHashes messages /// @@ -250,6 +250,8 @@ impl ChainSync { self.peers.clear(); } + + #[allow(for_kv_map)] // Because it's not possible to get `values_mut()` /// Rest sync. Clear all downloaded data but keep the queue fn reset(&mut self) { self.downloading_headers.clear(); @@ -466,6 +468,7 @@ impl ChainSync { trace!(target: "sync", "New block already queued {:?}", h); }, Ok(_) => { + self.last_imported_block = Some(header.number); trace!(target: "sync", "New block queued {:?}", h); }, Err(ImportError::UnknownParent) => { @@ -1062,7 +1065,7 @@ impl ChainSync { GET_NODE_DATA_PACKET => self.return_rlp(io, &rlp, ChainSync::return_node_data, |e| format!("Error sending nodes: {:?}", e)), - + _ => { debug!(target: "sync", "Unknown packet {}", packet_id); Ok(()) @@ -1099,8 +1102,7 @@ impl ChainSync { let mut rlp_stream = RlpStream::new_list(route.blocks.len()); for block_hash in route.blocks { let mut hash_rlp = RlpStream::new_list(2); - let difficulty = chain.block_total_difficulty(BlockId::Hash(block_hash.clone())).unwrap(); - + let difficulty = chain.block_total_difficulty(BlockId::Hash(block_hash.clone())).expect("Mallformed block without a difficulty on the chain!"); hash_rlp.append(&block_hash); hash_rlp.append(&difficulty); rlp_stream.append_raw(&hash_rlp.out(), 1); diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 522062778..74edab4a5 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -16,8 +16,11 @@ #![warn(missing_docs)] #![feature(plugin)] -#![plugin(clippy)] #![feature(augmented_assignments)] +#![plugin(clippy)] +// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. +#![allow(clone_on_copy)] + //! Blockchain sync module //! Implements ethereum protocol version 63 as specified here: //! https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol diff --git a/sync/src/range_collection.rs b/sync/src/range_collection.rs index c70bac4ca..c3333ab63 100644 --- a/sync/src/range_collection.rs +++ b/sync/src/range_collection.rs @@ -40,7 +40,7 @@ pub trait RangeCollection { fn get_tail(&mut self, key: &K) -> Range; /// Remove all elements < `start` in the range that contains `start` - 1 fn remove_head(&mut self, start: &K); - /// Remove all elements >= `start` in the range that contains `start` + /// Remove all elements >= `start` in the range that contains `start` fn remove_tail(&mut self, start: &K); /// Remove all elements >= `tail` fn insert_item(&mut self, key: K, value: V); @@ -168,9 +168,9 @@ impl RangeCollection for Vec<(K, Vec)> where K: Ord + PartialEq + fn insert_item(&mut self, key: K, value: V) { assert!(!self.have_item(&key)); + // todo: fix warning let lower = match self.binary_search_by(|&(k, _)| k.cmp(&key).reverse()) { - Ok(index) => index, - Err(index) => index, + Ok(index) | Err(index) => index }; let mut to_remove: Option = None; diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 5ee5df831..1dd9a1e78 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -160,3 +160,14 @@ fn propagade_blocks() { // NEW_BLOCK_PACKET assert_eq!(0x07, net.peer(0).queue[0].packet_id); } + +#[test] +fn restart_on_malformed_block() { + let mut net = TestNet::new(2); + net.peer_mut(1).chain.add_blocks(10, false); + net.peer_mut(1).chain.corrupt_block(6); + net.sync_steps(10); + + assert_eq!(net.peer(0).chain.chain_info().best_block_number, 4); +} + diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index d8cd5e54a..c561b65a3 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -71,6 +71,17 @@ impl TestBlockChainClient { } } + pub fn corrupt_block(&mut self, n: BlockNumber) { + let hash = self.block_hash(BlockId::Number(n)).unwrap(); + let mut header: BlockHeader = decode(&self.block_header(BlockId::Number(n)).unwrap()); + header.parent_hash = H256::new(); + let mut rlp = RlpStream::new_list(3); + rlp.append(&header); + rlp.append_raw(&rlp::NULL_RLP, 1); + rlp.append_raw(&rlp::NULL_RLP, 1); + self.blocks.write().unwrap().insert(hash, rlp.out()); + } + pub fn block_hash_delta_minus(&mut self, delta: usize) -> H256 { let blocks_read = self.numbers.read().unwrap(); let index = blocks_read.len() - delta; diff --git a/util/Cargo.toml b/util/Cargo.toml index 733b08701..b1e9bbc1e 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -26,7 +26,7 @@ crossbeam = "0.2" slab = { git = "https://github.com/arkpar/slab.git" } sha3 = { path = "sha3" } serde = "0.6.7" -clippy = "0.0.37" +clippy = "0.0.41" json-tests = { path = "json-tests" } target_info = "0.1.0" igd = "0.4.2" diff --git a/util/benches/trie.rs b/util/benches/trie.rs index 2c07dbc08..8c573e170 100644 --- a/util/benches/trie.rs +++ b/util/benches/trie.rs @@ -17,7 +17,6 @@ #![feature(test)] extern crate test; -extern crate rand; extern crate ethcore_util; #[macro_use] extern crate log; diff --git a/util/src/bytes.rs b/util/src/bytes.rs index 4923e6eb4..4e1a11e4d 100644 --- a/util/src/bytes.rs +++ b/util/src/bytes.rs @@ -170,8 +170,8 @@ pub trait BytesConvertable { fn to_bytes(&self) -> Bytes { self.as_slice().to_vec() } } -impl BytesConvertable for T where T: Deref { - fn bytes(&self) -> &[u8] { self.deref() } +impl BytesConvertable for T where T: AsRef<[u8]> { + fn bytes(&self) -> &[u8] { self.as_ref() } } #[test] diff --git a/util/src/crypto.rs b/util/src/crypto.rs index 405646887..596265cd0 100644 --- a/util/src/crypto.rs +++ b/util/src/crypto.rs @@ -74,7 +74,6 @@ impl From<::secp256k1::Error> for CryptoError { match e { ::secp256k1::Error::InvalidMessage => CryptoError::InvalidMessage, ::secp256k1::Error::InvalidPublicKey => CryptoError::InvalidPublic, - ::secp256k1::Error::InvalidSignature => CryptoError::InvalidSignature, ::secp256k1::Error::InvalidSecretKey => CryptoError::InvalidSecret, _ => CryptoError::InvalidSignature, } diff --git a/util/src/hash.rs b/util/src/hash.rs index c678d13a7..aefa7795b 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -86,6 +86,13 @@ macro_rules! impl_hash { } } + impl AsRef<[u8]> for $from { + #[inline] + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + impl DerefMut for $from { #[inline] fn deref_mut(&mut self) -> &mut [u8] { @@ -290,7 +297,7 @@ macro_rules! impl_hash { try!(write!(f, "{:02x}", i)); } try!(write!(f, "…")); - for i in &self.0[$size - 4..$size] { + for i in &self.0[$size - 2..$size] { try!(write!(f, "{:02x}", i)); } Ok(()) @@ -641,7 +648,7 @@ mod tests { fn hash() { let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]); assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h); - assert_eq!(format!("{}", h), "0123…89abcdef"); + assert_eq!(format!("{}", h), "0123…cdef"); assert_eq!(format!("{:?}", h), "0123456789abcdef"); assert_eq!(h.hex(), "0123456789abcdef"); assert!(h == h); diff --git a/util/src/io/service.rs b/util/src/io/service.rs index c5f4a6072..83fa71b8a 100644 --- a/util/src/io/service.rs +++ b/util/src/io/service.rs @@ -256,6 +256,11 @@ impl Handler for IoManager where Message: Send + Clone + Sync IoMessage::DeregisterStream { handler_id, token } => { let handler = self.handlers.get(handler_id).expect("Unknown handler id").clone(); handler.deregister_stream(token, event_loop); + // unregister a timer associated with the token (if any) + let timer_id = token + handler_id * TOKENS_PER_HANDLER; + if let Some(timer) = self.timers.write().unwrap().remove(&timer_id) { + event_loop.clear_timeout(timer.timeout); + } }, IoMessage::UpdateStreamRegistration { handler_id, token } => { let handler = self.handlers.get(handler_id).expect("Unknown handler id").clone(); diff --git a/util/src/lib.rs b/util/src/lib.rs index 05162bca7..2dafa8599 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -20,9 +20,17 @@ #![feature(associated_consts)] #![feature(plugin)] #![feature(ip)] -#![plugin(clippy)] -#![allow(needless_range_loop, match_bool)] #![feature(catch_panic)] +// Clippy settings +#![plugin(clippy)] +// TODO [todr] not really sure +#![allow(needless_range_loop)] +// Shorter than if-else +#![allow(match_bool)] +// We use that to be more explicit about handled cases +#![allow(match_same_arms)] +// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. +#![allow(clone_on_copy)] //! Ethcore-util library //! diff --git a/util/src/network/connection.rs b/util/src/network/connection.rs index 242e8935e..9e9304ca6 100644 --- a/util/src/network/connection.rs +++ b/util/src/network/connection.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use std::collections::VecDeque; +use std::net::SocketAddr; use mio::{Handler, Token, EventSet, EventLoop, PollOpt, TryRead, TryWrite}; use mio::tcp::*; use hash::*; @@ -169,6 +170,11 @@ impl Connection { self.token = token; } + /// Get remote peer address + pub fn remote_addr(&self) -> io::Result { + self.socket.peer_addr() + } + /// Register this connection with the IO event loop. pub fn register_socket(&self, reg: Token, event_loop: &mut EventLoop) -> io::Result<()> { trace!(target: "net", "connection register; token={:?}", reg); @@ -253,6 +259,11 @@ impl EncryptedConnection { self.connection.set_token(token); } + /// Get remote peer address + pub fn remote_addr(&self) -> io::Result { + self.connection.remote_addr() + } + /// Create an encrypted connection out of the handshake. Consumes a handshake object. pub fn new(mut handshake: Handshake) -> Result { let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public)); diff --git a/util/src/network/discovery.rs b/util/src/network/discovery.rs index 9feef9c74..08f5e5cf1 100644 --- a/util/src/network/discovery.rs +++ b/util/src/network/discovery.rs @@ -110,12 +110,20 @@ impl Discovery { } } - pub fn add_node(&mut self, e: NodeEntry) { + /// Add a new node to discovery table. Pings the node. + pub fn add_node(&mut self, e: NodeEntry) { let endpoint = e.endpoint.clone(); self.update_node(e); self.ping(&endpoint); } + /// Add a list of known nodes to the table. + pub fn init_node_list(&mut self, mut nodes: Vec) { + for n in nodes.drain(..) { + self.update_node(n); + } + } + fn update_node(&mut self, e: NodeEntry) { trace!(target: "discovery", "Inserting {:?}", &e); let ping = { @@ -209,7 +217,7 @@ impl Discovery { rlp.append(×tamp); let bytes = rlp.drain(); - let hash = bytes.sha3(); + let hash = bytes.as_ref().sha3(); let signature = match ec::sign(&self.secret, &hash) { Ok(s) => s, Err(_) => { @@ -254,7 +262,7 @@ impl Discovery { } let mut ret:Vec = Vec::new(); - for (_, nodes) in found { + for nodes in found.values() { ret.extend(nodes.iter().map(|&n| n.clone())); } ret @@ -368,7 +376,7 @@ impl Discovery { // TODO: validate pong packet let dest = try!(NodeEndpoint::from_rlp(&try!(rlp.at(0)))); let timestamp: u64 = try!(rlp.val_at(2)); - if timestamp > time::get_time().sec as u64 { + if timestamp < time::get_time().sec as u64 { return Err(NetworkError::Expired); } let mut entry = NodeEntry { id: node.clone(), endpoint: dest }; @@ -386,7 +394,7 @@ impl Discovery { trace!(target: "discovery", "Got FindNode from {:?}", &from); let target: NodeId = try!(rlp.val_at(0)); let timestamp: u64 = try!(rlp.val_at(1)); - if timestamp > time::get_time().sec as u64 { + if timestamp < time::get_time().sec as u64 { return Err(NetworkError::Expired); } @@ -395,8 +403,8 @@ impl Discovery { if nearest.is_empty() { return Ok(None); } - let mut rlp = RlpStream::new_list(cmp::min(limit, nearest.len())); - rlp.begin_list(1); + let mut rlp = RlpStream::new_list(1); + rlp.begin_list(cmp::min(limit, nearest.len())); for n in 0 .. nearest.len() { rlp.begin_list(4); nearest[n].endpoint.to_rlp(&mut rlp); @@ -404,8 +412,8 @@ impl Discovery { if (n + 1) % limit == 0 || n == nearest.len() - 1 { self.send_packet(PACKET_NEIGHBOURS, &from, &rlp.drain()); trace!(target: "discovery", "Sent {} Neighbours to {:?}", n, &from); - rlp = RlpStream::new_list(cmp::min(limit, nearest.len() - n)); - rlp.begin_list(1); + rlp = RlpStream::new_list(1); + rlp.begin_list(cmp::min(limit, nearest.len() - n)); } } Ok(None) @@ -422,6 +430,9 @@ impl Discovery { continue; } let node_id: NodeId = try!(r.val_at(3)); + if node_id == self.id { + continue; + } let entry = NodeEntry { id: node_id.clone(), endpoint: endpoint }; added.insert(node_id, entry.clone()); self.ping(&entry.endpoint); @@ -476,3 +487,48 @@ impl Discovery { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + use hash::*; + use std::net::*; + use network::node_table::*; + use crypto::KeyPair; + use std::str::FromStr; + + #[test] + fn discovery() { + let key1 = KeyPair::create().unwrap(); + let key2 = KeyPair::create().unwrap(); + let ep1 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40444").unwrap(), udp_port: 40444 }; + let ep2 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40445").unwrap(), udp_port: 40445 }; + let mut discovery1 = Discovery::new(&key1, ep1.clone(), 0); + let mut discovery2 = Discovery::new(&key2, ep2.clone(), 0); + + let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7770").unwrap(); + let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@127.0.0.1:7771").unwrap(); + discovery1.add_node(NodeEntry { id: node1.id.clone(), endpoint: node1. endpoint.clone() }); + discovery1.add_node(NodeEntry { id: node2.id.clone(), endpoint: node2. endpoint.clone() }); + + discovery2.add_node(NodeEntry { id: key1.public().clone(), endpoint: ep1.clone() }); + discovery2.refresh(); + + for _ in 0 .. 10 { + while !discovery1.send_queue.is_empty() { + let datagramm = discovery1.send_queue.pop_front().unwrap(); + if datagramm.address == ep2.address { + discovery2.on_packet(&datagramm.payload, ep1.address.clone()).ok(); + } + } + while !discovery2.send_queue.is_empty() { + let datagramm = discovery2.send_queue.pop_front().unwrap(); + if datagramm.address == ep1.address { + discovery1.on_packet(&datagramm.payload, ep2.address.clone()).ok(); + } + } + discovery2.round(); + } + assert_eq!(Discovery::nearest_node_entries(&NodeId::new(), &discovery2.node_buckets).len(), 3) + } +} diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 7366e129b..c548d07cf 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -21,6 +21,9 @@ use std::str::{FromStr}; use std::sync::*; use std::ops::*; use std::cmp::min; +use std::path::{Path, PathBuf}; +use std::io::{Read, Write}; +use std::fs; use mio::*; use mio::tcp::*; use target_info::Target; @@ -340,7 +343,19 @@ impl Host where Message: Send + Sync + Clone { let addr = config.listen_address; // Setup the server socket let tcp_listener = TcpListener::bind(&addr).unwrap(); - let keys = if let Some(ref secret) = config.use_secret { KeyPair::from_secret(secret.clone()).unwrap() } else { KeyPair::create().unwrap() }; + let keys = if let Some(ref secret) = config.use_secret { + KeyPair::from_secret(secret.clone()).unwrap() + } else { + config.config_path.clone().and_then(|ref p| load_key(&Path::new(&p))) + .map_or_else(|| { + let key = KeyPair::create().unwrap(); + if let Some(path) = config.config_path.clone() { + save_key(&Path::new(&path), &key.secret()); + } + key + }, + |s| KeyPair::from_secret(s).expect("Error creating node secret key")) + }; let endpoint = NodeEndpoint { address: addr.clone(), udp_port: addr.port() }; let discovery = Discovery::new(&keys, endpoint, DISCOVERY); let path = config.config_path.clone(); @@ -371,6 +386,7 @@ impl Host where Message: Send + Sync + Clone { for n in boot_nodes { host.add_node(&n); } + host.discovery.lock().unwrap().init_node_list(host.nodes.read().unwrap().unordered_entries()); host } @@ -648,6 +664,7 @@ impl Host where Message: Send + Sync + Clone { } } let h = Arc::try_unwrap(h).ok().unwrap().into_inner().unwrap(); + let originated = h.originated; let mut session = match Session::new(h, &self.info.read().unwrap()) { Ok(s) => s, Err(e) => { @@ -659,6 +676,14 @@ impl Host where Message: Send + Sync + Clone { session.set_token(session_token); io.update_registration(session_token).expect("Error updating session registration"); self.stats.inc_sessions(); + if !originated { + // Add it no node table + if let Ok(address) = session.remote_addr() { + let entry = NodeEntry { id: session.id().clone(), endpoint: NodeEndpoint { address: address, udp_port: address.port() } }; + self.nodes.write().unwrap().add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + self.discovery.lock().unwrap().add_node(entry); + } + } Arc::new(Mutex::new(session)) }); if result.is_none() { @@ -914,3 +939,49 @@ impl IoHandler> for Host where Messa } } } + +fn save_key(path: &Path, key: &Secret) { + let mut path_buf = PathBuf::from(path); + if let Err(e) = fs::create_dir_all(path_buf.as_path()) { + warn!("Error creating key directory: {:?}", e); + return; + }; + path_buf.push("key"); + let mut file = match fs::File::create(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + warn!("Error creating key file: {:?}", e); + return; + } + }; + if let Err(e) = file.write(&key.hex().into_bytes()) { + warn!("Error writing key file: {:?}", e); + } +} + +fn load_key(path: &Path) -> Option { + let mut path_buf = PathBuf::from(path); + path_buf.push("key"); + let mut file = match fs::File::open(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + debug!("Error opening key file: {:?}", e); + return None; + } + }; + let mut buf = String::new(); + match file.read_to_string(&mut buf) { + Ok(_) => {}, + Err(e) => { + warn!("Error reading key file: {:?}", e); + return None; + } + } + match Secret::from_str(&buf) { + Ok(key) => Some(key), + Err(e) => { + warn!("Error parsing key file: {:?}", e); + None + } + } +} diff --git a/util/src/network/mod.rs b/util/src/network/mod.rs index 7d5aac8f7..c5066ff99 100644 --- a/util/src/network/mod.rs +++ b/util/src/network/mod.rs @@ -56,7 +56,7 @@ //! } //! //! fn main () { -//! let mut service = NetworkService::::start(NetworkConfiguration::new()).expect("Error creating network service"); +//! let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40412)).expect("Error creating network service"); //! service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]); //! //! // Wait for quit condition diff --git a/util/src/network/node_table.rs b/util/src/network/node_table.rs index a3ee57481..9bce2d334 100644 --- a/util/src/network/node_table.rs +++ b/util/src/network/node_table.rs @@ -20,11 +20,17 @@ use std::net::{SocketAddr, ToSocketAddrs, SocketAddrV4, SocketAddrV6, Ipv4Addr, use std::hash::{Hash, Hasher}; use std::str::{FromStr}; use std::collections::HashMap; +use std::fmt::{Display, Formatter}; +use std::path::{PathBuf}; +use std::fmt; +use std::fs; +use std::io::{Read, Write}; use hash::*; use rlp::*; use time::Tm; use error::*; -use network::discovery::TableUpdates; +use network::discovery::{TableUpdates, NodeEntry}; +pub use rustc_serialize::json::Json; /// Node public key pub type NodeId = H512; @@ -135,6 +141,17 @@ impl Node { } } +impl Display for Node { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + if self.endpoint.udp_port != self.endpoint.address.port() { + try!(write!(f, "enode://{}@{}+{}", self.id.hex(), self.endpoint.address, self.endpoint.udp_port)); + } else { + try!(write!(f, "enode://{}@{}", self.id.hex(), self.endpoint.address)); + } + Ok(()) + } +} + impl FromStr for Node { type Err = UtilError; fn from_str(s: &str) -> Result { @@ -170,18 +187,23 @@ impl Hash for Node { /// Node table backed by disk file. pub struct NodeTable { - nodes: HashMap + nodes: HashMap, + path: Option, } impl NodeTable { - pub fn new(_path: Option) -> NodeTable { + pub fn new(path: Option) -> NodeTable { NodeTable { - nodes: HashMap::new() + path: path.clone(), + nodes: NodeTable::load(path), } } /// Add a node to table - pub fn add_node(&mut self, node: Node) { + pub fn add_node(&mut self, mut node: Node) { + // preserve failure counter + let failures = self.nodes.get(&node.id).map_or(0, |n| n.failures); + node.failures = failures; self.nodes.insert(node.id.clone(), node); } @@ -192,6 +214,12 @@ impl NodeTable { refs.iter().map(|n| n.id.clone()).collect() } + /// Unordered list of all entries + pub fn unordered_entries(&self) -> Vec { + // preserve failure counter + self.nodes.values().map(|n| NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }).collect() + } + /// Get particular node pub fn get_mut(&mut self, id: &NodeId) -> Option<&mut Node> { self.nodes.get_mut(id) @@ -208,11 +236,92 @@ impl NodeTable { } } + /// Increase failure counte for a node pub fn note_failure(&mut self, id: &NodeId) { if let Some(node) = self.nodes.get_mut(id) { node.failures += 1; } } + + fn save(&self) { + if let Some(ref path) = self.path { + let mut path_buf = PathBuf::from(path); + if let Err(e) = fs::create_dir_all(path_buf.as_path()) { + warn!("Error creating node table directory: {:?}", e); + return; + }; + path_buf.push("nodes.json"); + let mut json = String::new(); + json.push_str("{\n"); + json.push_str("\"nodes\": [\n"); + let node_ids = self.nodes(); + for i in 0 .. node_ids.len() { + let node = self.nodes.get(&node_ids[i]).unwrap(); + json.push_str(&format!("\t{{ \"url\": \"{}\", \"failures\": {} }}{}\n", node, node.failures, if i == node_ids.len() - 1 {""} else {","})) + } + json.push_str("]\n"); + json.push_str("}"); + let mut file = match fs::File::create(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + warn!("Error creating node table file: {:?}", e); + return; + } + }; + if let Err(e) = file.write(&json.into_bytes()) { + warn!("Error writing node table file: {:?}", e); + } + } + } + + fn load(path: Option) -> HashMap { + let mut nodes: HashMap = HashMap::new(); + if let Some(path) = path { + let mut path_buf = PathBuf::from(path); + path_buf.push("nodes.json"); + let mut file = match fs::File::open(path_buf.as_path()) { + Ok(file) => file, + Err(e) => { + debug!("Error opening node table file: {:?}", e); + return nodes; + } + }; + let mut buf = String::new(); + match file.read_to_string(&mut buf) { + Ok(_) => {}, + Err(e) => { + warn!("Error reading node table file: {:?}", e); + return nodes; + } + } + let json = match Json::from_str(&buf) { + Ok(json) => json, + Err(e) => { + warn!("Error parsing node table file: {:?}", e); + return nodes; + } + }; + if let Some(list) = json.as_object().and_then(|o| o.get("nodes")).and_then(|n| n.as_array()) { + for n in list.iter().filter_map(|n| n.as_object()) { + if let Some(url) = n.get("url").and_then(|u| u.as_string()) { + if let Ok(mut node) = Node::from_str(url) { + if let Some(failures) = n.get("failures").and_then(|f| f.as_u64()) { + node.failures = failures as u32; + } + nodes.insert(node.id.clone(), node); + } + } + } + } + } + nodes + } +} + +impl Drop for NodeTable { + fn drop(&mut self) { + self.save(); + } } #[cfg(test)] @@ -247,4 +356,84 @@ mod tests { H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(), node.id); } + + #[test] + fn table_failure_order() { + let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node3 = Node::from_str("enode://c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id3 = H512::from_str("c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let mut table = NodeTable::new(None); + table.add_node(node3); + table.add_node(node1); + table.add_node(node2); + + table.note_failure(&id1); + table.note_failure(&id1); + table.note_failure(&id2); + + let r = table.nodes(); + assert_eq!(r[0][..], id3[..]); + assert_eq!(r[1][..], id2[..]); + assert_eq!(r[2][..], id1[..]); + } + + use std::path::PathBuf; + use std::env; + use std::fs::{remove_dir_all}; + // TODO: use common impl + pub struct RandomTempPath { + path: PathBuf + } + + impl RandomTempPath { + pub fn new() -> RandomTempPath { + let mut dir = env::temp_dir(); + dir.push(H32::random().hex()); + RandomTempPath { + path: dir.clone() + } + } + + pub fn as_path(&self) -> &PathBuf { + &self.path + } + + pub fn as_str(&self) -> &str { + self.path.to_str().unwrap() + } + } + + impl Drop for RandomTempPath { + fn drop(&mut self) { + if let Err(e) = remove_dir_all(self.as_path()) { + panic!("failed to remove temp directory, probably something failed to destroyed ({})", e); + } + } + } + + + #[test] + fn table_save_load() { + let temp_path = RandomTempPath::new(); + let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap(); + let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap(); + { + let mut table = NodeTable::new(Some(temp_path.as_str().to_owned())); + table.add_node(node1); + table.add_node(node2); + table.note_failure(&id2); + } + + { + let table = NodeTable::new(Some(temp_path.as_str().to_owned())); + let r = table.nodes(); + assert_eq!(r[0][..], id1[..]); + assert_eq!(r[1][..], id2[..]); + } + } } diff --git a/util/src/network/session.rs b/util/src/network/session.rs index f501e9c79..f08fef385 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::net::SocketAddr; +use std::io; use mio::*; use hash::*; use rlp::*; @@ -144,6 +146,11 @@ impl Session { self.connection.set_token(token); } + /// Get remote peer address + pub fn remote_addr(&self) -> io::Result { + self.connection.remote_addr() + } + /// Readable IO handler. Returns packet data if available. pub fn readable(&mut self, io: &IoContext, host: &HostInfo) -> Result where Message: Send + Sync + Clone { match try!(self.connection.readable(io)) { @@ -335,7 +342,7 @@ impl Session { let mut rlp = RlpStream::new(); rlp.append(&(PACKET_DISCONNECT as u32)); rlp.begin_list(1); - rlp.append(&(reason.clone() as u32)); + rlp.append(&(reason as u32)); self.connection.send_packet(&rlp.out()).ok(); NetworkError::Disconnect(reason) } diff --git a/util/src/network/tests.rs b/util/src/network/tests.rs index c1b59df9b..a3d5290c9 100644 --- a/util/src/network/tests.rs +++ b/util/src/network/tests.rs @@ -85,7 +85,7 @@ impl NetworkProtocolHandler for TestProtocol { #[test] fn net_service() { - let mut service = NetworkService::::start(NetworkConfiguration::new()).expect("Error creating network service"); + let mut service = NetworkService::::start(NetworkConfiguration::new_with_port(40414)).expect("Error creating network service"); service.register_protocol(Arc::new(TestProtocol::default()), "myproto", &[1u8]).unwrap(); } diff --git a/util/src/panics.rs b/util/src/panics.rs index 72718db58..27dd605f0 100644 --- a/util/src/panics.rs +++ b/util/src/panics.rs @@ -104,7 +104,7 @@ impl OnPanicListener for F } fn convert_to_string(t: &Box) -> Option { - let as_str = t.downcast_ref::<&'static str>().map(|t| t.clone().to_owned()); + let as_str = t.downcast_ref::<&'static str>().cloned().map(|t| t.to_owned()); let as_string = t.downcast_ref::().cloned(); as_str.or(as_string) diff --git a/util/src/rlp/untrusted_rlp.rs b/util/src/rlp/untrusted_rlp.rs index 7126e868d..463d5cb2f 100644 --- a/util/src/rlp/untrusted_rlp.rs +++ b/util/src/rlp/untrusted_rlp.rs @@ -408,7 +408,7 @@ impl Decodable for Vec { fn decode(decoder: &D) -> Result where D: Decoder { decoder.read_value(| bytes | { let mut res = vec![]; - res.extend(bytes); + res.extend_from_slice(bytes); Ok(res) }) } diff --git a/util/src/sha3.rs b/util/src/sha3.rs index 7e8382250..4079e8ba4 100644 --- a/util/src/sha3.rs +++ b/util/src/sha3.rs @@ -66,7 +66,7 @@ impl Hashable for T where T: BytesConvertable { #[test] fn sha3_empty() { - assert_eq!([0u8; 0].sha3(), SHA3_EMPTY); + assert_eq!((&[0u8; 0]).sha3(), SHA3_EMPTY); } #[test] fn sha3_as() { diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index b6cc81137..e7884a177 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -293,7 +293,7 @@ impl<'a> Iterator for TrieDBIterator<'a> { fn next(&mut self) -> Option { let b = match self.trail.last_mut() { - Some(ref mut b) => { b.increment(); b.clone() }, + Some(mut b) => { b.increment(); b.clone() }, None => return None }; match (b.status, b.node) { @@ -309,9 +309,8 @@ impl<'a> Iterator for TrieDBIterator<'a> { self.trail.pop(); self.next() }, - (Status::At, Node::Leaf(_, v)) => Some((self.key(), v)), + (Status::At, Node::Leaf(_, v)) | (Status::At, Node::Branch(_, Some(v))) => Some((self.key(), v)), (Status::At, Node::Extension(_, d)) => self.descend_next(d), - (Status::At, Node::Branch(_, Some(v))) => Some((self.key(), v)), (Status::At, Node::Branch(_, _)) => self.next(), (Status::AtChild(i), Node::Branch(children, _)) if children[i].len() > 0 => { match i {