Merge branch 'master' of github.com:ethcore/parity into db

This commit is contained in:
arkpar 2016-02-19 13:52:07 +01:00
commit f15275bb5b
46 changed files with 958 additions and 455 deletions

View File

@ -9,10 +9,14 @@ branches:
- /^beta$/ - /^beta$/
- /^stable$/ - /^stable$/
matrix: matrix:
fast_finish: true fast_finish: false
include: allow_failures:
- rust: nightly - rust: nightly
env: FEATURES="--features ethcore/json-tests" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}" include:
- rust: beta
env: FEATURES="--features travis-beta" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
- rust: nightly
env: FEATURES="--features travis-nightly" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
cache: cache:
apt: true apt: true
directories: directories:
@ -20,6 +24,7 @@ cache:
- target/debug/build - target/debug/build
- target/release/deps - target/release/deps
- target/release/build - target/release/build
- $HOME/.cargo
addons: addons:
apt: apt:
packages: packages:
@ -33,7 +38,7 @@ before_script: |
script: script:
- cargo build --release --verbose ${FEATURES} - cargo build --release --verbose ${FEATURES}
- cargo test --release --verbose ${FEATURES} ${TARGETS} - cargo test --release --verbose ${FEATURES} ${TARGETS}
- cargo bench --no-run ${FEATURES} ${TARGETS} #- cargo bench --no-run ${FEATURES} ${TARGETS}
- tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity - tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity
after_success: | after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
@ -47,7 +52,7 @@ after_success: |
./kcov-master/tmp/usr/local/bin/kcov --coveralls-id=${TRAVIS_JOB_ID} --exclude-pattern /.cargo,/root/.multirust target/kcov target/debug/parity-* && ./kcov-master/tmp/usr/local/bin/kcov --coveralls-id=${TRAVIS_JOB_ID} --exclude-pattern /.cargo,/root/.multirust target/kcov target/debug/parity-* &&
[ $TRAVIS_BRANCH = master ] && [ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] && [ $TRAVIS_PULL_REQUEST = false ] &&
[ $TRAVIS_RUST_VERSION = nightly ] && [ $TRAVIS_RUST_VERSION = beta ] &&
cargo doc --no-deps --verbose ${KCOV_FEATURES} ${TARGETS} && cargo doc --no-deps --verbose ${KCOV_FEATURES} ${TARGETS} &&
echo '<meta http-equiv=refresh content=0;url=ethcore/index.html>' > target/doc/index.html && echo '<meta http-equiv=refresh content=0;url=ethcore/index.html>' > target/doc/index.html &&
pip install --user ghp-import && pip install --user ghp-import &&

186
Cargo.lock generated
View File

