Merge branch 'master' into td-evm-json
This commit is contained in:
commit
4ac406da6b
@ -93,7 +93,7 @@ linux-snap:
|
||||
paths:
|
||||
- scripts/parity_*_amd64.snap
|
||||
name: "stable-x86_64-unknown-snap-gnu_parity"
|
||||
allow_failure: true
|
||||
allow_failure: true
|
||||
linux-stable-debian:
|
||||
stage: build
|
||||
image: parity/rust-debian:gitlab-ci
|
||||
@ -244,7 +244,7 @@ linux-i686:
|
||||
- strip target/$PLATFORM/release/parity
|
||||
- strip target/$PLATFORM/release/parity-evm
|
||||
- strip target/$PLATFORM/release/ethstore
|
||||
- strip target/$PLATFORM/release/ethkey
|
||||
- strip target/$PLATFORM/release/ethkey
|
||||
- strip target/$PLATFORM/release/parity
|
||||
- md5sum target/$PLATFORM/release/parity > parity.md5
|
||||
- export SHA3=$(target/$PLATFORM/release/parity tools hash target/$PLATFORM/release/parity)
|
||||
@ -627,8 +627,12 @@ js-test:
|
||||
- git submodule update --init --recursive
|
||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
|
||||
- export JS_OLD_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js-old/ | wc -l)
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) deps install since no JS files modified."; else ./js-old/scripts/install-deps.sh;fi
|
||||
|
||||
script:
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) lint since no JS files modified."; else ./js-old/scripts/lint.sh && ./js-old/scripts/test.sh && ./js-old/scripts/build.sh; fi
|
||||
tags:
|
||||
- rust
|
||||
- rust-stable
|
||||
@ -679,10 +683,17 @@ js-release:
|
||||
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
|
||||
- echo $JS_FILES_MODIFIED
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
|
||||
- export JS_OLD_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js-old/ | wc -l)
|
||||
- echo $JS_OLD_FILES_MODIFIED
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) deps install since no JS files modified."; else ./js-old/scripts/install-deps.sh;fi
|
||||
|
||||
script:
|
||||
- rustup default stable
|
||||
- echo $JS_FILES_MODIFIED
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi
|
||||
- echo $JS_OLD_FILES_MODIFIED
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) rebuild since no JS files modified."; else ./js-old/scripts/build.sh && ./js-old/scripts/release.sh; fi
|
||||
|
||||
tags:
|
||||
- javascript
|
||||
push-release:
|
||||
|
41
CHANGELOG.md
41
CHANGELOG.md
@ -1,25 +1,32 @@
|
||||
## Parity [v1.8.0](https://github.com/paritytech/parity/releases/tag/v1.8.0) (2017-10-13)
|
||||
## Parity [v1.8.0](https://github.com/paritytech/parity/releases/tag/v1.8.0) (2017-10-15)
|
||||
|
||||
@TODO describe and document
|
||||
We are happy to announce our newest Parity 1.8 release. Among others, it enables the following features:
|
||||
|
||||
- WASM contracts
|
||||
- light cient improvements (POA chain compatibility)
|
||||
- Trezor wallet support
|
||||
- Abstraction of engine: Generalize engine trait, Move more params to the common section
|
||||
- PICOPS certification badge
|
||||
- Vouch for Dapps
|
||||
- Premissioned p2p-connections
|
||||
- Transaction permissioning
|
||||
- Add Musicoin and MCIP-3 UBI hardfork.
|
||||
- Add pagination for trace_filter rpc method
|
||||
- Rename network_id to chain_id where applicable
|
||||
- Compatibility with whisper v6
|
||||
- Byzantium updates
|
||||
- Rewards on closing blocks
|
||||
- Full Whisper v6 integration
|
||||
- Trezor hardware-wallet support
|
||||
- WASM contract support
|
||||
- PICOPS KYC-certified accounts and vouching for community-dapps
|
||||
- Light client compatibility for Proof-of-Authority networks
|
||||
- Transaction permissioning and permissioned p2p-connections
|
||||
- Full Byzantium-fork compatibility
|
||||
- Full Musicoin MCIP-3 UBI-fork compatibility
|
||||
|
||||
Further, users upgrading from 1.7 should acknowledge the following changes:
|
||||
|
||||
- The chain-engine was further abstracted and chain-specs need to be upgraded. [#6134](https://github.com/paritytech/parity/pull/6134) [#6591](https://github.com/paritytech/parity/pull/6591)
|
||||
- `network_id` was renamed to `chain_id` where applicable. [#6345](https://github.com/paritytech/parity/pull/6345)
|
||||
- `trace_filter` RPC method now comes with pagination. [#6312](https://github.com/paritytech/parity/pull/6312)
|
||||
- Added tracing of rewards on closing blocks. [#6194](https://github.com/paritytech/parity/pull/6194)
|
||||
|
||||
Full list of included changes:
|
||||
|
||||
- CLI: Reject invalid argument values rather than ignore them (#6747)
|
||||
- Updated ethabi to fix auto-update ([#6771](https://github.com/paritytech/parity/pull/6771))
|
||||
- Fixed kovan chain validation ([#6760](https://github.com/paritytech/parity/pull/6760))
|
||||
- Fixed kovan chain validation
|
||||
- Fork detection
|
||||
- Fixed typo
|
||||
- Bumped fork block number for auto-update ([#6755](https://github.com/paritytech/parity/pull/6755))
|
||||
- CLI: Reject invalid argument values rather than ignore them ([#6747](https://github.com/paritytech/parity/pull/6747))
|
||||
- Fixed modexp gas calculation overflow ([#6745](https://github.com/paritytech/parity/pull/6745))
|
||||
- Backport beta - Fixes Badges ([#6732](https://github.com/paritytech/parity/pull/6732))
|
||||
- Fix badges not showing up ([#6730](https://github.com/paritytech/parity/pull/6730))
|
||||
|
391
Cargo.lock
generated
391
Cargo.lock
generated
@ -233,16 +233,6 @@ dependencies = [
|
||||
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.0"
|
||||
@ -287,14 +277,6 @@ dependencies = [
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"clippy_lints 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.0.103"
|
||||
@ -303,29 +285,6 @@ dependencies = [
|
||||
"clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.0.163"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy_lints 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.0.103"
|
||||
@ -340,24 +299,6 @@ dependencies = [
|
||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.0.163"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itertools 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coco"
|
||||
version = "0.1.1"
|
||||
@ -542,9 +483,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethabi"
|
||||
version = "2.0.0"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -583,9 +525,6 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-stratum 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
@ -600,12 +539,16 @@ dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"memory-cache 0.1.0",
|
||||
"memorydb 0.1.0",
|
||||
"migration 0.1.0",
|
||||
"native-contracts 0.1.0",
|
||||
@ -676,68 +619,6 @@ dependencies = [
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-ipc"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-ipc-codegen"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-ipc-hypervisor"
|
||||
version = "1.2.0"
|
||||
dependencies = [
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-ipc-nano"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ethcore-ipc 1.9.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-ipc-tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-light"
|
||||
version = "1.9.0"
|
||||
@ -748,8 +629,6 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"evm 0.1.0",
|
||||
@ -758,7 +637,10 @@ dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory-cache 0.1.0",
|
||||
"memorydb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia_trie 0.1.0",
|
||||
@ -818,6 +700,8 @@ dependencies = [
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"snappy 0.1.0",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -827,14 +711,10 @@ name = "ethcore-secretstore"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcrypto 0.1.0",
|
||||
@ -844,6 +724,7 @@ dependencies = [
|
||||
"hash 0.1.0",
|
||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contracts 0.1.0",
|
||||
@ -867,9 +748,6 @@ dependencies = [
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"hash 0.1.0",
|
||||
@ -889,19 +767,18 @@ dependencies = [
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"hash 0.1.0",
|
||||
"hashdb 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia_trie 0.1.0",
|
||||
@ -1013,9 +890,6 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
@ -1024,6 +898,7 @@ dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1047,6 +922,7 @@ dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory-cache 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
@ -1351,17 +1227,6 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipc-common-types"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.12.7"
|
||||
@ -1385,19 +1250,30 @@ dependencies = [
|
||||
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "journaldb"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"hash 0.1.0",
|
||||
"hashdb 0.1.0",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
"util-error 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-core"
|
||||
version = "8.0.0"
|
||||
@ -1508,15 +1384,31 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"hashdb 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kvdb-memorydb"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kvdb 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kvdb-rocksdb"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"kvdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
"rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1645,6 +1537,14 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memory-cache"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memorydb"
|
||||
version = "0.1.0"
|
||||
@ -1662,10 +1562,12 @@ dependencies = [
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-devtools 1.9.0",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1781,29 +1683,11 @@ dependencies = [
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanomsg"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
||||
dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanomsg-sys"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7#673b79beef6e149273899850d7692335a481a920"
|
||||
dependencies = [
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-contract-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heck 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1812,7 +1696,7 @@ name = "native-contracts"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contract-generator 0.1.0",
|
||||
@ -1853,7 +1737,7 @@ dependencies = [
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-contracts 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2050,7 +1934,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2065,10 +1949,6 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-hypervisor 1.2.0",
|
||||
"ethcore-ipc-nano 1.9.0",
|
||||
"ethcore-ipc-tests 0.1.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
@ -2083,8 +1963,10 @@ dependencies = [
|
||||
"hash 0.1.0",
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"migration 0.1.0",
|
||||
"node-filter 1.9.0",
|
||||
@ -2106,7 +1988,7 @@ dependencies = [
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
"rpassword 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rpc-cli 1.4.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2142,7 +2024,7 @@ dependencies = [
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"node-health 0.1.0",
|
||||
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.9.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-ui 1.9.0",
|
||||
@ -2158,7 +2040,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-dapps-glue"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-dapps-glue"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2170,26 +2067,11 @@ dependencies = [
|
||||
"syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-dapps-glue"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-hash-fetch"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
@ -2231,6 +2113,7 @@ dependencies = [
|
||||
"ethcore-util 1.9.0",
|
||||
"ethkey 0.2.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.0",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2267,7 +2150,6 @@ dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
@ -2278,6 +2160,7 @@ dependencies = [
|
||||
"ethstore 0.1.0",
|
||||
"ethsync 1.9.0",
|
||||
"fetch 0.1.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hardware-wallet 1.9.0",
|
||||
"hash 0.1.0",
|
||||
@ -2288,7 +2171,7 @@ dependencies = [
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2352,6 +2235,8 @@ name = "parity-ui"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"parity-ui-dev 1.9.0",
|
||||
"parity-ui-old-dev 1.9.0",
|
||||
"parity-ui-old-precompiled 1.8.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)",
|
||||
"parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2360,36 +2245,49 @@ dependencies = [
|
||||
name = "parity-ui-dev"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-old-dev"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-old-precompiled"
|
||||
version = "1.8.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=v1#94b0a89aac7eb5ddfdb53cd9bb039da6fdbf7583"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git#4b77a23c3e55aed45725f43cd2a499676375b995"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git#29360e67331334a9ec3aafdb3725d8f7d8b5d2a1"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-updater"
|
||||
version = "1.9.0"
|
||||
dependencies = [
|
||||
"ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-ipc 1.9.0",
|
||||
"ethcore-ipc-codegen 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethsync 1.9.0",
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-common-types 1.9.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.9.0",
|
||||
"parity-reactor 0.1.0",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2615,15 +2513,6 @@ dependencies = [
|
||||
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quasi"
|
||||
version = "0.32.0"
|
||||
@ -2818,23 +2707,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "0.2.3"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -2847,9 +2725,14 @@ dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-rpc 1.9.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rprompt"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rust-crypto"
|
||||
version = "0.2.36"
|
||||
@ -3229,14 +3112,6 @@ dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termios"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.8.0"
|
||||
@ -3514,6 +3389,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.1.3",
|
||||
"kvdb 0.1.0",
|
||||
"rlp 0.2.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -3681,17 +3557,12 @@ dependencies = [
|
||||
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
||||
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
|
||||
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
|
||||
"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
|
||||
"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7"
|
||||
"checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2"
|
||||
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
||||
"checksum clippy 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad3f3dc94d81a6505eb28bf545b501fc9d7525ee9864df5a4b2b6d82629f038"
|
||||
"checksum clippy 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "d19bda68c3db98e3a780342f6101b44312fef20a5f13ce756d1202a35922b01b"
|
||||
"checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a"
|
||||
"checksum clippy_lints 0.0.163 (registry+https://github.com/rust-lang/crates.io-index)" = "c058b299bb1289c7e8c063bd49477715c91cb3c3344bcf2e25326860b0675654"
|
||||
"checksum clippy_lints 0.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4ed67c69b9bb35169be2538691d290a3aa0cbfd4b9f0bfb7c221fc1d399a96"
|
||||
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
||||
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
||||
"checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591"
|
||||
@ -3713,7 +3584,7 @@ dependencies = [
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143"
|
||||
"checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
||||
"checksum ethabi 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3d62319ee0f35abf20afe8859dd2668195912614346447bb2dee9fb8da7c62"
|
||||
"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f"
|
||||
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
||||
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
@ -3742,7 +3613,6 @@ dependencies = [
|
||||
"checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336"
|
||||
"checksum isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa500db770a99afe2a0f2229be2a3d09c7ed9d7e4e8440bf71253141994e240f"
|
||||
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
|
||||
"checksum itertools 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ab4d6a273c31ef276c917019239588b23bc696f277af8db10742cba3c27ec2f0"
|
||||
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
||||
"checksum jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
@ -3781,8 +3651,6 @@ dependencies = [
|
||||
"checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"
|
||||
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
||||
"checksum multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d14363c7695e2e5adbbb8fe139d806a19b8b13f02b9b1fb770fab0c12edaff58"
|
||||
"checksum nanomsg 0.5.1 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
||||
"checksum nanomsg-sys 0.5.0 (git+https://github.com/paritytech/nanomsg.rs.git?branch=parity-1.7)" = "<none>"
|
||||
"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5"
|
||||
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
||||
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
|
||||
@ -3804,8 +3672,9 @@ dependencies = [
|
||||
"checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb"
|
||||
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parity-dapps-glue 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddaeb8543c6823e93dae65a25eb8083ebfeee8f0000031119d7a0055b2e8fc63"
|
||||
"checksum parity-dapps-glue 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9df5504a83dbbbd25ddb0645372bd09dff5a7716e18690a21211873b81606fe9"
|
||||
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
|
||||
"checksum parity-ui-old-precompiled 1.8.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)" = "<none>"
|
||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/paritytech/js-precompiled.git)" = "<none>"
|
||||
"checksum parity-wasm 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4502e18417d96bd8e72fca9ea4cc18f4d80288ff565582d10aefe86f18b4fc3"
|
||||
"checksum parity-wordlist 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81451bfab101d186f8fc4a0aa13cb5539b31b02c4ed96425a0842e2a413daba6"
|
||||
@ -3825,7 +3694,6 @@ dependencies = [
|
||||
"checksum primal-estimate 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56ea4531dde757b56906493c8604641da14607bf9cdaa80fb9c9cabd2429f8d5"
|
||||
"checksum primal-sieve 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e058e7a369c70c0103d138ef71f052a48b102592aadb8ca38ee80d85d303e1de"
|
||||
"checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4"
|
||||
"checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b"
|
||||
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
|
||||
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
|
||||
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
|
||||
@ -3846,8 +3714,8 @@ dependencies = [
|
||||
"checksum rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)" = "<none>"
|
||||
"checksum rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb)" = "<none>"
|
||||
"checksum rotor 0.6.3 (git+https://github.com/tailhook/rotor)" = "<none>"
|
||||
"checksum rpassword 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "320da1dfcf5c570a6c07ff60bb7cd4cdc986d2ea89caea139f2247371ab6a1df"
|
||||
"checksum rpassword 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec4bdede957362ec6fdd550f7e79c6d14cad2bc26b2d062786234c6ee0cb27bb"
|
||||
"checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4"
|
||||
"checksum rprompt 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1601f32bc5858aae3cbfa1c645c96c4d820cc5c16be0194f089560c00b6eb625"
|
||||
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
@ -3895,7 +3763,6 @@ dependencies = [
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
||||
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
|
||||
"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
|
||||
"checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd"
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
|
||||
|
11
Cargo.toml
11
Cargo.toml
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
@ -15,7 +15,7 @@ clap = "2"
|
||||
time = "0.1"
|
||||
num_cpus = "1.2"
|
||||
number_prefix = "0.2"
|
||||
rpassword = "0.2.1"
|
||||
rpassword = "1.0"
|
||||
semver = "0.6"
|
||||
ansi_term = "0.9"
|
||||
parking_lot = "0.4"
|
||||
@ -39,9 +39,6 @@ ethcore-bytes = { path = "util/bytes" }
|
||||
ethcore-bigint = { path = "util/bigint" }
|
||||
ethcore-io = { path = "util/io" }
|
||||
ethcore-devtools = { path = "devtools" }
|
||||
ethcore-ipc = { path = "ipc/rpc" }
|
||||
ethcore-ipc-nano = { path = "ipc/nano" }
|
||||
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
|
||||
ethcore-light = { path = "ethcore/light" }
|
||||
ethcore-logger = { path = "logger" }
|
||||
ethcore-stratum = { path = "stratum" }
|
||||
@ -64,6 +61,8 @@ panic_hook = { path = "panic_hook" }
|
||||
hash = { path = "util/hash" }
|
||||
migration = { path = "util/migration" }
|
||||
kvdb = { path = "util/kvdb" }
|
||||
kvdb-rocksdb = { path = "util/kvdb-rocksdb" }
|
||||
journaldb = { path = "util/journaldb" }
|
||||
|
||||
parity-dapps = { path = "dapps", optional = true }
|
||||
clippy = { version = "0.0.103", optional = true}
|
||||
@ -73,7 +72,6 @@ ethcore-secretstore = { path = "secret_store", optional = true }
|
||||
rustc_version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
ethcore-ipc-tests = { path = "ipc/tests" }
|
||||
pretty_assertions = "0.1"
|
||||
ipnetwork = "0.12.6"
|
||||
|
||||
@ -95,7 +93,6 @@ ui-precompiled = [
|
||||
]
|
||||
ui-enabled = ["dapps"]
|
||||
dapps = ["parity-dapps"]
|
||||
ipc = ["ethcore/ipc", "ethsync/ipc"]
|
||||
jit = ["ethcore/jit"]
|
||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "parity-rpc/dev", "parity-dapps/dev"]
|
||||
json-tests = ["ethcore/json-tests"]
|
||||
|
@ -13,7 +13,7 @@ futures = "0.1"
|
||||
futures-cpupool = "0.1"
|
||||
linked-hash-map = "0.5"
|
||||
log = "0.3"
|
||||
parity-dapps-glue = "1.8"
|
||||
parity-dapps-glue = "1.9"
|
||||
parking_lot = "0.4"
|
||||
mime_guess = "2.0.0-alpha.2"
|
||||
rand = "0.3"
|
||||
|
@ -18,7 +18,7 @@ quasi = { version = "0.32", default-features = false }
|
||||
quasi_macros = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
syntex_syntax = { version = "0.58", optional = true }
|
||||
clippy = { version = "0.0.90", optional = true }
|
||||
clippy = { version = "0.0.103", optional = true }
|
||||
|
||||
[features]
|
||||
dev = ["clippy"]
|
||||
|
@ -77,6 +77,9 @@ pub fn all_endpoints<F: Fetch>(
|
||||
|
||||
// NOTE [ToDr] Dapps will be currently embeded on 8180
|
||||
insert::<parity_ui::App>(&mut pages, "ui", Embeddable::Yes(embeddable.clone()), pool.clone());
|
||||
// old version
|
||||
insert::<parity_ui::old::App>(&mut pages, "v1", Embeddable::Yes(embeddable.clone()), pool.clone());
|
||||
|
||||
pages.insert("proxy".into(), ProxyPac::boxed(embeddable.clone(), dapps_domain.to_owned()));
|
||||
pages.insert(WEB_PATH.into(), Web::boxed(embeddable.clone(), web_proxy_tokens.clone(), fetch.clone()));
|
||||
|
||||
|
@ -138,6 +138,7 @@ impl Router {
|
||||
},
|
||||
// Any other GET|HEAD requests to home page.
|
||||
_ if (is_get_request || is_head_request) && self.special.contains_key(&SpecialEndpoint::Home) => {
|
||||
trace!(target: "dapps", "Resolving to home page.");
|
||||
let special = self.special.get(&SpecialEndpoint::Home).expect("special known to contain key; qed");
|
||||
match *special {
|
||||
Some(ref special) => {
|
||||
|
@ -268,7 +268,7 @@ impl Server {
|
||||
};
|
||||
|
||||
let mut allowed_hosts: Option<Vec<Host>> = allowed_hosts.into();
|
||||
allowed_hosts.as_mut().map(|mut hosts| {
|
||||
allowed_hosts.as_mut().map(|hosts| {
|
||||
hosts.push(format!("http://*.{}:*", DAPPS_DOMAIN).into());
|
||||
hosts.push(format!("http://*.{}", DAPPS_DOMAIN).into());
|
||||
});
|
||||
|
@ -11,9 +11,11 @@ rustc_version = "0.1"
|
||||
|
||||
[dependencies]
|
||||
parity-ui-dev = { path = "../../js", optional = true }
|
||||
parity-ui-old-dev = { path = "../../js-old", optional = true }
|
||||
# This is managed by the js/scripts/release.sh script on CI - keep it in a single line
|
||||
parity-ui-old-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", optional = true, branch = "v1" }
|
||||
parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", optional = true, branch = "master" }
|
||||
|
||||
[features]
|
||||
no-precompiled-js = ["parity-ui-dev"]
|
||||
use-precompiled-js = ["parity-ui-precompiled"]
|
||||
no-precompiled-js = ["parity-ui-dev", "parity-ui-old-dev"]
|
||||
use-precompiled-js = ["parity-ui-precompiled", "parity-ui-old-precompiled"]
|
||||
|
@ -29,5 +29,18 @@ mod inner {
|
||||
pub use self::parity_ui_precompiled::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "parity-ui-old-dev")]
|
||||
pub mod old {
|
||||
extern crate parity_ui_old_dev;
|
||||
|
||||
pub use self::parity_ui_old_dev::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "parity-ui-old-precompiled")]
|
||||
pub mod old {
|
||||
extern crate parity_ui_old_precompiled;
|
||||
|
||||
pub use self::parity_ui_old_precompiled::*;
|
||||
}
|
||||
|
||||
pub use self::inner::*;
|
||||
|
@ -1,3 +1,14 @@
|
||||
## Parity [v1.7.7](https://github.com/paritytech/parity/releases/tag/v1.7.7) (2017-10-15)
|
||||
|
||||
Parity 1.7.7 Fixes an issue with auto-update system. Updating is recommended, but not required for Byzantium.
|
||||
|
||||
Full list of included changes:
|
||||
|
||||
- Fix auto-update ([#6769](https://github.com/paritytech/parity/pull/6759))
|
||||
- Bump to v1.7.7
|
||||
- Updated ethabi to fix auto-update
|
||||
- Bumped fork block number for auto-update ([#6754](https://github.com/paritytech/parity/pull/6754))
|
||||
|
||||
## Parity [v1.7.6](https://github.com/paritytech/parity/releases/tag/v1.7.6) (2017-10-13)
|
||||
|
||||
Parity 1.7.6 includes a critical consensus-relevant fix for the Byzantium hard-fork. Please upgrade your Ethereum client before block number `4_370_000`.
|
||||
|
@ -5,10 +5,6 @@ license = "GPL-3.0"
|
||||
name = "ethcore"
|
||||
version = "1.9.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
"ethcore-ipc-codegen" = { path = "../ipc/codegen" }
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.9"
|
||||
@ -26,12 +22,11 @@ memorydb = { path = "../util/memorydb" }
|
||||
patricia_trie = { path = "../util/patricia_trie" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
ethcore-io = { path = "../util/io" }
|
||||
ethcore-ipc = { path = "../ipc/rpc" }
|
||||
ethcore-ipc-nano = { path = "../ipc/nano" }
|
||||
ethcore-logger = { path = "../logger" }
|
||||
ethcore-stratum = { path = "../stratum" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
||||
memory-cache = { path = "../util/memory_cache" }
|
||||
ethjson = { path = "../json" }
|
||||
ethkey = { path = "../ethkey" }
|
||||
ethstore = { path = "../ethstore" }
|
||||
@ -56,6 +51,8 @@ rand = "0.3"
|
||||
rlp = { path = "../util/rlp" }
|
||||
rlp_derive = { path = "../util/rlp_derive" }
|
||||
kvdb = { path = "../util/kvdb" }
|
||||
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
|
||||
kvdb-memorydb = { path = "../util/kvdb-memorydb" }
|
||||
util-error = { path = "../util/error" }
|
||||
snappy = { path = "../util/snappy" }
|
||||
migration = { path = "../util/migration" }
|
||||
@ -74,6 +71,7 @@ hash = { path = "../util/hash" }
|
||||
triehash = { path = "../util/triehash" }
|
||||
semantic_version = { path = "../util/semantic_version" }
|
||||
unexpected = { path = "../util/unexpected" }
|
||||
journaldb = { path = "../util/journaldb" }
|
||||
|
||||
[dev-dependencies]
|
||||
native-contracts = { path = "native_contracts", features = ["test_contracts"] }
|
||||
@ -88,4 +86,3 @@ test-heavy = []
|
||||
dev = ["clippy"]
|
||||
default = []
|
||||
benches = []
|
||||
ipc = []
|
||||
|
@ -14,6 +14,7 @@ log = "0.3"
|
||||
vm = { path = "../vm" }
|
||||
hash = { path = "../../util/hash" }
|
||||
parking_lot = "0.4"
|
||||
memory-cache = { path = "../../util/memory_cache" }
|
||||
|
||||
[dev-dependencies]
|
||||
rustc-hex = "1.0"
|
||||
|
@ -19,7 +19,7 @@ use hash::KECCAK_EMPTY;
|
||||
use heapsize::HeapSizeOf;
|
||||
use bigint::hash::H256;
|
||||
use parking_lot::Mutex;
|
||||
use util::cache::MemoryLruCache;
|
||||
use memory_cache::MemoryLruCache;
|
||||
use bit_set::BitSet;
|
||||
use super::super::instructions;
|
||||
|
||||
|
@ -23,6 +23,7 @@ extern crate parking_lot;
|
||||
extern crate heapsize;
|
||||
extern crate vm;
|
||||
extern crate hash;
|
||||
extern crate memory_cache;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
@ -5,10 +5,6 @@ license = "GPL-3.0"
|
||||
name = "ethcore-light"
|
||||
version = "1.9.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
"ethcore-ipc-codegen" = { path = "../../ipc/codegen", optional = true }
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
@ -20,7 +16,6 @@ memorydb = { path = "../../util/memorydb" }
|
||||
patricia_trie = { path = "../../util/patricia_trie" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
ethcore-ipc = { path = "../../ipc/rpc", optional = true }
|
||||
ethcore-devtools = { path = "../../devtools" }
|
||||
evm = { path = "../evm" }
|
||||
heapsize = "0.4"
|
||||
@ -40,7 +35,9 @@ stats = { path = "../../util/stats" }
|
||||
hash = { path = "../../util/hash" }
|
||||
triehash = { path = "../../util/triehash" }
|
||||
kvdb = { path = "../../util/kvdb" }
|
||||
kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" }
|
||||
kvdb-memorydb = { path = "../../util/kvdb-memorydb" }
|
||||
memory-cache = { path = "../../util/memory_cache" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
ipc = ["ethcore-ipc", "ethcore-ipc-codegen"]
|
||||
|
@ -29,7 +29,7 @@ use time::{SteadyTime, Duration};
|
||||
use heapsize::HeapSizeOf;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use util::cache::MemoryLruCache;
|
||||
use memory_cache::MemoryLruCache;
|
||||
|
||||
/// Configuration for how much data to cache.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -45,7 +45,7 @@ use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp, UntrustedRlp};
|
||||
use heapsize::HeapSizeOf;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::{H256, H256FastMap, H264};
|
||||
use kvdb::{DBTransaction, KeyValueDB};
|
||||
use kvdb::{self, DBTransaction, KeyValueDB};
|
||||
|
||||
use cache::Cache;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
@ -198,7 +198,7 @@ impl HeaderChain {
|
||||
col: Option<u32>,
|
||||
spec: &Spec,
|
||||
cache: Arc<Mutex<Cache>>,
|
||||
) -> Result<Self, String> {
|
||||
) -> Result<Self, kvdb::Error> {
|
||||
let mut live_epoch_proofs = ::std::collections::HashMap::default();
|
||||
|
||||
let genesis = ::rlp::encode(&spec.genesis_header()).into_vec();
|
||||
@ -240,7 +240,7 @@ impl HeaderChain {
|
||||
let best_block = {
|
||||
let era = match candidates.get(&best_number) {
|
||||
Some(era) => era,
|
||||
None => return Err(format!("Database corrupt: highest block referenced but no data.")),
|
||||
None => return Err("Database corrupt: highest block referenced but no data.".into()),
|
||||
};
|
||||
|
||||
let best = &era.candidates[0];
|
||||
@ -728,13 +728,14 @@ mod tests {
|
||||
use ethcore::header::Header;
|
||||
use ethcore::spec::Spec;
|
||||
use cache::Cache;
|
||||
use kvdb::{in_memory, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_memorydb;
|
||||
|
||||
use time::Duration;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
fn make_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(0))
|
||||
Arc::new(kvdb_memorydb::create(0))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -36,7 +36,8 @@ use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use futures::{IntoFuture, Future};
|
||||
|
||||
use kvdb::{KeyValueDB, CompactionProfile};
|
||||
use kvdb::{self, KeyValueDB};
|
||||
use kvdb_rocksdb::CompactionProfile;
|
||||
|
||||
use self::fetch::ChainDataFetcher;
|
||||
use self::header_chain::{AncestryIter, HeaderChain};
|
||||
@ -186,7 +187,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
||||
fetcher: T,
|
||||
io_channel: IoChannel<ClientIoMessage>,
|
||||
cache: Arc<Mutex<Cache>>
|
||||
) -> Result<Self, String> {
|
||||
) -> Result<Self, kvdb::Error> {
|
||||
Ok(Client {
|
||||
queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, config.check_seal),
|
||||
engine: spec.engine.clone(),
|
||||
@ -214,7 +215,7 @@ impl<T: ChainDataFetcher> Client<T> {
|
||||
io_channel: IoChannel<ClientIoMessage>,
|
||||
cache: Arc<Mutex<Cache>>
|
||||
) -> Self {
|
||||
let db = ::kvdb::in_memory(0);
|
||||
let db = ::kvdb_memorydb::create(0);
|
||||
|
||||
Client::new(
|
||||
config,
|
||||
|
@ -25,7 +25,8 @@ use ethcore::db;
|
||||
use ethcore::service::ClientIoMessage;
|
||||
use ethcore::spec::Spec;
|
||||
use io::{IoContext, IoError, IoHandler, IoService};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb;
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
use cache::Cache;
|
||||
use parking_lot::Mutex;
|
||||
@ -36,7 +37,7 @@ use super::{ChainDataFetcher, Client, Config as ClientConfig};
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Database error.
|
||||
Database(String),
|
||||
Database(kvdb::Error),
|
||||
/// I/O service error.
|
||||
Io(IoError),
|
||||
}
|
||||
|
@ -38,21 +38,8 @@ pub mod net;
|
||||
pub mod on_demand;
|
||||
pub mod transaction_queue;
|
||||
pub mod cache;
|
||||
|
||||
#[cfg(not(feature = "ipc"))]
|
||||
pub mod provider;
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
pub mod provider {
|
||||
#![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues
|
||||
include!(concat!(env!("OUT_DIR"), "/provider.rs"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
pub mod remote {
|
||||
pub use provider::LightProviderClient;
|
||||
}
|
||||
|
||||
mod types;
|
||||
|
||||
pub use self::cache::Cache;
|
||||
@ -92,9 +79,9 @@ extern crate vm;
|
||||
extern crate hash;
|
||||
extern crate triehash;
|
||||
extern crate kvdb;
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
extern crate ethcore_ipc as ipc;
|
||||
extern crate kvdb_memorydb;
|
||||
extern crate kvdb_rocksdb;
|
||||
extern crate memory_cache;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_devtools as devtools;
|
||||
|
@ -34,7 +34,6 @@ use transaction_queue::TransactionQueue;
|
||||
use request;
|
||||
|
||||
/// Defines the operations that a provider for the light subprotocol must fulfill.
|
||||
#[cfg_attr(feature = "ipc", ipc(client_ident="LightProviderClient"))]
|
||||
pub trait Provider: Send + Sync {
|
||||
/// Provide current blockchain info.
|
||||
fn chain_info(&self) -> BlockChainInfo;
|
||||
@ -328,7 +327,7 @@ impl<L: AsLightClient + Send + Sync> Provider for LightProvider<L> {
|
||||
}
|
||||
|
||||
fn transaction_index(&self, _req: request::CompleteTransactionIndexRequest)
|
||||
-> Option<request::TransactionIndexResponse>
|
||||
-> Option<request::TransactionIndexResponse>
|
||||
{
|
||||
None
|
||||
}
|
||||
|
@ -14,11 +14,4 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Types used in the public (IPC) api which require custom code generation.
|
||||
#![cfg_attr(feature = "ipc", allow(dead_code, unused_assignments, unused_variables))] // codegen issues
|
||||
|
||||
#[cfg(feature = "ipc")]
|
||||
include!(concat!(env!("OUT_DIR"), "/mod.rs.in"));
|
||||
|
||||
#[cfg(not(feature = "ipc"))]
|
||||
include!("mod.rs.in");
|
||||
pub mod request;
|
||||
|
@ -204,7 +204,6 @@ pub enum OutputKind {
|
||||
|
||||
/// Either a hash or a number.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub enum HashOrNumber {
|
||||
/// Block hash variant.
|
||||
Hash(H256),
|
||||
|
@ -6,7 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
ethabi = "2.0"
|
||||
ethabi = "4.0"
|
||||
futures = "0.1"
|
||||
byteorder = "1.0"
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
|
@ -5,5 +5,5 @@ version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
ethabi = "2.0"
|
||||
ethabi = "4.0"
|
||||
heck = "0.2"
|
||||
|
@ -21,18 +21,17 @@
|
||||
//! due to missing crates or name collisions. This will change when
|
||||
//! it can be ported to a procedural macro.
|
||||
|
||||
use ethabi::Contract;
|
||||
use ethabi::spec::{Interface, ParamType, Error as AbiError};
|
||||
use heck::SnakeCase;
|
||||
|
||||
extern crate ethabi;
|
||||
extern crate heck;
|
||||
|
||||
use ethabi::{Contract, ParamType};
|
||||
use heck::SnakeCase;
|
||||
|
||||
/// Errors in generation.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Bad ABI.
|
||||
Abi(AbiError),
|
||||
Abi(ethabi::Error),
|
||||
/// Unsupported parameter type in given function.
|
||||
UnsupportedType(String, ParamType),
|
||||
}
|
||||
@ -41,13 +40,13 @@ pub enum Error {
|
||||
/// a struct which can be used to call it.
|
||||
// TODO: make this a proc macro when that's possible.
|
||||
pub fn generate_module(struct_name: &str, abi: &str) -> Result<String, Error> {
|
||||
let contract = Contract::new(Interface::load(abi.as_bytes()).map_err(Error::Abi)?);
|
||||
let contract = Contract::load(abi.as_bytes()).map_err(Error::Abi)?;
|
||||
let functions = generate_functions(&contract)?;
|
||||
|
||||
Ok(format!(r##"
|
||||
use byteorder::{{BigEndian, ByteOrder}};
|
||||
use futures::{{future, Future, IntoFuture}};
|
||||
use ethabi::{{Contract, Interface, Token, Event}};
|
||||
use ethabi::{{Contract, Token, Event}};
|
||||
use bigint;
|
||||
|
||||
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||
@ -66,8 +65,8 @@ impl {name} {{
|
||||
/// Create a new instance of `{name}` with an address.
|
||||
/// Calls can be made, given a callback for dispatching calls asynchronously.
|
||||
pub fn new(address: bigint::prelude::H160) -> Self {{
|
||||
let contract = Contract::new(Interface::load(ABI.as_bytes())
|
||||
.expect("ABI checked at generation-time; qed"));
|
||||
let contract = Contract::load(ABI.as_bytes())
|
||||
.expect("ABI checked at generation-time; qed");
|
||||
{name} {{
|
||||
contract: contract,
|
||||
address: address,
|
||||
@ -92,16 +91,16 @@ impl {name} {{
|
||||
fn generate_functions(contract: &Contract) -> Result<String, Error> {
|
||||
let mut functions = String::new();
|
||||
for function in contract.functions() {
|
||||
let name = function.name();
|
||||
let name = &function.name;
|
||||
let snake_name = name.to_snake_case();
|
||||
let inputs = function.input_params();
|
||||
let outputs = function.output_params();
|
||||
let inputs: Vec<_> = function.inputs.iter().map(|i| i.kind.clone()).collect();
|
||||
let outputs: Vec<_> = function.outputs.iter().map(|i| i.kind.clone()).collect();
|
||||
|
||||
let (input_params, to_tokens) = input_params_codegen(&inputs)
|
||||
.map_err(|bad_type| Error::UnsupportedType(name.into(), bad_type))?;
|
||||
.map_err(|bad_type| Error::UnsupportedType(name.clone(), bad_type))?;
|
||||
|
||||
let (output_type, decode_outputs) = output_params_codegen(&outputs)
|
||||
.map_err(|bad_type| Error::UnsupportedType(name.into(), bad_type))?;
|
||||
.map_err(|bad_type| Error::UnsupportedType(name.clone(), bad_type))?;
|
||||
|
||||
functions.push_str(&format!(r##"
|
||||
/// Call the function "{abi_name}" on the contract.
|
||||
@ -115,17 +114,17 @@ pub fn {snake_name}<F, U>(&self, call: F, {params}) -> BoxFuture<{output_type},
|
||||
U::Future: Send + 'static
|
||||
{{
|
||||
let function = self.contract.function(r#"{abi_name}"#)
|
||||
.expect("function existence checked at compile-time; qed");
|
||||
.expect("function existence checked at compile-time; qed").clone();
|
||||
let call_addr = self.address;
|
||||
|
||||
let call_future = match function.encode_call({to_tokens}) {{
|
||||
let call_future = match function.encode_input(&{to_tokens}) {{
|
||||
Ok(call_data) => (call)(call_addr, call_data),
|
||||
Err(e) => return Box::new(future::err(format!("Error encoding call: {{:?}}", e))),
|
||||
}};
|
||||
|
||||
Box::new(call_future
|
||||
.into_future()
|
||||
.and_then(move |out| function.decode_output(out).map_err(|e| format!("{{:?}}", e)))
|
||||
.and_then(move |out| function.decode_output(&out).map_err(|e| format!("{{:?}}", e)))
|
||||
.map(Vec::into_iter)
|
||||
.and_then(|mut outputs| {decode_outputs}))
|
||||
}}
|
||||
@ -325,7 +324,7 @@ fn detokenize(name: &str, output_type: ParamType) -> String {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethabi::spec::ParamType;
|
||||
use ethabi::ParamType;
|
||||
|
||||
#[test]
|
||||
fn input_types() {
|
||||
|
@ -11,10 +11,12 @@ ethcore = { path = ".."}
|
||||
ethcore-util = { path = "../../util" }
|
||||
ethcore-bigint = { path = "../../util/bigint" }
|
||||
ethcore-bytes = { path = "../../util/bytes" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
kvdb = { path = "../../util/kvdb" }
|
||||
native-contracts = { path = "../native_contracts" }
|
||||
futures = "0.1"
|
||||
log = "0.3"
|
||||
parking_lot = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
kvdb-memorydb = { path = "../../util/kvdb-memorydb" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
|
@ -24,9 +24,14 @@ extern crate ethcore_network as network;
|
||||
extern crate native_contracts;
|
||||
extern crate futures;
|
||||
extern crate parking_lot;
|
||||
extern crate kvdb;
|
||||
#[cfg(test)] extern crate ethcore_io as io;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate kvdb_memorydb;
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_io as io;
|
||||
|
||||
use std::sync::Weak;
|
||||
use std::collections::HashMap;
|
||||
@ -135,7 +140,7 @@ mod test {
|
||||
let contract_addr = Address::from_str("0000000000000000000000000000000000000005").unwrap();
|
||||
let data = include_bytes!("../res/node_filter.json");
|
||||
let spec = Spec::load(&::std::env::temp_dir(), &data[..]).unwrap();
|
||||
let client_db = Arc::new(::kvdb::in_memory(::ethcore::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let client_db = Arc::new(::kvdb_memorydb::create(::ethcore::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfig::default(),
|
||||
|
@ -13,6 +13,7 @@
|
||||
"eip160Transition": 1915000,
|
||||
"ecip1010PauseTransition": 1915000,
|
||||
"ecip1010ContinueTransition": 3415000,
|
||||
"ecip1017EraRounds": 2000000,
|
||||
|
||||
"eip161abcTransition": "0x7fffffffffffffff",
|
||||
"eip161dTransition": "0x7fffffffffffffff"
|
||||
@ -49,11 +50,13 @@
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"nodes": [
|
||||
"enode://e731347db0521f3476e6bbbb83375dcd7133a1601425ebd15fd10f3835fd4c304fba6282087ca5a0deeafadf0aa0d4fd56c3323331901c1f38bd181c283e3e35@128.199.55.137:30303",
|
||||
"enode://ceb5c0f85eb994dbe9693bf46d99b03f6b838d17cc74e68d5eb003171ff39e5f120b17f965b267c319303f94d80b9d994b77062fb1486d76ce95d9f3d8fe1cb4@46.101.122.141:30303",
|
||||
"enode://fb28713820e718066a2f5df6250ae9d07cff22f672dbf26be6c75d088f821a9ad230138ba492c533a80407d054b1436ef18e951bb65e6901553516c8dffe8ff0@104.155.176.151:30304",
|
||||
"enode://afdc6076b9bf3e7d3d01442d6841071e84c76c73a7016cb4f35c0437df219db38565766234448f1592a07ba5295a867f0ce87b359bf50311ed0b830a2361392d@104.154.136.117:30403",
|
||||
"enode://21101a9597b79e933e17bc94ef3506fe99a137808907aa8fefa67eea4b789792ad11fb391f38b00087f8800a2d3dff011572b62a31232133dd1591ac2d1502c8@104.198.71.200:30403"
|
||||
"enode://21101a9597b79e933e17bc94ef3506fe99a137808907aa8fefa67eea4b789792ad11fb391f38b00087f8800a2d3dff011572b62a31232133dd1591ac2d1502c8@104.198.71.200:30403",
|
||||
"enode://fd008499e9c4662f384b3cff23438879d31ced24e2d19504c6389bc6da6c882f9c2f8dbed972f7058d7650337f54e4ba17bb49c7d11882dd1731d26a6e62e3cb@35.187.57.94:30304",
|
||||
"enode://30a1fd71f28aa6f66fe662af9ecc75f0a6980f06b71598f2b19d3dda04223fc0e53b47e40c9171d5014e9f5b59d9954de125782da592f5d95ea39066e2591d5d@104.237.131.102:30304",
|
||||
"enode://7909d51011d8a153351169f21d3a7bbedb3be1e17d38c1f2fad06504dd5aa07a00f00845835d535fe702bf379c4d7209a51f4d1b723e0ca8b8732bd21fba3b30@139.162.133.42:30303",
|
||||
"enode://a088dfb2f5305be9232e8071c5535f13718a4017e247a0b35074b807d43d99e022880c27302cdb5b1e98ad34c083dbbb483f2b17bdc66149bad037154d6ace96@139.162.127.72:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
@ -64,7 +64,7 @@ impl AddressBook {
|
||||
/// Sets new name for given address.
|
||||
pub fn set_name(&mut self, a: Address, name: String) {
|
||||
{
|
||||
let mut x = self.cache.entry(a)
|
||||
let x = self.cache.entry(a)
|
||||
.or_insert_with(|| AccountMeta {name: Default::default(), meta: "{}".to_owned(), uuid: None});
|
||||
x.name = name;
|
||||
}
|
||||
@ -74,7 +74,7 @@ impl AddressBook {
|
||||
/// Sets new meta for given address.
|
||||
pub fn set_meta(&mut self, a: Address, meta: String) {
|
||||
{
|
||||
let mut x = self.cache.entry(a)
|
||||
let x = self.cache.entry(a)
|
||||
.or_insert_with(|| AccountMeta {name: "Anonymous".to_owned(), meta: Default::default(), uuid: None});
|
||||
x.meta = meta;
|
||||
}
|
||||
@ -253,7 +253,7 @@ impl DappsSettingsStore {
|
||||
/// Marks recent dapp as used
|
||||
pub fn mark_dapp_used(&mut self, dapp: DappId) {
|
||||
{
|
||||
let mut entry = self.history.entry(dapp).or_insert_with(|| Default::default());
|
||||
let entry = self.history.entry(dapp).or_insert_with(|| Default::default());
|
||||
entry.last_accessed = self.time.get();
|
||||
}
|
||||
// Clear extraneous entries
|
||||
@ -280,7 +280,7 @@ impl DappsSettingsStore {
|
||||
/// Sets accounts for specific dapp.
|
||||
pub fn set_accounts(&mut self, id: DappId, accounts: Option<Vec<Address>>) {
|
||||
{
|
||||
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.accounts = accounts;
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
@ -289,7 +289,7 @@ impl DappsSettingsStore {
|
||||
/// Sets a default account for specific dapp.
|
||||
pub fn set_default(&mut self, id: DappId, default: Address) {
|
||||
{
|
||||
let mut settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
let settings = self.settings.entry(id).or_insert_with(DappsSettings::default);
|
||||
settings.default = Some(default);
|
||||
}
|
||||
self.settings.save(JsonSettings::write);
|
||||
|
@ -1479,7 +1479,8 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
use rustc_hex::FromHex;
|
||||
use hash::keccak;
|
||||
use kvdb::{in_memory, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_memorydb;
|
||||
use bigint::hash::*;
|
||||
use receipt::{Receipt, TransactionOutcome};
|
||||
use blockchain::{BlockProvider, BlockChain, Config, ImportRoute};
|
||||
@ -1493,7 +1494,7 @@ mod tests {
|
||||
use header::BlockNumber;
|
||||
|
||||
fn new_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
fn new_chain(genesis: &[u8], db: Arc<KeyValueDB>) -> BlockChain {
|
||||
|
@ -14,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ipc::IpcConfig;
|
||||
use bigint::hash::H256;
|
||||
use bytes::Bytes;
|
||||
|
||||
/// Represents what has to be handled by actor listening to chain events
|
||||
#[ipc]
|
||||
pub trait ChainNotify : Send + Sync {
|
||||
/// fires when chain has new blocks.
|
||||
fn new_blocks(
|
||||
@ -57,5 +55,3 @@ pub trait ChainNotify : Send + Sync {
|
||||
// does nothing by default
|
||||
}
|
||||
}
|
||||
|
||||
impl IpcConfig for ChainNotify { }
|
||||
|
@ -26,10 +26,11 @@ use itertools::Itertools;
|
||||
use hash::keccak;
|
||||
use timer::PerfTimer;
|
||||
use bytes::Bytes;
|
||||
use util::{Address, journaldb, DBValue};
|
||||
use util::{Address, DBValue};
|
||||
use journaldb;
|
||||
use util_error::UtilError;
|
||||
use trie::{TrieSpec, TrieFactory, Trie};
|
||||
use kvdb::*;
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
|
||||
// other
|
||||
use bigint::prelude::U256;
|
||||
|
@ -20,8 +20,8 @@ use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
use mode::Mode as IpcMode;
|
||||
use verification::{VerifierType, QueueConfig};
|
||||
use util::journaldb;
|
||||
use kvdb::CompactionProfile;
|
||||
use journaldb;
|
||||
use kvdb_rocksdb::CompactionProfile;
|
||||
|
||||
pub use std::time::Duration;
|
||||
pub use blockchain::Config as BlockChainConfig;
|
||||
|
@ -14,9 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use util_error::UtilError;
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
use util_error::UtilError;
|
||||
use kvdb;
|
||||
use trie::TrieError;
|
||||
|
||||
/// Client configuration errors.
|
||||
@ -25,7 +25,7 @@ pub enum Error {
|
||||
/// TrieDB-related error.
|
||||
Trie(TrieError),
|
||||
/// Database error
|
||||
Database(String),
|
||||
Database(kvdb::Error),
|
||||
/// Util error
|
||||
Util(UtilError),
|
||||
}
|
||||
|
@ -20,9 +20,8 @@ use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use util::journaldb;
|
||||
use trie;
|
||||
use bytes;
|
||||
use journaldb;
|
||||
use {trie, kvdb_memorydb, bytes};
|
||||
use kvdb::{self, KeyValueDB};
|
||||
use {state, state_db, client, executive, trace, transaction, db, spec, pod_state};
|
||||
use factory::Factories;
|
||||
@ -39,7 +38,7 @@ pub enum EvmTestError {
|
||||
/// Initialization error.
|
||||
ClientError(::error::Error),
|
||||
/// Low-level database error.
|
||||
Database(String),
|
||||
Database(kvdb::Error),
|
||||
/// Post-condition failure,
|
||||
PostCondition(String),
|
||||
}
|
||||
@ -128,7 +127,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
}
|
||||
|
||||
fn state_from_spec(spec: &'a spec::Spec, factories: &Factories) -> Result<state::State<state_db::StateDB>, EvmTestError> {
|
||||
let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE);
|
||||
let mut state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024);
|
||||
state_db = spec.ensure_db_good(state_db, factories)?;
|
||||
@ -150,7 +149,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
}
|
||||
|
||||
fn state_from_pod(spec: &'a spec::Spec, factories: &Factories, pod_state: pod_state::PodState) -> Result<state::State<state_db::StateDB>, EvmTestError> {
|
||||
let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let db = Arc::new(kvdb_memorydb::create(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE);
|
||||
let state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024);
|
||||
let mut state = state::State::new(
|
||||
|
@ -45,21 +45,6 @@ pub use vm::{LastHashes, EnvInfo};
|
||||
pub use error::{BlockImportError, TransactionImportError, TransactionImportResult};
|
||||
pub use verification::VerifierType;
|
||||
|
||||
/// IPC interfaces
|
||||
#[cfg(feature="ipc")]
|
||||
pub mod remote {
|
||||
pub use super::traits::RemoteClient;
|
||||
pub use super::chain_notify::ChainNotifyClient;
|
||||
}
|
||||
|
||||
mod traits {
|
||||
#![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues
|
||||
include!(concat!(env!("OUT_DIR"), "/traits.rs"));
|
||||
}
|
||||
|
||||
pub mod chain_notify {
|
||||
//! Chain notify interface
|
||||
#![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues
|
||||
include!(concat!(env!("OUT_DIR"), "/chain_notify.rs"));
|
||||
}
|
||||
mod traits;
|
||||
|
||||
mod chain_notify;
|
||||
|
@ -26,8 +26,9 @@ use hash::keccak;
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use parking_lot::RwLock;
|
||||
use util::*;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use journaldb;
|
||||
use util::{Address, DBValue};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use bytes::Bytes;
|
||||
use rlp::*;
|
||||
use ethkey::{Generator, Random};
|
||||
|
@ -27,7 +27,6 @@ use evm::{Factory as EvmFactory, Schedule};
|
||||
use executive::Executed;
|
||||
use filter::Filter;
|
||||
use header::{BlockNumber};
|
||||
use ipc::IpcConfig;
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use receipt::LocalizedReceipt;
|
||||
use trace::LocalizedTrace;
|
||||
@ -49,7 +48,6 @@ use types::block_status::BlockStatus;
|
||||
use types::mode::Mode;
|
||||
use types::pruning_info::PruningInfo;
|
||||
|
||||
#[ipc(client_ident="RemoteClient")]
|
||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||
pub trait BlockChainClient : Sync + Send {
|
||||
|
||||
@ -287,8 +285,6 @@ pub trait BlockChainClient : Sync + Send {
|
||||
fn eip86_transition(&self) -> u64;
|
||||
}
|
||||
|
||||
impl IpcConfig for BlockChainClient { }
|
||||
|
||||
/// Extended client interface used for mining
|
||||
pub trait MiningBlockChainClient: BlockChainClient {
|
||||
/// Returns OpenBlock prepared for closing.
|
||||
|
@ -37,7 +37,6 @@ use rlp::Rlp;
|
||||
|
||||
/// Owning header view.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Header(Vec<u8>);
|
||||
|
||||
impl HeapSizeOf for Header {
|
||||
@ -115,7 +114,6 @@ impl Header {
|
||||
|
||||
/// Owning block body view.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Body(Vec<u8>);
|
||||
|
||||
impl HeapSizeOf for Body {
|
||||
@ -175,7 +173,6 @@ impl Body {
|
||||
|
||||
/// Owning block view.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Block(Vec<u8>);
|
||||
|
||||
impl HeapSizeOf for Block {
|
||||
|
@ -421,7 +421,7 @@ pub mod common {
|
||||
.and_then(|_| fields.state.commit());
|
||||
|
||||
let block_author = fields.header.author().clone();
|
||||
fields.traces.as_mut().map(move |mut traces| {
|
||||
fields.traces.as_mut().map(move |traces| {
|
||||
let mut tracer = ExecutiveTracer::default();
|
||||
tracer.trace_reward(block_author, reward, RewardType::Block);
|
||||
traces.push(tracer.drain())
|
||||
|
@ -782,7 +782,7 @@ mod tests {
|
||||
use block::*;
|
||||
use error::{Error, BlockError};
|
||||
use header::Header;
|
||||
use client::chain_notify::ChainNotify;
|
||||
use client::ChainNotify;
|
||||
use miner::MinerService;
|
||||
use tests::helpers::*;
|
||||
use account_provider::AccountProvider;
|
||||
|
@ -27,7 +27,7 @@ use parking_lot::{Mutex, RwLock};
|
||||
|
||||
use util::*;
|
||||
use bytes::Bytes;
|
||||
use util::cache::MemoryLruCache;
|
||||
use memory_cache::MemoryLruCache;
|
||||
use unexpected::Mismatch;
|
||||
use rlp::{UntrustedRlp, RlpStream};
|
||||
|
||||
@ -276,7 +276,7 @@ impl ValidatorSafeContract {
|
||||
.filter(move |l| check_log(l))
|
||||
.filter_map(|log| {
|
||||
let topics = log.topics.iter().map(|x| x.0.clone()).collect();
|
||||
event.decode_log(topics, log.data.clone()).ok()
|
||||
event.parse_log((topics, log.data.clone()).into()).ok()
|
||||
});
|
||||
|
||||
match decoded_events.next() {
|
||||
@ -285,7 +285,7 @@ impl ValidatorSafeContract {
|
||||
|
||||
// decode log manually until the native contract generator is
|
||||
// good enough to do it for us.
|
||||
let validators_token = &matched_event[1].value;
|
||||
let validators_token = &matched_event.params[1].value;
|
||||
|
||||
let validators = validators_token.clone().to_array()
|
||||
.and_then(|a| a.into_iter()
|
||||
|
@ -29,7 +29,6 @@ use io::*;
|
||||
use header::BlockNumber;
|
||||
use basic_types::LogBloom;
|
||||
use client::Error as ClientError;
|
||||
use ipc::binary::{BinaryConvertError, BinaryConvertable};
|
||||
use snapshot::Error as SnapshotError;
|
||||
use engines::EngineError;
|
||||
use ethkey::Error as EthkeyError;
|
||||
@ -486,21 +485,3 @@ impl<E> From<Box<E>> for Error where Error: From<E> {
|
||||
Error::from(*err)
|
||||
}
|
||||
}
|
||||
|
||||
binary_fixed_size!(BlockError);
|
||||
binary_fixed_size!(ImportError);
|
||||
binary_fixed_size!(TransactionError);
|
||||
|
||||
// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted.
|
||||
/*#![feature(concat_idents)]
|
||||
macro_rules! assimilate {
|
||||
($name:ident) => (
|
||||
impl From<concat_idents!($name, Error)> for Error {
|
||||
fn from(err: concat_idents!($name, Error)) -> Error {
|
||||
Error:: $name (err)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
assimilate!(FromHex);
|
||||
assimilate!(BaseData);*/
|
||||
|
@ -31,7 +31,7 @@ use machine::EthereumMachine;
|
||||
use super::spec::*;
|
||||
|
||||
/// Most recent fork block that we support on Mainnet.
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 2675000;
|
||||
pub const FORK_SUPPORTED_FOUNDATION: u64 = 4370000;
|
||||
|
||||
/// Most recent fork block that we support on Ropsten.
|
||||
pub const FORK_SUPPORTED_ROPSTEN: u64 = 10;
|
||||
|
@ -433,7 +433,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
// trace only top level calls to builtins to avoid DDoS attacks
|
||||
if self.depth == 0 {
|
||||
let mut trace_output = tracer.prepare_trace_output();
|
||||
if let Some(mut out) = trace_output.as_mut() {
|
||||
if let Some(out) = trace_output.as_mut() {
|
||||
*out = output.to_owned();
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
|
||||
};
|
||||
|
||||
{
|
||||
let db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let mut config = ClientConfig::default();
|
||||
config.history = 8;
|
||||
let client = Client::new(
|
||||
|
@ -81,7 +81,6 @@ extern crate ethash;
|
||||
extern crate ethcore_bloom_journal as bloom_journal;
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate ethcore_io as io;
|
||||
extern crate ethcore_ipc_nano as nanoipc;
|
||||
extern crate ethcore_bigint as bigint;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate ethcore_logger;
|
||||
@ -113,6 +112,8 @@ extern crate ansi_term;
|
||||
extern crate semantic_version;
|
||||
extern crate unexpected;
|
||||
extern crate kvdb;
|
||||
extern crate kvdb_rocksdb;
|
||||
extern crate kvdb_memorydb;
|
||||
extern crate util_error;
|
||||
extern crate snappy;
|
||||
extern crate migration;
|
||||
@ -129,6 +130,8 @@ extern crate bloomable;
|
||||
extern crate vm;
|
||||
extern crate wasm;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate memory_cache;
|
||||
extern crate journaldb;
|
||||
|
||||
#[macro_use]
|
||||
extern crate macros;
|
||||
@ -136,8 +139,6 @@ extern crate macros;
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate ethcore_ipc as ipc;
|
||||
#[cfg_attr(test, macro_use)]
|
||||
extern crate evm;
|
||||
|
||||
|
@ -263,7 +263,7 @@ impl EthereumMachine {
|
||||
} else if block_number < ext.eip150_transition {
|
||||
Schedule::new_homestead()
|
||||
} else {
|
||||
/// There's no max_code_size transition so we tie it to eip161abc
|
||||
// There's no max_code_size transition so we tie it to eip161abc
|
||||
let max_code_size = if block_number >= ext.eip161abc_transition {
|
||||
self.params.max_code_size as usize
|
||||
} else {
|
||||
|
@ -22,8 +22,8 @@ use std::collections::HashMap;
|
||||
use bigint::hash::H256;
|
||||
use util::Address;
|
||||
use bytes::Bytes;
|
||||
use kvdb::Database;
|
||||
use migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
||||
use kvdb_rocksdb::Database;
|
||||
use migration::{Batch, Config, Error, ErrorKind, Migration, SimpleMigration, Progress};
|
||||
use hash::keccak;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -109,7 +109,7 @@ impl OverlayRecentV7 {
|
||||
// walk all journal entries in the database backwards.
|
||||
// find migrations for any possible inserted keys.
|
||||
fn walk_journal(&mut self, source: Arc<Database>) -> Result<(), Error> {
|
||||
if let Some(val) = source.get(None, V7_LATEST_ERA_KEY).map_err(Error::Custom)? {
|
||||
if let Some(val) = source.get(None, V7_LATEST_ERA_KEY)? {
|
||||
let mut era = decode::<u64>(&val);
|
||||
loop {
|
||||
let mut index: usize = 0;
|
||||
@ -120,7 +120,7 @@ impl OverlayRecentV7 {
|
||||
r.out()
|
||||
};
|
||||
|
||||
if let Some(journal_raw) = source.get(None, &entry_key).map_err(Error::Custom)? {
|
||||
if let Some(journal_raw) = source.get(None, &entry_key)? {
|
||||
let rlp = Rlp::new(&journal_raw);
|
||||
|
||||
// migrate all inserted keys.
|
||||
@ -153,7 +153,7 @@ impl OverlayRecentV7 {
|
||||
// replace all possible inserted/deleted keys with their migrated counterparts
|
||||
// and commit the altered entries.
|
||||
fn migrate_journal(&self, source: Arc<Database>, mut batch: Batch, dest: &mut Database) -> Result<(), Error> {
|
||||
if let Some(val) = source.get(None, V7_LATEST_ERA_KEY).map_err(Error::Custom)? {
|
||||
if let Some(val) = source.get(None, V7_LATEST_ERA_KEY)? {
|
||||
batch.insert(V7_LATEST_ERA_KEY.into(), val.clone().into_vec(), dest)?;
|
||||
|
||||
let mut era = decode::<u64>(&val);
|
||||
@ -166,7 +166,7 @@ impl OverlayRecentV7 {
|
||||
r.out()
|
||||
};
|
||||
|
||||
if let Some(journal_raw) = source.get(None, &entry_key).map_err(Error::Custom)? {
|
||||
if let Some(journal_raw) = source.get(None, &entry_key)? {
|
||||
let rlp = Rlp::new(&journal_raw);
|
||||
let id: H256 = rlp.val_at(0);
|
||||
let mut inserted_keys: Vec<(H256, Bytes)> = Vec::new();
|
||||
@ -233,9 +233,9 @@ impl Migration for OverlayRecentV7 {
|
||||
let mut batch = Batch::new(config, col);
|
||||
|
||||
// check version metadata.
|
||||
match source.get(None, V7_VERSION_KEY).map_err(Error::Custom)? {
|
||||
match source.get(None, V7_VERSION_KEY)? {
|
||||
Some(ref version) if decode::<u32>(&*version) == DB_VERSION => {}
|
||||
_ => return Err(Error::MigrationImpossible), // missing or wrong version
|
||||
_ => return Err(ErrorKind::MigrationImpossible.into()), // missing or wrong version
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
|
@ -22,11 +22,12 @@ use state_db::{ACCOUNT_BLOOM_SPACE, DEFAULT_ACCOUNT_PRESET, StateDB};
|
||||
use trie::TrieDB;
|
||||
use views::HeaderView;
|
||||
use bloom_journal::Bloom;
|
||||
use migration::{Error, Migration, Progress, Batch, Config};
|
||||
use util::journaldb;
|
||||
use migration::{Error, Migration, Progress, Batch, Config, ErrorKind};
|
||||
use journaldb;
|
||||
use bigint::hash::H256;
|
||||
use trie::Trie;
|
||||
use kvdb::{Database, DBTransaction};
|
||||
use kvdb::{DBTransaction, ResultExt};
|
||||
use kvdb_rocksdb::Database;
|
||||
|
||||
/// Account bloom upgrade routine. If bloom already present, does nothing.
|
||||
/// If database empty (no best block), does nothing.
|
||||
@ -59,9 +60,9 @@ pub fn generate_bloom(source: Arc<Database>, dest: &mut Database) -> Result<(),
|
||||
source.clone(),
|
||||
journaldb::Algorithm::OverlayRecent,
|
||||
COL_STATE);
|
||||
let account_trie = TrieDB::new(state_db.as_hashdb(), &state_root).map_err(|e| Error::Custom(format!("Cannot open trie: {:?}", e)))?;
|
||||
for item in account_trie.iter().map_err(|_| Error::MigrationImpossible)? {
|
||||
let (ref account_key, _) = item.map_err(|_| Error::MigrationImpossible)?;
|
||||
let account_trie = TrieDB::new(state_db.as_hashdb(), &state_root).chain_err(|| "Cannot open trie")?;
|
||||
for item in account_trie.iter().map_err(|_| ErrorKind::MigrationImpossible)? {
|
||||
let (ref account_key, _) = item.map_err(|_| ErrorKind::MigrationImpossible)?;
|
||||
let account_key_hash = H256::from_slice(account_key);
|
||||
bloom.set(&*account_key_hash);
|
||||
}
|
||||
@ -72,7 +73,7 @@ pub fn generate_bloom(source: Arc<Database>, dest: &mut Database) -> Result<(),
|
||||
trace!(target: "migration", "Generated {} bloom updates", bloom_journal.entries.len());
|
||||
|
||||
let mut batch = DBTransaction::new();
|
||||
StateDB::commit_bloom(&mut batch, bloom_journal).map_err(|_| Error::Custom("Failed to commit bloom".to_owned()))?;
|
||||
StateDB::commit_bloom(&mut batch, bloom_journal).chain_err(|| "Failed to commit bloom")?;
|
||||
dest.write(batch)?;
|
||||
|
||||
trace!(target: "migration", "Finished bloom update");
|
||||
|
@ -18,7 +18,7 @@
|
||||
//! This migration consolidates all databases into single one using Column Families.
|
||||
|
||||
use rlp::{Rlp, RlpStream};
|
||||
use kvdb::Database;
|
||||
use kvdb_rocksdb::Database;
|
||||
use migration::{Batch, Config, Error, Migration, Progress};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl BanningTransactionQueue {
|
||||
/// queue.
|
||||
fn ban_sender(&mut self, address: Address) -> bool {
|
||||
let count = {
|
||||
let mut count = self.senders_bans.entry(address).or_insert_with(|| 0);
|
||||
let count = self.senders_bans.entry(address).or_insert_with(|| 0);
|
||||
*count = count.saturating_add(1);
|
||||
*count
|
||||
};
|
||||
@ -169,7 +169,7 @@ impl BanningTransactionQueue {
|
||||
/// Returns true if bans threshold has been reached.
|
||||
fn ban_recipient(&mut self, address: Address) -> bool {
|
||||
let count = {
|
||||
let mut count = self.recipients_bans.entry(address).or_insert_with(|| 0);
|
||||
let count = self.recipients_bans.entry(address).or_insert_with(|| 0);
|
||||
*count = count.saturating_add(1);
|
||||
*count
|
||||
};
|
||||
@ -185,7 +185,7 @@ impl BanningTransactionQueue {
|
||||
/// If bans threshold is reached all subsequent transactions to contracts with this codehash will be rejected.
|
||||
/// Returns true if bans threshold has been reached.
|
||||
fn ban_codehash(&mut self, code_hash: H256) -> bool {
|
||||
let mut count = self.codes_bans.entry(code_hash).or_insert_with(|| 0);
|
||||
let count = self.codes_bans.entry(code_hash).or_insert_with(|| 0);
|
||||
*count = count.saturating_add(1);
|
||||
|
||||
match self.ban_threshold {
|
||||
|
@ -341,7 +341,7 @@ impl GasPriceQueue {
|
||||
/// Remove an item from a BTreeMap/HashSet "multimap".
|
||||
/// Returns true if the item was removed successfully.
|
||||
pub fn remove(&mut self, gas_price: &U256, hash: &H256) -> bool {
|
||||
if let Some(mut hashes) = self.backing.get_mut(gas_price) {
|
||||
if let Some(hashes) = self.backing.get_mut(gas_price) {
|
||||
let only_one_left = hashes.len() == 1;
|
||||
if !only_one_left {
|
||||
// Operation may be ok: only if hash is in gas-price's Set.
|
||||
@ -1225,7 +1225,7 @@ impl TransactionQueue {
|
||||
if by_nonce.is_none() {
|
||||
return;
|
||||
}
|
||||
let mut by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
||||
let by_nonce = by_nonce.expect("None is tested in early-exit condition above; qed");
|
||||
while let Some(order) = by_nonce.remove(¤t_nonce) {
|
||||
// remove also from priority and gas_price
|
||||
self.future.by_priority.remove(&order);
|
||||
|
@ -19,7 +19,8 @@
|
||||
use std::sync::Arc;
|
||||
use std::path::Path;
|
||||
use bigint::hash::H256;
|
||||
use kvdb::{Database, DatabaseConfig, KeyValueDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use bytes::Bytes;
|
||||
use io::*;
|
||||
use spec::Spec;
|
||||
@ -29,12 +30,8 @@ use miner::Miner;
|
||||
|
||||
use snapshot::{ManifestData, RestorationStatus};
|
||||
use snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use ansi_term::Colour;
|
||||
|
||||
#[cfg(feature="ipc")]
|
||||
use nanoipc;
|
||||
|
||||
/// Message type for external and internal events
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum ClientIoMessage {
|
||||
@ -72,7 +69,7 @@ impl ClientService {
|
||||
spec: &Spec,
|
||||
client_path: &Path,
|
||||
snapshot_path: &Path,
|
||||
ipc_path: &Path,
|
||||
_ipc_path: &Path,
|
||||
miner: Arc<Miner>,
|
||||
) -> Result<ClientService, Error>
|
||||
{
|
||||
@ -120,7 +117,6 @@ impl ClientService {
|
||||
spec.engine.register_client(Arc::downgrade(&client) as _);
|
||||
|
||||
let stop_guard = ::devtools::StopGuard::new();
|
||||
run_ipc(ipc_path, client.clone(), snapshot.clone(), stop_guard.share());
|
||||
|
||||
Ok(ClientService {
|
||||
io_service: Arc::new(io_service),
|
||||
@ -228,38 +224,6 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="ipc")]
|
||||
fn run_ipc(base_path: &Path, client: Arc<Client>, snapshot_service: Arc<SnapshotService>, stop: Arc<AtomicBool>) {
|
||||
let mut path = base_path.to_owned();
|
||||
path.push("parity-chain.ipc");
|
||||
let socket_addr = format!("ipc://{}", path.to_string_lossy());
|
||||
let s = stop.clone();
|
||||
::std::thread::spawn(move || {
|
||||
let mut worker = nanoipc::Worker::new(&(client as Arc<BlockChainClient>));
|
||||
worker.add_reqrep(&socket_addr).expect("Ipc expected to initialize with no issues");
|
||||
|
||||
while !s.load(::std::sync::atomic::Ordering::Relaxed) {
|
||||
worker.poll();
|
||||
}
|
||||
});
|
||||
|
||||
let mut path = base_path.to_owned();
|
||||
path.push("parity-snapshot.ipc");
|
||||
let socket_addr = format!("ipc://{}", path.to_string_lossy());
|
||||
::std::thread::spawn(move || {
|
||||
let mut worker = nanoipc::Worker::new(&(snapshot_service as Arc<::snapshot::SnapshotService>));
|
||||
worker.add_reqrep(&socket_addr).expect("Ipc expected to initialize with no issues");
|
||||
|
||||
while !stop.load(::std::sync::atomic::Ordering::Relaxed) {
|
||||
worker.poll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(feature="ipc"))]
|
||||
fn run_ipc(_base_path: &Path, _client: Arc<Client>, _snapshot_service: Arc<SnapshotService>, _stop: Arc<AtomicBool>) {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -36,7 +36,7 @@ use util::{HashDB, DBValue};
|
||||
use snappy;
|
||||
use bytes::Bytes;
|
||||
use parking_lot::Mutex;
|
||||
use util::journaldb::{self, Algorithm, JournalDB};
|
||||
use journaldb::{self, Algorithm, JournalDB};
|
||||
use kvdb::KeyValueDB;
|
||||
use trie::{TrieDB, TrieDBMut, Trie, TrieMut};
|
||||
use rlp::{RlpStream, UntrustedRlp};
|
||||
@ -72,16 +72,7 @@ mod watcher;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// IPC interfaces
|
||||
#[cfg(feature="ipc")]
|
||||
pub mod remote {
|
||||
pub use super::traits::RemoteSnapshotService;
|
||||
}
|
||||
|
||||
mod traits {
|
||||
#![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues
|
||||
include!(concat!(env!("OUT_DIR"), "/snapshot_service_trait.rs"));
|
||||
}
|
||||
mod traits;
|
||||
|
||||
// Try to have chunks be around 4MB (before compression)
|
||||
const PREFERRED_CHUNK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
@ -39,8 +39,8 @@ use bigint::hash::H256;
|
||||
use parking_lot::{Mutex, RwLock, RwLockReadGuard};
|
||||
use util_error::UtilError;
|
||||
use bytes::Bytes;
|
||||
use util::journaldb::Algorithm;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use journaldb::Algorithm;
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use snappy;
|
||||
|
||||
/// Helper for removing directories in case of error.
|
||||
@ -625,7 +625,7 @@ mod tests {
|
||||
use io::{IoService};
|
||||
use devtools::RandomTempPath;
|
||||
use tests::helpers::get_test_spec;
|
||||
use util::journaldb::Algorithm;
|
||||
use journaldb::Algorithm;
|
||||
use error::Error;
|
||||
use snapshot::{ManifestData, RestorationStatus, SnapshotService};
|
||||
use super::*;
|
||||
@ -682,7 +682,7 @@ mod tests {
|
||||
#[test]
|
||||
fn cannot_finish_with_invalid_chunks() {
|
||||
use bigint::hash::H256;
|
||||
use kvdb::DatabaseConfig;
|
||||
use kvdb_rocksdb::DatabaseConfig;
|
||||
|
||||
let spec = get_test_spec();
|
||||
let dir = RandomTempPath::new();
|
||||
|
@ -35,7 +35,7 @@ use util::DBValue;
|
||||
use kvdb::KeyValueDB;
|
||||
use bigint::hash::H256;
|
||||
use hashdb::HashDB;
|
||||
use util::journaldb;
|
||||
use journaldb;
|
||||
use trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
|
||||
use trie::{TrieDB, TrieDBMut, Trie};
|
||||
|
||||
|
@ -31,7 +31,7 @@ use tests::helpers;
|
||||
use transaction::{Transaction, Action, SignedTransaction};
|
||||
|
||||
use util::Address;
|
||||
use kvdb;
|
||||
use kvdb_memorydb;
|
||||
|
||||
const PASS: &'static str = "";
|
||||
const TRANSITION_BLOCK_1: usize = 2; // block at which the contract becomes activated.
|
||||
@ -238,7 +238,7 @@ fn fixed_to_contract_only() {
|
||||
assert_eq!(client.chain_info().best_block_number, 11);
|
||||
let reader = snapshot_helpers::snap(&*client);
|
||||
|
||||
let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let spec = spec_fixed_to_contract();
|
||||
|
||||
// ensure fresh engine's step matches.
|
||||
@ -270,7 +270,7 @@ fn fixed_to_contract_to_contract() {
|
||||
|
||||
assert_eq!(client.chain_info().best_block_number, 16);
|
||||
let reader = snapshot_helpers::snap(&*client);
|
||||
let new_db = kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let new_db = kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0));
|
||||
let spec = spec_fixed_to_contract();
|
||||
|
||||
for _ in 0..16 { spec.engine.step() }
|
||||
|
@ -26,7 +26,8 @@ use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use snappy;
|
||||
use kvdb::{self, KeyValueDB, DBTransaction};
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use kvdb_memorydb;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
@ -43,7 +44,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
let mut snapshot_path = new_path.as_path().to_owned();
|
||||
snapshot_path.push("SNAP");
|
||||
|
||||
let old_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let old_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
||||
|
||||
// build the blockchain.
|
||||
@ -80,7 +81,7 @@ fn chunk_and_restore(amount: u64) {
|
||||
writer.into_inner().finish(manifest.clone()).unwrap();
|
||||
|
||||
// restore it.
|
||||
let new_db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let new_db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone());
|
||||
let mut rebuilder = SNAPSHOT_MODE.rebuilder(new_chain, new_db.clone(), &manifest).unwrap();
|
||||
|
||||
@ -127,7 +128,7 @@ fn checks_flag() {
|
||||
|
||||
let chunk = stream.out();
|
||||
|
||||
let db = Arc::new(kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let db = Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let engine = ::spec::Spec::new_test().engine;
|
||||
let chain = BlockChain::new(Default::default(), &genesis, db.clone());
|
||||
|
||||
|
@ -27,7 +27,7 @@ use tests::helpers::generate_dummy_client_with_spec_and_data;
|
||||
|
||||
use devtools::RandomTempPath;
|
||||
use io::IoChannel;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
|
||||
struct NoopDBRestore;
|
||||
|
||||
@ -69,7 +69,7 @@ fn restored_is_equivalent() {
|
||||
engine: spec.engine.clone(),
|
||||
genesis_block: spec.genesis_block(),
|
||||
db_config: db_config,
|
||||
pruning: ::util::journaldb::Algorithm::Archive,
|
||||
pruning: ::journaldb::Algorithm::Archive,
|
||||
channel: IoChannel::disconnected(),
|
||||
snapshot_root: path,
|
||||
db_restore: client2.clone(),
|
||||
@ -112,7 +112,7 @@ fn guards_delete_folders() {
|
||||
engine: spec.engine.clone(),
|
||||
genesis_block: spec.genesis_block(),
|
||||
db_config: DatabaseConfig::with_columns(::db::NUM_COLUMNS),
|
||||
pruning: ::util::journaldb::Algorithm::Archive,
|
||||
pruning: ::journaldb::Algorithm::Archive,
|
||||
channel: IoChannel::disconnected(),
|
||||
snapshot_root: path.clone(),
|
||||
db_restore: Arc::new(NoopDBRestore),
|
||||
|
@ -26,8 +26,8 @@ use error::Error;
|
||||
|
||||
use rand::{XorShiftRng, SeedableRng};
|
||||
use bigint::hash::H256;
|
||||
use util::journaldb::{self, Algorithm};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use journaldb::{self, Algorithm};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use memorydb::MemoryDB;
|
||||
use parking_lot::Mutex;
|
||||
use devtools::RandomTempPath;
|
||||
|
@ -17,13 +17,11 @@
|
||||
use super::{ManifestData, RestorationStatus};
|
||||
use bigint::hash::H256;
|
||||
use bytes::Bytes;
|
||||
use ipc::IpcConfig;
|
||||
|
||||
/// The interface for a snapshot network service.
|
||||
/// This handles:
|
||||
/// - restoration of snapshots to temporary databases.
|
||||
/// - responding to queries for snapshot manifests and chunks
|
||||
#[ipc(client_ident="RemoteSnapshotService")]
|
||||
pub trait SnapshotService : Sync + Send {
|
||||
/// Query the most recent manifest data.
|
||||
fn manifest(&self) -> Option<ManifestData>;
|
||||
@ -54,5 +52,3 @@ pub trait SnapshotService : Sync + Send {
|
||||
/// no-op if currently restoring.
|
||||
fn restore_block_chunk(&self, hash: H256, chunk: Bytes);
|
||||
}
|
||||
|
||||
impl IpcConfig for SnapshotService { }
|
@ -670,14 +670,14 @@ impl Spec {
|
||||
/// constructor.
|
||||
pub fn genesis_epoch_data(&self) -> Result<Vec<u8>, String> {
|
||||
use transaction::{Action, Transaction};
|
||||
use util::journaldb;
|
||||
use kvdb;
|
||||
use journaldb;
|
||||
use kvdb_memorydb;
|
||||
|
||||
let genesis = self.genesis_header();
|
||||
|
||||
let factories = Default::default();
|
||||
let mut db = journaldb::new(
|
||||
Arc::new(kvdb::in_memory(0)),
|
||||
Arc::new(kvdb_memorydb::create(0)),
|
||||
journaldb::Algorithm::Archive,
|
||||
None,
|
||||
);
|
||||
|
@ -962,7 +962,7 @@ impl<B: Backend> State<B> {
|
||||
|
||||
// at this point the entry is guaranteed to be in the cache.
|
||||
Ok(RefMut::map(self.cache.borrow_mut(), |c| {
|
||||
let mut entry = c.get_mut(a).expect("entry known to exist in the cache; qed");
|
||||
let entry = c.get_mut(a).expect("entry known to exist in the cache; qed");
|
||||
|
||||
match &mut entry.account {
|
||||
&mut Some(ref mut acc) => not_default(acc),
|
||||
|
@ -17,8 +17,8 @@
|
||||
use std::collections::{VecDeque, HashSet};
|
||||
use std::sync::Arc;
|
||||
use lru_cache::LruCache;
|
||||
use util::cache::MemoryLruCache;
|
||||
use util::journaldb::JournalDB;
|
||||
use memory_cache::MemoryLruCache;
|
||||
use journaldb::JournalDB;
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use bigint::hash::H256;
|
||||
use hashdb::HashDB;
|
||||
@ -211,7 +211,7 @@ impl StateDB {
|
||||
pub fn sync_cache(&mut self, enacted: &[H256], retracted: &[H256], is_best: bool) {
|
||||
trace!("sync_cache id = (#{:?}, {:?}), parent={:?}, best={}", self.commit_number, self.commit_hash, self.parent_hash, is_best);
|
||||
let mut cache = self.account_cache.lock();
|
||||
let mut cache = &mut *cache;
|
||||
let cache = &mut *cache;
|
||||
|
||||
// Purge changes from re-enacted and retracted blocks.
|
||||
// Filter out commiting block if any.
|
||||
|
@ -27,7 +27,7 @@ use tests::helpers::*;
|
||||
use types::filter::Filter;
|
||||
use bigint::prelude::U256;
|
||||
use util::*;
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use devtools::*;
|
||||
use miner::Miner;
|
||||
use spec::Spec;
|
||||
|
@ -36,7 +36,6 @@ use state_db::StateDB;
|
||||
use state::*;
|
||||
use std::sync::Arc;
|
||||
use transaction::{Action, Transaction, SignedTransaction};
|
||||
use util::*;
|
||||
use views::BlockView;
|
||||
|
||||
// TODO: move everything over to get_null_spec.
|
||||
@ -232,7 +231,7 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> Arc<Client> {
|
||||
}
|
||||
|
||||
fn new_db() -> Arc<::kvdb::KeyValueDB> {
|
||||
Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
pub fn generate_dummy_blockchain(block_number: u32) -> BlockChain {
|
||||
@ -282,7 +281,7 @@ pub fn get_temp_state_with_factory(factory: EvmFactory) -> State<::state_db::Sta
|
||||
|
||||
pub fn get_temp_state_db() -> StateDB {
|
||||
let db = new_db();
|
||||
let journal_db = journaldb::new(db, journaldb::Algorithm::EarlyMerge, ::db::COL_STATE);
|
||||
let journal_db = ::journaldb::new(db, ::journaldb::Algorithm::EarlyMerge, ::db::COL_STATE);
|
||||
StateDB::new(journal_db, 5 * 1024 * 1024)
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,3 @@ pub mod helpers;
|
||||
mod client;
|
||||
mod evm;
|
||||
mod trace;
|
||||
|
||||
#[cfg(feature="ipc")]
|
||||
mod rpc;
|
||||
|
||||
|
@ -1,78 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! Client RPC tests
|
||||
|
||||
use nanoipc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{Ordering, AtomicBool};
|
||||
use client::{Client, BlockChainClient, ClientConfig, BlockId};
|
||||
use client::remote::RemoteClient;
|
||||
use tests::helpers::*;
|
||||
use devtools::*;
|
||||
use miner::Miner;
|
||||
use crossbeam;
|
||||
use io::IoChannel;
|
||||
use util::kvdb::DatabaseConfig;
|
||||
|
||||
pub fn run_test_worker(scope: &crossbeam::Scope, stop: Arc<AtomicBool>, socket_path: &str) {
|
||||
let socket_path = socket_path.to_owned();
|
||||
scope.spawn(move || {
|
||||
let temp = RandomTempPath::create_dir();
|
||||
let spec = get_test_spec();
|
||||
let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfig::default(),
|
||||
&spec,
|
||||
temp.as_path(),
|
||||
Arc::new(Miner::with_spec(&spec)),
|
||||
IoChannel::disconnected(),
|
||||
&db_config
|
||||
).unwrap();
|
||||
let mut worker = nanoipc::Worker::new(&(client as Arc<BlockChainClient>));
|
||||
worker.add_reqrep(&socket_path).unwrap();
|
||||
while !stop.load(Ordering::Relaxed) {
|
||||
worker.poll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_handshake() {
|
||||
crossbeam::scope(|scope| {
|
||||
let stop_guard = StopGuard::new();
|
||||
let socket_path = "ipc:///tmp/parity-client-rpc-10.ipc";
|
||||
run_test_worker(scope, stop_guard.share(), socket_path);
|
||||
let remote_client = nanoipc::generic_client::<RemoteClient<_>>(socket_path).unwrap();
|
||||
|
||||
assert!(remote_client.handshake().is_ok());
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_query_block() {
|
||||
crossbeam::scope(|scope| {
|
||||
let stop_guard = StopGuard::new();
|
||||
let socket_path = "ipc:///tmp/parity-client-rpc-20.ipc";
|
||||
run_test_worker(scope, stop_guard.share(), socket_path);
|
||||
let remote_client = nanoipc::generic_client::<RemoteClient<_>>(socket_path).unwrap();
|
||||
|
||||
let non_existant_block = remote_client.block_header(BlockId::Number(999));
|
||||
|
||||
assert!(non_existant_block.is_none());
|
||||
})
|
||||
}
|
@ -27,7 +27,7 @@ use client::*;
|
||||
use tests::helpers::*;
|
||||
use devtools::RandomTempPath;
|
||||
use client::{BlockChainClient, Client, ClientConfig};
|
||||
use kvdb::{Database, DatabaseConfig};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use std::sync::Arc;
|
||||
use header::Header;
|
||||
use miner::Miner;
|
||||
|
@ -416,7 +416,8 @@ mod tests {
|
||||
use bigint::prelude::U256;
|
||||
use bigint::hash::H256;
|
||||
use util::Address;
|
||||
use kvdb::{DBTransaction, in_memory, KeyValueDB};
|
||||
use kvdb::{DBTransaction, KeyValueDB};
|
||||
use kvdb_memorydb;
|
||||
use header::BlockNumber;
|
||||
use trace::{Config, TraceDB, Database as TraceDatabase, DatabaseExtras, ImportRequest};
|
||||
use trace::{Filter, LocalizedTrace, AddressesFilter, TraceError};
|
||||
@ -467,7 +468,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn new_db() -> Arc<KeyValueDB> {
|
||||
Arc::new(in_memory(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
Arc::new(kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -30,7 +30,6 @@ use super::error::Error;
|
||||
|
||||
/// `Call` result.
|
||||
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct CallResult {
|
||||
/// Gas used by call.
|
||||
pub gas_used: U256,
|
||||
@ -40,7 +39,6 @@ pub struct CallResult {
|
||||
|
||||
/// `Create` result.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct CreateResult {
|
||||
/// Gas used by create.
|
||||
pub gas_used: U256,
|
||||
@ -59,7 +57,6 @@ impl CreateResult {
|
||||
|
||||
/// Description of a _call_ action, either a `CALL` operation or a message transction.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Call {
|
||||
/// The sending account.
|
||||
pub from: Address,
|
||||
@ -99,7 +96,6 @@ impl Call {
|
||||
|
||||
/// Description of a _create_ action, either a `CREATE` operation or a create transction.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Create {
|
||||
/// The address of the creator.
|
||||
pub from: Address,
|
||||
@ -132,7 +128,6 @@ impl Create {
|
||||
|
||||
/// Reward type.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub enum RewardType {
|
||||
/// Block
|
||||
Block,
|
||||
@ -162,7 +157,6 @@ impl Decodable for RewardType {
|
||||
|
||||
/// Reward action
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Reward {
|
||||
/// Author's address.
|
||||
pub author: Address,
|
||||
@ -203,7 +197,6 @@ impl Decodable for Reward {
|
||||
|
||||
/// Suicide action.
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub struct Suicide {
|
||||
/// Suicided address.
|
||||
pub address: Address,
|
||||
@ -223,7 +216,6 @@ impl Suicide {
|
||||
|
||||
/// Description of an action that we trace; will be either a call or a create.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub enum Action {
|
||||
/// It's a call action.
|
||||
Call(Call),
|
||||
@ -287,7 +279,6 @@ impl Action {
|
||||
|
||||
/// The result of the performed action.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
pub enum Res {
|
||||
/// Successful call action result.
|
||||
Call(CallResult),
|
||||
@ -365,7 +356,6 @@ impl Res {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// A diff of some chunk of memory.
|
||||
pub struct MemoryDiff {
|
||||
/// Offset into memory the change begins.
|
||||
@ -375,7 +365,6 @@ pub struct MemoryDiff {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// A diff of some storage value.
|
||||
pub struct StorageDiff {
|
||||
/// Which key in storage is changed.
|
||||
@ -385,7 +374,6 @@ pub struct StorageDiff {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// A record of an executed VM operation.
|
||||
pub struct VMExecutedOperation {
|
||||
/// The total gas used.
|
||||
@ -399,7 +387,6 @@ pub struct VMExecutedOperation {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// A record of the execution of a single VM operation.
|
||||
pub struct VMOperation {
|
||||
/// The program counter.
|
||||
@ -413,7 +400,6 @@ pub struct VMOperation {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Default, RlpEncodable, RlpDecodable)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// A record of a full VM trace for a CALL/CREATE.
|
||||
pub struct VMTrace {
|
||||
/// The step (i.e. index into operations) at which this trace corresponds.
|
||||
|
@ -178,7 +178,7 @@ mod test {
|
||||
"#;
|
||||
|
||||
let spec = Spec::load(&::std::env::temp_dir(), spec_data.as_bytes()).unwrap();
|
||||
let client_db = Arc::new(::kvdb::in_memory(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
let client_db = Arc::new(::kvdb_memorydb::create(::db::NUM_COLUMNS.unwrap_or(0)));
|
||||
|
||||
let client = Client::new(
|
||||
ClientConfig::default(),
|
||||
|
@ -522,7 +522,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
return;
|
||||
}
|
||||
let mut verified_lock = self.verification.verified.lock();
|
||||
let mut verified = &mut *verified_lock;
|
||||
let verified = &mut *verified_lock;
|
||||
let mut bad = self.verification.bad.lock();
|
||||
let mut processing = self.processing.write();
|
||||
bad.reserve(hashes.len());
|
||||
|
@ -51,7 +51,6 @@ impl<T> Diff<T> where T: Eq {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// Account diff.
|
||||
pub struct AccountDiff {
|
||||
/// Change in balance, allowed to be `Diff::Same`.
|
||||
@ -65,7 +64,6 @@ pub struct AccountDiff {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "ipc", binary)]
|
||||
/// Change in existance type.
|
||||
// TODO: include other types of change.
|
||||
pub enum Existance {
|
||||
|
@ -477,8 +477,8 @@ mod tests {
|
||||
.expect("Seed should be valid H128")
|
||||
.to_vec();
|
||||
|
||||
/// private key from bitcoin test vector
|
||||
/// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs
|
||||
// private key from bitcoin test vector
|
||||
// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs
|
||||
let test_private = H256::from_str("e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35")
|
||||
.expect("Private should be decoded ok");
|
||||
|
||||
@ -489,8 +489,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_vector_1() {
|
||||
/// xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7
|
||||
/// H(0)
|
||||
// xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7
|
||||
// H(0)
|
||||
test_extended(
|
||||
|secret| secret.derive(2147483648.into()),
|
||||
H256::from_str("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
||||
@ -500,8 +500,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_vector_2() {
|
||||
/// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs
|
||||
/// H(0)/1
|
||||
// xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs
|
||||
// H(0)/1
|
||||
test_extended(
|
||||
|secret| secret.derive(2147483648.into()).derive(1.into()),
|
||||
H256::from_str("3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368")
|
||||
|
@ -35,7 +35,7 @@ impl KeyDirectory for MemoryDirectory {
|
||||
|
||||
fn update(&self, account: SafeAccount) -> Result<SafeAccount, Error> {
|
||||
let mut lock = self.accounts.write();
|
||||
let mut accounts = lock.entry(account.address.clone()).or_insert_with(Vec::new);
|
||||
let accounts = lock.entry(account.address.clone()).or_insert_with(Vec::new);
|
||||
// If the filename is the same we just need to replace the entry
|
||||
accounts.retain(|acc| acc.filename != account.filename);
|
||||
accounts.push(account.clone());
|
||||
@ -44,14 +44,14 @@ impl KeyDirectory for MemoryDirectory {
|
||||
|
||||
fn insert(&self, account: SafeAccount) -> Result<SafeAccount, Error> {
|
||||
let mut lock = self.accounts.write();
|
||||
let mut accounts = lock.entry(account.address.clone()).or_insert_with(Vec::new);
|
||||
let accounts = lock.entry(account.address.clone()).or_insert_with(Vec::new);
|
||||
accounts.push(account.clone());
|
||||
Ok(account)
|
||||
}
|
||||
|
||||
fn remove(&self, account: &SafeAccount) -> Result<(), Error> {
|
||||
let mut accounts = self.accounts.write();
|
||||
let is_empty = if let Some(mut accounts) = accounts.get_mut(&account.address) {
|
||||
let is_empty = if let Some(accounts) = accounts.get_mut(&account.address) {
|
||||
if let Some(position) = accounts.iter().position(|acc| acc == account) {
|
||||
accounts.remove(position);
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ impl EthMultiStore {
|
||||
|
||||
// update cache
|
||||
let mut cache = self.cache.write();
|
||||
let mut accounts = cache.entry(account_ref.clone()).or_insert_with(Vec::new);
|
||||
let accounts = cache.entry(account_ref.clone()).or_insert_with(Vec::new);
|
||||
// Remove old account
|
||||
accounts.retain(|acc| acc != &old);
|
||||
// And push updated to the end
|
||||
|
@ -22,5 +22,5 @@ native-contracts = { path = "../ethcore/native_contracts" }
|
||||
hash = { path = "../util/hash" }
|
||||
|
||||
[dev-dependencies]
|
||||
ethabi = "2.0"
|
||||
ethabi = "4.0"
|
||||
parking_lot = "0.4"
|
||||
|
@ -265,8 +265,8 @@ pub mod tests {
|
||||
// given
|
||||
let registrar = FakeRegistrar::new();
|
||||
let resolve_result = {
|
||||
use ethabi::{Encoder, Token};
|
||||
Encoder::encode(vec![Token::String(String::new()), Token::FixedBytes(vec![0; 20]), Token::Address([0; 20])])
|
||||
use ethabi::{encode, Token};
|
||||
encode(&[Token::String(String::new()), Token::FixedBytes(vec![0; 20]), Token::Address([0; 20])])
|
||||
};
|
||||
registrar.responses.lock()[1] = Ok(resolve_result);
|
||||
|
||||
|
@ -255,7 +255,7 @@ impl Manager {
|
||||
let mut chunk_size = if chunk_index == 0 { 12 } else { 5 };
|
||||
let size = min(64 - chunk_size, data.len() - offset);
|
||||
{
|
||||
let mut chunk = &mut hid_chunk[HID_PREFIX_ZERO..];
|
||||
let chunk = &mut hid_chunk[HID_PREFIX_ZERO..];
|
||||
&mut chunk[0..5].copy_from_slice(&[0x01, 0x01, APDU_TAG, (chunk_index >> 8) as u8, (chunk_index & 0xff) as u8 ]);
|
||||
|
||||
if chunk_index == 0 {
|
||||
|
@ -37,8 +37,8 @@ use trezor_sys::messages::{EthereumAddress, PinMatrixAck, MessageType, EthereumT
|
||||
|
||||
const TREZOR_VID: u16 = 0x534c;
|
||||
const TREZOR_PIDS: [u16; 1] = [0x0001]; // Trezor v1, keeping this as an array to leave room for Trezor v2 which is in progress
|
||||
const ETH_DERIVATION_PATH: [u32; 4] = [0x8000002C, 0x8000003C, 0x80000000, 0]; // m/44'/60'/0'/0
|
||||
const ETC_DERIVATION_PATH: [u32; 4] = [0x8000002C, 0x8000003D, 0x80000000, 0]; // m/44'/61'/0'/0
|
||||
const ETH_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003C, 0x80000000, 0, 0]; // m/44'/60'/0'/0/0
|
||||
const ETC_DERIVATION_PATH: [u32; 5] = [0x8000002C, 0x8000003D, 0x80000000, 0, 0]; // m/44'/61'/0'/0/0
|
||||
|
||||
|
||||
/// Hardware wallet error.
|
||||
@ -201,7 +201,7 @@ impl Manager {
|
||||
where F: Fn() -> Result<R, &'static str>
|
||||
{
|
||||
let mut err = Error::KeyNotFound;
|
||||
/// Try to open device a few times.
|
||||
// Try to open device a few times.
|
||||
for _ in 0..10 {
|
||||
match f() {
|
||||
Ok(handle) => return Ok(handle),
|
||||
|
@ -1,16 +0,0 @@
|
||||
[package]
|
||||
description = "Types that implement IPC and are common to multiple modules."
|
||||
name = "ipc-common-types"
|
||||
version = "1.9.0"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
ethcore-ipc-codegen = { path = "../ipc/codegen" }
|
||||
|
||||
[dependencies]
|
||||
semver = "0.6"
|
||||
ethcore-ipc = { path = "../ipc/rpc" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "ethcore-ipc-codegen"
|
||||
version = "1.9.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "GPL-3.0"
|
||||
description = "Macros to auto-generate implementations for ipc call"
|
||||
build = "build.rs"
|
||||
keywords = ["ipc", "codegen"]
|
||||
|
||||
[features]
|
||||
default = ["with-syntex"]
|
||||
nightly = ["quasi_macros"]
|
||||
nightly-testing = ["clippy"]
|
||||
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
||||
|
||||
[build-dependencies]
|
||||
quasi_codegen = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
|
||||
[dependencies]
|
||||
aster = { version = "0.41", default-features = false }
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
quasi = { version = "0.32", default-features = false }
|
||||
quasi_macros = { version = "0.32", optional = true }
|
||||
syntex = { version = "0.58", optional = true }
|
||||
syntex_syntax = { version = "0.58", optional = true }
|
@ -1,898 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
use aster;
|
||||
|
||||
use syntax::ast::{
|
||||
MetaItem,
|
||||
Item,
|
||||
ImplItemKind,
|
||||
MethodSig,
|
||||
Arg,
|
||||
PatKind,
|
||||
FunctionRetTy,
|
||||
Ty,
|
||||
TraitRef,
|
||||
Ident,
|
||||
Generics,
|
||||
TraitItemKind,
|
||||
};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub struct Error;
|
||||
|
||||
const RESERVED_MESSAGE_IDS: u16 = 16;
|
||||
|
||||
pub fn expand_ipc_implementation(
|
||||
cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
meta_item: &MetaItem,
|
||||
annotatable: &Annotatable,
|
||||
push: &mut FnMut(Annotatable)
|
||||
) {
|
||||
let item = match *annotatable {
|
||||
Annotatable::Item(ref item) => item,
|
||||
_ => {
|
||||
cx.span_err(meta_item.span, "`#[ipc]` may only be applied to implementations and traits");
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
let builder = aster::AstBuilder::new().span(span);
|
||||
|
||||
let interface_map = match implement_interface(cx, &builder, &item, push, meta_item) {
|
||||
Ok(interface_map) => interface_map,
|
||||
Err(Error) => { return; },
|
||||
};
|
||||
|
||||
push_client(cx, &builder, &interface_map, push);
|
||||
|
||||
push(Annotatable::Item(interface_map.item));
|
||||
}
|
||||
|
||||
macro_rules! literal {
|
||||
($builder:ident, $($arg:tt)*) => {
|
||||
$builder.expr().lit().str::<&str>(&format!($($arg)*))
|
||||
}
|
||||
}
|
||||
|
||||
fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident {
|
||||
match arg.pat.node {
|
||||
PatKind::Ident(_, ref ident, _) => builder.id(ident.node),
|
||||
_ => { panic!("unexpected param in interface: {:?}", arg.pat.node) }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_slice_u8(builder: &aster::AstBuilder, ty: &P<ast::Ty>) -> P<ast::Ty> {
|
||||
if ::syntax::print::pprust::ty_to_string(&strip_ptr(ty)) == "[u8]" {
|
||||
return builder.ty().id("Vec<u8>")
|
||||
}
|
||||
ty.clone()
|
||||
}
|
||||
|
||||
struct NamedSignature<'a> {
|
||||
sig: &'a MethodSig,
|
||||
ident: &'a Ident,
|
||||
}
|
||||
|
||||
fn push_invoke_signature_aster(
|
||||
builder: &aster::AstBuilder,
|
||||
named_signature: &NamedSignature,
|
||||
push: &mut FnMut(Annotatable),
|
||||
) -> Dispatch {
|
||||
let inputs = &named_signature.sig.decl.inputs;
|
||||
let (input_type_name, input_arg_names, input_arg_tys) = if inputs.len() > 0 {
|
||||
let first_field_name = field_name(builder, &inputs[0]).name.as_str();
|
||||
if &*first_field_name == "self" && inputs.len() == 1 { (None, vec![], vec![]) }
|
||||
else {
|
||||
let skip = if &*first_field_name == "self" { 2 } else { 1 };
|
||||
let name_str = format!("{}_input", named_signature.ident.name.as_str());
|
||||
|
||||
let mut arg_names = Vec::new();
|
||||
let mut arg_tys = Vec::new();
|
||||
|
||||
let arg_name = format!("{}", field_name(builder, &inputs[skip-1]).name);
|
||||
let arg_ty = &inputs[skip-1].ty;
|
||||
|
||||
let mut tree = builder.item()
|
||||
.attr().word("binary")
|
||||
.attr().word("allow(non_camel_case_types)")
|
||||
.struct_(name_str.as_str())
|
||||
.field(arg_name.as_str())
|
||||
.ty().build(replace_slice_u8(builder, &strip_ptr(arg_ty)));
|
||||
|
||||
arg_names.push(arg_name);
|
||||
arg_tys.push(arg_ty.clone());
|
||||
for arg in inputs.iter().skip(skip) {
|
||||
let arg_name = format!("{}", field_name(builder, &arg));
|
||||
let arg_ty = &arg.ty;
|
||||
|
||||
tree = tree.field(arg_name.as_str()).ty().build(replace_slice_u8(builder, &strip_ptr(arg_ty)));
|
||||
arg_names.push(arg_name);
|
||||
arg_tys.push(arg_ty.clone());
|
||||
}
|
||||
|
||||
push(Annotatable::Item(tree.build()));
|
||||
(Some(name_str.to_owned()), arg_names, arg_tys)
|
||||
}
|
||||
}
|
||||
else {
|
||||
(None, vec![], vec![])
|
||||
};
|
||||
|
||||
let return_type_ty = match named_signature.sig.decl.output {
|
||||
FunctionRetTy::Ty(ref ty) => {
|
||||
let name_str = format!("{}_output", named_signature.ident.name.as_str());
|
||||
let tree = builder.item()
|
||||
.attr().word("binary")
|
||||
.attr().word("allow(non_camel_case_types)")
|
||||
.struct_(name_str.as_str())
|
||||
.field(format!("payload")).ty().build(ty.clone());
|
||||
push(Annotatable::Item(tree.build()));
|
||||
Some(ty.clone())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
|
||||
Dispatch {
|
||||
function_name: format!("{}", named_signature.ident.name.as_str()),
|
||||
input_type_name: input_type_name,
|
||||
input_arg_names: input_arg_names,
|
||||
input_arg_tys: input_arg_tys,
|
||||
return_type_ty: return_type_ty,
|
||||
}
|
||||
}
|
||||
|
||||
struct Dispatch {
|
||||
function_name: String,
|
||||
input_type_name: Option<String>,
|
||||
input_arg_names: Vec<String>,
|
||||
input_arg_tys: Vec<P<Ty>>,
|
||||
return_type_ty: Option<P<Ty>>,
|
||||
}
|
||||
|
||||
// This is the expanded version of this:
|
||||
//
|
||||
// let invoke_serialize_stmt = quote_stmt!(cx, {
|
||||
// ::bincode::serde::serialize(& $output_type_id { payload: self. $function_name ($hand_param_a, $hand_param_b) }, ::bincode::SizeLimit::Infinite).unwrap()
|
||||
// });
|
||||
//
|
||||
// But the above does not allow comma-separated expressions for arbitrary number
|
||||
// of parameters ...$hand_param_a, $hand_param_b, ... $hand_param_n
|
||||
fn implement_dispatch_arm_invoke_stmt(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
dispatch: &Dispatch,
|
||||
) -> ast::Stmt
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
let function_name = builder.id(dispatch.function_name.as_str());
|
||||
|
||||
let input_args_exprs = dispatch.input_arg_names.iter().enumerate().map(|(arg_index, arg_name)| {
|
||||
let arg_ident = builder.id(arg_name);
|
||||
let expr = quote_expr!(cx, input. $arg_ident);
|
||||
if has_ptr(&dispatch.input_arg_tys[arg_index]) { quote_expr!(cx, & $expr) }
|
||||
else { expr }
|
||||
}).collect::<Vec<P<ast::Expr>>>();
|
||||
|
||||
let ext_cx = &*cx;
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&function_name, ext_cx).into_iter());
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
for arg_expr in input_args_exprs {
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&arg_expr, ext_cx).into_iter());
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
if dispatch.return_type_ty.is_some() {
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Dot));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
}
|
||||
else {
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Semi));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::ModSep));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
}
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
tt
|
||||
}
|
||||
)).unwrap()
|
||||
}
|
||||
|
||||
fn implement_dispatch_arm_invoke(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
dispatch: &Dispatch,
|
||||
buffer: bool,
|
||||
) -> P<ast::Expr>
|
||||
{
|
||||
let deserialize_expr = if buffer {
|
||||
quote_expr!(cx,
|
||||
::ipc::binary::deserialize(buf)
|
||||
.unwrap_or_else(|e| { panic!("ipc error while deserializing payload, aborting \n payload: {:?}, \n error: {:?}", buf, e); } )
|
||||
)
|
||||
} else {
|
||||
quote_expr!(cx,
|
||||
::ipc::binary::deserialize_from(r)
|
||||
.unwrap_or_else(|e| { panic!("ipc error while deserializing payload, aborting \n error: {:?}", e); } )
|
||||
)
|
||||
};
|
||||
|
||||
let invoke_serialize_stmt = implement_dispatch_arm_invoke_stmt(cx, builder, dispatch);
|
||||
dispatch.input_type_name.as_ref().map(|val| {
|
||||
let input_type_id = builder.id(val.clone().as_str());
|
||||
quote_expr!(cx, {
|
||||
let input: $input_type_id = $deserialize_expr;
|
||||
$invoke_serialize_stmt
|
||||
})
|
||||
}).unwrap_or(quote_expr!(cx, { $invoke_serialize_stmt }))
|
||||
}
|
||||
|
||||
/// generates dispatch match for method id
|
||||
fn implement_dispatch_arm(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
index: u32,
|
||||
dispatch: &Dispatch,
|
||||
buffer: bool,
|
||||
) -> ast::Arm
|
||||
{
|
||||
let index_ident = builder.id(format!("{}", index + (RESERVED_MESSAGE_IDS as u32)).as_str());
|
||||
let invoke_expr = implement_dispatch_arm_invoke(cx, builder, dispatch, buffer);
|
||||
let trace = literal!(builder, "Dispatching: {}", &dispatch.function_name);
|
||||
quote_arm!(cx, $index_ident => {
|
||||
trace!(target: "ipc", $trace);
|
||||
$invoke_expr
|
||||
})
|
||||
}
|
||||
|
||||
fn implement_dispatch_arms(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
dispatches: &[Dispatch],
|
||||
buffer: bool,
|
||||
) -> Vec<ast::Arm>
|
||||
{
|
||||
let mut index = -1;
|
||||
dispatches.iter()
|
||||
.map(|dispatch| { index = index + 1; implement_dispatch_arm(cx, builder, index as u32, dispatch, buffer) }).collect()
|
||||
}
|
||||
|
||||
pub fn strip_ptr(ty: &P<ast::Ty>) -> P<ast::Ty> {
|
||||
if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node {
|
||||
ptr_mut.ty.clone()
|
||||
}
|
||||
else { ty.clone() }
|
||||
}
|
||||
|
||||
pub fn has_ptr(ty: &P<ast::Ty>) -> bool {
|
||||
if let ast::TyKind::Rptr(_, ref _ptr_mut) = ty.node {
|
||||
true
|
||||
}
|
||||
else { false }
|
||||
}
|
||||
|
||||
/// returns an expression with the body for single operation that is being sent to server
|
||||
/// operation itself serializes input, writes to socket and waits for socket to respond
|
||||
/// (the latter only if original method signature returns anyting)
|
||||
///
|
||||
/// assuming expanded class contains method
|
||||
/// fn commit(&self, f: u32) -> u32
|
||||
///
|
||||
/// the expanded implementation will generate method for the client like that
|
||||
/// #[binary]
|
||||
/// struct Request<'a> {
|
||||
/// f: &'a u32,
|
||||
/// }
|
||||
/// let payload = Request{f: &f,};
|
||||
/// let mut socket_ref = self.socket.borrow_mut();
|
||||
/// let mut socket = socket_ref.deref_mut();
|
||||
/// let serialized_payload = ::bincode::serde::serialize(&payload, ::bincode::SizeLimit::Infinite).unwrap();
|
||||
/// ::ipc::invoke(0, &Some(serialized_payload), &mut socket);
|
||||
/// while !socket.ready().load(::std::sync::atomic::Ordering::Relaxed) { }
|
||||
/// ::bincode::serde::deserialize_from::<_, u32>(&mut socket, ::bincode::SizeLimit::Infinite).unwrap()
|
||||
fn implement_client_method_body(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
index: u16,
|
||||
interface_map: &InterfaceMap,
|
||||
) -> P<ast::Expr>
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let dispatch = &interface_map.dispatches[index as usize];
|
||||
let index_ident = builder.id(format!("{}", index + RESERVED_MESSAGE_IDS).as_str());
|
||||
|
||||
let request = if dispatch.input_arg_names.len() > 0 {
|
||||
|
||||
let arg_name = dispatch.input_arg_names[0].as_str();
|
||||
let static_ty = strip_ptr(&dispatch.input_arg_tys[0]);
|
||||
let arg_ty = builder
|
||||
.ty().ref_()
|
||||
.lifetime("'a")
|
||||
.ty()
|
||||
.build(static_ty.clone());
|
||||
|
||||
let mut tree = builder.item()
|
||||
.attr().word("binary")
|
||||
.struct_("Request")
|
||||
.generics()
|
||||
.lifetime_name("'a")
|
||||
.build()
|
||||
.field(arg_name).ty()
|
||||
.build(arg_ty);
|
||||
|
||||
for arg_idx in 1..dispatch.input_arg_names.len() {
|
||||
let arg_name = dispatch.input_arg_names[arg_idx].as_str();
|
||||
let static_ty = strip_ptr(&dispatch.input_arg_tys[arg_idx]);
|
||||
|
||||
let arg_ty = builder
|
||||
.ty().ref_()
|
||||
.lifetime("'a")
|
||||
.ty()
|
||||
.build(static_ty);
|
||||
tree = tree.field(arg_name).ty().build(arg_ty);
|
||||
|
||||
}
|
||||
let mut request_serialization_statements = Vec::new();
|
||||
|
||||
let struct_tree = tree.build();
|
||||
let struct_stmt = quote_stmt!(cx, $struct_tree);
|
||||
request_serialization_statements.push(struct_stmt);
|
||||
|
||||
// actually this is just expanded version of this:
|
||||
// request_serialization_statements.push(quote_stmt!(cx, let payload = Request { p1: &p1, p2: &p2, ... pn: &pn, }));
|
||||
// again, cannot dynamically create expression with arbitrary number of comma-separated members
|
||||
request_serialization_statements.push({
|
||||
let ext_cx = &*cx;
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("let"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("payload"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Eq));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Request"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
for arg in dispatch.input_arg_names.iter() {
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg.as_str()))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
tt
|
||||
}))
|
||||
});
|
||||
|
||||
request_serialization_statements.push(
|
||||
quote_stmt!(cx, let mut socket = self.socket.write().unwrap(); ));
|
||||
|
||||
request_serialization_statements.push(
|
||||
quote_stmt!(cx, let serialized_payload = ::ipc::binary::serialize(&payload).unwrap()));
|
||||
|
||||
request_serialization_statements.push(
|
||||
quote_stmt!(cx, ::ipc::invoke($index_ident, &Some(serialized_payload), &mut *socket)));
|
||||
|
||||
|
||||
request_serialization_statements
|
||||
}
|
||||
else {
|
||||
let mut request_serialization_statements = Vec::new();
|
||||
request_serialization_statements.push(
|
||||
quote_stmt!(cx, let mut socket = self.socket.write().unwrap(); ));
|
||||
request_serialization_statements.push(
|
||||
quote_stmt!(cx, ::ipc::invoke($index_ident, &None, &mut *socket)));
|
||||
request_serialization_statements
|
||||
};
|
||||
|
||||
let trace = literal!(builder, "Invoking: {}", &dispatch.function_name);
|
||||
if let Some(ref return_ty) = dispatch.return_type_ty {
|
||||
let return_expr = quote_expr!(cx,
|
||||
::ipc::binary::deserialize_from::<$return_ty, _>(&mut *socket).unwrap()
|
||||
);
|
||||
quote_expr!(cx, {
|
||||
trace!(target: "ipc", $trace);
|
||||
$request;
|
||||
$return_expr
|
||||
})
|
||||
}
|
||||
else {
|
||||
quote_expr!(cx, {
|
||||
trace!(target: "ipc", $trace);
|
||||
$request
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates signature and body (see `implement_client_method_body`)
|
||||
/// for the client (signature is identical to the original method)
|
||||
fn implement_client_method(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
index: u16,
|
||||
interface_map: &InterfaceMap,
|
||||
)
|
||||
-> ast::ImplItem
|
||||
{
|
||||
use ::syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let dispatch = &interface_map.dispatches[index as usize];
|
||||
let method_name = builder.id(dispatch.function_name.as_str());
|
||||
let body = implement_client_method_body(cx, builder, index, interface_map);
|
||||
|
||||
let ext_cx = &*cx;
|
||||
// expanded version of this
|
||||
// pub fn $method_name(&self, p1: p1_ty, p2: p2_ty ... pn: pn_ty, ) [-> return_ty] { $body }
|
||||
// looks like it's tricky to build function declaration with aster if body already generated
|
||||
let signature = ::syntax::parse::parser::Parser::parse_impl_item(
|
||||
&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("fn"))));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&method_name, ext_cx).into_iter());
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And)));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self"))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
|
||||
for arg_idx in 0..dispatch.input_arg_names.len() {
|
||||
let arg_name = dispatch.input_arg_names[arg_idx].as_str();
|
||||
let arg_ty = dispatch.input_arg_tys[arg_idx].clone();
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of(arg_name))));
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Colon));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&arg_ty, ext_cx).into_iter());
|
||||
tt.push(Token(_sp, ::syntax::parse::token::Comma));
|
||||
}
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren)));
|
||||
|
||||
if let Some(ref return_ty) = dispatch.return_type_ty {
|
||||
tt.push(Token(_sp, ::syntax::parse::token::RArrow));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(return_ty, ext_cx).into_iter());
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace)));
|
||||
tt.extend(::quasi::ToTokens::to_tokens(&body, ext_cx).into_iter());
|
||||
tt.push(Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace)));
|
||||
|
||||
tt
|
||||
}));
|
||||
|
||||
signature.unwrap()
|
||||
}
|
||||
|
||||
fn client_generics(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> Generics {
|
||||
let ty_param = aster::ty_param::TyParamBuilder::new(
|
||||
builder.id("S")).trait_bound(
|
||||
builder.path().global().ids(&["ipc", "IpcSocket"]).build()
|
||||
).build().build();
|
||||
|
||||
builder.from_generics(interface_map.generics.clone())
|
||||
.with_ty_param(ty_param)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn client_qualified_ident(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P<Ty> {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder))
|
||||
.with_generics(generics).build()
|
||||
.build()
|
||||
}
|
||||
|
||||
fn client_phantom_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P<Ty> {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
aster::ty::TyBuilder::new().phantom_data()
|
||||
.tuple().with_tys(generics.ty_params.iter().map(|x| aster::ty::TyBuilder::new().id(x.ident)))
|
||||
.build()
|
||||
}
|
||||
|
||||
/// generates client type for specified server type
|
||||
/// for say `Service` it generates `ServiceClient`
|
||||
fn push_client_struct(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap, push: &mut FnMut(Annotatable)) {
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder);
|
||||
let phantom = client_phantom_ident(builder, interface_map);
|
||||
|
||||
let client_struct_item = quote_item!(cx,
|
||||
pub struct $client_short_ident $generics {
|
||||
socket: ::std::sync::RwLock<S>,
|
||||
phantom: $phantom,
|
||||
});
|
||||
|
||||
push(Annotatable::Item(client_struct_item.expect(&format!("could not generate client struct for {:?}", client_short_ident.name))));
|
||||
}
|
||||
|
||||
/// pushes generated code for the client class (type declaration and method invocation implementations)
|
||||
fn push_client(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
interface_map: &InterfaceMap,
|
||||
push: &mut FnMut(Annotatable),
|
||||
) {
|
||||
push_client_struct(cx, builder, interface_map, push);
|
||||
push_client_implementation(cx, builder, interface_map, push);
|
||||
push_with_socket_client_implementation(cx, builder, interface_map, push);
|
||||
}
|
||||
|
||||
fn push_with_socket_client_implementation(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
interface_map: &InterfaceMap,
|
||||
push: &mut FnMut(Annotatable))
|
||||
{
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(cx, builder, interface_map);
|
||||
let where_clause = &generics.where_clause;
|
||||
let client_short_ident = interface_map.ident_map.client_ident(cx, builder);
|
||||
|
||||
let implement = quote_item!(cx,
|
||||
impl $generics ::ipc::WithSocket<S> for $client_ident $where_clause {
|
||||
fn init(socket: S) -> $client_ident {
|
||||
$client_short_ident {
|
||||
socket: ::std::sync::RwLock::new(socket),
|
||||
phantom: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}).unwrap();
|
||||
push(Annotatable::Item(implement));
|
||||
}
|
||||
|
||||
/// pushes full client side code for the original class exposed via ipc
|
||||
fn push_client_implementation(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
interface_map: &InterfaceMap,
|
||||
push: &mut FnMut(Annotatable),
|
||||
) {
|
||||
let mut index = -1i32;
|
||||
let items = interface_map.dispatches.iter()
|
||||
.map(|_| { index = index + 1; P(implement_client_method(cx, builder, index as u16, interface_map)) })
|
||||
.collect::<Vec<P<ast::ImplItem>>>();
|
||||
|
||||
let generics = client_generics(builder, interface_map);
|
||||
let client_ident = client_qualified_ident(cx, builder, interface_map);
|
||||
let where_clause = &generics.where_clause;
|
||||
let endpoint = interface_map.endpoint;
|
||||
|
||||
let handshake_item = quote_impl_item!(cx,
|
||||
pub fn handshake(&self) -> Result<(), ::ipc::Error> {
|
||||
let payload = ::ipc::Handshake {
|
||||
protocol_version: $endpoint::protocol_version(),
|
||||
api_version: $endpoint::api_version(),
|
||||
};
|
||||
|
||||
::ipc::invoke(
|
||||
0,
|
||||
&Some(::ipc::binary::serialize(&::ipc::BinHandshake::from(payload)).unwrap()),
|
||||
&mut *self.socket.write().unwrap());
|
||||
|
||||
let mut result = vec![0u8; 1];
|
||||
if try!(self.socket.write().unwrap().read(&mut result).map_err(|_| ::ipc::Error::HandshakeFailed)) == 1 {
|
||||
match result[0] {
|
||||
1 => Ok(()),
|
||||
_ => Err(::ipc::Error::RemoteServiceUnsupported),
|
||||
}
|
||||
}
|
||||
else { Err(::ipc::Error::HandshakeFailed) }
|
||||
}).unwrap();
|
||||
|
||||
let socket_item = quote_impl_item!(cx,
|
||||
#[cfg(test)]
|
||||
pub fn socket(&self) -> &::std::sync::RwLock<S> {
|
||||
&self.socket
|
||||
}).unwrap();
|
||||
|
||||
let generic_items = vec![P(handshake_item), P(socket_item)];
|
||||
|
||||
if interface_map.impl_trait.is_some() {
|
||||
let trait_ty = builder.id(
|
||||
::syntax::print::pprust::path_to_string(
|
||||
&interface_map.impl_trait.as_ref().unwrap().path));
|
||||
|
||||
let implement_trait =
|
||||
quote_item!(cx,
|
||||
impl $generics $trait_ty for $client_ident $where_clause {
|
||||
$items
|
||||
}
|
||||
).unwrap();
|
||||
push(Annotatable::Item(implement_trait));
|
||||
|
||||
let implement =
|
||||
quote_item!(cx,
|
||||
impl $generics $client_ident $where_clause {
|
||||
$generic_items
|
||||
}
|
||||
).unwrap();
|
||||
push(Annotatable::Item(implement));
|
||||
}
|
||||
else {
|
||||
let pub_items = items.iter().map(|item| {
|
||||
let pub_item = item.clone();
|
||||
pub_item.map(|mut val| { val.vis = ast::Visibility::Public; val })
|
||||
}).collect::<Vec<P<ast::ImplItem>>>();
|
||||
|
||||
let implement = quote_item!(cx,
|
||||
impl $generics $client_ident $where_clause {
|
||||
$pub_items
|
||||
$generic_items
|
||||
}).unwrap();
|
||||
push(Annotatable::Item(implement));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// implements dispatching of system handshake invocation (method_num 0)
|
||||
fn implement_handshake_arm(
|
||||
cx: &ExtCtxt,
|
||||
) -> (ast::Arm, ast::Arm)
|
||||
{
|
||||
let handshake_deserialize = quote_stmt!(&cx,
|
||||
let handshake_payload = ::ipc::binary::deserialize_from::<::ipc::BinHandshake, _>(r).unwrap();
|
||||
);
|
||||
|
||||
let handshake_deserialize_buf = quote_stmt!(&cx,
|
||||
let handshake_payload = ::ipc::binary::deserialize::<::ipc::BinHandshake>(buf).unwrap();
|
||||
);
|
||||
|
||||
let handshake_serialize = quote_expr!(&cx,
|
||||
::ipc::binary::serialize::<bool>(&Self::handshake(&handshake_payload.to_semver())).unwrap()
|
||||
);
|
||||
|
||||
(
|
||||
quote_arm!(&cx, 0 => {
|
||||
$handshake_deserialize
|
||||
$handshake_serialize
|
||||
}),
|
||||
quote_arm!(&cx, 0 => {
|
||||
$handshake_deserialize_buf
|
||||
$handshake_serialize
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<String, ()> {
|
||||
match lit.node {
|
||||
ast::LitKind::Str(ref s, _) => Ok(format!("{}", s)),
|
||||
_ => {
|
||||
cx.span_err(
|
||||
lit.span,
|
||||
&format!("ipc client_ident annotation `{}` must be a string, not `{}`",
|
||||
name,
|
||||
::syntax::print::pprust::lit_to_string(lit)));
|
||||
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn client_ident_renamed(cx: &ExtCtxt, meta_item: &MetaItem) -> Option<String> {
|
||||
if let ast::MetaItemKind::List(ref list) = meta_item.node {
|
||||
for nested in list {
|
||||
match nested.node {
|
||||
ast::NestedMetaItemKind::MetaItem(ref meta_item) => {
|
||||
let is_client_ident = &*meta_item.name.as_str() == "client_ident";
|
||||
match meta_item.node {
|
||||
ast::MetaItemKind::NameValue(ref lit) if is_client_ident => {
|
||||
if let Ok(s) = get_str_from_lit(cx, "client_ident", lit) {
|
||||
return Some(s);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
cx.span_err(
|
||||
meta_item.span,
|
||||
&format!("unknown client_ident container attribute `{}`",
|
||||
::syntax::print::pprust::meta_item_to_string(&meta_item)));
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
struct InterfaceMap {
|
||||
pub original_item: Item,
|
||||
pub item: P<ast::Item>,
|
||||
pub dispatches: Vec<Dispatch>,
|
||||
pub generics: Generics,
|
||||
pub impl_trait: Option<TraitRef>,
|
||||
pub ident_map: IdentMap,
|
||||
pub endpoint: Ident,
|
||||
}
|
||||
|
||||
struct IdentMap {
|
||||
original_path: ast::Path,
|
||||
meta_item: MetaItem,
|
||||
}
|
||||
|
||||
impl IdentMap {
|
||||
fn ident(&self, builder: &aster::AstBuilder) -> Ident {
|
||||
builder.id(format!("{}", ::syntax::print::pprust::path_to_string(&self.original_path)))
|
||||
}
|
||||
|
||||
fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder) -> Ident {
|
||||
if let Some(new_name) = client_ident_renamed(cx, &self.meta_item) {
|
||||
builder.id(new_name)
|
||||
}
|
||||
else {
|
||||
builder.id(format!("{}Client", self.original_path.segments[0].identifier))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_ident_map(original_ty: &P<Ty>, meta_item: &MetaItem) -> IdentMap {
|
||||
let original_path = match original_ty.node {
|
||||
::syntax::ast::TyKind::Path(_, ref path) => path.clone(),
|
||||
_ => { panic!("incompatible implementation"); }
|
||||
};
|
||||
let ident_map = IdentMap { original_path: original_path, meta_item: meta_item.clone() };
|
||||
ident_map
|
||||
}
|
||||
|
||||
/// implements `IpcInterface` for the given class `C`
|
||||
fn implement_interface(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
item: &Item,
|
||||
push: &mut FnMut(Annotatable),
|
||||
meta_item: &MetaItem,
|
||||
) -> Result<InterfaceMap, Error> {
|
||||
let (generics, impl_trait, original_ty, dispatch_table) = match item.node {
|
||||
ast::ItemKind::Impl(_, _, ref generics, ref impl_trait, ref ty, ref impl_items) => {
|
||||
let mut method_signatures = Vec::new();
|
||||
for impl_item in impl_items {
|
||||
if let ImplItemKind::Method(ref signature, _) = impl_item.node {
|
||||
method_signatures.push(NamedSignature { ident: &impl_item.ident, sig: signature });
|
||||
}
|
||||
}
|
||||
|
||||
let dispatch_table = method_signatures.iter().map(|named_signature|
|
||||
push_invoke_signature_aster(builder, named_signature, push))
|
||||
.collect::<Vec<Dispatch>>();
|
||||
|
||||
(generics, impl_trait.clone(), ty.clone(), dispatch_table)
|
||||
},
|
||||
ast::ItemKind::Trait(_, ref generics, _, ref trait_items) => {
|
||||
let mut method_signatures = Vec::new();
|
||||
for trait_item in trait_items {
|
||||
if let TraitItemKind::Method(ref signature, _) = trait_item.node {
|
||||
method_signatures.push(NamedSignature { ident: &trait_item.ident, sig: signature });
|
||||
}
|
||||
}
|
||||
|
||||
let dispatch_table = method_signatures.iter().map(|named_signature|
|
||||
push_invoke_signature_aster(builder, named_signature, push))
|
||||
.collect::<Vec<Dispatch>>();
|
||||
|
||||
(
|
||||
generics,
|
||||
Some(ast::TraitRef {
|
||||
path: builder.path().ids(&[item.ident.name]).build(),
|
||||
ref_id: item.id,
|
||||
}),
|
||||
builder.ty().id(item.ident),
|
||||
dispatch_table
|
||||
)
|
||||
},
|
||||
_ => {
|
||||
cx.span_err(
|
||||
item.span,
|
||||
"`#[ipc]` may only be applied to implementations and traits");
|
||||
return Err(Error);
|
||||
},
|
||||
};
|
||||
let impl_generics = builder.from_generics(generics.clone()).build();
|
||||
let where_clause = &impl_generics.where_clause;
|
||||
|
||||
let dispatch_arms = implement_dispatch_arms(cx, builder, &dispatch_table, false);
|
||||
let dispatch_arms_buffered = implement_dispatch_arms(cx, builder, &dispatch_table, true);
|
||||
|
||||
let (handshake_arm, handshake_arm_buf) = implement_handshake_arm(cx);
|
||||
|
||||
let ty = ty_ident_map(&original_ty, meta_item).ident(builder);
|
||||
let (interface_endpoint, host_generics) = match impl_trait {
|
||||
Some(ref trait_) => (builder.id(::syntax::print::pprust::path_to_string(&trait_.path)), None),
|
||||
None => (ty, Some(&impl_generics)),
|
||||
};
|
||||
|
||||
let ipc_item = quote_item!(cx,
|
||||
impl $host_generics ::ipc::IpcInterface for $interface_endpoint $where_clause {
|
||||
fn dispatch<R>(&self, r: &mut R) -> Vec<u8>
|
||||
where R: ::std::io::Read
|
||||
{
|
||||
let mut method_num = vec![0u8;2];
|
||||
match r.read(&mut method_num) {
|
||||
Ok(size) if size == 0 => { panic!("method id not supplied" ); }
|
||||
Err(e) => { panic!("ipc read error: {:?}, aborting", e); }
|
||||
_ => { }
|
||||
}
|
||||
|
||||
// method_num is a 16-bit little-endian unsigned number
|
||||
match method_num[1] as u16 + (method_num[0] as u16)*256 {
|
||||
// handshake
|
||||
$handshake_arm
|
||||
// user methods
|
||||
$dispatch_arms
|
||||
_ => vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec<u8>
|
||||
{
|
||||
match method_num {
|
||||
$handshake_arm_buf
|
||||
$dispatch_arms_buffered
|
||||
_ => vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
|
||||
Ok(InterfaceMap {
|
||||
ident_map: ty_ident_map(&original_ty, meta_item),
|
||||
original_item: item.clone(),
|
||||
item: ipc_item,
|
||||
dispatches: dispatch_table,
|
||||
generics: generics.clone(),
|
||||
impl_trait: impl_trait.clone(),
|
||||
endpoint: interface_endpoint,
|
||||
})
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! Codegen for IPC RPC
|
||||
|
||||
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
|
||||
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
|
||||
#![cfg_attr(feature = "nightly-testing", allow(used_underscore_binding))]
|
||||
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
|
||||
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
|
||||
|
||||
extern crate aster;
|
||||
extern crate quasi;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
extern crate syntex;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
extern crate syntex_syntax as syntax;
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
#[macro_use]
|
||||
extern crate syntax;
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
extern crate rustc_plugin;
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
use syntax::feature_gate::AttributeType;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
use syntax::{ast, fold};
|
||||
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
include!("lib.rs.in");
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
pub fn expand(src: &std::path::Path, dst: &std::path::Path) {
|
||||
let mut registry = syntex::Registry::new();
|
||||
register(&mut registry);
|
||||
registry.expand("", src, dst).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
struct StripAttributeFolder<'a> {
|
||||
attr_title: &'a str,
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
impl<'a> fold::Folder for StripAttributeFolder<'a> {
|
||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||
let is_self = &*attr.value.name.as_str() == self.attr_title;
|
||||
|
||||
match attr.value.node {
|
||||
ast::MetaItemKind::List(_) if is_self => { return None; }
|
||||
ast::MetaItemKind::Word if is_self => { return None; }
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Some(attr)
|
||||
}
|
||||
|
||||
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
|
||||
fold::noop_fold_mac(mac, self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
pub fn register_cleaner_ipc(reg: &mut syntex::Registry) {
|
||||
#[cfg(feature = "with-syntex")]
|
||||
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
|
||||
let mut folder = StripAttributeFolder { attr_title: "ipc" };
|
||||
fold::Folder::fold_crate(&mut folder, krate)
|
||||
}
|
||||
|
||||
reg.add_post_expansion_pass(strip_attributes);
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
pub fn register_cleaner_binary(reg: &mut syntex::Registry) {
|
||||
#[cfg(feature = "with-syntex")]
|
||||
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
|
||||
let mut folder = StripAttributeFolder { attr_title: "binary" };
|
||||
fold::Folder::fold_crate(&mut folder, krate)
|
||||
}
|
||||
|
||||
reg.add_post_expansion_pass(strip_attributes);
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
pub fn register(reg: &mut syntex::Registry) {
|
||||
reg.add_attr("feature(custom_derive)");
|
||||
reg.add_attr("feature(custom_attribute)");
|
||||
|
||||
reg.add_decorator("ipc", codegen::expand_ipc_implementation);
|
||||
reg.add_decorator("binary", serialization::expand_serialization_implementation);
|
||||
|
||||
register_cleaner_ipc(reg);
|
||||
register_cleaner_binary(reg);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "with-syntex"))]
|
||||
pub fn register(reg: &mut rustc_plugin::Registry) {
|
||||
reg.register_syntax_extension(
|
||||
syntax::parse::token::intern("ipc"),
|
||||
syntax::ext::base::MultiDecorator(
|
||||
Box::new(codegen::expand_ipc_implementation)));
|
||||
reg.register_syntax_extension(
|
||||
syntax::parse::token::intern("binary"),
|
||||
syntax::ext::base::MultiDecorator(
|
||||
Box::new(serialization::expand_serialization_implementation)));
|
||||
|
||||
reg.register_attribute("ipc".to_owned(), AttributeType::Normal);
|
||||
reg.register_attribute("binary".to_owned(), AttributeType::Normal);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error { InvalidFileName, ExpandFailure, Io(std::io::Error) }
|
||||
|
||||
impl std::convert::From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Error::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn derive_ipc_cond(src_path: &str, has_feature: bool) -> Result<(), Error> {
|
||||
if has_feature { derive_ipc(src_path) }
|
||||
else { cleanup_ipc(src_path) }
|
||||
}
|
||||
|
||||
pub fn cleanup_ipc(src_path: &str) -> Result<(), Error> {
|
||||
cleanup(src_path, AttributeKind::Ipc)
|
||||
}
|
||||
|
||||
pub fn cleanup_binary(src_path: &str) -> Result<(), Error> {
|
||||
cleanup(src_path, AttributeKind::Binary)
|
||||
}
|
||||
|
||||
enum AttributeKind {
|
||||
Ipc,
|
||||
Binary,
|
||||
}
|
||||
|
||||
fn cleanup(src_path: &str, attr: AttributeKind) -> Result<(), Error> {
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?;
|
||||
let mut registry = syntex::Registry::new();
|
||||
|
||||
match attr {
|
||||
AttributeKind::Ipc => { register_cleaner_ipc(&mut registry); }
|
||||
AttributeKind::Binary => { register_cleaner_binary(&mut registry); }
|
||||
}
|
||||
|
||||
if let Err(_) = registry.expand("", &Path::new(src_path), &Path::new(&out_dir).join(&file_name))
|
||||
{
|
||||
// will be reported by compiler
|
||||
return Err(Error::ExpandFailure)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn derive_ipc(src_path: &str) -> Result<(), Error> {
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?;
|
||||
|
||||
let final_path = Path::new(&out_dir).join(&file_name);
|
||||
|
||||
let mut intermediate_file_name = file_name.clone();
|
||||
intermediate_file_name.push_str(".rpc.in");
|
||||
let intermediate_path = Path::new(&out_dir).join(&intermediate_file_name);
|
||||
|
||||
{
|
||||
let mut registry = syntex::Registry::new();
|
||||
register(&mut registry);
|
||||
if let Err(_) = registry.expand("", &Path::new(src_path), &intermediate_path) {
|
||||
// will be reported by compiler
|
||||
return Err(Error::ExpandFailure)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let mut registry = syntex::Registry::new();
|
||||
register(&mut registry);
|
||||
if let Err(_) = registry.expand("", &intermediate_path, &final_path) {
|
||||
// will be reported by compiler
|
||||
return Err(Error::ExpandFailure)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn derive_binary(src_path: &str) -> Result<(), Error> {
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let file_name = PathBuf::from(src_path).file_name().ok_or(Error::InvalidFileName).map(|val| val.to_str().unwrap().to_owned())?;
|
||||
let final_path = Path::new(&out_dir).join(&file_name);
|
||||
|
||||
let mut registry = syntex::Registry::new();
|
||||
register(&mut registry);
|
||||
if let Err(_) = registry.expand("", &Path::new(src_path), &final_path) {
|
||||
// will be reported by compiler
|
||||
return Err(Error::ExpandFailure)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn derive_binary_cond(src_path: &str, has_feature: bool) -> Result<(), Error> {
|
||||
if has_feature { derive_binary(src_path) }
|
||||
else { cleanup_binary(src_path) }
|
||||
}
|
@ -1,810 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
use aster;
|
||||
|
||||
use syntax::ast::{
|
||||
MetaItem,
|
||||
Item,
|
||||
Ident,
|
||||
};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub struct Error;
|
||||
|
||||
use super::codegen;
|
||||
|
||||
pub fn expand_serialization_implementation(
|
||||
cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
meta_item: &MetaItem,
|
||||
annotatable: &Annotatable,
|
||||
push: &mut FnMut(Annotatable)
|
||||
) {
|
||||
let item = match *annotatable {
|
||||
Annotatable::Item(ref item) => item,
|
||||
_ => {
|
||||
cx.span_err(meta_item.span, "`#[derive(Binary)]` may only be applied to structs and enums");
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
let builder = aster::AstBuilder::new().span(span);
|
||||
|
||||
let impl_item = match serialize_item(cx, &builder, &item) {
|
||||
Ok(item) => item,
|
||||
Err(Error) => {
|
||||
// An error occurred, but it should have been reported already.
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
push(Annotatable::Item(impl_item))
|
||||
}
|
||||
|
||||
fn serialize_item(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
item: &Item,
|
||||
) -> Result<P<ast::Item>, Error> {
|
||||
let generics = match item.node {
|
||||
ast::ItemKind::Struct(_, ref generics) => generics,
|
||||
ast::ItemKind::Enum(_, ref generics) => generics,
|
||||
_ => {
|
||||
cx.span_err(
|
||||
item.span,
|
||||
"`#[derive(Binary)]` may only be applied to structs and enums");
|
||||
return Err(Error);
|
||||
},
|
||||
};
|
||||
|
||||
let ty = builder.ty().path()
|
||||
.segment(item.ident).with_generics(generics.clone()).build()
|
||||
.build();
|
||||
|
||||
let where_clause = &generics.where_clause;
|
||||
|
||||
let binary_expressions = try!(binary_expr(cx,
|
||||
&builder,
|
||||
&item,
|
||||
&generics,
|
||||
ty.clone()));
|
||||
|
||||
let (size_expr, read_expr, write_expr) =
|
||||
(binary_expressions.size, binary_expressions.read, binary_expressions.write);
|
||||
|
||||
match quote_item!(cx,
|
||||
impl $generics ::ipc::BinaryConvertable for $ty $where_clause {
|
||||
fn size(&self) -> usize {
|
||||
$size_expr
|
||||
}
|
||||
|
||||
fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<(), ::ipc::BinaryConvertError> {
|
||||
$write_expr
|
||||
}
|
||||
|
||||
fn from_bytes(buffer: &[u8], length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, ::ipc::BinaryConvertError> {
|
||||
$read_expr
|
||||
}
|
||||
|
||||
fn len_params() -> usize {
|
||||
1
|
||||
}
|
||||
})
|
||||
{
|
||||
Some(item) => Ok(item),
|
||||
None => {
|
||||
cx.span_err(
|
||||
item.span,
|
||||
"syntax error expanding serialization implementation");
|
||||
Err(Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn binary_expr(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
item: &Item,
|
||||
impl_generics: &ast::Generics,
|
||||
ty: P<ast::Ty>,
|
||||
) -> Result<BinaryExpressions, Error> {
|
||||
match item.node {
|
||||
ast::ItemKind::Struct(ref variant_data, _) => {
|
||||
binary_expr_item_struct(
|
||||
cx,
|
||||
builder,
|
||||
impl_generics,
|
||||
ty,
|
||||
item.span,
|
||||
variant_data,
|
||||
)
|
||||
},
|
||||
ast::ItemKind::Enum(ref enum_def, _) => {
|
||||
binary_expr_enum(
|
||||
cx,
|
||||
builder,
|
||||
item.ident,
|
||||
impl_generics,
|
||||
ty,
|
||||
item.span,
|
||||
enum_def,
|
||||
)
|
||||
},
|
||||
_ => {
|
||||
cx.span_bug(item.span,
|
||||
"expected ItemStruct or ItemEnum in #[derive(Binary)]");
|
||||
Err(Error) as Result<BinaryExpressions, Error>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
struct BinaryExpressions {
|
||||
pub size: P<ast::Expr>,
|
||||
pub write: P<ast::Expr>,
|
||||
pub read: P<ast::Expr>,
|
||||
}
|
||||
|
||||
fn replace_qualified(s: &str) -> String {
|
||||
if let Some(pos) = s.find("<") {
|
||||
let mut source = s.to_owned();
|
||||
source.insert(pos, ':');
|
||||
source.insert(pos, ':');
|
||||
source
|
||||
}
|
||||
else { s.to_owned() }
|
||||
}
|
||||
|
||||
fn binary_expr_struct(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
ty: P<ast::Ty>,
|
||||
fields: &[ast::StructField],
|
||||
value_ident: Option<ast::Ident>,
|
||||
instance_ident: Option<ast::Ident>,
|
||||
) -> Result<BinaryExpressions, Error> {
|
||||
|
||||
let size_exprs: Vec<P<ast::Expr>> = fields.iter().enumerate().map(|(index, field)| {
|
||||
let raw_ident = ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty));
|
||||
let index_ident = builder.id(format!("__field{}", index));
|
||||
let field_id = match field.ident {
|
||||
Some(ident) => builder.id(ident),
|
||||
None => builder.id(format!("{}", index)),
|
||||
};
|
||||
|
||||
match raw_ident.as_ref() {
|
||||
"u8" => {
|
||||
quote_expr!(cx, 1)
|
||||
},
|
||||
"[u8]" => {
|
||||
value_ident.and_then(|x| {
|
||||
Some(quote_expr!(cx, $x. $field_id .len()))
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
quote_expr!(cx, $index_ident .len())
|
||||
}
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let field_type_ident = builder.id(
|
||||
&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)));
|
||||
|
||||
let field_type_ident_qualified = builder.id(
|
||||
replace_qualified(&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty))));
|
||||
|
||||
value_ident.and_then(|x|
|
||||
{
|
||||
Some(quote_expr!(cx,
|
||||
match $field_type_ident_qualified::len_params() {
|
||||
0 => ::std::mem::size_of::<$field_type_ident>(),
|
||||
_ => $x. $field_id .size(),
|
||||
}))
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
quote_expr!(cx, match $field_type_ident_qualified::len_params() {
|
||||
0 => ::std::mem::size_of::<$field_type_ident>(),
|
||||
_ => $index_ident .size(),
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let first_size_expr = size_exprs[0].clone();
|
||||
let mut total_size_expr = quote_expr!(cx, 0usize + $first_size_expr);
|
||||
for index in 1..size_exprs.len() {
|
||||
let next_expr = size_exprs[index].clone();
|
||||
total_size_expr = quote_expr!(cx, $total_size_expr + $next_expr);
|
||||
}
|
||||
|
||||
let mut write_stmts = Vec::<ast::Stmt>::new();
|
||||
write_stmts.push(quote_stmt!(cx, let mut offset = 0usize;).expect("stmt1"));
|
||||
|
||||
let mut map_stmts = Vec::<ast::Stmt>::new();
|
||||
let field_amount = builder.id(&format!("{}",fields.len()));
|
||||
map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).expect("stmt2"));
|
||||
map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).expect("stmt3"));
|
||||
|
||||
let mut post_write_stmts = Vec::<ast::Stmt>::new();
|
||||
|
||||
for (index, field) in fields.iter().enumerate() {
|
||||
let field_type_ident = builder.id(
|
||||
&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)));
|
||||
|
||||
let field_type_ident_qualified = builder.id(
|
||||
replace_qualified(&::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty))));
|
||||
|
||||
let field_id = match field.ident {
|
||||
Some(ident) => builder.id(ident),
|
||||
None => builder.id(format!("{}", index)),
|
||||
};
|
||||
let member_expr = match value_ident {
|
||||
Some(x) => {
|
||||
quote_expr!(cx, $x . $field_id)
|
||||
},
|
||||
None => {
|
||||
let index_ident = builder.id(format!("__field{}", index));
|
||||
quote_expr!(cx, $index_ident)
|
||||
},
|
||||
};
|
||||
|
||||
let raw_ident = ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty));
|
||||
let range_ident = builder.id(format!("r{}", index));
|
||||
|
||||
let error_message = "Error serializing member: ".to_owned() + &::syntax::print::pprust::expr_to_string(&member_expr);
|
||||
let _error_message_literal = builder.expr().lit().str::<&str>(&error_message);
|
||||
|
||||
match raw_ident.as_ref() {
|
||||
"u8" => {
|
||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + 1;).expect("stmt4"));
|
||||
write_stmts.push(quote_stmt!(cx, buffer[offset] = $member_expr; ).expect("stm5"));
|
||||
},
|
||||
"[u8]" => {
|
||||
write_stmts.push(quote_stmt!(cx, let size = $member_expr .len();).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + size;).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, length_stack.push_back(size);).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, let $range_ident = offset..next_line; ).unwrap());
|
||||
post_write_stmts.push(quote_stmt!(cx, buffer[$range_ident].clone_from_slice($member_expr); ).unwrap());
|
||||
}
|
||||
_ => {
|
||||
write_stmts.push(quote_stmt!(cx, let next_line = offset + match $field_type_ident_qualified::len_params() {
|
||||
0 => ::std::mem::size_of::<$field_type_ident>(),
|
||||
_ => { let size = $member_expr .size(); length_stack.push_back(size); size },
|
||||
}).unwrap());
|
||||
write_stmts.push(quote_stmt!(cx, let $range_ident = offset..next_line; ).unwrap());
|
||||
post_write_stmts.push(quote_stmt!(cx,
|
||||
if $range_ident.end - $range_ident.start > 0 {
|
||||
if let Err(e) = $member_expr .to_bytes(&mut buffer[$range_ident], length_stack) {
|
||||
return Err(e)
|
||||
};
|
||||
}
|
||||
).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
write_stmts.push(quote_stmt!(cx, offset = next_line; ).unwrap());
|
||||
|
||||
let field_index = builder.id(&format!("{}", index));
|
||||
map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap());
|
||||
|
||||
match raw_ident.as_ref() {
|
||||
"u8" => {
|
||||
map_stmts.push(quote_stmt!(cx, total += 1;).unwrap());
|
||||
},
|
||||
"[u8]" => {
|
||||
map_stmts.push(quote_stmt!(cx, let size = length_stack.pop_front().unwrap();).unwrap());
|
||||
map_stmts.push(quote_stmt!(cx, total += size;).unwrap());
|
||||
},
|
||||
_ => {
|
||||
map_stmts.push(quote_stmt!(cx, let size = match $field_type_ident_qualified::len_params() {
|
||||
0 => ::std::mem::size_of::<$field_type_ident>(),
|
||||
_ => length_stack.pop_front().unwrap(),
|
||||
}).unwrap());
|
||||
map_stmts.push(quote_stmt!(cx, total += size;).unwrap());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let read_expr = match fields.iter().any(|f| codegen::has_ptr(&f.ty)) {
|
||||
true => {
|
||||
// cannot create structs with pointers
|
||||
quote_expr!(cx, Err(::ipc::binary::BinaryConvertError::not_supported()))
|
||||
},
|
||||
false => {
|
||||
if value_ident.is_some() {
|
||||
let instance_create = named_fields_sequence(cx, &ty, fields);
|
||||
quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) })
|
||||
}
|
||||
else {
|
||||
let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self"))));
|
||||
quote_expr!(cx, { $map_stmts; Ok($map_variant) })
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Ok(BinaryExpressions {
|
||||
size: total_size_expr,
|
||||
write: quote_expr!(cx, { $write_stmts; $post_write_stmts; Ok(()) } ),
|
||||
read: read_expr,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn binary_expr_item_struct(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
_impl_generics: &ast::Generics,
|
||||
ty: P<ast::Ty>,
|
||||
span: Span,
|
||||
variant_data: &ast::VariantData,
|
||||
) -> Result<BinaryExpressions, Error> {
|
||||
match *variant_data {
|
||||
ast::VariantData::Tuple(ref fields, _) => {
|
||||
binary_expr_struct(
|
||||
cx,
|
||||
&builder,
|
||||
ty,
|
||||
fields,
|
||||
Some(builder.id("self")),
|
||||
None,
|
||||
)
|
||||
},
|
||||
ast::VariantData::Struct(ref fields, _) => {
|
||||
binary_expr_struct(
|
||||
cx,
|
||||
&builder,
|
||||
ty,
|
||||
fields,
|
||||
Some(builder.id("self")),
|
||||
None,
|
||||
)
|
||||
},
|
||||
_ => {
|
||||
cx.span_bug(span,
|
||||
&format!("#[derive(Binary)] Unsupported struct content, expected tuple/struct, found: {:?}",
|
||||
variant_data));
|
||||
Err(Error) as Result<BinaryExpressions, Error>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn binary_expr_enum(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
type_ident: Ident,
|
||||
impl_generics: &ast::Generics,
|
||||
ty: P<ast::Ty>,
|
||||
span: Span,
|
||||
enum_def: &ast::EnumDef,
|
||||
) -> Result<BinaryExpressions, Error> {
|
||||
let arms: Vec<_> = try!(enum_def.variants.iter()
|
||||
.enumerate()
|
||||
.map(|(variant_index, variant)| {
|
||||
binary_expr_variant(
|
||||
cx,
|
||||
builder,
|
||||
type_ident,
|
||||
impl_generics,
|
||||
ty.clone(),
|
||||
span,
|
||||
variant,
|
||||
variant_index,
|
||||
)
|
||||
})
|
||||
.collect());
|
||||
|
||||
let (size_arms, write_arms, mut read_arms) = (
|
||||
arms.iter().map(|x| x.size.clone()).collect::<Vec<ast::Arm>>(),
|
||||
arms.iter().map(|x| x.write.clone()).collect::<Vec<ast::Arm>>(),
|
||||
arms.iter().map(|x| x.read.clone()).collect::<Vec<ast::Arm>>());
|
||||
|
||||
read_arms.push(quote_arm!(cx, _ => { Err(::ipc::BinaryConvertError::variant(buffer[0])) } ));
|
||||
|
||||
Ok(BinaryExpressions {
|
||||
size: quote_expr!(cx, 1usize + match *self { $size_arms }),
|
||||
write: quote_expr!(cx, match *self { $write_arms }; ),
|
||||
read: quote_expr!(cx, match buffer[0] { $read_arms }),
|
||||
})
|
||||
}
|
||||
|
||||
struct BinaryArm {
|
||||
size: ast::Arm,
|
||||
write: ast::Arm,
|
||||
read: ast::Arm,
|
||||
}
|
||||
|
||||
fn fields_sequence(
|
||||
ext_cx: &ExtCtxt,
|
||||
_ty: &P<ast::Ty>,
|
||||
fields: &[ast::StructField],
|
||||
variant_ident: &ast::Ident,
|
||||
) -> ast::Expr {
|
||||
use syntax::parse::token;
|
||||
use syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
let named_members = fields.iter().any(|f| f.ident.is_some());
|
||||
|
||||
::quasi::parse_expr_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(Token(_sp, token::Ident(variant_ident.clone())));
|
||||
if named_members {
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Brace)));
|
||||
}
|
||||
else {
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
}
|
||||
|
||||
for (idx, field) in fields.iter().enumerate() {
|
||||
if field.ident.is_some() {
|
||||
tt.push(Token(_sp, token::Ident(field.ident.clone().unwrap())));
|
||||
tt.push(Token(_sp, token::Colon));
|
||||
}
|
||||
|
||||
// special case for u8, it just takes byte form sequence
|
||||
if ::syntax::print::pprust::ty_to_string(&field.ty) == "u8" {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
continue;
|
||||
}
|
||||
|
||||
// special case for [u8], it just takes a byte sequence
|
||||
if ::syntax::print::pprust::ty_to_string(&field.ty) == "[u8]" {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::DotDot));
|
||||
|
||||
if idx+1 != fields.len() {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
continue;
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(
|
||||
Token(
|
||||
_sp,
|
||||
token::Ident(ext_cx.ident_of(&replace_qualified(&::syntax::print::pprust::ty_to_string(&field.ty))))
|
||||
));
|
||||
tt.push(Token(_sp, token::ModSep));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
|
||||
tt.push(Token(_sp, token::BinOp(token::And)));
|
||||
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::DotDot));
|
||||
|
||||
if idx+1 != fields.len() {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack"))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
|
||||
// name member if it has resulted in the error
|
||||
tt.push(Token(_sp, token::Dot));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map_err"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::BinOp(token::Or)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e"))));
|
||||
tt.push(Token(_sp, token::BinOp(token::Or)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e"))));
|
||||
tt.push(Token(_sp, token::Dot));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("named"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::Literal(token::Lit::Str_(
|
||||
field.ident.unwrap_or(ext_cx.ident_of(&format!("f{}", idx))).name),
|
||||
None))
|
||||
);
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
}
|
||||
if named_members {
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Brace)));
|
||||
}
|
||||
else {
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
}
|
||||
tt
|
||||
})
|
||||
).unwrap()
|
||||
}
|
||||
|
||||
fn named_fields_sequence(
|
||||
ext_cx: &ExtCtxt,
|
||||
ty: &P<ast::Ty>,
|
||||
fields: &[ast::StructField],
|
||||
) -> ast::Stmt {
|
||||
use syntax::parse::token;
|
||||
use syntax::tokenstream::TokenTree::Token;
|
||||
|
||||
::quasi::parse_stmt_panic(&mut ::syntax::parse::new_parser_from_tts(
|
||||
ext_cx.parse_sess(),
|
||||
{
|
||||
let _sp = ext_cx.call_site();
|
||||
let mut tt = ::std::vec::Vec::new();
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("let"))));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("result"))));
|
||||
tt.push(Token(_sp, token::Eq));
|
||||
|
||||
tt.push(Token(
|
||||
_sp,
|
||||
token::Ident(
|
||||
ext_cx.ident_of(&::syntax::print::pprust::ty_to_string(ty))
|
||||
)));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Brace)));
|
||||
|
||||
for (idx, field) in fields.iter().enumerate() {
|
||||
tt.push(Token(_sp, match field.ident {
|
||||
Some(ident) => token::Ident(ident),
|
||||
None => token::Ident(ext_cx.ident_of(&format!("{}", idx))),
|
||||
}));
|
||||
tt.push(Token(_sp, token::Colon));
|
||||
|
||||
// special case for u8, it just takes byte form sequence
|
||||
if ::syntax::print::pprust::ty_to_string(&field.ty) == "u8" {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
continue;
|
||||
}
|
||||
|
||||
// special case for [u8], it just takes a byte sequence
|
||||
if ::syntax::print::pprust::ty_to_string(&field.ty) == "[u8]" {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::DotDot));
|
||||
|
||||
if idx+1 != fields.len() {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
continue;
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("try!"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(Token(
|
||||
_sp,
|
||||
token::Ident(
|
||||
ext_cx.ident_of(&replace_qualified(&::syntax::print::pprust::ty_to_string(&field.ty)))
|
||||
)));
|
||||
tt.push(Token(_sp, token::ModSep));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("from_bytes"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
|
||||
tt.push(Token(_sp, token::BinOp(token::And)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("buffer"))));
|
||||
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::DotDot));
|
||||
if idx + 1 != fields.len() {
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Bracket)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of(&format!("{}", idx+1)))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Bracket)));
|
||||
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("length_stack"))));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
|
||||
// name member if it has resulted in the error
|
||||
tt.push(Token(_sp, token::Dot));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("map_err"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::BinOp(token::Or)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e"))));
|
||||
tt.push(Token(_sp, token::BinOp(token::Or)));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("e"))));
|
||||
tt.push(Token(_sp, token::Dot));
|
||||
tt.push(Token(_sp, token::Ident(ext_cx.ident_of("named"))));
|
||||
tt.push(Token(_sp, token::OpenDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::Literal(token::Lit::Str_(
|
||||
field.ident.unwrap_or(ext_cx.ident_of(&format!("f{}", idx))).name),
|
||||
None))
|
||||
);
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Paren)));
|
||||
tt.push(Token(_sp, token::Comma));
|
||||
}
|
||||
|
||||
tt.push(Token(_sp, token::CloseDelim(token::Brace)));
|
||||
tt
|
||||
})
|
||||
).unwrap()
|
||||
}
|
||||
|
||||
fn binary_expr_variant(
|
||||
cx: &ExtCtxt,
|
||||
builder: &aster::AstBuilder,
|
||||
type_ident: Ident,
|
||||
_generics: &ast::Generics,
|
||||
ty: P<ast::Ty>,
|
||||
_span: Span,
|
||||
variant: &ast::Variant,
|
||||
variant_index: usize,
|
||||
) -> Result<BinaryArm, Error> {
|
||||
let variant_ident = variant.node.name;
|
||||
let variant_index_ident = builder.id(format!("{}", variant_index));
|
||||
|
||||
match variant.node.data {
|
||||
ast::VariantData::Unit(_) => {
|
||||
let pat = builder.pat().path()
|
||||
.id(type_ident).id(variant_ident)
|
||||
.build();
|
||||
|
||||
let variant_val = builder.id(format!("{}::{}", type_ident, variant_ident));
|
||||
|
||||
Ok(BinaryArm {
|
||||
size: quote_arm!(cx, $pat => { 0usize } ),
|
||||
write: quote_arm!(cx, $pat => { buffer[0] = $variant_index_ident; Ok(()) } ),
|
||||
read: quote_arm!(cx, $variant_index_ident => { Ok($variant_val) } ),
|
||||
})
|
||||
},
|
||||
ast::VariantData::Tuple(ref fields, _) => {
|
||||
let field_names: Vec<ast::Ident> = (0 .. fields.len())
|
||||
.map(|i| builder.id(format!("__field{}", i)))
|
||||
.collect();
|
||||
|
||||
let pat = builder.pat().enum_()
|
||||
.id(type_ident).id(variant_ident).build()
|
||||
.with_pats(
|
||||
field_names.iter()
|
||||
.map(|field| builder.pat().ref_id(field))
|
||||
)
|
||||
.build();
|
||||
|
||||
let binary_expr = try!(binary_expr_struct(
|
||||
cx,
|
||||
&builder,
|
||||
ty,
|
||||
fields,
|
||||
None,
|
||||
Some(builder.id(format!("{}::{}", type_ident, variant_ident))),
|
||||
));
|
||||
|
||||
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
|
||||
Ok(BinaryArm {
|
||||
size: quote_arm!(cx, $pat => { $size_expr } ),
|
||||
write: quote_arm!(cx,
|
||||
$pat => {
|
||||
buffer[0] = $variant_index_ident;
|
||||
let buffer = &mut buffer[1..];
|
||||
$write_expr
|
||||
}),
|
||||
read: quote_arm!(cx,
|
||||
$variant_index_ident => {
|
||||
let buffer = &buffer[1..];
|
||||
$read_expr
|
||||
}
|
||||
),
|
||||
})
|
||||
},
|
||||
ast::VariantData::Struct(ref fields, _) => {
|
||||
let field_names: Vec<_> = (0 .. fields.len())
|
||||
.map(|i| builder.id(format!("__field{}", i)))
|
||||
.collect();
|
||||
|
||||
let pat = builder.pat().struct_()
|
||||
.id(type_ident).id(variant_ident).build()
|
||||
.with_pats(
|
||||
field_names.iter()
|
||||
.zip(fields.iter())
|
||||
.map(|(id, field)|(field.ident.unwrap(), builder.pat().ref_id(id))))
|
||||
.build();
|
||||
|
||||
let binary_expr = try!(binary_expr_struct(
|
||||
cx,
|
||||
&builder,
|
||||
ty,
|
||||
fields,
|
||||
None,
|
||||
Some(builder.id(format!("{}::{}", type_ident, variant_ident))),
|
||||
));
|
||||
|
||||
let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read);
|
||||
|
||||
Ok(BinaryArm {
|
||||
size: quote_arm!(cx, $pat => { $size_expr } ),
|
||||
write: quote_arm!(cx,
|
||||
$pat => {
|
||||
buffer[0] = $variant_index_ident;
|
||||
let buffer = &mut buffer[1..];
|
||||
$write_expr
|
||||
}),
|
||||
read: quote_arm!(cx,
|
||||
$variant_index_ident => {
|
||||
let buffer = &buffer[1..];
|
||||
$read_expr
|
||||
}
|
||||
),
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
[package]
|
||||
name = "ethcore-ipc-hypervisor"
|
||||
version = "1.2.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "GPL-3.0"
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
ethcore-ipc = { path = "../rpc" }
|
||||
nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
ethcore-ipc-nano = { path = "../nano" }
|
||||
semver = "0.6"
|
||||
log = "0.3"
|
||||
time = "0.1"
|
||||
|
||||
[build-dependencies]
|
||||
ethcore-ipc-codegen = { path = "../codegen" }
|
@ -1,273 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! Parity interprocess hypervisor module
|
||||
|
||||
#![cfg_attr(feature="dev", allow(used_underscore_binding))]
|
||||
|
||||
extern crate ethcore_ipc as ipc;
|
||||
extern crate ethcore_ipc_nano as nanoipc;
|
||||
extern crate semver;
|
||||
#[macro_use] extern crate log;
|
||||
extern crate time;
|
||||
|
||||
pub mod service;
|
||||
|
||||
/// Default value for hypervisor ipc listener
|
||||
pub const HYPERVISOR_IPC_URL: &'static str = "parity-internal-hyper-status.ipc";
|
||||
|
||||
use std::sync::{Arc,RwLock};
|
||||
use service::{HypervisorService, IpcModuleId};
|
||||
use std::process::{Command,Child};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub use service::{HypervisorServiceClient, ControlService, CLIENT_MODULE_ID, SYNC_MODULE_ID};
|
||||
|
||||
pub type BinaryId = &'static str;
|
||||
|
||||
pub struct Hypervisor {
|
||||
ipc_addr: String,
|
||||
service: Arc<HypervisorService>,
|
||||
ipc_worker: RwLock<nanoipc::Worker<HypervisorService>>,
|
||||
processes: RwLock<HashMap<IpcModuleId, Child>>,
|
||||
modules: HashMap<IpcModuleId, BootArgs>,
|
||||
pub io_path: String,
|
||||
}
|
||||
|
||||
/// Boot arguments for binary
|
||||
pub struct BootArgs {
|
||||
cli: Option<Vec<String>>,
|
||||
stdin: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl BootArgs {
|
||||
/// New empty boot arguments
|
||||
pub fn new() -> BootArgs {
|
||||
BootArgs {
|
||||
cli: None,
|
||||
stdin: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set command-line arguments for boot
|
||||
pub fn cli(mut self, cli: Vec<String>) -> BootArgs {
|
||||
self.cli = Some(cli);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set std-in stream for boot
|
||||
pub fn stdin(mut self, stdin: Vec<u8>) -> BootArgs {
|
||||
self.stdin = Some(stdin);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Hypervisor {
|
||||
/// initializes the Hypervisor service with the open ipc socket for incoming clients
|
||||
pub fn new() -> Hypervisor {
|
||||
Hypervisor::with_url(HYPERVISOR_IPC_URL)
|
||||
}
|
||||
|
||||
pub fn module(mut self, module_id: IpcModuleId, args: BootArgs) -> Hypervisor {
|
||||
self.modules.insert(module_id, args);
|
||||
self.service.add_module(module_id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn local_module(self, module_id: IpcModuleId) -> Hypervisor {
|
||||
self.service.add_module(module_id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn io_path(mut self, directory: &str) -> Hypervisor {
|
||||
self.io_path = directory.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
/// Starts with the specified address for the ipc listener and
|
||||
/// the specified list of modules in form of created service
|
||||
pub fn with_url(addr: &str) -> Hypervisor {
|
||||
let service = HypervisorService::new();
|
||||
let worker = nanoipc::Worker::new(&service);
|
||||
Hypervisor{
|
||||
ipc_addr: addr.to_owned(),
|
||||
service: service,
|
||||
ipc_worker: RwLock::new(worker),
|
||||
processes: RwLock::new(HashMap::new()),
|
||||
modules: HashMap::new(),
|
||||
io_path: "/tmp".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Since one binary can host multiple modules
|
||||
/// we match binaries
|
||||
fn match_module(&self, module_id: &IpcModuleId) -> Option<&BootArgs> {
|
||||
self.modules.get(module_id)
|
||||
}
|
||||
|
||||
/// Creates IPC listener and starts all binaries
|
||||
pub fn start(&self) {
|
||||
let mut worker = self.ipc_worker.write().unwrap();
|
||||
worker.add_reqrep(&self.ipc_addr).unwrap_or_else(|e| panic!("Hypervisor ipc worker can not start - critical! ({:?})", e));
|
||||
|
||||
for module_id in self.service.module_ids() {
|
||||
self.start_module(module_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Start binary for the specified module
|
||||
/// Does nothing when it is already started on module is inside the
|
||||
/// main binary
|
||||
fn start_module(&self, module_id: IpcModuleId) {
|
||||
use std::io::Write;
|
||||
|
||||
self.match_module(&module_id).map(|boot_args| {
|
||||
let mut processes = self.processes.write().unwrap();
|
||||
{
|
||||
if processes.get(&module_id).is_some() {
|
||||
// already started for another module
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let mut command = Command::new(&std::env::current_exe().unwrap());
|
||||
command.stderr(std::process::Stdio::inherit());
|
||||
|
||||
if let Some(ref cli_args) = boot_args.cli {
|
||||
for arg in cli_args { command.arg(arg); }
|
||||
}
|
||||
|
||||
command.stdin(std::process::Stdio::piped());
|
||||
|
||||
trace!(target: "hypervisor", "Spawn executable: {:?}", command);
|
||||
|
||||
let mut child = command.spawn().unwrap_or_else(
|
||||
|e| panic!("Hypervisor cannot execute command ({:?}): {}", command, e));
|
||||
|
||||
if let Some(ref std_in) = boot_args.stdin {
|
||||
trace!(target: "hypervisor", "Pushing std-in payload...");
|
||||
child.stdin.as_mut()
|
||||
.expect("std-in should be piped above")
|
||||
.write(std_in)
|
||||
.unwrap_or_else(|e| panic!(format!("Error trying to pipe stdin for {:?}: {:?}", &command, e)));
|
||||
drop(child.stdin.take());
|
||||
}
|
||||
|
||||
processes.insert(module_id, child);
|
||||
});
|
||||
}
|
||||
|
||||
/// Reports if all modules are checked in
|
||||
pub fn modules_ready(&self) -> bool {
|
||||
self.service.unchecked_count() == 0
|
||||
}
|
||||
|
||||
pub fn modules_shutdown(&self) -> bool {
|
||||
self.service.running_count() == 0
|
||||
}
|
||||
|
||||
/// Waits for every required module to check in
|
||||
pub fn wait_for_startup(&self) {
|
||||
let mut worker = self.ipc_worker.write().unwrap();
|
||||
while !self.modules_ready() {
|
||||
worker.poll()
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for every required module to check in
|
||||
pub fn wait_for_shutdown(&self) -> bool {
|
||||
use time::{PreciseTime, Duration};
|
||||
|
||||
let mut worker = self.ipc_worker.write().unwrap();
|
||||
let start = PreciseTime::now();
|
||||
while !self.modules_shutdown() {
|
||||
worker.poll();
|
||||
if start.to(PreciseTime::now()) > Duration::seconds(30) {
|
||||
warn!("Some modules failed to shutdown gracefully, they will be terminated.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.modules_shutdown()
|
||||
}
|
||||
|
||||
/// Shutdown the ipc and all managed child processes
|
||||
pub fn shutdown(&self) {
|
||||
let mut childs = self.processes.write().unwrap();
|
||||
for (ref module, _) in childs.iter() {
|
||||
trace!(target: "hypervisor", "Stopping process module: {}", module);
|
||||
self.service.send_shutdown(**module);
|
||||
}
|
||||
trace!(target: "hypervisor", "Waiting for shutdown...");
|
||||
if self.wait_for_shutdown() {
|
||||
trace!(target: "hypervisor", "All modules reported shutdown");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ref module, ref mut process) in childs.iter_mut() {
|
||||
if self.service.is_running(**module) {
|
||||
process.kill().unwrap();
|
||||
trace!("Terminated {}", module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Hypervisor {
|
||||
fn drop(&mut self) {
|
||||
self.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::sync::atomic::{AtomicBool,Ordering};
|
||||
use std::sync::Arc;
|
||||
use nanoipc;
|
||||
|
||||
#[test]
|
||||
fn can_init() {
|
||||
let url = "ipc:///tmp/test-parity-hypervisor-10.ipc";
|
||||
let test_module_id = 8080u64;
|
||||
|
||||
let hypervisor = Hypervisor::with_url(url).local_module(test_module_id);
|
||||
assert_eq!(false, hypervisor.modules_ready());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_wait_for_startup() {
|
||||
let url = "ipc:///tmp/test-parity-hypervisor-20.ipc";
|
||||
let test_module_id = 8080u64;
|
||||
|
||||
let hypervisor_ready = Arc::new(AtomicBool::new(false));
|
||||
let hypervisor_ready_local = hypervisor_ready.clone();
|
||||
|
||||
::std::thread::spawn(move || {
|
||||
while !hypervisor_ready.load(Ordering::Relaxed) { }
|
||||
|
||||
let client = nanoipc::fast_client::<HypervisorServiceClient<_>>(url).unwrap();
|
||||
client.handshake().unwrap();
|
||||
client.module_ready(test_module_id, url.to_owned());
|
||||
});
|
||||
|
||||
let hypervisor = Hypervisor::with_url(url).local_module(test_module_id);
|
||||
hypervisor.start();
|
||||
hypervisor_ready_local.store(true, Ordering::Relaxed);
|
||||
hypervisor.wait_for_startup();
|
||||
|
||||
assert_eq!(true, hypervisor.modules_ready());
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! Parity interprocess hypervisor IPC service
|
||||
#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/service.rs.in"));
|
@ -1,125 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
use std::sync::{RwLock,Arc};
|
||||
use ipc::IpcConfig;
|
||||
use std::collections::HashMap;
|
||||
use nanoipc;
|
||||
|
||||
pub type IpcModuleId = u64;
|
||||
|
||||
/// Blockhain database module id
|
||||
pub const CLIENT_MODULE_ID: IpcModuleId = 2000;
|
||||
|
||||
/// Sync module id
|
||||
pub const SYNC_MODULE_ID: IpcModuleId = 2100;
|
||||
|
||||
/// IPC service that handles module management
|
||||
pub struct HypervisorService {
|
||||
modules: RwLock<HashMap<IpcModuleId, ModuleState>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ModuleState {
|
||||
started: bool,
|
||||
control_url: String,
|
||||
shutdown: bool,
|
||||
}
|
||||
|
||||
#[ipc]
|
||||
pub trait ControlService {
|
||||
fn shutdown(&self) -> bool;
|
||||
}
|
||||
|
||||
#[ipc]
|
||||
impl HypervisorService {
|
||||
// return type for making method synchronous
|
||||
fn module_ready(&self, module_id: u64, control_url: String) -> bool {
|
||||
let mut modules = self.modules.write().unwrap();
|
||||
modules.get_mut(&module_id).map(|mut module| {
|
||||
module.started = true;
|
||||
module.control_url = control_url;
|
||||
});
|
||||
trace!(target: "hypervisor", "Module ready: {}", module_id);
|
||||
true
|
||||
}
|
||||
|
||||
// return type for making method synchronous
|
||||
fn module_shutdown(&self, module_id: u64) -> bool {
|
||||
let mut modules = self.modules.write().unwrap();
|
||||
modules.get_mut(&module_id).map(|mut module| {
|
||||
module.shutdown = true;
|
||||
});
|
||||
trace!(target: "hypervisor", "Module shutdown: {}", module_id);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl HypervisorService {
|
||||
/// New service with the default list of modules
|
||||
pub fn new() -> Arc<HypervisorService> {
|
||||
HypervisorService::with_modules(vec![])
|
||||
}
|
||||
|
||||
/// New service with list of modules that will report for being ready
|
||||
pub fn with_modules(module_ids: Vec<IpcModuleId>) -> Arc<HypervisorService> {
|
||||
let mut modules = HashMap::new();
|
||||
for module_id in module_ids {
|
||||
modules.insert(module_id, ModuleState::default());
|
||||
}
|
||||
Arc::new(HypervisorService {
|
||||
modules: RwLock::new(modules),
|
||||
})
|
||||
}
|
||||
|
||||
/// Add the module to the check-list
|
||||
pub fn add_module(&self, module_id: IpcModuleId) {
|
||||
self.modules.write().unwrap().insert(module_id, ModuleState::default());
|
||||
}
|
||||
|
||||
/// Number of modules still being waited for check-in
|
||||
pub fn unchecked_count(&self) -> usize {
|
||||
self.modules.read().unwrap().iter().filter(|&(_, module)| !module.started).count()
|
||||
}
|
||||
|
||||
/// List of all modules within this service
|
||||
pub fn module_ids(&self) -> Vec<IpcModuleId> {
|
||||
self.modules.read().unwrap().iter().map(|(module_id, _)| module_id).cloned().collect()
|
||||
}
|
||||
|
||||
/// Number of modules started and running
|
||||
pub fn running_count(&self) -> usize {
|
||||
self.modules.read().unwrap().iter().filter(|&(_, module)| module.started && !module.shutdown).count()
|
||||
}
|
||||
|
||||
pub fn is_running(&self, id: IpcModuleId) -> bool {
|
||||
self.modules.read().unwrap().get(&id).map(|module| module.started && !module.shutdown).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn send_shutdown(&self, module_id: IpcModuleId) {
|
||||
let modules = self.modules.read().unwrap();
|
||||
modules.get(&module_id).map(|module| {
|
||||
trace!(target: "hypervisor", "Sending shutdown to {}({})", module_id, &module.control_url);
|
||||
let client = nanoipc::fast_client::<ControlServiceClient<_>>(&module.control_url).unwrap();
|
||||
client.shutdown();
|
||||
trace!(target: "hypervisor", "Sent shutdown to {}", module_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl ::ipc::IpcConfig for HypervisorService {}
|
||||
|
||||
impl ::ipc::IpcConfig for ControlService {}
|
@ -1,13 +0,0 @@
|
||||
[package]
|
||||
name = "ethcore-ipc-nano"
|
||||
version = "1.9.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "GPL-3.0"
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
ethcore-ipc = { path = "../rpc" }
|
||||
nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
log = "0.3"
|
||||
lazy_static = "0.2"
|
@ -1,355 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! IPC over nanomsg transport
|
||||
|
||||
extern crate ethcore_ipc as ipc;
|
||||
extern crate nanomsg;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
pub use ipc::{WithSocket, IpcInterface, IpcConfig};
|
||||
pub use nanomsg::Socket as NanoSocket;
|
||||
|
||||
use std::sync::*;
|
||||
use nanomsg::{Socket, Protocol, Error, Endpoint, PollRequest, PollFd, PollInOut};
|
||||
use std::ops::Deref;
|
||||
|
||||
const POLL_TIMEOUT: isize = 200;
|
||||
const DEFAULT_CONNECTION_TIMEOUT: isize = 30000;
|
||||
const DEBUG_CONNECTION_TIMEOUT: isize = 5000;
|
||||
|
||||
/// Generic worker to handle service (binded) sockets
|
||||
pub struct Worker<S: ?Sized> where S: IpcInterface {
|
||||
service: Arc<S>,
|
||||
sockets: Vec<(Socket, Endpoint)>,
|
||||
polls: Vec<PollFd>,
|
||||
buf: Vec<u8>,
|
||||
}
|
||||
|
||||
/// struct for guarding `_endpoint` (so that it wont drop)
|
||||
/// derefs to client `S`
|
||||
pub struct GuardedSocket<S> where S: WithSocket<Socket> {
|
||||
client: Arc<S>,
|
||||
_endpoint: Endpoint,
|
||||
}
|
||||
|
||||
impl<S> GuardedSocket<S> where S: WithSocket<Socket> {
|
||||
pub fn service(&self) -> Arc<S> {
|
||||
self.client.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Deref for GuardedSocket<S> where S: WithSocket<Socket> {
|
||||
type Target = Arc<S>;
|
||||
|
||||
fn deref(&self) -> &Arc<S> {
|
||||
&self.client
|
||||
}
|
||||
}
|
||||
|
||||
/// Spawns client <`S`> over specified address
|
||||
/// creates socket and connects endpoint to it
|
||||
/// for duplex (paired) connections with the service
|
||||
pub fn init_duplex_client<S>(socket_addr: &str) -> Result<GuardedSocket<S>, SocketError> where S: WithSocket<Socket> {
|
||||
let mut socket = Socket::new(Protocol::Pair).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to create ipc socket: {:?}", e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
socket.set_receive_timeout(DEFAULT_CONNECTION_TIMEOUT).unwrap();
|
||||
|
||||
let endpoint = socket.connect(socket_addr).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", socket_addr, e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
Ok(GuardedSocket {
|
||||
client: Arc::new(S::init(socket)),
|
||||
_endpoint: endpoint,
|
||||
})
|
||||
}
|
||||
|
||||
/// Spawns client <`S`> over specified address
|
||||
/// creates socket and connects endpoint to it
|
||||
/// for request-reply connections to the service
|
||||
pub fn client<S>(socket_addr: &str, receive_timeout: Option<isize>) -> Result<GuardedSocket<S>, SocketError> where S: WithSocket<Socket> {
|
||||
let mut socket = Socket::new(Protocol::Req).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to create ipc socket: {:?}", e);
|
||||
SocketError::RequestLink
|
||||
})?;
|
||||
|
||||
if let Some(timeout) = receive_timeout {
|
||||
socket.set_receive_timeout(timeout).unwrap();
|
||||
}
|
||||
|
||||
let endpoint = socket.connect(socket_addr).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", socket_addr, e);
|
||||
SocketError::RequestLink
|
||||
})?;
|
||||
|
||||
trace!(target: "ipc", "Created client for {}", socket_addr);
|
||||
Ok(GuardedSocket {
|
||||
client: Arc::new(S::init(socket)),
|
||||
_endpoint: endpoint,
|
||||
})
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// Set PARITY_IPC_DEBUG=1 for fail-fast connectivity problems diagnostic
|
||||
pub static ref DEBUG_FLAG: bool = {
|
||||
use std::env;
|
||||
|
||||
if let Ok(debug) = env::var("PARITY_IPC_DEBUG") {
|
||||
debug == "1" || debug.to_uppercase() == "TRUE"
|
||||
}
|
||||
else { false }
|
||||
};
|
||||
}
|
||||
|
||||
/// Client with no default timeout on operations
|
||||
pub fn generic_client<S>(socket_addr: &str) -> Result<GuardedSocket<S>, SocketError> where S: WithSocket<Socket> {
|
||||
if *DEBUG_FLAG {
|
||||
client(socket_addr, Some(DEBUG_CONNECTION_TIMEOUT))
|
||||
} else {
|
||||
client(socket_addr, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Client over interface that is supposed to give quick almost non-blocking responses
|
||||
pub fn fast_client<S>(socket_addr: &str) -> Result<GuardedSocket<S>, SocketError> where S: WithSocket<Socket> {
|
||||
if *DEBUG_FLAG {
|
||||
client(socket_addr, Some(DEBUG_CONNECTION_TIMEOUT))
|
||||
} else {
|
||||
client(socket_addr, Some(DEFAULT_CONNECTION_TIMEOUT))
|
||||
}
|
||||
}
|
||||
|
||||
/// Error occurred while establising socket or endpoint
|
||||
#[derive(Debug)]
|
||||
pub enum SocketError {
|
||||
/// Error establising duplex (paired) socket and/or endpoint
|
||||
DuplexLink,
|
||||
/// Error establising duplex (paired) socket and/or endpoint
|
||||
RequestLink,
|
||||
}
|
||||
|
||||
impl<S: ?Sized> Worker<S> where S: IpcInterface {
|
||||
/// New worker over specified `service`
|
||||
pub fn new(service: &Arc<S>) -> Worker<S> {
|
||||
Worker::<S> {
|
||||
service: service.clone(),
|
||||
sockets: Vec::new(),
|
||||
polls: Vec::new(),
|
||||
buf: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Polls all sockets, reads and dispatches method invocations
|
||||
pub fn poll(&mut self) {
|
||||
use std::io::Write;
|
||||
|
||||
let mut request = PollRequest::new(&mut self.polls[..]);
|
||||
let _result_guard = Socket::poll(&mut request, POLL_TIMEOUT);
|
||||
|
||||
for (fd_index, fd) in request.get_fds().iter().enumerate() {
|
||||
if fd.can_read() {
|
||||
let (ref mut socket, _) = self.sockets[fd_index];
|
||||
unsafe { self.buf.set_len(0); }
|
||||
match socket.nb_read_to_end(&mut self.buf) {
|
||||
Ok(method_sign_len) => {
|
||||
if method_sign_len >= 2 {
|
||||
|
||||
// method_num
|
||||
let method_num = self.buf[0] as u16 * 256 + self.buf[1] as u16;
|
||||
// payload
|
||||
let payload = &self.buf[2..];
|
||||
|
||||
// dispatching for ipc interface
|
||||
let result = self.service.dispatch_buf(method_num, payload);
|
||||
|
||||
if let Err(e) = socket.write(&result) {
|
||||
warn!(target: "ipc", "Failed to write response: {:?}", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
warn!(target: "ipc", "Failed to read method signature from socket: unexpected message length({})", method_sign_len);
|
||||
}
|
||||
},
|
||||
Err(Error::TryAgain) => {
|
||||
},
|
||||
Err(x) => {
|
||||
warn!(target: "ipc", "Error polling connections {:?}", x);
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores nanomsg poll request for reuse
|
||||
fn rebuild_poll_request(&mut self) {
|
||||
self.polls = self.sockets.iter()
|
||||
.map(|&(ref socket, _)| socket.new_pollfd(PollInOut::In))
|
||||
.collect::<Vec<PollFd>>();
|
||||
}
|
||||
|
||||
/// Add exclusive socket for paired client
|
||||
/// Only one connection over this address is allowed
|
||||
pub fn add_duplex(&mut self, addr: &str) -> Result<(), SocketError> {
|
||||
let mut socket = Socket::new(Protocol::Pair).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to create ipc socket: {:?}", e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
let endpoint = socket.bind(addr).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", addr, e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
self.sockets.push((socket, endpoint));
|
||||
|
||||
self.rebuild_poll_request();
|
||||
|
||||
trace!(target: "ipc", "Started duplex worker at {}", addr);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add generic socket for request-reply style communications
|
||||
/// with multiple clients
|
||||
pub fn add_reqrep(&mut self, addr: &str) -> Result<(), SocketError> {
|
||||
let mut socket = Socket::new(Protocol::Rep).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to create ipc socket: {:?}", e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
|
||||
let endpoint = socket.bind(addr).map_err(|e| {
|
||||
warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", addr, e);
|
||||
SocketError::DuplexLink
|
||||
})?;
|
||||
|
||||
self.sockets.push((socket, endpoint));
|
||||
|
||||
self.rebuild_poll_request();
|
||||
|
||||
trace!(target: "ipc", "Started request-reply worker at {}", addr);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod service_tests {
|
||||
|
||||
use super::Worker;
|
||||
use ipc::*;
|
||||
use std::io::{Read, Write};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use nanomsg::{Socket, Protocol, Endpoint};
|
||||
|
||||
struct TestInvoke {
|
||||
method_num: u16,
|
||||
params: Vec<u8>,
|
||||
}
|
||||
|
||||
struct DummyService {
|
||||
methods_stack: RwLock<Vec<TestInvoke>>,
|
||||
}
|
||||
|
||||
impl DummyService {
|
||||
fn new() -> DummyService {
|
||||
DummyService { methods_stack: RwLock::new(Vec::new()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl IpcInterface for DummyService {
|
||||
fn dispatch<R>(&self, _r: &mut R) -> Vec<u8> where R: Read {
|
||||
vec![]
|
||||
}
|
||||
fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec<u8> {
|
||||
self.methods_stack.write().unwrap().push(
|
||||
TestInvoke {
|
||||
method_num: method_num,
|
||||
params: buf.to_vec(),
|
||||
});
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl IpcConfig for DummyService {}
|
||||
|
||||
fn dummy_write(addr: &str, buf: &[u8]) -> (Socket, Endpoint) {
|
||||
let mut socket = Socket::new(Protocol::Pair).unwrap();
|
||||
let endpoint = socket.connect(addr).unwrap();
|
||||
socket.write(buf).unwrap();
|
||||
(socket, endpoint)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_create_worker() {
|
||||
let worker = Worker::<DummyService>::new(&Arc::new(DummyService::new()));
|
||||
assert_eq!(0, worker.sockets.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_add_duplex_socket_to_worker() {
|
||||
let mut worker = Worker::<DummyService>::new(&Arc::new(DummyService::new()));
|
||||
worker.add_duplex("ipc:///tmp/parity-test10.ipc").unwrap();
|
||||
assert_eq!(1, worker.sockets.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_can_poll_empty() {
|
||||
let service = Arc::new(DummyService::new());
|
||||
let mut worker = Worker::<DummyService>::new(&service);
|
||||
worker.add_duplex("ipc:///tmp/parity-test20.ipc").unwrap();
|
||||
worker.poll();
|
||||
assert_eq!(0, service.methods_stack.read().unwrap().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_can_poll() {
|
||||
let url = "ipc:///tmp/parity-test30.ipc";
|
||||
|
||||
let mut worker = Worker::<DummyService>::new(&Arc::new(DummyService::new()));
|
||||
worker.add_duplex(url).unwrap();
|
||||
|
||||
let (_socket, _endpoint) = dummy_write(url, &vec![0, 0, 7, 7, 6, 6]);
|
||||
worker.poll();
|
||||
|
||||
assert_eq!(1, worker.service.methods_stack.read().unwrap().len());
|
||||
assert_eq!(0, worker.service.methods_stack.read().unwrap()[0].method_num);
|
||||
assert_eq!([7, 7, 6, 6], worker.service.methods_stack.read().unwrap()[0].params[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_can_poll_long() {
|
||||
let url = "ipc:///tmp/parity-test40.ipc";
|
||||
|
||||
let mut worker = Worker::<DummyService>::new(&Arc::new(DummyService::new()));
|
||||
worker.add_duplex(url).unwrap();
|
||||
|
||||
let message = [0u8; 1024*1024];
|
||||
|
||||
let (_socket, _endpoint) = dummy_write(url, &message);
|
||||
worker.poll();
|
||||
|
||||
assert_eq!(1, worker.service.methods_stack.read().unwrap().len());
|
||||
assert_eq!(0, worker.service.methods_stack.read().unwrap()[0].method_num);
|
||||
assert_eq!(vec![0u8; 1024*1024-2], worker.service.methods_stack.read().unwrap()[0].params);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
[package]
|
||||
name = "ethcore-ipc"
|
||||
version = "1.9.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
license = "GPL-3.0"
|
||||
|
||||
[features]
|
||||
|
||||
[dependencies]
|
||||
ethcore-devtools = { path = "../../devtools" }
|
||||
nanomsg = { git = "https://github.com/paritytech/nanomsg.rs.git", branch = "parity-1.7" }
|
||||
ethcore-bigint = { path = "../../util/bigint"}
|
||||
ethcore-util = { path = "../../util" }
|
||||
semver = "0.6"
|
File diff suppressed because it is too large
Load Diff
@ -1,106 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! IPC RPC interface
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use std::marker::Sync;
|
||||
use semver::Version;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
/// Handshake for client and server to negotiate api/protocol version
|
||||
pub struct Handshake {
|
||||
pub protocol_version: Version,
|
||||
pub api_version: Version,
|
||||
}
|
||||
|
||||
/// Allows to configure custom version and custom handshake response for
|
||||
/// ipc host
|
||||
pub trait IpcConfig {
|
||||
/// Current service api version
|
||||
/// Should be increased if any of the methods changes signature
|
||||
fn api_version() -> Version {
|
||||
Version::parse("1.0.0").unwrap()
|
||||
}
|
||||
|
||||
/// Current ipc protocol version
|
||||
/// Should be increased only if signature of system methods changes
|
||||
fn protocol_version() -> Version {
|
||||
Version::parse("1.0.0").unwrap()
|
||||
}
|
||||
|
||||
/// Default handshake requires exact versions match
|
||||
fn handshake(handshake: &Handshake) -> bool {
|
||||
handshake.protocol_version == Self::protocol_version() &&
|
||||
handshake.api_version == Self::api_version()
|
||||
}
|
||||
}
|
||||
|
||||
/// Error in dispatching or invoking methods via IPC
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
UnknownSystemCall,
|
||||
ClientUnsupported,
|
||||
RemoteServiceUnsupported,
|
||||
HandshakeFailed,
|
||||
}
|
||||
|
||||
/// Allows implementor to be attached to generic worker and dispatch rpc requests
|
||||
/// over IPC
|
||||
pub trait IpcInterface : IpcConfig {
|
||||
/// reads the message from io, dispatches the call and returns serialized result
|
||||
fn dispatch<R>(&self, r: &mut R) -> Vec<u8> where R: Read;
|
||||
|
||||
/// deserializes the payload from buffer, dispatches invoke and returns serialized result
|
||||
/// (for non-blocking io)
|
||||
fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec<u8>;
|
||||
}
|
||||
|
||||
/// serializes method invocation (method_num and parameters) to the stream specified by `w`
|
||||
pub fn invoke<W>(method_num: u16, params: &Option<Vec<u8>>, w: &mut W) where W: Write {
|
||||
// creating buffer to contain all message
|
||||
let buf_len = match *params { None => 2, Some(ref val) => val.len() + 2 };
|
||||
let mut buf = vec![0u8; buf_len];
|
||||
|
||||
// writing method_num as u16
|
||||
buf[1] = (method_num & 255) as u8;
|
||||
buf[0] = (method_num >> 8) as u8;
|
||||
|
||||
// serializing parameters only if provided with any
|
||||
if params.is_some() {
|
||||
buf[2..buf_len].clone_from_slice(params.as_ref().unwrap());
|
||||
}
|
||||
|
||||
if w.write(&buf).unwrap() != buf_len
|
||||
{
|
||||
// if write was inconsistent
|
||||
panic!("failed to write to socket");
|
||||
}
|
||||
}
|
||||
|
||||
/// IpcSocket, read/write generalization
|
||||
pub trait IpcSocket: Read + Write + Sync + Send {
|
||||
}
|
||||
|
||||
/// Basically something that needs only socket to be spawned
|
||||
pub trait WithSocket<S: IpcSocket> {
|
||||
fn init(socket: S) -> Self;
|
||||
}
|
||||
|
||||
|
||||
impl IpcSocket for ::devtools::TestSocket {}
|
||||
|
||||
impl IpcSocket for ::nanomsg::Socket {}
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||
|
||||
//! IPC RPC interface
|
||||
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate semver;
|
||||
extern crate nanomsg;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate ethcore_bigint as bigint;
|
||||
|
||||
pub mod interface;
|
||||
pub mod binary;
|
||||
pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error, WithSocket};
|
||||
pub use binary::{BinaryConvertable, BinaryConvertError, BinVersion, BinHandshake};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user