Merge branch 'master' of github.com:ethcore/parity into db
This commit is contained in:
commit
f15275bb5b
15
.travis.yml
15
.travis.yml
@ -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
186
Cargo.lock
generated
@ -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"
|
||||||
|
@ -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"
|
||||||
|
34
README.md
34
README.md
@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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" }
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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 = []
|
||||||
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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(¤t_gas, &gas_cost));
|
try!(self.verify_gas(¤t_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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
//!
|
//!
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
@ -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.
|
||||||
|
@ -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()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
154
parity/main.rs
154
parity/main.rs
@ -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 {
|
||||||
|
@ -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
29
rpc/build.rs
Normal 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();
|
||||||
|
}
|
@ -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
30
rpc/src/lib.rs.in
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"]
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
@ -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"]
|
||||||
|
@ -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];
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
297
util/src/keys/store.rs
Normal 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, ¶ms.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())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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
|
||||||
//!
|
//!
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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> {
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
/// }
|
/// }
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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]);
|
||||||
|
Loading…
Reference in New Issue
Block a user