@ -2,10 +2,10 @@
name = "parity" name = "parity"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"ctrlc 1.0.1 (git+https://github.com/tomusdrw/rust-ctrlc.git)", "ctrlc 1.0.1 (git+https://github.com/tomusdrw/rust-ctrlc.git)",
"daemonize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 0.9.99", "ethcore 0.9.99",
"ethcore-rpc 0.9.99", "ethcore-rpc 0.9.99",
@ -19,7 +19,7 @@ dependencies = [
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.5.0" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -36,8 +36,11 @@ dependencies = [
[[package]] [[package]]
name = "aster" name = "aster"
version = "0.12.0" version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syntex_syntax 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@ -61,11 +64,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "clippy" name = "clippy"
version = "0.0.41" version = "0.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"regex-syntax 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 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)", "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -108,24 +111,24 @@ dependencies = [
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "daemonize"
version = "0.2.1"
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]] [[package]]
name = "docopt" name = "docopt"
version = "0.6.78" version = "0.6.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"regex 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (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)", "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]] [[package]]
name = "elastic-array" name = "elastic-array"
version = "0.4.0" version = "0.4.0"
@ -137,20 +140,20 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "eth-secp256k1" name = "eth-secp256k1"
version = "0.5.4" version = "0.5.4"
source = "git+https://github.com/arkpar/rust-secp256k1.git#321e6c22a83606d1875f89cb61c9cb37c7d249ae" source = "git+https://github.com/arkpar/rust-secp256k1.git#45503e1de68d909b1862e3f2bdb9e1cdfdff3f1e"
dependencies = [ dependencies = [
"arrayvec 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.12 (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)", "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)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -159,7 +162,6 @@ name = "ethash"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "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", "sha3 0.1.0",
] ]
@ -167,12 +169,12 @@ dependencies = [
name = "ethcore" name = "ethcore"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.1.6 (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)", "env_logger 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethash 0.9.99", "ethash 0.9.99",
"ethcore-util 0.9.99", "ethcore-util 0.9.99",
"heapsize 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (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)", "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)", "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -185,16 +187,17 @@ dependencies = [
name = "ethcore-rpc" name = "ethcore-rpc"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 0.9.99", "ethcore 0.9.99",
"ethcore-util 0.9.99", "ethcore-util 0.9.99",
"ethsync 0.9.99", "ethsync 0.9.99",
"jsonrpc-core 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-http-server 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)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.6.0 (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)", "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -203,12 +206,12 @@ name = "ethcore-util"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"arrayvec 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "clippy 0.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.2.8 (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)", "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)", "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)", "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)", "heapsize 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"igd 0.4.2 (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)", "itertools 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"json-tests 0.1.0", "json-tests 0.1.0",
@ -219,7 +222,7 @@ dependencies = [
"rocksdb 0.3.0 (git+https://github.com/arkpar/rust-rocksdb.git)", "rocksdb 0.3.0 (git+https://github.com/arkpar/rust-rocksdb.git)",
"rust-crypto 0.2.34 (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)", "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"sha3 0.1.0", "sha3 0.1.0",
"slab 0.1.4 (git+https://github.com/arkpar/slab.git)", "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)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -231,7 +234,7 @@ dependencies = [
name = "ethsync" name = "ethsync"
version = "0.9.99" version = "0.9.99"
dependencies = [ dependencies = [
"clippy 0.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.2 (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.99", "ethcore 0.9.99",
"ethcore-util 0.9.99", "ethcore-util 0.9.99",
@ -259,11 +262,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "heapsize" name = "heapsize"
version = "0.2.5" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "hpack" name = "hpack"
@ -325,7 +325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"hyper 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.1.26 (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)", "xmltree 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -345,12 +345,13 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-core" name = "jsonrpc-core"
version = "1.1.2" version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.6.0 (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)", "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -359,7 +360,7 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"hyper 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "jsonrpc-core 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -399,17 +400,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "librocksdb-sys" name = "librocksdb-sys"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/arkpar/rust-rocksdb.git#e7f79d31e467c405a12db629daf5a86f81ed3e60" source = "git+https://github.com/arkpar/rust-rocksdb.git#31d2761f5132222f5277c8c0c31b0b55b65e0bee"
dependencies = [ dependencies = [
"libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.7 (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]] [[package]]
name = "log" name = "log"
version = "0.3.5" version = "0.3.5"
@ -418,14 +414,6 @@ dependencies = [
"libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "matches" name = "matches"
version = "0.1.2" version = "0.1.2"
@ -445,7 +433,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -511,7 +499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "num" name = "num"
version = "0.1.30" version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -540,23 +528,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quasi" name = "quasi"
version = "0.6.0" version = "0.7.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" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aster 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "quasi_macros" name = "quasi_codegen"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"quasi_codegen 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -569,10 +554,10 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "0.1.51" version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aho-corasick 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -586,7 +571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "rocksdb" name = "rocksdb"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/arkpar/rust-rocksdb.git#e7f79d31e467c405a12db629daf5a86f81ed3e60" source = "git+https://github.com/arkpar/rust-rocksdb.git#31d2761f5132222f5277c8c0c31b0b55b65e0bee"
dependencies = [ dependencies = [
"libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"librocksdb-sys 0.1.0 (git+https://github.com/arkpar/rust-rocksdb.git)", "librocksdb-sys 0.1.0 (git+https://github.com/arkpar/rust-rocksdb.git)",
@ -611,7 +596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.1.6" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
@ -624,7 +609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"nom 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -632,20 +617,22 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "0.6.13" version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "serde_codegen" name = "serde_codegen"
version = "0.6.13" version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aster 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi_macros 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -653,16 +640,8 @@ name = "serde_json"
version = "0.6.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"num 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.14 (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]] [[package]]
@ -696,11 +675,41 @@ name = "strsim"
version = "0.3.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syntex"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syntex_syntax 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntex_syntax"
version = "0.29.0"
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.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
"term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "target_info" name = "target_info"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "term"
version = "0.2.14"
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)",
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.34" version = "0.1.34"
@ -731,7 +740,7 @@ name = "unicase"
version = "1.2.1" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -747,6 +756,11 @@ name = "unicode-normalization"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "url" name = "url"
version = "0.2.38" version = "0.2.38"

View File

@ -10,19 +10,22 @@ log = "0.3"
env_logger = "0.3" env_logger = "0.3"
rustc-serialize = "0.3" rustc-serialize = "0.3"
docopt = "0.6" docopt = "0.6"
docopt_macros = "0.6"
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" } ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
clippy = "0.0.41" clippy = { version = "0.0.42", optional = true }
ethcore-util = { path = "util" } ethcore-util = { path = "util" }
ethcore = { path = "ethcore" } ethcore = { path = "ethcore" }
ethsync = { path = "sync" } ethsync = { path = "sync" }
ethcore-rpc = { path = "rpc", optional = true } ethcore-rpc = { path = "rpc", optional = true }
fdlimit = { path = "util/fdlimit" } fdlimit = { path = "util/fdlimit" }
target_info = "0.1" target_info = "0.1"
daemonize = "0.2"
[features] [features]
default = ["rpc"] default = ["rpc"]
rpc = ["ethcore-rpc"] rpc = ["ethcore-rpc"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev"]
travis-beta = ["ethcore/json-tests"]
travis-nightly = ["ethcore/json-tests", "dev"]
[[bin]] [[bin]]
path = "parity/main.rs" path = "parity/main.rs"

View File

@ -1,6 +1,6 @@
# ethcore # ethcore
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url] [![GPLv3][license-image]][license-url]
[travis-image]: https://travis-ci.org/ethcore/parity.svg?branch=master [travis-image]: https://travis-ci.org/ethcore/parity.svg?branch=master
[travis-url]: https://travis-ci.org/ethcore/parity [travis-url]: https://travis-ci.org/ethcore/parity
@ -8,6 +8,8 @@
[coveralls-url]: https://coveralls.io/github/ethcore/parity?branch=master [coveralls-url]: https://coveralls.io/github/ethcore/parity?branch=master
[gitter-image]: https://badges.gitter.im/Join%20Chat.svg [gitter-image]: https://badges.gitter.im/Join%20Chat.svg
[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg
[license-url]: http://www.gnu.org/licenses/gpl-3.0.en.html
[Documentation](http://ethcore.github.io/parity/ethcore/index.html) [Documentation](http://ethcore.github.io/parity/ethcore/index.html)
@ -24,13 +26,17 @@ apt-get install -y --force-yes librocksdb-dev
# install multirust # install multirust
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
# install nightly and make it default # install beta
multirust update nightly multirust update beta
multirust default nightly
# download and build parity # download and build parity
git clone https://github.com/ethcore/parity git clone https://github.com/ethcore/parity
cd parity cd parity
# parity should be build with rust beta
multirust override beta
# build in release
cargo build --release cargo build --release
``` ```
@ -45,16 +51,20 @@ sudo cp -a librocksdb.so* /usr/lib
sudo ldconfig sudo ldconfig
cd .. cd ..
# install rust nightly # install rust beta
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
# install nightly and make it default # install rust beta
sudo multirust update nightly sudo multirust update beta
sudo multirust default nightly
# download and build parity # download and build parity
git clone https://github.com/ethcore/parity git clone https://github.com/ethcore/parity
cd parity cd parity
# parity should be build with rust beta
sudo multirust override beta
# build in release
cargo build --release cargo build --release
``` ```
@ -66,12 +76,16 @@ brew update
brew install rocksdb brew install rocksdb
brew install multirust brew install multirust
# install nightly and make it default # install beta
multirust update nightly && multirust default nightly multirust update beta
# download and build parity # download and build parity
git clone https://github.com/ethcore/parity git clone https://github.com/ethcore/parity
cd parity cd parity
# use rust beta for building parity
multirust override beta
cargo build --release cargo build --release
``` ```

View File

@ -7,5 +7,4 @@ authors = ["arkpar <arkadiy@ethcore.io"]
[dependencies] [dependencies]
log = "0.3" log = "0.3"
lru-cache = "0.0"
sha3 = { path = "../util/sha3" } sha3 = { path = "../util/sha3" }

View File

@ -17,28 +17,39 @@
//! Ethash implementation //! Ethash implementation
//! See https://github.com/ethereum/wiki/wiki/Ethash //! See https://github.com/ethereum/wiki/wiki/Ethash
extern crate sha3; extern crate sha3;
extern crate lru_cache;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
mod sizes; mod sizes;
mod compute; mod compute;
use lru_cache::LruCache; use std::mem;
use compute::Light; use compute::Light;
pub use compute::{quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH}; pub use compute::{quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
struct LightCache {
recent_epoch: Option<u64>,
recent: Option<Arc<Light>>,
prev_epoch: Option<u64>,
prev: Option<Arc<Light>>,
}
/// Lighy/Full cache manager /// Lighy/Full cache manager
pub struct EthashManager { pub struct EthashManager {
lights: Mutex<LruCache<u64, Arc<Light>>> cache: Mutex<LightCache>,
} }
impl EthashManager { impl EthashManager {
/// Create a new new instance of ethash manager /// Create a new new instance of ethash manager
pub fn new() -> EthashManager { pub fn new() -> EthashManager {
EthashManager { EthashManager {
lights: Mutex::new(LruCache::new(2)) cache: Mutex::new(LightCache {
recent_epoch: None,
recent: None,
prev_epoch: None,
prev: None,
}),
} }
} }
@ -50,8 +61,24 @@ impl EthashManager {
pub fn compute_light(&self, block_number: u64, header_hash: &H256, nonce: u64) -> ProofOfWork { pub fn compute_light(&self, block_number: u64, header_hash: &H256, nonce: u64) -> ProofOfWork {
let epoch = block_number / ETHASH_EPOCH_LENGTH; let epoch = block_number / ETHASH_EPOCH_LENGTH;
let light = { let light = {
let mut lights = self.lights.lock().unwrap(); let mut lights = self.cache.lock().unwrap();
match lights.get_mut(&epoch).map(|l| l.clone()) { let light = match lights.recent_epoch.clone() {
Some(ref e) if *e == epoch => lights.recent.clone(),
_ => match lights.prev_epoch.clone() {
Some(e) if e == epoch => {
// swap
let t = lights.prev_epoch;
lights.prev_epoch = lights.recent_epoch;
lights.recent_epoch = t;
let t = lights.prev.clone();
lights.prev = lights.recent.clone();
lights.recent = t;
lights.recent.clone()
}
_ => None,
}
};
match light {
None => { None => {
let light = match Light::from_file(block_number) { let light = match Light::from_file(block_number) {
Ok(light) => Arc::new(light), Ok(light) => Arc::new(light),
@ -64,7 +91,8 @@ impl EthashManager {
Arc::new(light) Arc::new(light)
} }
}; };
lights.insert(epoch, light.clone()); lights.prev_epoch = mem::replace(&mut lights.recent_epoch, Some(epoch));
lights.prev = mem::replace(&mut lights.recent, Some(light.clone()));
light light
} }
Some(light) => light Some(light) => light
@ -73,3 +101,19 @@ impl EthashManager {
light.compute(header_hash, nonce) light.compute(header_hash, nonce)
} }
} }
#[test]
fn test_lru() {
let ethash = EthashManager::new();
let hash = [0u8; 32];
ethash.compute_light(1, &hash, 1);
ethash.compute_light(50000, &hash, 1);
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 1);
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 0);
ethash.compute_light(1, &hash, 1);
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 0);
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 1);
ethash.compute_light(70000, &hash, 1);
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 2);
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 0);
}

View File

@ -10,14 +10,14 @@ authors = ["Ethcore <admin@ethcore.io>"]
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.3"
rustc-serialize = "0.3" rustc-serialize = "0.3"
heapsize = "0.2.0" heapsize = "0.3"
rust-crypto = "0.2.34" rust-crypto = "0.2.34"
time = "0.1" time = "0.1"
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
evmjit = { path = "../evmjit", optional = true } evmjit = { path = "../evmjit", optional = true }
ethash = { path = "../ethash" } ethash = { path = "../ethash" }
num_cpus = "0.2" num_cpus = "0.2"
clippy = "0.0.41" clippy = { version = "0.0.42", optional = true }
crossbeam = "0.1.5" crossbeam = "0.1.5"
lazy_static = "0.1" lazy_static = "0.1"
@ -26,3 +26,5 @@ jit = ["evmjit"]
evm-debug = [] evm-debug = []
json-tests = [] json-tests = []
test-heavy = [] test-heavy = []
dev = ["clippy"]
default = []

View File

@ -24,7 +24,7 @@ pub type LogBloom = H2048;
/// Constant 2048-bit datum for 0. Often used as a default. /// Constant 2048-bit datum for 0. Often used as a default.
pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]); pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]);
#[allow(enum_variant_names)] #[cfg_attr(feature="dev", allow(enum_variant_names))]
/// Semantic boolean for when a seal/signature is included. /// Semantic boolean for when a seal/signature is included.
pub enum Seal { pub enum Seal {
/// The seal/signature is included. /// The seal/signature is included.

View File

@ -16,7 +16,7 @@
//! Blockchain block. //! Blockchain block.
#![allow(ptr_arg)] // Because of &LastHashes -> &Vec<_> #![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
use common::*; use common::*;
use engine::*; use engine::*;
@ -267,7 +267,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
s.block.base.header.uncles_hash = uncle_bytes.sha3(); s.block.base.header.uncles_hash = uncle_bytes.sha3();
s.block.base.header.state_root = s.block.state.root().clone(); s.block.base.header.state_root = s.block.state.root().clone();
s.block.base.header.receipts_root = ordered_trie_root(s.block.receipts.iter().map(|ref r| r.rlp_bytes().to_vec()).collect()); s.block.base.header.receipts_root = ordered_trie_root(s.block.receipts.iter().map(|ref r| r.rlp_bytes().to_vec()).collect());
s.block.base.header.log_bloom = s.block.receipts.iter().fold(LogBloom::zero(), |mut b, r| {b |= &r.log_bloom; b}); s.block.base.header.log_bloom = s.block.receipts.iter().fold(LogBloom::zero(), |mut b, r| {b = &b | &r.log_bloom; b}); //TODO: use |= operator
s.block.base.header.gas_used = s.block.receipts.last().map_or(U256::zero(), |r| r.gas_used); s.block.base.header.gas_used = s.block.receipts.last().map_or(U256::zero(), |r| r.gas_used);
s.block.base.header.note_dirty(); s.block.base.header.note_dirty();

View File

@ -87,7 +87,7 @@ struct QueueSignal {
} }
impl QueueSignal { impl QueueSignal {
#[allow(bool_comparison)] #[cfg_attr(feature="dev", allow(bool_comparison))]
fn set(&self) { fn set(&self) {
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false { if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message"); self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");

View File

@ -161,7 +161,7 @@ impl ClientReport {
pub fn accrue_block(&mut self, block: &PreVerifiedBlock) { pub fn accrue_block(&mut self, block: &PreVerifiedBlock) {
self.blocks_imported += 1; self.blocks_imported += 1;
self.transactions_applied += block.transactions.len(); self.transactions_applied += block.transactions.len();
self.gas_processed += block.header.gas_used; self.gas_processed = self.gas_processed + block.header.gas_used;
} }
} }

View File

@ -206,7 +206,7 @@ impl Engine for Ethash {
} }
} }
#[allow(wrong_self_convention)] // to_ethash should take self #[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self
impl Ethash { impl Ethash {
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 { fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
const EXP_DIFF_PERIOD: u64 = 100000; const EXP_DIFF_PERIOD: u64 = 100000;

View File

@ -243,7 +243,7 @@ struct CodeReader<'a> {
code: &'a Bytes code: &'a Bytes
} }
#[allow(len_without_is_empty)] #[cfg_attr(feature="dev", allow(len_without_is_empty))]
impl<'a> CodeReader<'a> { impl<'a> CodeReader<'a> {
/// Get `no_of_bytes` from code and convert to U256. Move PC /// Get `no_of_bytes` from code and convert to U256. Move PC
fn read(&mut self, no_of_bytes: usize) -> U256 { fn read(&mut self, no_of_bytes: usize) -> U256 {
@ -258,7 +258,7 @@ impl<'a> CodeReader<'a> {
} }
} }
#[allow(enum_variant_names)] #[cfg_attr(feature="dev", allow(enum_variant_names))]
enum InstructionCost { enum InstructionCost {
Gas(U256), Gas(U256),
GasMem(U256, U256), GasMem(U256, U256),
@ -299,7 +299,7 @@ impl evm::Evm for Interpreter {
let (gas_cost, mem_size) = try!(self.get_gas_cost_mem(ext, instruction, &mut mem, &stack)); let (gas_cost, mem_size) = try!(self.get_gas_cost_mem(ext, instruction, &mut mem, &stack));
try!(self.verify_gas(&current_gas, &gas_cost)); try!(self.verify_gas(&current_gas, &gas_cost));
mem.expand(mem_size); mem.expand(mem_size);
current_gas -= gas_cost; current_gas = current_gas - gas_cost; //TODO: use operator -=
evm_debug!({ evm_debug!({
println!("[0x{:x}][{}(0x{:x}) Gas: {:x}\n Gas Before: {:x}", println!("[0x{:x}][{}(0x{:x}) Gas: {:x}\n Gas Before: {:x}",
@ -320,7 +320,7 @@ impl evm::Evm for Interpreter {
match result { match result {
InstructionResult::Ok => {}, InstructionResult::Ok => {},
InstructionResult::UnusedGas(gas) => { InstructionResult::UnusedGas(gas) => {
current_gas += gas; current_gas = current_gas + gas; //TODO: use operator +=
}, },
InstructionResult::UseAllGas => { InstructionResult::UseAllGas => {
current_gas = U256::zero(); current_gas = U256::zero();
@ -347,7 +347,7 @@ impl evm::Evm for Interpreter {
} }
impl Interpreter { impl Interpreter {
#[allow(cyclomatic_complexity)] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
fn get_gas_cost_mem(&self, fn get_gas_cost_mem(&self,
ext: &evm::Ext, ext: &evm::Ext,
instruction: Instruction, instruction: Instruction,

View File

@ -188,7 +188,7 @@ impl<'a> Ext for Externalities<'a> {
self.state.code(address).unwrap_or_else(|| vec![]) self.state.code(address).unwrap_or_else(|| vec![])
} }
#[allow(match_ref_pats)] #[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> { fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> {
match &mut self.output { match &mut self.output {
&mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe { &mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe {

View File

@ -15,18 +15,16 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(cell_extras)] #![cfg_attr(feature="dev", feature(plugin))]
#![feature(augmented_assignments)] #![cfg_attr(feature="dev", plugin(clippy))]
#![feature(plugin)]
// Clippy
#![plugin(clippy)]
// 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)]
// Clippy config
// TODO [todr] not really sure
#![cfg_attr(feature="dev", allow(needless_range_loop))]
// Shorter than if-else
#![cfg_attr(feautre="dev", allow(match_bool))]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![cfg_attr(feature="dev", allow(clone_on_copy))]
//! Ethcore library //! Ethcore library
//! //!

View File

@ -39,7 +39,7 @@ impl Receipt {
Receipt { Receipt {
state_root: state_root, state_root: state_root,
gas_used: gas_used, gas_used: gas_used,
log_bloom: logs.iter().fold(LogBloom::new(), |mut b, l| { b |= &l.bloom(); b }), log_bloom: logs.iter().fold(LogBloom::new(), |mut b, l| { b = &b | &l.bloom(); b }), //TODO: use |= operator
logs: logs, logs: logs,
} }
} }

View File

@ -110,8 +110,8 @@ impl IoHandler<NetSyncMessage> for ClientIoHandler {
} }
} }
#[allow(match_ref_pats)] #[cfg_attr(feature="dev", allow(match_ref_pats))]
#[allow(single_match)] #[cfg_attr(feature="dev", allow(single_match))]
fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) { fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) {
if let &UserMessage(ref message) = net_message { if let &UserMessage(ref message) = net_message {
match message { match message {
@ -124,6 +124,8 @@ impl IoHandler<NetSyncMessage> for ClientIoHandler {
} }
} }
// TODO: rewrite into something that doesn't dependent on the testing environment having a particular port ready for use.
/*
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -138,3 +140,4 @@ mod tests {
assert!(service.is_ok()); assert!(service.is_ok());
} }
} }
*/

View File

@ -97,7 +97,7 @@ pub struct Spec {
genesis_state: PodState, genesis_state: PodState,
} }
#[allow(wrong_self_convention)] // because to_engine(self) should be to_engine(&self) #[cfg_attr(feature="dev", allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self)
impl Spec { impl Spec {
/// Convert this object into a boxed Engine of the right underlying type. /// Convert this object into a boxed Engine of the right underlying type.
// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead. // TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead.

View File

@ -224,7 +224,7 @@ impl State {
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit. /// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
/// `accounts` is mutable because we may need to commit the code or storage and record that. /// `accounts` is mutable because we may need to commit the code or storage and record that.
#[allow(match_ref_pats)] #[cfg_attr(feature="dev", allow(match_ref_pats))]
pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) { pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
// first, commit the sub trees. // first, commit the sub trees.
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`? // TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
@ -282,7 +282,7 @@ impl State {
/// Pull account `a` in our cache from the trie DB and return it. /// Pull account `a` in our cache from the trie DB and return it.
/// `require_code` requires that the code be cached, too. /// `require_code` requires that the code be cached, too.
fn get(&self, a: &Address, require_code: bool) -> Ref<Option<Account>> { fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option<Account> {
let have_key = self.cache.borrow().contains_key(a); let have_key = self.cache.borrow().contains_key(a);
if !have_key { if !have_key {
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp)) self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
@ -292,17 +292,17 @@ impl State {
account.cache_code(&AccountDB::new(&self.db, a)); account.cache_code(&AccountDB::new(&self.db, a));
} }
} }
Ref::map(self.cache.borrow(), |m| m.get(a).unwrap()) unsafe { ::std::mem::transmute(self.cache.borrow().get(a).unwrap()) }
} }
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too. /// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
fn require(&self, a: &Address, require_code: bool) -> RefMut<Account> { fn require<'a>(&'a self, a: &Address, require_code: bool) -> &'a mut Account {
self.require_or_from(a, require_code, || Account::new_basic(U256::from(0u8), self.account_start_nonce), |_|{}) self.require_or_from(a, require_code, || Account::new_basic(U256::from(0u8), self.account_start_nonce), |_|{})
} }
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too. /// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
/// If it doesn't exist, make account equal the evaluation of `default`. /// If it doesn't exist, make account equal the evaluation of `default`.
fn require_or_from<F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> RefMut<Account> { fn require_or_from<'a, F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> &'a mut Account {
let have_key = self.cache.borrow().contains_key(a); let have_key = self.cache.borrow().contains_key(a);
if !have_key { if !have_key {
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp)) self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
@ -316,13 +316,12 @@ impl State {
not_default(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().unwrap()); not_default(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().unwrap());
} }
let b = self.cache.borrow_mut(); unsafe { ::std::mem::transmute(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().map(|account| {
RefMut::map(b, |m| m.get_mut(a).unwrap().as_mut().map(|account| {
if require_code { if require_code {
account.cache_code(&AccountDB::new(&self.db, a)); account.cache_code(&AccountDB::new(&self.db, a));
} }
account account
}).unwrap()) }).unwrap()) }
} }
} }

View File

@ -346,8 +346,7 @@ function run_installer()
exe brew install rocksdb exe brew install rocksdb
info "Installing multirust" info "Installing multirust"
exe brew install multirust exe brew install multirust
sudo multirust update nightly sudo multirust default beta
sudo multirust default nightly
echo echo
} }
@ -426,20 +425,20 @@ function run_installer()
depFound=$((depFound+1)) depFound=$((depFound+1))
check "multirust" check "multirust"
isMultirust=true isMultirust=true
if [[ $(multirust show-default 2>/dev/null | grep nightly | wc -l) == 4 ]]; then if [[ $(multirust show-default 2>/dev/null | grep beta | wc -l) == 4 ]]; then
depFound=$((depFound+1)) depFound=$((depFound+1))
check "rust nightly" check "rust beta"
isMultirustNightly=true isMultirustBeta=true
else else
uncheck "rust is not nightly" uncheck "rust is not beta"
isMultirustNightly=false isMultirustBeta=false
INSTALL_FILES+="${blue}${dim}==> multirust -> rust nightly:${reset}${n}" INSTALL_FILES+="${blue}${dim}==> multirust -> rust beta:${reset}${n}"
fi fi
else else
uncheck "multirust is missing" uncheck "multirust is missing"
uncheck "rust nightly is missing" uncheck "rust beta is missing"
isMultirust=false isMultirust=false
isMultirustNightly=false isMultirustBeta=false
INSTALL_FILES+="${blue}${dim}==> multirust:${reset}${n}" INSTALL_FILES+="${blue}${dim}==> multirust:${reset}${n}"
fi fi
} }
@ -626,10 +625,9 @@ function run_installer()
echo echo
fi fi
if [[ $isMultirustNightly == false ]]; then if [[ $isMultirustBeta == false ]]; then
info "Installing rust nightly..." info "Installing rust beta..."
multirust update nightly multirust default beta
multirust default nightly
echo echo
fi fi
} }
@ -660,7 +658,7 @@ function run_installer()
find_rocksdb find_rocksdb
find_multirust find_multirust
if [[ $isCurl == false || $isGit == false || $isMake == false || $isGCC == false || $isRocksDB == false || $isMultirustNightly == false ]]; then if [[ $isCurl == false || $isGit == false || $isMake == false || $isGCC == false || $isRocksDB == false || $isMultirustBeta == false ]]; then
abort_install abort_install
fi fi
fi fi

View File

@ -17,19 +17,20 @@
//! Ethcore client application. //! Ethcore client application.
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(plugin)] #![cfg_attr(feature="dev", feature(plugin))]
#![plugin(docopt_macros)] #![cfg_attr(feature="dev", plugin(clippy))]
#![plugin(clippy)]
extern crate docopt; extern crate docopt;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate ethcore; extern crate ethcore;
extern crate ethsync; extern crate ethsync;
#[macro_use]
extern crate log as rlog; extern crate log as rlog;
extern crate env_logger; extern crate env_logger;
extern crate ctrlc; extern crate ctrlc;
extern crate fdlimit; extern crate fdlimit;
extern crate target_info; extern crate target_info;
extern crate daemonize;
#[cfg(feature = "rpc")] #[cfg(feature = "rpc")]
extern crate ethcore_rpc as rpc; extern crate ethcore_rpc as rpc;
@ -47,20 +48,24 @@ use ethcore::service::{ClientService, NetSyncMessage};
use ethcore::ethereum; use ethcore::ethereum;
use ethcore::blockchain::CacheSize; use ethcore::blockchain::CacheSize;
use ethsync::EthSync; use ethsync::EthSync;
use docopt::Docopt;
use target_info::Target; use target_info::Target;
use daemonize::Daemonize;
docopt!(Args derive Debug, " const USAGE: &'static str = "
Parity. Ethereum Client. Parity. Ethereum Client.
By Wood/Paronyan/Kotewicz/Drwięga/Volf. By Wood/Paronyan/Kotewicz/Drwięga/Volf.
Copyright 2015, 2016 Ethcore (UK) Limited Copyright 2015, 2016 Ethcore (UK) Limited
Usage: Usage:
parity daemon <pid-file> [options] [ --no-bootstrap | <enode>... ]
parity [options] [ --no-bootstrap | <enode>... ] parity [options] [ --no-bootstrap | <enode>... ]
Options: Options:
--chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file --chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file
or frontier, mainnet, morden, or testnet [default: frontier]. or frontier, mainnet, morden, or testnet [default: frontier].
-d --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity] -d --db-path PATH Specify the database & configuration directory path [default: $HOME/.parity]
--keys-path PATH Specify the path for JSON key files to be found [default: $HOME/.web3/keys]
--no-bootstrap Don't bother trying to connect to any nodes initially. --no-bootstrap Don't bother trying to connect to any nodes initially.
--listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304]. --listen-address URL Specify the IP/port on which to listen for peers [default: 0.0.0.0:30304].
@ -78,9 +83,31 @@ Options:
-l --logging LOGGING Specify the logging level. -l --logging LOGGING Specify the logging level.
-v --version Show information about version. -v --version Show information about version.
-h --help Show this screen. -h --help Show this screen.
", flag_cache_pref_size: usize, flag_cache_max_size: usize, flag_address: Option<String>, flag_node_key: Option<String>); ";
fn setup_log(init: &str) { #[derive(Debug, RustcDecodable)]
struct Args {
cmd_daemon: bool,
arg_pid_file: String,
arg_enode: Vec<String>,
flag_chain: String,
flag_db_path: String,
flag_keys_path: String,
flag_no_bootstrap: bool,
flag_listen_address: String,
flag_public_address: String,
flag_address: Option<String>,
flag_upnp: bool,
flag_node_key: Option<String>,
flag_cache_pref_size: usize,
flag_cache_max_size: usize,
flag_jsonrpc: bool,
flag_jsonrpc_url: String,
flag_logging: Option<String>,
flag_version: bool,
}
fn setup_log(init: &Option<String>) {
let mut builder = LogBuilder::new(); let mut builder = LogBuilder::new();
builder.filter(None, LogLevelFilter::Info); builder.filter(None, LogLevelFilter::Info);
@ -88,7 +115,9 @@ fn setup_log(init: &str) {
builder.parse(&env::var("RUST_LOG").unwrap()); builder.parse(&env::var("RUST_LOG").unwrap());
} }
builder.parse(init); if let Some(ref s) = *init {
builder.parse(s);
}
builder.init().unwrap(); builder.init().unwrap();
} }
@ -128,7 +157,7 @@ struct Configuration {
impl Configuration { impl Configuration {
fn parse() -> Self { fn parse() -> Self {
Configuration { Configuration {
args: Args::docopt().decode().unwrap_or_else(|e| e.exit()) args: Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()),
} }
} }
@ -136,6 +165,10 @@ impl Configuration {
self.args.flag_db_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap()) self.args.flag_db_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
} }
fn keys_path(&self) -> String {
self.args.flag_keys_path.replace("$HOME", env::home_dir().unwrap().to_str().unwrap())
}
fn spec(&self) -> Spec { fn spec(&self) -> Spec {
match self.args.flag_chain.as_ref() { match self.args.flag_chain.as_ref() {
"frontier" | "mainnet" => ethereum::new_frontier(), "frontier" | "mainnet" => ethereum::new_frontier(),
@ -149,7 +182,7 @@ impl Configuration {
if self.args.flag_no_bootstrap { Vec::new() } else { if self.args.flag_no_bootstrap { Vec::new() } else {
match self.args.arg_enode.len() { match self.args.arg_enode.len() {
0 => spec.nodes().clone(), 0 => spec.nodes().clone(),
_ => self.args.arg_enode.clone(), _ => self.args.arg_enode.clone(), // TODO check format first.
} }
} }
} }
@ -171,6 +204,63 @@ impl Configuration {
(listen_address, public_address) (listen_address, public_address)
} }
fn execute(&self) {
if self.args.flag_version {
print_version();
return;
}
if self.args.cmd_daemon {
let daemonize = Daemonize::new().pid_file(self.args.arg_pid_file.clone()).chown_pid_file(true);
match daemonize.start() {
Ok(_) => info!("Daemonized"),
Err(e) => { error!("{}", e); return; },
}
}
self.execute_client();
}
fn execute_client(&self) {
// Setup logging
setup_log(&self.args.flag_logging);
// Raise fdlimit
unsafe { ::fdlimit::raise_fd_limit(); }
let spec = self.spec();
// Configure network
let mut net_settings = NetworkConfiguration::new();
net_settings.nat_enabled = self.args.flag_upnp;
net_settings.boot_nodes = self.init_nodes(&spec);
let (listen, public) = self.net_addresses();
net_settings.listen_address = listen;
net_settings.public_address = public;
net_settings.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).expect("Invalid key string"));
// Build client
let mut service = ClientService::start(spec, net_settings, &Path::new(&self.path())).unwrap();
let client = service.client().clone();
client.configure_cache(self.args.flag_cache_pref_size, self.args.flag_cache_max_size);
// Sync
let sync = EthSync::register(service.network(), client);
// Setup rpc
if self.args.flag_jsonrpc {
setup_rpc_server(service.client(), sync.clone(), &self.args.flag_jsonrpc_url);
}
// Register IO handler
let io_handler = Arc::new(ClientIoHandler {
client: service.client(),
info: Default::default(),
sync: sync
});
service.io().register_handler(io_handler).expect("Error registering IO handler");
// Handle exit
wait_for_exit(&service);
}
} }
fn wait_for_exit(client_service: &ClientService) { fn wait_for_exit(client_service: &ClientService) {
@ -186,51 +276,7 @@ fn wait_for_exit(client_service: &ClientService) {
} }
fn main() { fn main() {
let conf = Configuration::parse(); Configuration::parse().execute();
if conf.args.flag_version {
print_version();
return;
}
let spec = conf.spec();
// Setup logging
setup_log(&conf.args.flag_logging);
// Raise fdlimit
unsafe { ::fdlimit::raise_fd_limit(); }
// Configure network
let mut net_settings = NetworkConfiguration::new();
net_settings.nat_enabled = conf.args.flag_upnp;
net_settings.boot_nodes = conf.init_nodes(&spec);
let (listen, public) = conf.net_addresses();
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"));
// Build client
let mut service = ClientService::start(spec, net_settings, &Path::new(&conf.path())).unwrap();
let client = service.client().clone();
client.configure_cache(conf.args.flag_cache_pref_size, conf.args.flag_cache_max_size);
// Sync
let sync = EthSync::register(service.network(), client);
// Setup rpc
if conf.args.flag_jsonrpc {
setup_rpc_server(service.client(), sync.clone(), &conf.args.flag_jsonrpc_url);
}
// Register IO handler
let io_handler = Arc::new(ClientIoHandler {
client: service.client(),
info: Default::default(),
sync: sync
});
service.io().register_handler(io_handler).expect("Error registering IO handler");
// Handle exit
wait_for_exit(&service);
} }
struct Informant { struct Informant {

View File

@ -4,18 +4,28 @@ name = "ethcore-rpc"
version = "0.9.99" version = "0.9.99"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"] authors = ["Ethcore <admin@ethcore.io"]
build = "build.rs"
[lib] [lib]
[dependencies] [dependencies]
serde = "0.6.7" serde = "0.6.7"
serde_macros = "0.6.13"
serde_json = "0.6.0" serde_json = "0.6.0"
jsonrpc-core = "1.1.2" jsonrpc-core = "1.1"
jsonrpc-http-server = "1.1.2" jsonrpc-http-server = "1.1"
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
ethsync = { path = "../sync" } ethsync = { path = "../sync" }
clippy = "0.0.41" clippy = { version = "0.0.42", optional = true }
target_info = "0.1.0" target_info = "0.1.0"
rustc-serialize = "0.3" rustc-serialize = "0.3"
serde_macros = { version = "0.6.13", optional = true }
[build-dependencies]
serde_codegen = { version = "0.6.13", optional = true }
syntex = "0.29.0"
[features]
default = ["serde_codegen"]
nightly = ["serde_macros"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev"]

29
rpc/build.rs Normal file
View File

@ -0,0 +1,29 @@
#[cfg(not(feature = "serde_macros"))]
mod inner {
extern crate syntex;
extern crate serde_codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let src = Path::new("src/lib.rs.in");
let dst = Path::new(&out_dir).join("lib.rs");
let mut registry = syntex::Registry::new();
serde_codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}
#[cfg(feature = "serde_macros")]
mod inner {
pub fn main() {}
}
fn main() {
inner::main();
}

View File

@ -16,9 +16,8 @@
//! Ethcore rpc. //! Ethcore rpc.
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(custom_derive, custom_attribute, plugin)] #![cfg_attr(nightly, feature(custom_derive, custom_attribute, plugin))]
#![plugin(serde_macros)] #![cfg_attr(nightly, plugin(serde_macros, clippy))]
#![plugin(clippy)]
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate target_info; extern crate target_info;
@ -30,38 +29,8 @@ extern crate ethcore_util as util;
extern crate ethcore; extern crate ethcore;
extern crate ethsync; extern crate ethsync;
use self::jsonrpc_core::{IoHandler, IoDelegate}; #[cfg(feature = "serde_macros")]
include!("lib.rs.in");
pub mod v1; #[cfg(not(feature = "serde_macros"))]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
/// Http server.
pub struct HttpServer {
handler: IoHandler,
threads: usize
}
impl HttpServer {
/// Construct new http server object with given number of threads.
pub fn new(threads: usize) -> HttpServer {
HttpServer {
handler: IoHandler::new(),
threads: threads
}
}
/// Add io delegate.
pub fn add_delegate<D>(&mut self, delegate: IoDelegate<D>) where D: Send + Sync + 'static {
self.handler.add_delegate(delegate);
}
/// Start server asynchronously in new thread
pub fn start_async(self, addr: &str) {
let server = jsonrpc_http_server::Server::new(self.handler, self.threads);
server.start_async(addr)
}
}
/// Lib needs at least 1 test to generate coverage reports correctly.
#[test]
fn if_works() {
}

30
rpc/src/lib.rs.in Normal file
View File

@ -0,0 +1,30 @@
use self::jsonrpc_core::{IoHandler, IoDelegate};
pub mod v1;
/// Http server.
pub struct HttpServer {
handler: IoHandler,
threads: usize
}
impl HttpServer {
/// Construct new http server object with given number of threads.
pub fn new(threads: usize) -> HttpServer {
HttpServer {
handler: IoHandler::new(),
threads: threads
}
}
/// Add io delegate.
pub fn add_delegate<D>(&mut self, delegate: IoDelegate<D>) where D: Send + Sync + 'static {
self.handler.add_delegate(delegate);
}
/// Start server asynchronously in new thread
pub fn start_async(self, addr: &str) {
let server = jsonrpc_http_server::Server::new(self.handler, self.threads);
server.start_async(addr)
}
}

View File

@ -55,13 +55,12 @@ impl Visitor for BlockNumberVisitor {
} }
impl Into<BlockId> for BlockNumber { impl Into<BlockId> for BlockNumber {
#[allow(match_same_arms)]
fn into(self) -> BlockId { fn into(self) -> BlockId {
match self { match self {
BlockNumber::Num(n) => BlockId::Number(n), BlockNumber::Num(n) => BlockId::Number(n),
BlockNumber::Earliest => BlockId::Earliest, BlockNumber::Earliest => BlockId::Earliest,
BlockNumber::Latest => BlockId::Latest, // TODO: change this once blockid support pendingst,
BlockNumber::Pending => BlockId::Latest // TODO: change this once blockid support pending BlockNumber::Pending | BlockNumber::Latest => BlockId::Latest,
} }
} }
} }

View File

@ -10,8 +10,12 @@ authors = ["Ethcore <admin@ethcore.io"]
[dependencies] [dependencies]
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
ethcore = { path = ".." } ethcore = { path = ".." }
clippy = "0.0.41" clippy = { version = "0.0.42", optional = true }
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.3"
time = "0.1.34" time = "0.1.34"
rand = "0.3.13" rand = "0.3.13"
[features]
default = []
dev = ["clippy", "ethcore/dev", "ethcore-util/dev"]

View File

@ -251,7 +251,7 @@ impl ChainSync {
} }
#[allow(for_kv_map)] // Because it's not possible to get `values_mut()` #[cfg_attr(feature="dev", allow(for_kv_map))] // Because it's not possible to get `values_mut()`
/// Rest sync. Clear all downloaded data but keep the queue /// Rest sync. Clear all downloaded data but keep the queue
fn reset(&mut self) { fn reset(&mut self) {
self.downloading_headers.clear(); self.downloading_headers.clear();
@ -319,7 +319,7 @@ impl ChainSync {
Ok(()) Ok(())
} }
#[allow(cyclomatic_complexity)] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
/// Called by peer once it has new block headers during sync /// Called by peer once it has new block headers during sync
fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> {
self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders); self.reset_peer_asking(peer_id, PeerAsking::BlockHeaders);

View File

@ -15,11 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(plugin)] #![cfg_attr(feature="dev", feature(plugin))]
#![feature(augmented_assignments)] #![cfg_attr(feature="dev", plugin(clippy))]
#![plugin(clippy)]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![allow(clone_on_copy)] #![cfg_attr(feature="dev", allow(clone_on_copy))]
//! Blockchain sync module //! Blockchain sync module
//! Implements ethereum protocol version 63 as specified here: //! Implements ethereum protocol version 63 as specified here:
@ -59,7 +59,7 @@ use std::ops::*;
use std::sync::*; use std::sync::*;
use ethcore::client::Client; use ethcore::client::Client;
use util::network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId}; use util::network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId};
use util::io::TimerToken; use util::TimerToken;
use chain::ChainSync; use chain::ChainSync;
use ethcore::service::SyncMessage; use ethcore::service::SyncMessage;
use io::NetSyncIo; use io::NetSyncIo;

View File

@ -213,7 +213,10 @@ impl BlockChainClient for TestBlockChainClient {
} }
let len = self.numbers.read().unwrap().len(); let len = self.numbers.read().unwrap().len();
if number == len { if number == len {
*self.difficulty.write().unwrap().deref_mut() += header.difficulty; {
let mut difficulty = self.difficulty.write().unwrap();
*difficulty.deref_mut() = *difficulty.deref() + header.difficulty;
}
mem::replace(self.last_hash.write().unwrap().deref_mut(), h.clone()); mem::replace(self.last_hash.write().unwrap().deref_mut(), h.clone());
self.blocks.write().unwrap().insert(h.clone(), b); self.blocks.write().unwrap().insert(h.clone(), b);
self.numbers.write().unwrap().insert(number, h.clone()); self.numbers.write().unwrap().insert(number, h.clone());

View File

@ -20,13 +20,17 @@ lazy_static = "0.1"
eth-secp256k1 = { git = "https://github.com/arkpar/rust-secp256k1.git" } eth-secp256k1 = { git = "https://github.com/arkpar/rust-secp256k1.git" }
rust-crypto = "0.2.34" rust-crypto = "0.2.34"
elastic-array = "0.4" elastic-array = "0.4"
heapsize = "0.2" heapsize = "0.3"
itertools = "0.4" itertools = "0.4"
crossbeam = "0.2" crossbeam = "0.2"
slab = { git = "https://github.com/arkpar/slab.git" } slab = { git = "https://github.com/arkpar/slab.git" }
sha3 = { path = "sha3" } sha3 = { path = "sha3" }
serde = "0.6.7" serde = "0.6.7"
clippy = "0.0.41" clippy = { version = "0.0.42", optional = true }
json-tests = { path = "json-tests" } json-tests = { path = "json-tests" }
target_info = "0.1.0" target_info = "0.1.0"
igd = "0.4.2" igd = "0.4.2"
[features]
default = []
dev = ["clippy"]

View File

@ -141,7 +141,7 @@ impl<'a> Deref for BytesRef<'a> {
fn deref(&self) -> &[u8] { fn deref(&self) -> &[u8] {
match *self { match *self {
BytesRef::Flexible(ref bytes) => bytes, BytesRef::Flexible(ref bytes) => bytes,
BytesRef::Fixed(ref bytes) => bytes BytesRef::Fixed(ref bytes) => bytes,
} }
} }
} }
@ -150,7 +150,7 @@ impl <'a> DerefMut for BytesRef<'a> {
fn deref_mut(&mut self) -> &mut [u8] { fn deref_mut(&mut self) -> &mut [u8] {
match *self { match *self {
BytesRef::Flexible(ref mut bytes) => bytes, BytesRef::Flexible(ref mut bytes) => bytes,
BytesRef::Fixed(ref mut bytes) => bytes BytesRef::Fixed(ref mut bytes) => bytes,
} }
} }
} }
@ -178,6 +178,10 @@ impl BytesConvertable for Vec<u8> {
fn bytes(&self) -> &[u8] { self } fn bytes(&self) -> &[u8] { self }
} }
impl BytesConvertable for String {
fn bytes(&self) -> &[u8] { &self.as_bytes() }
}
macro_rules! impl_bytes_convertable_for_array { macro_rules! impl_bytes_convertable_for_array {
($zero: expr) => (); ($zero: expr) => ();
($len: expr, $($idx: expr),*) => { ($len: expr, $($idx: expr),*) => {
@ -252,6 +256,49 @@ impl<T> Populatable for [T] where T: Sized {
} }
} }
#[derive(Debug)]
/// Bytes array deserialization error
pub enum FromBytesError {
/// Not enough bytes for the requested type
NotLongEnough,
/// Too many bytes for the requested type
TooLong,
}
/// Value that can be serialized from bytes array
pub trait FromRawBytes : Sized {
/// function that will instantiate and initialize object from slice
fn from_bytes(d: &[u8]) -> Result<Self, FromBytesError>;
}
impl<T> FromRawBytes for T where T: Sized + FixedHash {
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
use std::mem;
use std::cmp::Ordering;
match bytes.len().cmp(&mem::size_of::<T>()) {
Ordering::Less => return Err(FromBytesError::NotLongEnough),
Ordering::Greater => return Err(FromBytesError::TooLong),
Ordering::Equal => ()
};
let mut res: Self = unsafe { mem::uninitialized() };
res.copy_raw(bytes);
Ok(res)
}
}
impl FromRawBytes for String {
fn from_bytes(bytes: &[u8]) -> Result<String, FromBytesError> {
Ok(::std::str::from_utf8(bytes).unwrap().to_owned())
}
}
impl FromRawBytes for Vec<u8> {
fn from_bytes(bytes: &[u8]) -> Result<Vec<u8>, FromBytesError> {
Ok(bytes.clone().to_vec())
}
}
#[test] #[test]
fn fax_raw() { fn fax_raw() {
let mut x = [255u8; 4]; let mut x = [255u8; 4];

View File

@ -413,15 +413,6 @@ macro_rules! impl_hash {
} }
} }
/// Moving BitOrAssign
impl<'a> BitOrAssign<&'a $from> for $from {
fn bitor_assign(&mut self, rhs: &'a Self) {
for i in 0..$size {
self.0[i] = self.0[i] | rhs.0[i];
}
}
}
/// BitAnd on references /// BitAnd on references
impl <'a> BitAnd for &'a $from { impl <'a> BitAnd for &'a $from {
type Output = $from; type Output = $from;

View File

@ -27,7 +27,7 @@ const MAX_CACHE_USAGE_TRACK: usize = 128;
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum CryptoCipherType { pub enum CryptoCipherType {
/// aes-128-ctr with 128-bit initialisation vector(iv) /// aes-128-ctr with 128-bit initialisation vector(iv)
Aes128Ctr(U128) Aes128Ctr(H128)
} }
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
@ -168,6 +168,8 @@ pub struct KeyFileCrypto {
pub cipher_text: Bytes, pub cipher_text: Bytes,
/// Password derived key generator function settings. /// Password derived key generator function settings.
pub kdf: KeyFileKdf, pub kdf: KeyFileKdf,
/// Mac
pub mac: H256
} }
impl KeyFileCrypto { impl KeyFileCrypto {
@ -182,7 +184,7 @@ impl KeyFileCrypto {
Some("aes-128-ctr") => CryptoCipherType::Aes128Ctr( Some("aes-128-ctr") => CryptoCipherType::Aes128Ctr(
match try!(as_object.get("cipherparams").ok_or(CryptoParseError::NoCipherParameters)).as_object() { match try!(as_object.get("cipherparams").ok_or(CryptoParseError::NoCipherParameters)).as_object() {
None => { return Err(CryptoParseError::NoCipherParameters); }, None => { return Err(CryptoParseError::NoCipherParameters); },
Some(cipher_param) => match U128::from_str(match cipher_param["iv"].as_string() { Some(cipher_param) => match H128::from_str(match cipher_param["iv"].as_string() {
None => { return Err(CryptoParseError::NoInitialVector); }, None => { return Err(CryptoParseError::NoInitialVector); },
Some(iv_hex_string) => iv_hex_string Some(iv_hex_string) => iv_hex_string
}) })
@ -216,22 +218,31 @@ impl KeyFileCrypto {
} }
}; };
let cipher_text = match as_object["ciphertext"].as_string() { let cipher_text = match try!(as_object.get("ciphertext").ok_or(CryptoParseError::NoCipherText)).as_string() {
None => { return Err(CryptoParseError::NoCipherText); } None => { return Err(CryptoParseError::InvalidCipherText); }
Some(text) => text Some(text) => text
}; };
let mac: H256 = match try!(as_object.get("mac").ok_or(CryptoParseError::NoMac)).as_string() {
None => { return Err(CryptoParseError::InvalidMacFormat(None)) },
Some(salt_value) => match H256::from_str(salt_value) {
Ok(salt_hex_value) => salt_hex_value,
Err(from_hex_error) => { return Err(CryptoParseError::InvalidMacFormat(Some(from_hex_error))); },
}
};
Ok(KeyFileCrypto { Ok(KeyFileCrypto {
cipher_text: Bytes::from(cipher_text), cipher_text: match FromHex::from_hex(cipher_text) { Ok(bytes) => bytes, Err(_) => { return Err(CryptoParseError::InvalidCipherText); } },
cipher_type: cipher_type, cipher_type: cipher_type,
kdf: kdf, kdf: kdf,
mac: mac,
}) })
} }
fn to_json(&self) -> Json { fn to_json(&self) -> Json {
let mut map = BTreeMap::new(); let mut map = BTreeMap::new();
match self.cipher_type { match self.cipher_type {
CryptoCipherType::Aes128Ctr(iv) => { CryptoCipherType::Aes128Ctr(ref iv) => {
map.insert("cipher".to_owned(), Json::String("aes-128-ctr".to_owned())); map.insert("cipher".to_owned(), Json::String("aes-128-ctr".to_owned()));
let mut cipher_params = BTreeMap::new(); let mut cipher_params = BTreeMap::new();
cipher_params.insert("iv".to_owned(), Json::String(format!("{:?}", iv))); cipher_params.insert("iv".to_owned(), Json::String(format!("{:?}", iv)));
@ -251,6 +262,8 @@ impl KeyFileCrypto {
KeyFileKdf::Scrypt(ref scrypt_params) => scrypt_params.to_json() KeyFileKdf::Scrypt(ref scrypt_params) => scrypt_params.to_json()
}); });
map.insert("mac".to_owned(), Json::String(format!("{:?}", self.mac)));
Json::Object(map) Json::Object(map)
} }
@ -260,7 +273,7 @@ impl KeyFileCrypto {
/// `c` - number of iterations for derived key. /// `c` - number of iterations for derived key.
/// `salt` - cryptographic site, random 256-bit hash (ensure it's crypto-random). /// `salt` - cryptographic site, random 256-bit hash (ensure it's crypto-random).
/// `iv` - initialisation vector. /// `iv` - initialisation vector.
pub fn new_pbkdf2(cipher_text: Bytes, iv: U128, salt: H256, c: u32, dk_len: u32) -> KeyFileCrypto { pub fn new_pbkdf2(cipher_text: Bytes, iv: H128, salt: H256, mac: H256, c: u32, dk_len: u32) -> KeyFileCrypto {
KeyFileCrypto { KeyFileCrypto {
cipher_type: CryptoCipherType::Aes128Ctr(iv), cipher_type: CryptoCipherType::Aes128Ctr(iv),
cipher_text: cipher_text, cipher_text: cipher_text,
@ -270,6 +283,7 @@ impl KeyFileCrypto {
c: c, c: c,
prf: Pbkdf2CryptoFunction::HMacSha256 prf: Pbkdf2CryptoFunction::HMacSha256
}), }),
mac: mac,
} }
} }
} }
@ -324,14 +338,17 @@ pub struct KeyFileContent {
#[derive(Debug)] #[derive(Debug)]
enum CryptoParseError { enum CryptoParseError {
InvalidMacFormat(Option<UtilError>),
NoMac,
NoCipherText, NoCipherText,
InvalidCipherText,
NoCipherType, NoCipherType,
InvalidJsonFormat, InvalidJsonFormat,
InvalidKdfType(Mismatch<String>), InvalidKdfType(Mismatch<String>),
InvalidCipherType(Mismatch<String>), InvalidCipherType(Mismatch<String>),
NoInitialVector, NoInitialVector,
NoCipherParameters, NoCipherParameters,
InvalidInitialVector(FromHexError), InvalidInitialVector(UtilError),
NoKdf, NoKdf,
NoKdfType, NoKdfType,
Scrypt(ScryptParseError), Scrypt(ScryptParseError),
@ -425,17 +442,17 @@ enum KeyFileLoadError {
pub struct KeyDirectory { pub struct KeyDirectory {
/// Directory path for key management. /// Directory path for key management.
path: String, path: String,
cache: HashMap<Uuid, KeyFileContent>, cache: RefCell<HashMap<Uuid, KeyFileContent>>,
cache_usage: VecDeque<Uuid>, cache_usage: RefCell<VecDeque<Uuid>>,
} }
impl KeyDirectory { impl KeyDirectory {
/// Initializes new cache directory context with a given `path` /// Initializes new cache directory context with a given `path`
pub fn new(path: &Path) -> KeyDirectory { pub fn new(path: &Path) -> KeyDirectory {
KeyDirectory { KeyDirectory {
cache: HashMap::new(), cache: RefCell::new(HashMap::new()),
path: path.to_str().expect("Initialized key directory with empty path").to_owned(), path: path.to_str().expect("Initialized key directory with empty path").to_owned(),
cache_usage: VecDeque::new(), cache_usage: RefCell::new(VecDeque::new()),
} }
} }
@ -448,25 +465,37 @@ impl KeyDirectory {
let json_bytes = json_text.into_bytes(); let json_bytes = json_text.into_bytes();
try!(file.write(&json_bytes)); try!(file.write(&json_bytes));
} }
let mut cache = self.cache.borrow_mut();
let id = key_file.id.clone(); let id = key_file.id.clone();
self.cache.insert(id.clone(), key_file); cache.insert(id.clone(), key_file);
Ok(id.clone()) Ok(id.clone())
} }
/// Returns key given by id if corresponding file exists and no load error occured. /// Returns key given by id if corresponding file exists and no load error occured.
/// Warns if any error occured during the key loading /// Warns if any error occured during the key loading
pub fn get(&mut self, id: &Uuid) -> Option<&KeyFileContent> { pub fn get(&self, id: &Uuid) -> Option<KeyFileContent> {
let path = self.key_path(id); let path = self.key_path(id);
self.cache_usage.push_back(id.clone()); {
Some(self.cache.entry(id.to_owned()).or_insert( let mut usage = self.cache_usage.borrow_mut();
usage.push_back(id.clone());
}
if !self.cache.borrow().contains_key(id) {
match KeyDirectory::load_key(&path) { match KeyDirectory::load_key(&path) {
Ok(loaded_key) => loaded_key, Ok(loaded_key) => {
self.cache.borrow_mut().insert(id.to_owned(), loaded_key);
}
Err(error) => { Err(error) => {
warn!(target: "sstore", "error loading key {:?}: {:?}", id, error); warn!(target: "sstore", "error loading key {:?}: {:?}", id, error);
return None; return None;
} }
} }
)) }
// todo: replace with Ref::map when it stabilized to avoid copies
Some(self.cache.borrow().get(id)
.expect("Key should be there, we have just inserted or checked it.")
.clone())
} }
/// Returns current path to the directory with keys /// Returns current path to the directory with keys
@ -476,29 +505,63 @@ impl KeyDirectory {
/// Removes keys that never been requested during last `MAX_USAGE_TRACK` times /// Removes keys that never been requested during last `MAX_USAGE_TRACK` times
pub fn collect_garbage(&mut self) { pub fn collect_garbage(&mut self) {
let total_usages = self.cache_usage.len(); let mut cache_usage = self.cache_usage.borrow_mut();
let total_usages = cache_usage.len();
let untracked_usages = max(total_usages as i64 - MAX_CACHE_USAGE_TRACK as i64, 0) as usize; let untracked_usages = max(total_usages as i64 - MAX_CACHE_USAGE_TRACK as i64, 0) as usize;
if untracked_usages > 0 { if untracked_usages > 0 {
self.cache_usage.drain(..untracked_usages); cache_usage.drain(..untracked_usages);
} }
if self.cache.len() <= MAX_CACHE_USAGE_TRACK { return; } if self.cache.borrow().len() <= MAX_CACHE_USAGE_TRACK { return; }
let uniqs: HashSet<&Uuid> = self.cache_usage.iter().collect(); let uniqs: HashSet<&Uuid> = cache_usage.iter().collect();
let mut removes = HashSet::new(); let removes:Vec<Uuid> = {
let cache = self.cache.borrow();
for key in self.cache.keys() { cache.keys().cloned().filter(|key| !uniqs.contains(key)).collect()
if !uniqs.contains(key) { };
removes.insert(key.clone()); if removes.is_empty() { return; }
} let mut cache = self.cache.borrow_mut();
} for key in removes { cache.remove(&key); }
for removed_key in removes { self.cache.remove(&removed_key); }
} }
/// Reports how many keys are currently cached. /// Reports how many keys are currently cached.
pub fn cache_size(&self) -> usize { pub fn cache_size(&self) -> usize {
self.cache.len() self.cache.borrow().len()
}
/// Removes key file from key directory
pub fn delete(&mut self, id: &Uuid) -> Result<(), ::std::io::Error> {
let path = self.key_path(id);
if !self.cache.borrow().contains_key(id) {
return match fs::remove_file(&path) {
Ok(_) => {
self.cache.borrow_mut().remove(&id);
Ok(())
},
Err(e) => Err(e)
};
}
Ok(())
}
/// Enumerates all keys in the directory
pub fn list(&self) -> Result<Vec<Uuid>, ::std::io::Error> {
let mut result = Vec::new();
for entry in try!(fs::read_dir(&self.path)) {
let entry = try!(entry);
if !try!(fs::metadata(entry.path())).is_dir() {
match entry.file_name().to_str() {
Some(ref name) => {
if let Ok(uuid) = uuid_from_string(name) { result.push(uuid); }
},
None => { continue; }
};
}
}
Ok(result)
} }
fn key_path(&self, id: &Uuid) -> PathBuf { fn key_path(&self, id: &Uuid) -> PathBuf {
@ -820,14 +883,14 @@ mod file_tests {
#[test] #[test]
fn can_create_key_with_new_id() { fn can_create_key_with_new_id() {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32)); let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32));
assert!(!uuid_to_string(&key.id).is_empty()); assert!(!uuid_to_string(&key.id).is_empty());
} }
#[test] #[test]
fn can_load_json_from_itself() { fn can_load_json_from_itself() {
let cipher_text: Bytes = FromHex::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaa22222222222222222222222").unwrap(); let cipher_text: Bytes = FromHex::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaa22222222222222222222222").unwrap();
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32)); let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32));
let json = key.to_json(); let json = key.to_json();
let loaded_key = KeyFileContent::from_json(&json).unwrap(); let loaded_key = KeyFileContent::from_json(&json).unwrap();
@ -985,7 +1048,7 @@ mod directory_tests {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let temp_path = RandomTempPath::create_dir(); let temp_path = RandomTempPath::create_dir();
let mut directory = KeyDirectory::new(&temp_path.as_path()); let mut directory = KeyDirectory::new(&temp_path.as_path());
let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32))).unwrap(); let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32))).unwrap();
let path = directory.key_path(&uuid); let path = directory.key_path(&uuid);
let key = KeyDirectory::load_key(&path).unwrap(); let key = KeyDirectory::load_key(&path).unwrap();
@ -1001,7 +1064,7 @@ mod directory_tests {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let mut keys = Vec::new(); let mut keys = Vec::new();
for _ in 0..1000 { for _ in 0..1000 {
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), U128::zero(), H256::random(), 32, 32)); let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32));
keys.push(directory.save(key).unwrap()); keys.push(directory.save(key).unwrap());
} }
@ -1021,7 +1084,7 @@ mod directory_tests {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let mut keys = Vec::new(); let mut keys = Vec::new();
for _ in 0..1000 { for _ in 0..1000 {
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), U128::zero(), H256::random(), 32, 32)); let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32));
keys.push(directory.save(key).unwrap()); keys.push(directory.save(key).unwrap());
} }
@ -1033,6 +1096,14 @@ mod directory_tests {
// since all keys are different, should be exactly MAX_CACHE_USAGE_TRACK // since all keys are different, should be exactly MAX_CACHE_USAGE_TRACK
assert_eq!(MAX_CACHE_USAGE_TRACK, directory.cache_size()) assert_eq!(MAX_CACHE_USAGE_TRACK, directory.cache_size())
} }
#[test]
fn collects_garbage_on_empty() {
let temp_path = RandomTempPath::create_dir();
let mut directory = KeyDirectory::new(&temp_path.as_path());
directory.collect_garbage();
assert_eq!(0, directory.cache_size())
}
} }
#[cfg(test)] #[cfg(test)]
@ -1054,7 +1125,7 @@ mod specs {
let temp_path = RandomTempPath::create_dir(); let temp_path = RandomTempPath::create_dir();
let mut directory = KeyDirectory::new(&temp_path.as_path()); let mut directory = KeyDirectory::new(&temp_path.as_path());
let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, U128::zero(), H256::random(), 32, 32))); let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32)));
assert!(uuid.is_ok()); assert!(uuid.is_ok());
} }
@ -1064,7 +1135,7 @@ mod specs {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let temp_path = RandomTempPath::create_dir(); let temp_path = RandomTempPath::create_dir();
let mut directory = KeyDirectory::new(&temp_path.as_path()); let mut directory = KeyDirectory::new(&temp_path.as_path());
let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), U128::zero(), H256::random(), 32, 32))).unwrap(); let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32))).unwrap();
let key = directory.get(&uuid).unwrap(); let key = directory.get(&uuid).unwrap();
@ -1079,10 +1150,25 @@ mod specs {
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let mut keys = Vec::new(); let mut keys = Vec::new();
for _ in 0..10 { for _ in 0..10 {
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), U128::zero(), H256::random(), 32, 32)); let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32));
keys.push(directory.save(key).unwrap()); keys.push(directory.save(key).unwrap());
} }
assert_eq!(10, keys.len()) assert_eq!(10, keys.len())
} }
#[test]
fn can_list_keys() {
let temp_path = RandomTempPath::create_dir();
let mut directory = KeyDirectory::new(&temp_path.as_path());
let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap();
let mut keys = Vec::new();
for _ in 0..33 {
let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32));
keys.push(directory.save(key).unwrap());
}
assert_eq!(33, directory.list().unwrap().len());
}
} }

View File

@ -17,3 +17,4 @@
//! Key management module //! Key management module
pub mod directory; pub mod directory;
pub mod store;

297
util/src/keys/store.rs Normal file
View File

@ -0,0 +1,297 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Secret Store
use keys::directory::*;
use common::*;
use rcrypto::pbkdf2::*;
use rcrypto::hmac::*;
use crypto;
const KEY_LENGTH: u32 = 32;
const KEY_ITERATIONS: u32 = 4096;
const KEY_LENGTH_AES: u32 = KEY_LENGTH/2;
const KEY_LENGTH_USIZE: usize = KEY_LENGTH as usize;
const KEY_LENGTH_AES_USIZE: usize = KEY_LENGTH_AES as usize;
/// Encrypted hash-map, each request should contain password
pub trait EncryptedHashMap<Key: Hash + Eq> {
/// Returns existing value for the key, if any
fn get<Value: FromRawBytes + BytesConvertable>(&self, key: &Key, password: &str) -> Result<Value, EncryptedHashMapError>;
/// Insert new encrypted key-value and returns previous if there was any
fn insert<Value: FromRawBytes + BytesConvertable>(&mut self, key: Key, value: Value, password: &str) -> Option<Value>;
/// Removes key-value by key and returns the removed one, if any exists and password was provided
fn remove<Value: FromRawBytes + BytesConvertable> (&mut self, key: &Key, password: Option<&str>) -> Option<Value>;
/// Deletes key-value by key and returns if the key-value existed
fn delete(&mut self, key: &Key) -> bool {
self.remove::<Bytes>(key, None).is_some()
}
}
/// Error retrieving value from encrypted hashmap
#[derive(Debug)]
pub enum EncryptedHashMapError {
/// Encryption failed
InvalidPassword,
/// No key in the hashmap
UnknownIdentifier,
/// Stored value is not well formed for the requested type
InvalidValueFormat(FromBytesError),
}
/// Represent service for storing encrypted arbitrary data
pub struct SecretStore {
directory: KeyDirectory
}
impl SecretStore {
/// new instance of Secret Store
pub fn new() -> SecretStore {
let mut path = ::std::env::home_dir().expect("Failed to get home dir");
path.push(".keys");
SecretStore {
directory: KeyDirectory::new(&path)
}
}
#[cfg(test)]
fn new_test(path: &::tests::helpers::RandomTempPath) -> SecretStore {
SecretStore {
directory: KeyDirectory::new(path.as_path())
}
}
}
fn derive_key_iterations(password: &str, salt: &H256, c: u32) -> (Bytes, Bytes) {
let mut h_mac = Hmac::new(::rcrypto::sha2::Sha256::new(), password.as_bytes());
let mut derived_key = vec![0u8; KEY_LENGTH_USIZE];
pbkdf2(&mut h_mac, &salt.as_slice(), c, &mut derived_key);
let derived_right_bits = &derived_key[0..KEY_LENGTH_AES_USIZE];
let derived_left_bits = &derived_key[KEY_LENGTH_AES_USIZE..KEY_LENGTH_USIZE];
(derived_right_bits.to_vec(), derived_left_bits.to_vec())
}
fn derive_key(password: &str, salt: &H256) -> (Bytes, Bytes) {
derive_key_iterations(password, salt, KEY_ITERATIONS)
}
fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Bytes {
let mut mac = vec![0u8; KEY_LENGTH_AES_USIZE + cipher_text.len()];
mac[0..KEY_LENGTH_AES_USIZE].clone_from_slice(derived_left_bits);
mac[KEY_LENGTH_AES_USIZE..cipher_text.len()+KEY_LENGTH_AES_USIZE].clone_from_slice(cipher_text);
mac
}
impl EncryptedHashMap<H128> for SecretStore {
fn get<Value: FromRawBytes + BytesConvertable>(&self, key: &H128, password: &str) -> Result<Value, EncryptedHashMapError> {
match self.directory.get(key) {
Some(key_file) => {
let decrypted_bytes = match key_file.crypto.kdf {
KeyFileKdf::Pbkdf2(ref params) => {
let (derived_left_bits, derived_right_bits) = derive_key_iterations(password, &params.salt, params.c);
if derive_mac(&derived_right_bits, &key_file.crypto.cipher_text)
.sha3() != key_file.crypto.mac { return Err(EncryptedHashMapError::InvalidPassword); }
let mut val = vec![0u8; key_file.crypto.cipher_text.len()];
match key_file.crypto.cipher_type {
CryptoCipherType::Aes128Ctr(ref iv) => {
crypto::aes::decrypt(&derived_left_bits, &iv.as_slice(), &key_file.crypto.cipher_text, &mut val);
}
}
val
}
_ => { unimplemented!(); }
};
match Value::from_bytes(&decrypted_bytes) {
Ok(value) => Ok(value),
Err(bytes_error) => Err(EncryptedHashMapError::InvalidValueFormat(bytes_error))
}
},
None => Err(EncryptedHashMapError::UnknownIdentifier)
}
}
fn insert<Value: FromRawBytes + BytesConvertable>(&mut self, key: H128, value: Value, password: &str) -> Option<Value> {
let previous = if let Ok(previous_value) = self.get(&key, password) { Some(previous_value) } else { None };
// crypto random initiators
let salt = H256::random();
let iv = H128::random();
// two parts of derived key
// DK = [ DK[0..15] DK[16..31] ] = [derived_left_bits, derived_right_bits]
let (derived_left_bits, derived_right_bits) = derive_key(password, &salt);
let mut cipher_text = vec![0u8; value.as_slice().len()];
// aes-128-ctr with initial vector of iv
crypto::aes::encrypt(&derived_left_bits, &iv.clone(), &value.as_slice(), &mut cipher_text);
// KECCAK(DK[16..31] ++ <ciphertext>), where DK[16..31] - derived_right_bits
let mac = derive_mac(&derived_right_bits, &cipher_text.clone()).sha3();
let mut key_file = KeyFileContent::new(
KeyFileCrypto::new_pbkdf2(
cipher_text,
iv,
salt,
mac,
KEY_ITERATIONS,
KEY_LENGTH));
key_file.id = key;
if let Err(io_error) = self.directory.save(key_file) {
warn!("Error saving key file: {:?}", io_error);
}
previous
}
fn remove<Value: FromRawBytes + BytesConvertable>(&mut self, key: &H128, password: Option<&str>) -> Option<Value> {
let previous = if let Some(pass) = password {
if let Ok(previous_value) = self.get(&key, pass) { Some(previous_value) } else { None }
}
else { None };
if let Err(io_error) = self.directory.delete(key) {
warn!("Error saving key file: {:?}", io_error);
}
previous
}
}
#[cfg(test)]
mod vector_tests {
use super::{derive_mac,derive_key_iterations};
use common::*;
#[test]
fn mac_vector() {
let password = "testpassword";
let salt = H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap();
let cipher_text = FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap();
let iterations = 262144u32;
let (derived_left_bits, derived_right_bits) = derive_key_iterations(password, &salt, iterations);
assert_eq!("f06d69cdc7da0faffb1008270bca38f5", derived_left_bits.to_hex());
assert_eq!("e31891a3a773950e6d0fea48a7188551", derived_right_bits.to_hex());
let mac_body = derive_mac(&derived_right_bits, &cipher_text);
assert_eq!("e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", mac_body.to_hex());
let mac = mac_body.sha3();
assert_eq!("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2", format!("{:?}", mac));
}
}
#[cfg(test)]
mod tests {
use super::*;
use tests::helpers::*;
use common::*;
#[test]
fn can_insert() {
let temp = RandomTempPath::create_dir();
let mut sstore = SecretStore::new_test(&temp);
let id = H128::random();
sstore.insert(id.clone(), "Cat".to_owned(), "pass");
assert!(sstore.get::<String>(&id, "pass").is_ok());
}
#[test]
fn can_get_fail() {
let temp = RandomTempPath::create_dir();
{
use keys::directory::{KeyFileContent, KeyFileCrypto};
let mut write_sstore = SecretStore::new_test(&temp);
write_sstore.directory.save(
KeyFileContent::new(
KeyFileCrypto::new_pbkdf2(
FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(),
H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(),
H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(),
H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(),
262144,
32)))
.unwrap();
}
let sstore = SecretStore::new_test(&temp);
if let Ok(_) = sstore.get::<Bytes>(&H128::from_str("3198bc9c66725ab3d9954942343ae5b6").unwrap(), "testpassword") {
panic!("should be error loading key, we requested the wrong key");
}
}
fn pregenerate_keys(temp: &RandomTempPath, count: usize) -> Vec<H128> {
use keys::directory::{KeyFileContent, KeyFileCrypto};
let mut write_sstore = SecretStore::new_test(&temp);
let mut result = Vec::new();
for _ in 0..count {
result.push(write_sstore.directory.save(
KeyFileContent::new(
KeyFileCrypto::new_pbkdf2(
FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(),
H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(),
H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(),
H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(),
262144,
32)))
.unwrap());
}
result
}
#[test]
fn can_get() {
let temp = RandomTempPath::create_dir();
let key_id = {
use keys::directory::{KeyFileContent, KeyFileCrypto};
let mut write_sstore = SecretStore::new_test(&temp);
write_sstore.directory.save(
KeyFileContent::new(
KeyFileCrypto::new_pbkdf2(
FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(),
H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(),
H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(),
H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(),
262144,
32)))
.unwrap()
};
let sstore = SecretStore::new_test(&temp);
if let Err(e) = sstore.get::<Bytes>(&key_id, "testpassword") {
panic!("got no key: {:?}", e);
}
}
#[test]
fn can_delete() {
let temp = RandomTempPath::create_dir();
let keys = pregenerate_keys(&temp, 5);
let mut sstore = SecretStore::new_test(&temp);
sstore.delete(&keys[2]);
assert_eq!(4, sstore.directory.list().unwrap().len())
}
}

View File

@ -15,21 +15,18 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(op_assign_traits)] #![cfg_attr(feature="dev", feature(plugin))]
#![feature(augmented_assignments)] #![cfg_attr(feature="dev", plugin(clippy))]
#![feature(associated_consts)]
#![feature(plugin)]
#![feature(catch_panic)]
// Clippy settings // Clippy settings
#![plugin(clippy)]
// TODO [todr] not really sure // TODO [todr] not really sure
#![allow(needless_range_loop)] #![cfg_attr(feature="dev", allow(needless_range_loop))]
// Shorter than if-else // Shorter than if-else
#![allow(match_bool)] #![cfg_attr(feature="dev", allow(match_bool))]
// We use that to be more explicit about handled cases // We use that to be more explicit about handled cases
#![allow(match_same_arms)] #![cfg_attr(feature="dev", allow(match_same_arms))]
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref. // Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
#![allow(clone_on_copy)] #![cfg_attr(feature="dev", allow(clone_on_copy))]
//! Ethcore-util library //! Ethcore-util library
//! //!

View File

@ -138,7 +138,7 @@ impl Discovery {
ret ret
} }
#[allow(cyclomatic_complexity)] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
fn nearest_node_entries<'b>(source: &NodeId, target: &NodeId, buckets: &'b [NodeBucket]) -> Vec<&'b NodeId> fn nearest_node_entries<'b>(source: &NodeId, target: &NodeId, buckets: &'b [NodeBucket]) -> Vec<&'b NodeId>
{ {
// send ALPHA FindNode packets to nodes we know, closest to target // send ALPHA FindNode packets to nodes we know, closest to target

View File

@ -471,7 +471,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
} }
} }
#[allow(single_match)] #[cfg_attr(feature="dev", allow(single_match))]
fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) { fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) {
if self.have_session(id) if self.have_session(id)
{ {
@ -501,7 +501,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
self.create_connection(socket, Some(id), io); self.create_connection(socket, Some(id), io);
} }
#[allow(block_in_if_condition_stmt)] #[cfg_attr(feature="dev", allow(block_in_if_condition_stmt))]
fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage<Message>>) { fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage<Message>>) {
let nonce = self.info.write().unwrap().next_nonce(); let nonce = self.info.write().unwrap().next_nonce();
let mut connections = self.connections.write().unwrap(); let mut connections = self.connections.write().unwrap();
@ -532,7 +532,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
io.update_registration(TCP_ACCEPT).expect("Error registering TCP listener"); io.update_registration(TCP_ACCEPT).expect("Error registering TCP listener");
} }
#[allow(single_match)] #[cfg_attr(feature="dev", allow(single_match))]
fn connection_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) { fn connection_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
let mut create_session = false; let mut create_session = false;
let mut kill = false; let mut kill = false;

View File

@ -40,6 +40,18 @@ pub trait MayPanic {
fn on_panic<F>(&self, closure: F) where F: OnPanicListener; fn on_panic<F>(&self, closure: F) where F: OnPanicListener;
} }
struct PanicGuard<'a> {
handler: &'a PanicHandler,
}
impl<'a> Drop for PanicGuard<'a> {
fn drop(&mut self) {
if thread::panicking() {
self.handler.notify_all("Panic!".to_owned());
}
}
}
/// Structure that allows to catch panics and notify listeners /// Structure that allows to catch panics and notify listeners
pub struct PanicHandler { pub struct PanicHandler {
listeners: Mutex<Vec<Box<OnPanicListener>>> listeners: Mutex<Vec<Box<OnPanicListener>>>
@ -60,19 +72,12 @@ impl PanicHandler {
/// Invoke closure and catch any possible panics. /// Invoke closure and catch any possible panics.
/// In case of panic notifies all listeners about it. /// In case of panic notifies all listeners about it.
#[allow(deprecated)] #[cfg_attr(feature="dev", allow(deprecated))]
// TODO [todr] catch_panic is deprecated but panic::recover has different bounds (not allowing mutex) // TODO [todr] catch_panic is deprecated but panic::recover has different bounds (not allowing mutex)
pub fn catch_panic<G, R>(&self, g: G) -> thread::Result<R> where G: FnOnce() -> R + Send + 'static { pub fn catch_panic<G, R>(&self, g: G) -> thread::Result<R> where G: FnOnce() -> R + Send + 'static {
let result = thread::catch_panic(g); let guard = PanicGuard { handler: self };
let result = g();
if let Err(ref e) = result { Ok(result)
let res = convert_to_string(e);
if let Some(r) = res {
self.notify_all(r);
}
}
result
} }
fn notify_all(&self, r: String) { fn notify_all(&self, r: String) {
@ -111,6 +116,7 @@ fn convert_to_string(t: &Box<Any + Send>) -> Option<String> {
} }
#[test] #[test]
#[ignore] // panic forwarding doesnt work on the same thread in beta
fn should_notify_listeners_about_panic () { fn should_notify_listeners_about_panic () {
use std::sync::RwLock; use std::sync::RwLock;
// given // given
@ -127,6 +133,7 @@ fn should_notify_listeners_about_panic () {
} }
#[test] #[test]
#[ignore] // panic forwarding doesnt work on the same thread in beta
fn should_notify_listeners_about_panic_when_string_is_dynamic () { fn should_notify_listeners_about_panic_when_string_is_dynamic () {
use std::sync::RwLock; use std::sync::RwLock;
// given // given
@ -164,6 +171,7 @@ fn should_notify_listeners_about_panic_in_other_thread () {
} }
#[test] #[test]
#[ignore] // panic forwarding doesnt work on the same thread in beta
fn should_forward_panics () { fn should_forward_panics () {
use std::sync::RwLock; use std::sync::RwLock;
// given // given

View File

@ -232,12 +232,12 @@ impl_uint_from_bytes!(u64);
impl_uint_from_bytes!(usize); impl_uint_from_bytes!(usize);
macro_rules! impl_uint_from_bytes { macro_rules! impl_uint_from_bytes {
($name: ident) => { ($name: ident, $size: expr) => {
impl FromBytes for $name { impl FromBytes for $name {
fn from_bytes(bytes: &[u8]) -> FromBytesResult<$name> { fn from_bytes(bytes: &[u8]) -> FromBytesResult<$name> {
if !bytes.is_empty() && bytes[0] == 0 { if !bytes.is_empty() && bytes[0] == 0 {
Err(FromBytesError::ZeroPrefixedInt) Err(FromBytesError::ZeroPrefixedInt)
} else if bytes.len() <= $name::SIZE { } else if bytes.len() <= $size {
Ok($name::from(bytes)) Ok($name::from(bytes))
} else { } else {
Err(FromBytesError::DataIsTooLong) Err(FromBytesError::DataIsTooLong)
@ -247,8 +247,8 @@ macro_rules! impl_uint_from_bytes {
} }
} }
impl_uint_from_bytes!(U256); impl_uint_from_bytes!(U256, 32);
impl_uint_from_bytes!(U128); impl_uint_from_bytes!(U128, 16);
impl <T>FromBytes for T where T: FixedHash { impl <T>FromBytes for T where T: FixedHash {
fn from_bytes(bytes: &[u8]) -> FromBytesResult<T> { fn from_bytes(bytes: &[u8]) -> FromBytesResult<T> {

View File

@ -429,7 +429,6 @@ impl<T> Decodable for Option<T> where T: Decodable {
macro_rules! impl_array_decodable { macro_rules! impl_array_decodable {
($index_type:ty, $len:expr ) => ( ($index_type:ty, $len:expr ) => (
impl<T> Decodable for [T; $len] where T: Decodable { impl<T> Decodable for [T; $len] where T: Decodable {
#[allow(len_zero)]
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let decoders = decoder.as_rlp(); let decoders = decoder.as_rlp();

View File

@ -16,13 +16,13 @@
//! Semantic version formatting and comparing. //! Semantic version formatting and comparing.
/// A version value with strict meaning. Use `to_u32` to convert to a simple integer. /// A version value with strict meaning. Use `as_u32` to convert to a simple integer.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::semantic_version::*; /// use util::semantic_version::*;
/// ///
/// fn main() { /// fn main() {
/// assert_eq!(SemanticVersion::new(1, 2, 3).as_u32(), 0x010203); /// assert_eq!(SemanticVersion::new(1, 2, 3).as_u32(), 0x010203);
/// } /// }

View File

@ -54,7 +54,7 @@ pub struct TrieDB<'db> {
pub hash_count: usize, pub hash_count: usize,
} }
#[allow(wrong_self_convention)] #[cfg_attr(feature="dev", allow(wrong_self_convention))]
impl<'db> TrieDB<'db> { impl<'db> TrieDB<'db> {
/// Create a new trie with the backing database `db` and `root` /// Create a new trie with the backing database `db` and `root`
/// Panics, if `root` does not exist /// Panics, if `root` does not exist

View File

@ -66,7 +66,7 @@ enum MaybeChanged<'a> {
Changed(Bytes), Changed(Bytes),
} }
#[allow(wrong_self_convention)] #[cfg_attr(feature="dev", allow(wrong_self_convention))]
impl<'db> TrieDBMut<'db> { impl<'db> TrieDBMut<'db> {
/// Create a new trie with the backing database `db` and empty `root` /// Create a new trie with the backing database `db` and empty `root`
/// Initialise to the state entailed by the genesis block. /// Initialise to the state entailed by the genesis block.
@ -350,7 +350,7 @@ impl<'db> TrieDBMut<'db> {
} }
} }
#[allow(cyclomatic_complexity)] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
/// Determine the RLP of the node, assuming we're inserting `partial` into the /// Determine the RLP of the node, assuming we're inserting `partial` into the
/// node currently of data `old`. This will *not* delete any hash of `old` from the database; /// node currently of data `old`. This will *not* delete any hash of `old` from the database;
/// it will just return the new RLP that includes the new node. /// it will just return the new RLP that includes the new node.

View File

@ -78,9 +78,6 @@ macro_rules! panic_on_overflow {
/// Large, fixed-length unsigned integer type. /// Large, fixed-length unsigned integer type.
pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug + fmt::Display + PartialOrd + Ord + PartialEq + Eq + Hash { pub trait Uint: Sized + Default + FromStr + From<u64> + FromJson + fmt::Debug + fmt::Display + PartialOrd + Ord + PartialEq + Eq + Hash {
/// Size of this type.
const SIZE: usize;
/// Returns new instance equalling zero. /// Returns new instance equalling zero.
fn zero() -> Self; fn zero() -> Self;
/// Returns new instance equalling one. /// Returns new instance equalling one.
@ -148,8 +145,6 @@ macro_rules! construct_uint {
pub struct $name(pub [u64; $n_words]); pub struct $name(pub [u64; $n_words]);
impl Uint for $name { impl Uint for $name {
const SIZE: usize = $n_words * 8;
type FromDecStrErr = FromHexError; type FromDecStrErr = FromHexError;
/// TODO: optimize, throw appropriate err /// TODO: optimize, throw appropriate err
@ -634,66 +629,6 @@ macro_rules! construct_uint {
// TODO: optimise and traitify. // TODO: optimise and traitify.
impl<'a> AddAssign<&'a $name> for $name {
fn add_assign(&mut self, other: &'a Self) {
*self = self.add(*other);
}
}
impl<'a> SubAssign<&'a $name> for $name {
fn sub_assign(&mut self, other: &'a Self) {
*self = self.sub(*other);
}
}
impl<'a> MulAssign<&'a $name> for $name {
fn mul_assign(&mut self, other: &'a Self) {
*self = self.mul(*other);
}
}
impl<'a> DivAssign<&'a $name> for $name {
fn div_assign(&mut self, other: &'a Self) {
*self = self.div(*other);
}
}
impl<'a> RemAssign<&'a $name> for $name {
fn rem_assign(&mut self, other: &'a Self) {
*self = self.rem(*other);
}
}
impl AddAssign<$name> for $name {
fn add_assign(&mut self, other: Self) {
*self = self.add(other);
}
}
impl SubAssign<$name> for $name {
fn sub_assign(&mut self, other: Self) {
*self = self.sub(other);
}
}
impl MulAssign<$name> for $name {
fn mul_assign(&mut self, other: Self) {
*self = self.mul(other);
}
}
impl DivAssign<$name> for $name {
fn div_assign(&mut self, other: Self) {
*self = self.div(other);
}
}
impl RemAssign<$name> for $name {
fn rem_assign(&mut self, other: Self) {
*self = self.rem(other);
}
}
impl BitAnd<$name> for $name { impl BitAnd<$name> for $name {
type Output = $name; type Output = $name;
@ -964,37 +899,6 @@ mod tests {
use uint::{Uint, U128, U256, U512}; use uint::{Uint, U128, U256, U512};
use std::str::FromStr; use std::str::FromStr;
#[test]
pub fn assign_ops() {
let x: U256 = x!(69);
let y: U256 = x!(42);
{
let mut z = x;
z += y;
assert_eq!(z, x + y);
}
{
let mut z = x;
z -= y;
assert_eq!(z, x - y);
}
{
let mut z = x;
z *= y;
assert_eq!(z, x * y);
}
{
let mut z = x;
z /= y;
assert_eq!(z, x / y);
}
{
let mut z = x;
z %= y;
assert_eq!(z, x % y);
}
}
#[test] #[test]
pub fn uint256_from() { pub fn uint256_from() {
let e = U256([10, 0, 0, 0]); let e = U256([10, 0, 0, 0]);