Merge branch 'master' into dapps-sync

Conflicts:
	dapps/src/handlers/fetch.rs
This commit is contained in:
Tomasz Drwięga 2016-09-05 08:43:07 +02:00
commit e2377dd510
133 changed files with 6367 additions and 633 deletions

82
Cargo.lock generated
View File

@ -32,6 +32,7 @@ dependencies = [
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -78,6 +79,11 @@ dependencies = [
"syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "base64"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bigint" name = "bigint"
version = "0.1.0" version = "0.1.0"
@ -218,8 +224,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "elastic-array" name = "elastic-array"
version = "0.4.0" version = "0.5.0"
source = "git+https://github.com/ethcore/elastic-array#9a9bebd6ea291c58e4d6b44dd5dc18368638fefe" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "env_logger" name = "env_logger"
@ -291,6 +297,7 @@ dependencies = [
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -306,6 +313,7 @@ dependencies = [
"ethcore-devtools 1.4.0", "ethcore-devtools 1.4.0",
"ethcore-rpc 1.4.0", "ethcore-rpc 1.4.0",
"ethcore-util 1.4.0", "ethcore-util 1.4.0",
"https-fetch 0.1.0",
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)", "hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
"jsonrpc-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
@ -429,6 +437,7 @@ dependencies = [
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)", "mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
"parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -455,6 +464,7 @@ dependencies = [
"jsonrpc-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -507,7 +517,7 @@ dependencies = [
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"bigint 0.1.0", "bigint 0.1.0",
"clippy 0.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.4.0 (git+https://github.com/ethcore/elastic-array)", "elastic-array 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)", "eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
"ethcore-devtools 1.4.0", "ethcore-devtools 1.4.0",
@ -518,6 +528,7 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)", "rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
@ -601,6 +612,7 @@ dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.1.0",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -657,6 +669,15 @@ name = "httparse"
version = "1.1.2" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "https-fetch"
version = "0.1.0"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)",
"rustls 0.1.1 (git+https://github.com/ctz/rustls)",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.9.4" version = "0.9.4"
@ -1307,6 +1328,25 @@ name = "regex-syntax"
version = "0.3.1" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ring"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rlp"
version = "0.1.0"
dependencies = [
"bigint 0.1.0",
"elastic-array 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "rocksdb" name = "rocksdb"
version = "0.4.5" version = "0.4.5"
@ -1372,6 +1412,19 @@ dependencies = [
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "rustls"
version = "0.1.1"
source = "git+https://github.com/ctz/rustls#a9c5a79f49337e22ac05bb1ea114240bdbe0fdd2"
dependencies = [
"base64 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "semver" name = "semver"
version = "0.1.20" version = "0.1.20"
@ -1664,6 +1717,11 @@ name = "unicode-xid"
version = "0.0.3" version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "untrusted"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "url" name = "url"
version = "1.2.0" version = "1.2.0"
@ -1705,6 +1763,17 @@ name = "void"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "webpki"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ring 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.2.6" version = "0.2.6"
@ -1772,6 +1841,7 @@ dependencies = [
"checksum arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "16e3bdb2f54b3ace0285975d59a97cf8ed3855294b2b6bc651fcf22a9c352975" "checksum arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "16e3bdb2f54b3ace0285975d59a97cf8ed3855294b2b6bc651fcf22a9c352975"
"checksum aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07d344974f0a155f091948aa389fb1b912d3a58414fbdb9c8d446d193ee3496a" "checksum aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07d344974f0a155f091948aa389fb1b912d3a58414fbdb9c8d446d193ee3496a"
"checksum aster 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4df293303e8a52e1df7984ac1415e195f5fcbf51e4bb7bda54557861a3954a08" "checksum aster 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4df293303e8a52e1df7984ac1415e195f5fcbf51e4bb7bda54557861a3954a08"
"checksum base64 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2015e3793554aa5b6007e3a72959e84c1070039e74f13dde08fa64afe1ddd892"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c" "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
@ -1790,7 +1860,7 @@ dependencies = [
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
"checksum docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc0acb4ce0828c6a5a11d47baa432fe885881c27428c3a4e473e454ffe57a76" "checksum docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc0acb4ce0828c6a5a11d47baa432fe885881c27428c3a4e473e454ffe57a76"
"checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d"
"checksum elastic-array 0.4.0 (git+https://github.com/ethcore/elastic-array)" = "<none>" "checksum elastic-array 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bc9250a632e7c001b741eb0ec6cee93c9a5b6d5f1879696a4b94d62b012210a"
"checksum env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aba65b63ffcc17ffacd6cf5aa843da7c5a25e3bd4bbe0b7def8b214e411250e5" "checksum env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aba65b63ffcc17ffacd6cf5aa843da7c5a25e3bd4bbe0b7def8b214e411250e5"
"checksum eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)" = "<none>" "checksum eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)" = "<none>"
"checksum ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0c53453517f620847be51943db329276ae52f2e210cfc659e81182864be2f" "checksum ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0c53453517f620847be51943db329276ae52f2e210cfc659e81182864be2f"
@ -1871,6 +1941,7 @@ dependencies = [
"checksum rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "941deb43a6254b9867fec1e0caeda38a2ad905ab18c57f7c68c396ca68998c07" "checksum rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "941deb43a6254b9867fec1e0caeda38a2ad905ab18c57f7c68c396ca68998c07"
"checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29" "checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29"
"checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9" "checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9"
"checksum ring 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d059a6a96d3be79042e3f70eb97945912839265f9d8ab45b921abaf266c70dbb"
"checksum rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>" "checksum rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>"
"checksum rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>" "checksum rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)" = "<none>"
"checksum rotor 0.6.3 (git+https://github.com/ethcore/rotor)" = "<none>" "checksum rotor 0.6.3 (git+https://github.com/ethcore/rotor)" = "<none>"
@ -1878,6 +1949,7 @@ dependencies = [
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
"checksum rustls 0.1.1 (git+https://github.com/ctz/rustls)" = "<none>"
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
"checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775" "checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775"
@ -1915,11 +1987,13 @@ dependencies = [
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172" "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
"checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb"
"checksum untrusted 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5d9bc0e6e73a10975d1fbff8ac3541e221181b0d8998351600fb5523de634c0d"
"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119" "checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119"
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
"checksum vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0795a11576d29ae80525a3fda315bf7b534f8feb9d34101e5fe63fb95bb2fd24" "checksum vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0795a11576d29ae80525a3fda315bf7b534f8feb9d34101e5fe63fb95bb2fd24"
"checksum vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b639f935488eb40f06d17c3e3bcc3054f6f75d264e187b1107c8d1cba8d31c" "checksum vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b639f935488eb40f06d17c3e3bcc3054f6f75d264e187b1107c8d1cba8d31c"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum webpki 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc10a815fabbb0c3145c1153240528f3a8703a47e26e8dbb4a5d4f6386200ad"
"checksum winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfaaa8fbdaa618fa6914b59b2769d690dd7521920a18d84b42d254678dd5fd4" "checksum winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfaaa8fbdaa618fa6914b59b2769d690dd7521920a18d84b42d254678dd5fd4"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum ws 0.5.2 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)" = "<none>" "checksum ws 0.5.2 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)" = "<none>"

View File

@ -38,6 +38,7 @@ ethcore-ipc-nano = { path = "ipc/nano" }
ethcore-ipc = { path = "ipc/rpc" } ethcore-ipc = { path = "ipc/rpc" }
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
ethcore-logger = { path = "logger" } ethcore-logger = { path = "logger" }
rlp = { path = "util/rlp" }
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
ethcore-dapps = { path = "dapps", optional = true } ethcore-dapps = { path = "dapps", optional = true }
clippy = { version = "0.0.85", optional = true} clippy = { version = "0.0.85", optional = true}

View File

@ -26,6 +26,7 @@ linked-hash-map = "0.3"
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethcore-rpc = { path = "../rpc" } ethcore-rpc = { path = "../rpc" }
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
https-fetch = { path = "../util/https-fetch" }
parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" } parity-dapps = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
# List of apps # List of apps
parity-dapps-status = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" } parity-dapps-status = { git = "https://github.com/ethcore/parity-ui.git", version = "1.4" }
@ -38,7 +39,7 @@ clippy = { version = "0.0.85", optional = true}
serde_codegen = { version = "0.8", optional = true } serde_codegen = { version = "0.8", optional = true }
[features] [features]
default = ["serde_codegen", "extra-dapps"] default = ["serde_codegen", "extra-dapps", "https-fetch/ca-github-only"]
extra-dapps = ["parity-dapps-wallet"] extra-dapps = ["parity-dapps-wallet"]
nightly = ["serde_macros"] nightly = ["serde_macros"]
dev = ["clippy", "ethcore-rpc/dev", "ethcore-util/dev"] dev = ["clippy", "ethcore-rpc/dev", "ethcore-util/dev"]

View File

@ -60,7 +60,7 @@ impl ContentCache {
ContentStatus::Fetching(ref abort) => { ContentStatus::Fetching(ref abort) => {
trace!(target: "dapps", "Aborting {} because of limit.", entry.0); trace!(target: "dapps", "Aborting {} because of limit.", entry.0);
// Mark as aborted // Mark as aborted
abort.store(true, Ordering::Relaxed); abort.store(true, Ordering::SeqCst);
}, },
ContentStatus::Ready(ref endpoint) => { ContentStatus::Ready(ref endpoint) => {
trace!(target: "dapps", "Removing {} because of limit.", entry.0); trace!(target: "dapps", "Removing {} because of limit.", entry.0);

View File

@ -19,7 +19,7 @@
//! Uses `URLHint` to resolve addresses into Dapps bundle file location. //! Uses `URLHint` to resolve addresses into Dapps bundle file location.
use zip; use zip;
use std::{fs, env}; use std::{fs, env, fmt};
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
@ -175,6 +175,23 @@ pub enum ValidationError {
HashMismatch { expected: H256, got: H256, }, HashMismatch { expected: H256, got: H256, },
} }
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
ValidationError::Io(ref io) => write!(f, "Unexpected IO error occured: {:?}", io),
ValidationError::Zip(ref zip) => write!(f, "Unable to read ZIP archive: {:?}", zip),
ValidationError::InvalidDappId => write!(f, "Dapp ID is invalid. It should be 32 bytes hash of content."),
ValidationError::ManifestNotFound => write!(f, "Downloaded Dapp bundle did not contain valid manifest.json file."),
ValidationError::ManifestSerialization(ref err) => {
write!(f, "There was an error during Dapp Manifest serialization: {:?}", err)
},
ValidationError::HashMismatch { ref expected, ref got } => {
write!(f, "Hash of downloaded content did not match. Expected:{:?}, Got:{:?}.", expected, got)
},
}
}
}
impl From<io::Error> for ValidationError { impl From<io::Error> for ValidationError {
fn from(err: io::Error) -> Self { fn from(err: io::Error) -> Self {
ValidationError::Io(err) ValidationError::Io(err)
@ -230,8 +247,8 @@ impl ContentValidator for DappInstaller {
fn validate_and_install(&self, app_path: PathBuf) -> Result<Manifest, ValidationError> { fn validate_and_install(&self, app_path: PathBuf) -> Result<Manifest, ValidationError> {
trace!(target: "dapps", "Opening dapp bundle at {:?}", app_path); trace!(target: "dapps", "Opening dapp bundle at {:?}", app_path);
let mut file = try!(fs::File::open(app_path)); let mut file_reader = io::BufReader::new(try!(fs::File::open(app_path)));
let hash = try!(sha3(&mut file)); let hash = try!(sha3(&mut file_reader));
let dapp_id = try!(self.dapp_id.as_str().parse().map_err(|_| ValidationError::InvalidDappId)); let dapp_id = try!(self.dapp_id.as_str().parse().map_err(|_| ValidationError::InvalidDappId));
if dapp_id != hash { if dapp_id != hash {
return Err(ValidationError::HashMismatch { return Err(ValidationError::HashMismatch {
@ -239,6 +256,7 @@ impl ContentValidator for DappInstaller {
got: hash, got: hash,
}); });
} }
let file = file_reader.into_inner();
// Unpack archive // Unpack archive
let mut zip = try!(zip::ZipArchive::new(file)); let mut zip = try!(zip::ZipArchive::new(file));
// First find manifest file // First find manifest file

View File

@ -33,8 +33,9 @@ pub struct GithubApp {
impl GithubApp { impl GithubApp {
pub fn url(&self) -> String { pub fn url(&self) -> String {
// Since https fetcher doesn't support redirections we use direct link
// format!("https://github.com/{}/{}/archive/{}.zip", self.account, self.repo, self.commit.to_hex()) // format!("https://github.com/{}/{}/archive/{}.zip", self.account, self.repo, self.commit.to_hex())
format!("http://github.todr.me/{}/{}/zip/{}", self.account, self.repo, self.commit.to_hex()) format!("https://codeload.github.com/{}/{}/zip/{}", self.account, self.repo, self.commit.to_hex())
} }
fn commit(bytes: &[u8]) -> Option<[u8;COMMIT_LEN]> { fn commit(bytes: &[u8]) -> Option<[u8;COMMIT_LEN]> {
@ -300,6 +301,6 @@ mod tests {
let url = app.url(); let url = app.url();
// then // then
assert_eq!(url, "http://github.todr.me/test/xyz/zip/000102030405060708090a0b0c0d0e0f10111213".to_owned()); assert_eq!(url, "https://codeload.github.com/test/xyz/zip/000102030405060708090a0b0c0d0e0f10111213".to_owned());
} }
} }

View File

@ -28,6 +28,8 @@ use hyper::client::{Request, Response, DefaultTransport as HttpStream};
use hyper::header::Connection; use hyper::header::Connection;
use hyper::{self, Decoder, Encoder, Next}; use hyper::{self, Decoder, Encoder, Next};
use super::FetchError;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
Aborted, Aborted,
@ -37,7 +39,7 @@ pub enum Error {
HyperError(hyper::Error), HyperError(hyper::Error),
} }
pub type FetchResult = Result<PathBuf, Error>; pub type FetchResult = Result<PathBuf, FetchError>;
pub type OnDone = Box<Fn() + Send>; pub type OnDone = Box<Fn() + Send>;
pub struct Fetch { pub struct Fetch {
@ -57,7 +59,7 @@ impl fmt::Debug for Fetch {
impl Drop for Fetch { impl Drop for Fetch {
fn drop(&mut self) { fn drop(&mut self) {
let res = self.result.take().unwrap_or(Err(Error::NotStarted)); let res = self.result.take().unwrap_or(Err(Error::NotStarted.into()));
// Remove file if there was an error // Remove file if there was an error
if res.is_err() || self.is_aborted() { if res.is_err() || self.is_aborted() {
if let Some(file) = self.file.take() { if let Some(file) = self.file.take() {
@ -92,10 +94,10 @@ impl Fetch {
impl Fetch { impl Fetch {
fn is_aborted(&self) -> bool { fn is_aborted(&self) -> bool {
self.abort.load(Ordering::Relaxed) self.abort.load(Ordering::SeqCst)
} }
fn mark_aborted(&mut self) -> Next { fn mark_aborted(&mut self) -> Next {
self.result = Some(Err(Error::Aborted)); self.result = Some(Err(Error::Aborted.into()));
Next::end() Next::end()
} }
} }
@ -121,7 +123,7 @@ impl hyper::client::Handler<HttpStream> for Fetch {
return self.mark_aborted(); return self.mark_aborted();
} }
if *res.status() != StatusCode::Ok { if *res.status() != StatusCode::Ok {
self.result = Some(Err(Error::UnexpectedStatus(*res.status()))); self.result = Some(Err(Error::UnexpectedStatus(*res.status()).into()));
return Next::end(); return Next::end();
} }
@ -133,7 +135,7 @@ impl hyper::client::Handler<HttpStream> for Fetch {
read() read()
}, },
Err(err) => { Err(err) => {
self.result = Some(Err(Error::IoError(err))); self.result = Some(Err(Error::IoError(err).into()));
Next::end() Next::end()
}, },
} }
@ -149,7 +151,7 @@ impl hyper::client::Handler<HttpStream> for Fetch {
Err(e) => match e.kind() { Err(e) => match e.kind() {
io::ErrorKind::WouldBlock => Next::read(), io::ErrorKind::WouldBlock => Next::read(),
_ => { _ => {
self.result = Some(Err(Error::IoError(e))); self.result = Some(Err(Error::IoError(e).into()));
Next::end() Next::end()
} }
} }
@ -157,7 +159,7 @@ impl hyper::client::Handler<HttpStream> for Fetch {
} }
fn on_error(&mut self, err: hyper::Error) -> Next { fn on_error(&mut self, err: hyper::Error) -> Next {
self.result = Some(Err(Error::HyperError(err))); self.result = Some(Err(Error::HyperError(err).into()));
Next::remove() Next::remove()
} }
} }

View File

@ -16,7 +16,98 @@
//! Hyper Client Handlers //! Hyper Client Handlers
mod fetch_file; pub mod fetch_file;
use std::env;
use std::sync::{mpsc, Arc};
use std::sync::atomic::AtomicBool;
use std::path::PathBuf;
use hyper;
use https_fetch as https;
use random_filename;
use self::fetch_file::{Fetch, Error as HttpFetchError};
pub type FetchResult = Result<PathBuf, FetchError>;
#[derive(Debug)]
pub enum FetchError {
InvalidUrl,
Http(HttpFetchError),
Https(https::FetchError),
Other(String),
}
impl From<HttpFetchError> for FetchError {
fn from(e: HttpFetchError) -> Self {
FetchError::Http(e)
}
}
pub struct Client {
http_client: hyper::Client<Fetch>,
https_client: https::Client,
}
impl Client {
pub fn new() -> Self {
Client {
http_client: hyper::Client::new().expect("Unable to initialize http client."),
https_client: https::Client::new().expect("Unable to initialize https client."),
}
}
pub fn close(self) {
self.http_client.close();
self.https_client.close();
}
pub fn request(&mut self, url: String, abort: Arc<AtomicBool>, on_done: Box<Fn() + Send>) -> Result<mpsc::Receiver<FetchResult>, FetchError> {
let is_https = url.starts_with("https://");
let url = try!(url.parse().map_err(|_| FetchError::InvalidUrl));
trace!(target: "dapps", "Fetching from: {:?}", url);
if is_https {
let url = try!(Self::convert_url(url));
let (tx, rx) = mpsc::channel();
let temp_path = Self::temp_path();
let res = self.https_client.fetch_to_file(url, temp_path.clone(), abort, move |result| {
let res = tx.send(
result.map(|_| temp_path).map_err(FetchError::Https)
);
if let Err(_) = res {
warn!("Fetch finished, but no one was listening");
}
on_done();
});
match res {
Ok(_) => Ok(rx),
Err(e) => Err(FetchError::Other(format!("{:?}", e))),
}
} else {
let (tx, rx) = mpsc::channel();
let res = self.http_client.request(url, Fetch::new(tx, abort, on_done));
match res {
Ok(_) => Ok(rx),
Err(e) => Err(FetchError::Other(format!("{:?}", e))),
}
}
}
fn convert_url(url: hyper::Url) -> Result<https::Url, FetchError> {
let host = format!("{}", try!(url.host().ok_or(FetchError::InvalidUrl)));
let port = try!(url.port_or_known_default().ok_or(FetchError::InvalidUrl));
https::Url::new(&host, port, url.path()).map_err(|_| FetchError::InvalidUrl)
}
fn temp_path() -> PathBuf {
let mut dir = env::temp_dir();
dir.push(random_filename());
dir
}
}
pub use self::fetch_file::{Fetch, FetchResult, OnDone};

View File

@ -16,18 +16,18 @@
//! Hyper Server Handler that fetches a file during a request (proxy). //! Hyper Server Handler that fetches a file during a request (proxy).
use std::{fs, fmt}; use std::fmt;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{mpsc, Arc}; use std::sync::{mpsc, Arc};
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use hyper::{header, server, Decoder, Encoder, Next, Method, Control, Client}; use hyper::{header, server, Decoder, Encoder, Next, Method, Control};
use hyper::net::HttpStream; use hyper::net::HttpStream;
use hyper::status::StatusCode; use hyper::status::StatusCode;
use handlers::ContentHandler; use handlers::ContentHandler;
use handlers::client::{Fetch, FetchResult}; use handlers::client::{Client, FetchResult};
use apps::redirection_address; use apps::redirection_address;
use apps::urlhint::GithubApp; use apps::urlhint::GithubApp;
use apps::manifest::Manifest; use apps::manifest::Manifest;
@ -45,7 +45,7 @@ enum FetchState {
} }
pub trait ContentValidator { pub trait ContentValidator {
type Error: fmt::Debug; type Error: fmt::Debug + fmt::Display;
fn validate_and_install(&self, app: PathBuf) -> Result<Manifest, Self::Error>; fn validate_and_install(&self, app: PathBuf) -> Result<Manifest, Self::Error>;
fn done(&self, Option<&Manifest>); fn done(&self, Option<&Manifest>);
@ -55,7 +55,7 @@ pub struct ContentFetcherHandler<H: ContentValidator> {
abort: Arc<AtomicBool>, abort: Arc<AtomicBool>,
control: Option<Control>, control: Option<Control>,
status: FetchState, status: FetchState,
client: Option<Client<Fetch>>, client: Option<Client>,
using_dapps_domains: bool, using_dapps_domains: bool,
dapp: H, dapp: H,
} }
@ -79,7 +79,7 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
using_dapps_domains: bool, using_dapps_domains: bool,
handler: H) -> Self { handler: H) -> Self {
let client = Client::new().expect("Failed to create a Client"); let client = Client::new();
ContentFetcherHandler { ContentFetcherHandler {
abort: abort, abort: abort,
control: Some(control), control: Some(control),
@ -90,28 +90,19 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
} }
} }
fn close_client(client: &mut Option<Client<Fetch>>) { fn close_client(client: &mut Option<Client>) {
client.take() client.take()
.expect("After client is closed we are going into write, hence we can never close it again") .expect("After client is closed we are going into write, hence we can never close it again")
.close(); .close();
} }
// TODO [todr] https support fn fetch_app(client: &mut Client, app: &GithubApp, abort: Arc<AtomicBool>, control: Control) -> Result<mpsc::Receiver<FetchResult>, String> {
fn fetch_app(client: &mut Client<Fetch>, app: &GithubApp, abort: Arc<AtomicBool>, control: Control) -> Result<mpsc::Receiver<FetchResult>, String> { client.request(app.url(), abort, Box::new(move || {
let url = try!(app.url().parse().map_err(|e| format!("{:?}", e)));
trace!(target: "dapps", "Fetching from: {:?}", url);
let (tx, rx) = mpsc::channel();
let res = client.request(url, Fetch::new(tx, abort, Box::new(move || {
trace!(target: "dapps", "Fetching finished."); trace!(target: "dapps", "Fetching finished.");
// Ignoring control errors // Ignoring control errors
let _ = control.ready(Next::read()); let _ = control.ready(Next::read());
}))); })).map_err(|e| format!("{:?}", e))
match res {
Ok(_) => Ok(rx),
Err(e) => Err(format!("{:?}", e)),
}
} }
} }
@ -191,7 +182,8 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
Ok(manifest) => FetchState::Done(manifest) Ok(manifest) => FetchState::Done(manifest)
}; };
// Remove temporary zip file // Remove temporary zip file
let _ = fs::remove_file(path); // TODO [todr] Uncomment me
// let _ = fs::remove_file(path);
(Some(state), Next::write()) (Some(state), Next::write())
}, },
Ok(Err(e)) => { Ok(Err(e)) => {

View File

@ -58,6 +58,7 @@ extern crate jsonrpc_http_server;
extern crate mime_guess; extern crate mime_guess;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate parity_dapps; extern crate parity_dapps;
extern crate https_fetch;
extern crate ethcore_rpc; extern crate ethcore_rpc;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate linked_hash_map; extern crate linked_hash_map;

View File

@ -35,6 +35,7 @@ ethcore-ipc = { path = "../ipc/rpc" }
ethstore = { path = "../ethstore" } ethstore = { path = "../ethstore" }
ethkey = { path = "../ethkey" } ethkey = { path = "../ethkey" }
ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-ipc-nano = { path = "../ipc/nano" }
rlp = { path = "../util/rlp" }
rand = "0.3" rand = "0.3"
[dependencies.hyper] [dependencies.hyper]

View File

@ -16,6 +16,7 @@
//! DB backend wrapper for Account trie //! DB backend wrapper for Account trie
use util::*; use util::*;
use rlp::NULL_RLP;
static NULL_RLP_STATIC: [u8; 1] = [0x80; 1]; static NULL_RLP_STATIC: [u8; 1] = [0x80; 1];

View File

@ -22,6 +22,7 @@ use state::*;
use verification::PreverifiedBlock; use verification::PreverifiedBlock;
use trace::FlatTrace; use trace::FlatTrace;
use factory::Factories; use factory::Factories;
use rlp::*;
/// A block, encoded as it is on the block chain. /// A block, encoded as it is on the block chain.
#[derive(Default, Debug, Clone, PartialEq)] #[derive(Default, Debug, Clone, PartialEq)]

View File

@ -18,6 +18,7 @@
use bloomchain as bc; use bloomchain as bc;
use util::*; use util::*;
use rlp::*;
use header::*; use header::*;
use super::extras::*; use super::extras::*;
use transaction::*; use transaction::*;

View File

@ -18,6 +18,7 @@
use bloomchain; use bloomchain;
use util::*; use util::*;
use rlp::*;
use header::BlockNumber; use header::BlockNumber;
use receipt::Receipt; use receipt::Receipt;
use db::Key; use db::Key;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::rlp::*; use rlp::*;
use util::{H256, H2048}; use util::{H256, H2048};
use util::bytes::Bytes; use util::bytes::Bytes;
use header::Header; use header::Header;

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain as bc; use bloomchain as bc;
use util::rlp::*; use rlp::*;
use util::HeapSizeOf; use util::HeapSizeOf;
use basic_types::LogBloom; use basic_types::LogBloom;

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use bloomchain::group as bc; use bloomchain::group as bc;
use util::rlp::*; use rlp::*;
use util::HeapSizeOf; use util::HeapSizeOf;
use super::Bloom; use super::Bloom;

View File

@ -127,14 +127,14 @@ impl Impl for EcRecover {
let s = H256::from_slice(&input[96..128]); let s = H256::from_slice(&input[96..128]);
let bit = match v[31] { let bit = match v[31] {
27 | 28 if &v.as_slice()[..31] == &[0; 31] => v[31] - 27, 27 | 28 if &v.0[..31] == &[0; 31] => v[31] - 27,
_ => return, _ => return,
}; };
let s = Signature::from_rsv(&r, &s, bit); let s = Signature::from_rsv(&r, &s, bit);
if s.is_valid() { if s.is_valid() {
if let Ok(p) = ec_recover(&s, &hash) { if let Ok(p) = ec_recover(&s, &hash) {
let r = p.as_slice().sha3(); let r = p.sha3();
let out_len = min(output.len(), 32); let out_len = min(output.len(), 32);

View File

@ -22,11 +22,11 @@ use std::time::{Instant};
use time::precise_time_ns; use time::precise_time_ns;
// util // util
use util::{journaldb, rlp, Bytes, View, PerfTimer, Itertools, Mutex, RwLock}; use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
use util::journaldb::JournalDB; use util::journaldb::{self, JournalDB};
use util::rlp::{UntrustedRlp};
use util::{U256, H256, Address, H2048, Uint}; use util::{U256, H256, Address, H2048, Uint};
use util::sha3::*; use util::sha3::*;
use util::TrieFactory;
use util::kvdb::*; use util::kvdb::*;
// other // other
@ -63,9 +63,10 @@ use trace;
use trace::FlatTransactionTraces; use trace::FlatTransactionTraces;
use evm::Factory as EvmFactory; use evm::Factory as EvmFactory;
use miner::{Miner, MinerService}; use miner::{Miner, MinerService};
use util::TrieFactory;
use snapshot::{self, io as snapshot_io}; use snapshot::{self, io as snapshot_io};
use factory::Factories; use factory::Factories;
use rlp::{View, UntrustedRlp};
// re-export // re-export
pub use types::blockchain_info::BlockChainInfo; pub use types::blockchain_info::BlockChainInfo;
@ -877,7 +878,7 @@ impl BlockChainClient for Client {
} }
fn block_receipts(&self, hash: &H256) -> Option<Bytes> { fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
self.chain.block_receipts(hash).map(|receipts| rlp::encode(&receipts).to_vec()) self.chain.block_receipts(hash).map(|receipts| ::rlp::encode(&receipts).to_vec())
} }
fn import_block(&self, bytes: Bytes) -> Result<H256, BlockImportError> { fn import_block(&self, bytes: Bytes) -> Result<H256, BlockImportError> {

View File

@ -18,6 +18,7 @@
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use util::*; use util::*;
use rlp::*;
use ethkey::{Generator, Random}; use ethkey::{Generator, Random};
use devtools::*; use devtools::*;
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action}; use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
@ -33,7 +34,7 @@ use receipt::{Receipt, LocalizedReceipt};
use blockchain::extras::BlockReceipts; use blockchain::extras::BlockReceipts;
use error::{ImportResult}; use error::{ImportResult};
use evm::{Factory as EvmFactory, VMType}; use evm::{Factory as EvmFactory, VMType};
use miner::{Miner, MinerService}; use miner::{Miner, MinerService, TransactionImportResult};
use spec::Spec; use spec::Spec;
use block_queue::BlockQueueInfo; use block_queue::BlockQueueInfo;
@ -204,7 +205,7 @@ impl TestBlockChainClient {
txs.append(&signed_tx); txs.append(&signed_tx);
txs.out() txs.out()
}, },
_ => rlp::EMPTY_LIST_RLP.to_vec() _ => ::rlp::EMPTY_LIST_RLP.to_vec()
}; };
let mut rlp = RlpStream::new_list(3); let mut rlp = RlpStream::new_list(3);
@ -222,8 +223,8 @@ impl TestBlockChainClient {
header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec()); header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec());
let mut rlp = RlpStream::new_list(3); let mut rlp = RlpStream::new_list(3);
rlp.append(&header); rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1); rlp.append_raw(&::rlp::NULL_RLP, 1);
rlp.append_raw(&rlp::NULL_RLP, 1); rlp.append_raw(&::rlp::NULL_RLP, 1);
self.blocks.write().insert(hash, rlp.out()); self.blocks.write().insert(hash, rlp.out());
} }
@ -234,8 +235,8 @@ impl TestBlockChainClient {
header.set_parent_hash(H256::from(42)); header.set_parent_hash(H256::from(42));
let mut rlp = RlpStream::new_list(3); let mut rlp = RlpStream::new_list(3);
rlp.append(&header); rlp.append(&header);
rlp.append_raw(&rlp::NULL_RLP, 1); rlp.append_raw(&::rlp::NULL_RLP, 1);
rlp.append_raw(&rlp::NULL_RLP, 1); rlp.append_raw(&::rlp::NULL_RLP, 1);
self.blocks.write().insert(hash, rlp.out()); self.blocks.write().insert(hash, rlp.out());
} }
@ -254,6 +255,24 @@ impl TestBlockChainClient {
BlockID::Latest | BlockID::Pending => self.numbers.read().get(&(self.numbers.read().len() - 1)).cloned() BlockID::Latest | BlockID::Pending => self.numbers.read().get(&(self.numbers.read().len() - 1)).cloned()
} }
} }
/// Inserts a transaction to miners transactions queue.
pub fn insert_transaction_to_queue(&self) {
let keypair = Random.generate().unwrap();
let tx = Transaction {
action: Action::Create,
value: U256::from(100),
data: "3331600055".from_hex().unwrap(),
gas: U256::from(100_000),
gas_price: U256::one(),
nonce: U256::zero()
};
let signed_tx = tx.sign(keypair.secret());
self.set_balance(signed_tx.sender().unwrap(), 10_000_000.into());
let res = self.miner.import_external_transactions(self, vec![signed_tx]);
let res = res.into_iter().next().unwrap().expect("Successful import");
assert_eq!(res, TransactionImportResult::Current);
}
} }
pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB>> { pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB>> {

View File

@ -20,7 +20,8 @@ use std::ops::Deref;
use std::hash::Hash; use std::hash::Hash;
use std::collections::HashMap; use std::collections::HashMap;
use util::{DBTransaction, Database, RwLock}; use util::{DBTransaction, Database, RwLock};
use util::rlp::{encode, Encodable, decode, Decodable};
use rlp;
// database columns // database columns
/// Column for State /// Column for State
@ -83,12 +84,12 @@ pub trait Key<T> {
/// Should be used to write value into database. /// Should be used to write value into database.
pub trait Writable { pub trait Writable {
/// Writes the value into the database. /// Writes the value into the database.
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>; fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]>;
/// Writes the value into the database and updates the cache. /// Writes the value into the database and updates the cache.
fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq, K: Key<T, Target = R> + Hash + Eq,
T: Encodable, T: rlp::Encodable,
R: Deref<Target = [u8]> { R: Deref<Target = [u8]> {
self.write(col, &key, &value); self.write(col, &key, &value);
match policy { match policy {
@ -104,7 +105,7 @@ pub trait Writable {
/// Writes the values into the database and updates the cache. /// Writes the values into the database and updates the cache.
fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq, K: Key<T, Target = R> + Hash + Eq,
T: Encodable, T: rlp::Encodable,
R: Deref<Target = [u8]> { R: Deref<Target = [u8]> {
match policy { match policy {
CacheUpdatePolicy::Overwrite => { CacheUpdatePolicy::Overwrite => {
@ -127,13 +128,13 @@ pub trait Writable {
pub trait Readable { pub trait Readable {
/// Returns value for given key. /// Returns value for given key.
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where
T: Decodable, T: rlp::Decodable,
R: Deref<Target = [u8]>; R: Deref<Target = [u8]>;
/// Returns value for given key either in cache or in database. /// Returns value for given key either in cache or in database.
fn read_with_cache<K, T, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> Option<T> where fn read_with_cache<K, T, C>(&self, col: Option<u32>, cache: &RwLock<C>, key: &K) -> Option<T> where
K: Key<T> + Eq + Hash + Clone, K: Key<T> + Eq + Hash + Clone,
T: Clone + Decodable, T: Clone + rlp::Decodable,
C: Cache<K, T> { C: Cache<K, T> {
{ {
let read = cache.read(); let read = cache.read();
@ -169,17 +170,17 @@ pub trait Readable {
} }
impl Writable for DBTransaction { impl Writable for DBTransaction {
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> { fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: rlp::Encodable, R: Deref<Target = [u8]> {
self.put(col, &key.key(), &encode(value)); self.put(col, &key.key(), &rlp::encode(value));
} }
} }
impl Readable for Database { impl Readable for Database {
fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: Decodable, R: Deref<Target = [u8]> { fn read<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>) -> Option<T> where T: rlp::Decodable, R: Deref<Target = [u8]> {
let result = self.get(col, &key.key()); let result = self.get(col, &key.key());
match result { match result {
Ok(option) => option.map(|v| decode(&v)), Ok(option) => option.map(|v| rlp::decode(&v)),
Err(err) => { Err(err) => {
panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err); panic!("db get failed, key: {:?}, err: {:?}", &key.key() as &[u8], err);
} }

View File

@ -109,7 +109,7 @@ impl Engine for BasicAuthority {
let message = header.bare_hash(); let message = header.bare_hash();
// account should be pernamently unlocked, otherwise sealing will fail // account should be pernamently unlocked, otherwise sealing will fail
if let Ok(signature) = ap.sign(*block.header().author(), message) { if let Ok(signature) = ap.sign(*block.header().author(), message) {
return Some(vec![encode(&(&*signature as &[u8])).to_vec()]); return Some(vec![::rlp::encode(&(&*signature as &[u8])).to_vec()]);
} else { } else {
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
} }
@ -131,6 +131,8 @@ impl Engine for BasicAuthority {
} }
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
use rlp::{UntrustedRlp, View};
// check the signature is legit. // check the signature is legit.
let sig = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<H520>()); let sig = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<H520>());
let signer = public_to_address(&try!(recover(&sig.into(), &header.bare_hash()))); let signer = public_to_address(&try!(recover(&sig.into(), &header.bare_hash())));
@ -172,7 +174,7 @@ impl Engine for BasicAuthority {
impl Header { impl Header {
/// Get the none field of the header. /// Get the none field of the header.
pub fn signature(&self) -> H520 { pub fn signature(&self) -> H520 {
decode(&self.seal()[0]) ::rlp::decode(&self.seal()[0])
} }
} }
@ -228,7 +230,7 @@ mod tests {
fn can_do_signature_verification_fail() { fn can_do_signature_verification_fail() {
let engine = new_test_authority().engine; let engine = new_test_authority().engine;
let mut header: Header = Header::default(); let mut header: Header = Header::default();
header.set_seal(vec![rlp::encode(&H520::default()).to_vec()]); header.set_seal(vec![::rlp::encode(&H520::default()).to_vec()]);
let verify_result = engine.verify_block_unordered(&header, None); let verify_result = engine.verify_block_unordered(&header, None);
assert!(verify_result.is_err()); assert!(verify_result.is_err());

View File

@ -100,7 +100,7 @@ mod tests {
assert!(engine.verify_block_basic(&header, None).is_ok()); assert!(engine.verify_block_basic(&header, None).is_ok());
header.set_seal(vec![rlp::encode(&H520::default()).to_vec()]); header.set_seal(vec![::rlp::encode(&H520::default()).to_vec()]);
assert!(engine.verify_block_unordered(&header, None).is_ok()); assert!(engine.verify_block_unordered(&header, None).is_ok());
} }

View File

@ -28,7 +28,7 @@ use ethkey::Error as EthkeyError;
pub use types::executed::{ExecutionError, CallError}; pub use types::executed::{ExecutionError, CallError};
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone, Copy)]
/// Errors concerning transaction processing. /// Errors concerning transaction processing.
pub enum TransactionError { pub enum TransactionError {
/// Transaction is already imported to the queue /// Transaction is already imported to the queue
@ -87,7 +87,7 @@ impl fmt::Display for TransactionError {
} }
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Clone, Copy, Eq)]
/// Errors concerning block processing. /// Errors concerning block processing.
pub enum BlockError { pub enum BlockError {
/// Block has too many uncles. /// Block has too many uncles.
@ -185,7 +185,7 @@ impl fmt::Display for BlockError {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// Import to the block queue result /// Import to the block queue result
pub enum ImportError { pub enum ImportError {
/// Already in the block chain. /// Already in the block chain.
@ -302,8 +302,8 @@ impl From<ExecutionError> for Error {
} }
} }
impl From<DecoderError> for Error { impl From<::rlp::DecoderError> for Error {
fn from(err: DecoderError) -> Error { fn from(err: ::rlp::DecoderError) -> Error {
Error::Util(UtilError::Decoder(err)) Error::Util(UtilError::Decoder(err))
} }
} }

View File

@ -21,6 +21,7 @@ use spec::CommonParams;
use engines::Engine; use engines::Engine;
use evm::Schedule; use evm::Schedule;
use ethjson; use ethjson;
use rlp::{self, UntrustedRlp, View};
/// Ethash params. /// Ethash params.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -328,17 +329,17 @@ impl Ethash {
impl Header { impl Header {
/// Get the none field of the header. /// Get the none field of the header.
pub fn nonce(&self) -> H64 { pub fn nonce(&self) -> H64 {
decode(&self.seal()[1]) rlp::decode(&self.seal()[1])
} }
/// Get the mix hash field of the header. /// Get the mix hash field of the header.
pub fn mix_hash(&self) -> H256 { pub fn mix_hash(&self) -> H256 {
decode(&self.seal()[0]) rlp::decode(&self.seal()[0])
} }
/// Set the nonce and mix hash fields of the header. /// Set the nonce and mix hash fields of the header.
pub fn set_nonce_and_mix_hash(&mut self, nonce: &H64, mix_hash: &H256) { pub fn set_nonce_and_mix_hash(&mut self, nonce: &H64, mix_hash: &H256) {
self.set_seal(vec![encode(mix_hash).to_vec(), encode(nonce).to_vec()]); self.set_seal(vec![rlp::encode(mix_hash).to_vec(), rlp::encode(nonce).to_vec()]);
} }
} }
@ -349,6 +350,7 @@ mod tests {
use tests::helpers::*; use tests::helpers::*;
use super::super::new_morden; use super::super::new_morden;
use super::Ethash; use super::Ethash;
use rlp;
#[test] #[test]
fn on_close_block() { fn on_close_block() {

View File

@ -76,7 +76,7 @@ impl<Gas: CostType> Gasometer<Gas> {
instructions::SSTORE => { instructions::SSTORE => {
let address = H256::from(stack.peek(0)); let address = H256::from(stack.peek(0));
let newval = stack.peek(1); let newval = stack.peek(1);
let val = U256::from(ext.storage_at(&address).as_slice()); let val = U256::from(&*ext.storage_at(&address));
let gas = if val.is_zero() && !newval.is_zero() { let gas = if val.is_zero() && !newval.is_zero() {
schedule.sstore_set_gas schedule.sstore_set_gas

View File

@ -403,18 +403,18 @@ impl<Cost: CostType> Interpreter<Cost> {
let offset = stack.pop_back(); let offset = stack.pop_back();
let size = stack.pop_back(); let size = stack.pop_back();
let sha3 = self.mem.read_slice(offset, size).sha3(); let sha3 = self.mem.read_slice(offset, size).sha3();
stack.push(U256::from(sha3.as_slice())); stack.push(U256::from(&*sha3));
}, },
instructions::SLOAD => { instructions::SLOAD => {
let key = H256::from(&stack.pop_back()); let key = H256::from(&stack.pop_back());
let word = U256::from(ext.storage_at(&key).as_slice()); let word = U256::from(&*ext.storage_at(&key));
stack.push(word); stack.push(word);
}, },
instructions::SSTORE => { instructions::SSTORE => {
let address = H256::from(&stack.pop_back()); let address = H256::from(&stack.pop_back());
let val = stack.pop_back(); let val = stack.pop_back();
let current_val = U256::from(ext.storage_at(&address).as_slice()); let current_val = U256::from(&*ext.storage_at(&address));
// Increase refund for clear // Increase refund for clear
if !self.is_zero(&current_val) && self.is_zero(&val) { if !self.is_zero(&current_val) && self.is_zero(&val) {
ext.inc_sstore_clears(); ext.inc_sstore_clears();
@ -491,7 +491,7 @@ impl<Cost: CostType> Interpreter<Cost> {
instructions::BLOCKHASH => { instructions::BLOCKHASH => {
let block_number = stack.pop_back(); let block_number = stack.pop_back();
let block_hash = ext.blockhash(&block_number); let block_hash = ext.blockhash(&block_number);
stack.push(U256::from(block_hash.as_slice())); stack.push(U256::from(&*block_hash));
}, },
instructions::COINBASE => { instructions::COINBASE => {
stack.push(address_to_u256(ext.env_info().author.clone())); stack.push(address_to_u256(ext.env_info().author.clone()));
@ -807,7 +807,7 @@ fn u256_to_address(value: &U256) -> Address {
#[inline] #[inline]
fn address_to_u256(value: Address) -> U256 { fn address_to_u256(value: Address) -> U256 {
U256::from(H256::from(value).as_slice()) U256::from(&*H256::from(value))
} }
#[test] #[test]

View File

@ -32,6 +32,8 @@ const MAX_VM_DEPTH_FOR_THREAD: usize = 64;
/// Returns new address created from address and given nonce. /// Returns new address created from address and given nonce.
pub fn contract_address(address: &Address, nonce: &U256) -> Address { pub fn contract_address(address: &Address, nonce: &U256) -> Address {
use rlp::{RlpStream, Stream};
let mut stream = RlpStream::new_list(2); let mut stream = RlpStream::new_list(2);
stream.append(address); stream.append(address);
stream.append(nonce); stream.append(nonce);

View File

@ -19,6 +19,7 @@
use util::*; use util::*;
use basic_types::*; use basic_types::*;
use time::get_time; use time::get_time;
use rlp::*;
use std::cell::RefCell; use std::cell::RefCell;
@ -297,7 +298,7 @@ impl Encodable for Header {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rustc_serialize::hex::FromHex; use rustc_serialize::hex::FromHex;
use util::rlp::{decode, encode}; use rlp;
use super::Header; use super::Header;
#[test] #[test]
@ -307,7 +308,7 @@ mod tests {
let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap();
let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = decode(&header_rlp); let header: Header = rlp::decode(&header_rlp);
let seal_fields = header.seal; let seal_fields = header.seal;
assert_eq!(seal_fields.len(), 2); assert_eq!(seal_fields.len(), 2);
assert_eq!(seal_fields[0], mix_hash); assert_eq!(seal_fields[0], mix_hash);
@ -319,8 +320,8 @@ mod tests {
// that's rlp of block header created with ethash engine. // that's rlp of block header created with ethash engine.
let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap();
let header: Header = decode(&header_rlp); let header: Header = rlp::decode(&header_rlp);
let encoded_header = encode(&header).to_vec(); let encoded_header = rlp::encode(&header).to_vec();
assert_eq!(header_rlp, encoded_header); assert_eq!(header_rlp, encoded_header);
} }

View File

@ -17,6 +17,7 @@
use super::test_common::*; use super::test_common::*;
use evm; use evm;
use ethjson; use ethjson;
use rlp::{UntrustedRlp, View};
fn do_json_test(json_data: &[u8]) -> Vec<String> { fn do_json_test(json_data: &[u8]) -> Vec<String> {
let tests = ethjson::transaction::Test::load(json_data).unwrap(); let tests = ethjson::transaction::Test::load(json_data).unwrap();

View File

@ -79,12 +79,9 @@
//! cargo build --release //! cargo build --release
//! ``` //! ```
#[macro_use] extern crate log;
#[macro_use] extern crate ethcore_util as util;
extern crate ethcore_io as io; extern crate ethcore_io as io;
#[macro_use] extern crate lazy_static;
extern crate rustc_serialize; extern crate rustc_serialize;
#[macro_use] extern crate heapsize;
extern crate crypto; extern crate crypto;
extern crate time; extern crate time;
extern crate env_logger; extern crate env_logger;
@ -92,19 +89,32 @@ extern crate num_cpus;
extern crate crossbeam; extern crate crossbeam;
extern crate ethjson; extern crate ethjson;
extern crate bloomchain; extern crate bloomchain;
#[macro_use] extern crate ethcore_ipc as ipc;
extern crate rayon; extern crate rayon;
extern crate hyper; extern crate hyper;
extern crate ethash; extern crate ethash;
extern crate ethkey; extern crate ethkey;
pub extern crate ethstore;
extern crate semver; extern crate semver;
extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_ipc_nano as nanoipc;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
extern crate rand; extern crate rand;
extern crate bit_set; extern crate bit_set;
extern crate rlp;
#[cfg(feature = "jit" )] extern crate evmjit; #[macro_use]
extern crate log;
#[macro_use]
extern crate ethcore_util as util;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate heapsize;
#[macro_use]
extern crate ethcore_ipc as ipc;
#[cfg(feature = "jit" )]
extern crate evmjit;
pub extern crate ethstore;
pub mod account_provider; pub mod account_provider;
pub mod engines; pub mod engines;

View File

@ -17,7 +17,7 @@
//! This migration compresses the state db. //! This migration compresses the state db.
use util::migration::{SimpleMigration, Progress}; use util::migration::{SimpleMigration, Progress};
use util::rlp::{Compressible, UntrustedRlp, View, RlpType}; use rlp::{Compressible, UntrustedRlp, View, RlpType};
/// Compressing migration. /// Compressing migration.
#[derive(Default)] #[derive(Default)]

View File

@ -23,9 +23,11 @@ use util::Bytes;
use util::{Address, FixedHash, H256}; use util::{Address, FixedHash, H256};
use util::kvdb::Database; use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress}; use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
use util::rlp::{decode, Rlp, RlpStream, Stream, View};
use util::sha3::Hashable; use util::sha3::Hashable;
use rlp::{decode, Rlp, RlpStream, Stream, View};
// attempt to migrate a key, value pair. None if migration not possible. // attempt to migrate a key, value pair. None if migration not possible.
fn attempt_migrate(mut key_h: H256, val: &[u8]) -> Option<H256> { fn attempt_migrate(mut key_h: H256, val: &[u8]) -> Option<H256> {
let val_hash = val.sha3(); let val_hash = val.sha3();

View File

@ -17,7 +17,7 @@
//! This migration consolidates all databases into single one using Column Families. //! This migration consolidates all databases into single one using Column Families.
use util::{Rlp, RlpStream, View, Stream}; use rlp::{Rlp, RlpStream, View, Stream};
use util::kvdb::Database; use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, Progress}; use util::migration::{Batch, Config, Error, Migration, Progress};

View File

@ -1229,6 +1229,8 @@ mod test {
#[test] #[test]
fn should_reject_incorectly_signed_transaction() { fn should_reject_incorectly_signed_transaction() {
use rlp::{self, RlpStream, Stream};
// given // given
let mut txq = TransactionQueue::new(); let mut txq = TransactionQueue::new();
let tx = new_unsigned_tx(123.into(), 1.into()); let tx = new_unsigned_tx(123.into(), 1.into());
@ -1243,7 +1245,7 @@ mod test {
s.append(&0u64); // v s.append(&0u64); // v
s.append(&U256::zero()); // r s.append(&U256::zero()); // r
s.append(&U256::zero()); // s s.append(&U256::zero()); // s
decode(s.as_raw()) rlp::decode(s.as_raw())
}; };
// when // when
let res = txq.add(stx, &default_account_details, TransactionOrigin::External); let res = txq.add(stx, &default_account_details, TransactionOrigin::External);

View File

@ -19,6 +19,7 @@ use state::Account;
use account_db::AccountDBMut; use account_db::AccountDBMut;
use ethjson; use ethjson;
use types::account_diff::*; use types::account_diff::*;
use rlp::{self, RlpStream, Stream};
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
/// An account, expressed as Plain-Old-Data (hence the name). /// An account, expressed as Plain-Old-Data (hence the name).
@ -57,7 +58,7 @@ impl PodAccount {
let mut stream = RlpStream::new_list(4); let mut stream = RlpStream::new_list(4);
stream.append(&self.nonce); stream.append(&self.nonce);
stream.append(&self.balance); stream.append(&self.balance);
stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), encode(&U256::from(v.as_slice())).to_vec())).collect())); stream.append(&sec_trie_root(self.storage.iter().map(|(k, v)| (k.to_vec(), rlp::encode(&U256::from(&**v)).to_vec())).collect()));
stream.append(&self.code.as_ref().unwrap_or(&vec![]).sha3()); stream.append(&self.code.as_ref().unwrap_or(&vec![]).sha3());
stream.out() stream.out()
} }
@ -71,7 +72,7 @@ impl PodAccount {
let mut r = H256::new(); let mut r = H256::new();
let mut t = SecTrieDBMut::new(db, &mut r); let mut t = SecTrieDBMut::new(db, &mut r);
for (k, v) in &self.storage { for (k, v) in &self.storage {
if let Err(e) = t.insert(k, &encode(&U256::from(v.as_slice()))) { if let Err(e) = t.insert(k, &rlp::encode(&U256::from(&**v))) {
warn!("Encountered potential DB corruption: {}", e); warn!("Encountered potential DB corruption: {}", e);
} }
} }

View File

@ -17,11 +17,12 @@
//! Account state encoding and decoding //! Account state encoding and decoding
use account_db::{AccountDB, AccountDBMut}; use account_db::{AccountDB, AccountDBMut};
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY};
use util::rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
use util::trie::{TrieDB, Trie};
use snapshot::Error; use snapshot::Error;
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY};
use util::trie::{TrieDB, Trie};
use rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
// whether an encoded account has code and how it is referred to. // whether an encoded account has code and how it is referred to.
@ -206,9 +207,9 @@ mod tests {
use tests::helpers::get_temp_journal_db; use tests::helpers::get_temp_journal_db;
use snapshot::tests::helpers::fill_storage; use snapshot::tests::helpers::fill_storage;
use util::{SHA3_NULL_RLP, SHA3_EMPTY}; use util::sha3::{SHA3_EMPTY, SHA3_NULL_RLP};
use util::{Address, FixedHash, H256, HashDB}; use util::{Address, FixedHash, H256, HashDB};
use util::rlp::{UntrustedRlp, View}; use rlp::{UntrustedRlp, View};
use std::collections::{HashSet, HashMap}; use std::collections::{HashSet, HashMap};

View File

@ -20,8 +20,8 @@ use block::Block;
use header::Header; use header::Header;
use views::BlockView; use views::BlockView;
use util::rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View}; use rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View};
use util::rlp::{Compressible, RlpType}; use rlp::{Compressible, RlpType};
use util::{Bytes, Hashable, H256}; use util::{Bytes, Hashable, H256};
const HEADER_FIELDS: usize = 10; const HEADER_FIELDS: usize = 10;

View File

@ -22,7 +22,7 @@ use ids::BlockID;
use util::H256; use util::H256;
use util::trie::TrieError; use util::trie::TrieError;
use util::rlp::DecoderError; use rlp::DecoderError;
/// Snapshot-related errors. /// Snapshot-related errors.
#[derive(Debug)] #[derive(Debug)]

View File

@ -27,7 +27,7 @@ use std::path::{Path, PathBuf};
use util::Bytes; use util::Bytes;
use util::hash::H256; use util::hash::H256;
use util::rlp::{self, Encodable, RlpStream, UntrustedRlp, Stream, View}; use rlp::{self, Encodable, RlpStream, UntrustedRlp, Stream, View};
use super::ManifestData; use super::ManifestData;

View File

@ -32,9 +32,9 @@ use util::Mutex;
use util::hash::{FixedHash, H256}; use util::hash::{FixedHash, H256};
use util::journaldb::{self, Algorithm, JournalDB}; use util::journaldb::{self, Algorithm, JournalDB};
use util::kvdb::Database; use util::kvdb::Database;
use util::rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View, Compressible, RlpType}; use util::sha3::SHA3_NULL_RLP;
use util::rlp::SHA3_NULL_RLP;
use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut}; use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut};
use rlp::{DecoderError, RlpStream, Stream, UntrustedRlp, View, Compressible, RlpType};
use self::account::Account; use self::account::Account;
use self::block::AbridgedBlock; use self::block::AbridgedBlock;

View File

@ -25,7 +25,7 @@ use util::hash::{FixedHash, H256};
use util::hashdb::HashDB; use util::hashdb::HashDB;
use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode}; use util::trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
use util::trie::{TrieDB, TrieDBMut, Trie}; use util::trie::{TrieDB, TrieDBMut, Trie};
use util::rlp::SHA3_NULL_RLP; use util::sha3::SHA3_NULL_RLP;
// the proportion of accounts we will alter each tick. // the proportion of accounts we will alter each tick.
const ACCOUNT_CHURN: f32 = 0.01; const ACCOUNT_CHURN: f32 = 0.01;

View File

@ -14,8 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::rlp::*;
use util::{Address, H256, Uint, U256}; use util::{Address, H256, Uint, U256};
use util::sha3::SHA3_NULL_RLP;
use ethjson; use ethjson;
use super::seal::Seal; use super::seal::Seal;

View File

@ -16,7 +16,7 @@
//! Spec seal. //! Spec seal.
use util::rlp::*; use rlp::*;
use util::hash::{H64, H256}; use util::hash::{H64, H256};
use ethjson; use ethjson;

View File

@ -24,6 +24,7 @@ use super::genesis::Genesis;
use super::seal::Generic as GenericSeal; use super::seal::Generic as GenericSeal;
use ethereum; use ethereum;
use ethjson; use ethjson;
use rlp::{Rlp, RlpStream, View, Stream};
/// Parameters common to all engines. /// Parameters common to all engines.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -231,7 +232,7 @@ impl Spec {
{ {
let mut t = SecTrieDBMut::new(db, &mut root); let mut t = SecTrieDBMut::new(db, &mut root);
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {
try!(t.insert(address.as_slice(), &account.rlp())); try!(t.insert(&**address, &account.rlp()));
} }
} }
for (address, account) in self.genesis_state.get().iter() { for (address, account) in self.genesis_state.get().iter() {

View File

@ -19,6 +19,7 @@
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use util::*; use util::*;
use pod_account::*; use pod_account::*;
use rlp::*;
use std::cell::{Ref, RefCell, Cell}; use std::cell::{Ref, RefCell, Cell};
@ -287,7 +288,7 @@ impl Account {
// so we can call overloaded `to_bytes` method // so we can call overloaded `to_bytes` method
let res = match v.is_zero() { let res = match v.is_zero() {
true => t.remove(k), true => t.remove(k),
false => t.insert(k, &encode(&U256::from(v.as_slice()))), false => t.insert(k, &encode(&U256::from(&*v))),
}; };
if let Err(e) = res { if let Err(e) = res {
@ -333,6 +334,7 @@ mod tests {
use util::*; use util::*;
use super::*; use super::*;
use account_db::*; use account_db::*;
use rlp::*;
#[test] #[test]
fn account_compress() { fn account_compress() {

View File

@ -22,6 +22,7 @@ use tests::helpers::*;
use common::*; use common::*;
use devtools::*; use devtools::*;
use miner::Miner; use miner::Miner;
use rlp::{Rlp, View};
#[test] #[test]
fn imports_from_empty() { fn imports_from_empty() {

View File

@ -27,6 +27,7 @@ use engines::Engine;
use ethereum; use ethereum;
use devtools::*; use devtools::*;
use miner::Miner; use miner::Miner;
use rlp::{self, RlpStream, Stream};
#[cfg(feature = "json-tests")] #[cfg(feature = "json-tests")]
pub enum ChainEra { pub enum ChainEra {
@ -116,7 +117,7 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransa
rlp.append(header); rlp.append(header);
rlp.begin_list(transactions.len()); rlp.begin_list(transactions.len());
for t in transactions { for t in transactions {
rlp.append_raw(&encode::<SignedTransaction>(t).to_vec(), 1); rlp.append_raw(&rlp::encode::<SignedTransaction>(t).to_vec(), 1);
} }
rlp.append(&uncles); rlp.append(&uncles);
rlp.out() rlp.out()

View File

@ -1,6 +1,6 @@
use bloomchain::Bloom; use bloomchain::Bloom;
use bloomchain::group::{BloomGroup, GroupPosition}; use bloomchain::group::{BloomGroup, GroupPosition};
use util::rlp::*; use rlp::*;
use basic_types::LogBloom; use basic_types::LogBloom;
/// Helper structure representing bloom of the trace. /// Helper structure representing bloom of the trace.

View File

@ -98,12 +98,10 @@ impl AccountDiff {
// TODO: refactor into something nicer. // TODO: refactor into something nicer.
fn interpreted_hash(u: &H256) -> String { fn interpreted_hash(u: &H256) -> String {
use util::bytes::*;
if u <= &H256::from(0xffffffff) { if u <= &H256::from(0xffffffff) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u32(), U256::from(u.as_slice()).low_u32()) format!("{} = 0x{:x}", U256::from(&**u).low_u32(), U256::from(&**u).low_u32())
} else if u <= &H256::from(u64::max_value()) { } else if u <= &H256::from(u64::max_value()) {
format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u64(), U256::from(u.as_slice()).low_u64()) format!("{} = 0x{:x}", U256::from(&**u).low_u64(), U256::from(&**u).low_u64())
// } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") { // } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") {
// format!("@{}", Address::from(u)) // format!("@{}", Address::from(u))
} else { } else {
@ -113,7 +111,7 @@ fn interpreted_hash(u: &H256) -> String {
impl fmt::Display for AccountDiff { impl fmt::Display for AccountDiff {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use util::bytes::*; use util::bytes::ToPretty;
match self.nonce { match self.nonce {
Diff::Born(ref x) => try!(write!(f, " non {}", x)), Diff::Born(ref x) => try!(write!(f, " non {}", x)),

View File

@ -17,7 +17,7 @@
//! Transaction execution format module. //! Transaction execution format module.
use util::{Bytes, U256, Address, U512}; use util::{Bytes, U256, Address, U512};
use util::rlp::*; use rlp::*;
use trace::{VMTrace, FlatTrace}; use trace::{VMTrace, FlatTrace};
use types::log_entry::LogEntry; use types::log_entry::LogEntry;
use types::state_diff::StateDiff; use types::state_diff::StateDiff;
@ -203,7 +203,8 @@ pub type ExecutionResult = Result<Executed, ExecutionError>;
#[test] #[test]
fn should_encode_and_decode_call_type() { fn should_encode_and_decode_call_type() {
use util::rlp; use rlp;
let original = CallType::Call; let original = CallType::Call;
let encoded = rlp::encode(&original); let encoded = rlp::encode(&original);
let decoded = rlp::decode(&encoded); let decoded = rlp::decode(&encoded);

View File

@ -18,8 +18,9 @@
use std::ops::Deref; use std::ops::Deref;
use util::{H256, Address, Bytes, HeapSizeOf, Hashable}; use util::{H256, Address, Bytes, HeapSizeOf, Hashable};
use util::rlp::*;
use util::bloom::Bloomable; use util::bloom::Bloomable;
use rlp::*;
use basic_types::LogBloom; use basic_types::LogBloom;
use header::BlockNumber; use header::BlockNumber;
use ethjson; use ethjson;

View File

@ -17,8 +17,9 @@
//! Receipt //! Receipt
use util::{H256, U256, Address}; use util::{H256, U256, Address};
use util::rlp::*;
use util::HeapSizeOf; use util::HeapSizeOf;
use rlp::*;
use basic_types::LogBloom; use basic_types::LogBloom;
use header::BlockNumber; use header::BlockNumber;
use log_entry::{LogEntry, LocalizedLogEntry}; use log_entry::{LogEntry, LocalizedLogEntry};

View File

@ -17,7 +17,7 @@
//! Flat trace module //! Flat trace module
use std::collections::VecDeque; use std::collections::VecDeque;
use util::rlp::*; use rlp::*;
use util::HeapSizeOf; use util::HeapSizeOf;
use basic_types::LogBloom; use basic_types::LogBloom;
use super::trace::{Action, Res}; use super::trace::{Action, Res};
@ -167,7 +167,6 @@ mod tests {
#[test] #[test]
fn test_trace_serialization() { fn test_trace_serialization() {
use util::rlp;
// block #51921 // block #51921
let flat_trace = FlatTrace { let flat_trace = FlatTrace {
@ -220,8 +219,8 @@ mod tests {
FlatTransactionTraces(vec![flat_trace1, flat_trace2]) FlatTransactionTraces(vec![flat_trace1, flat_trace2])
]); ]);
let encoded = rlp::encode(&block_traces); let encoded = ::rlp::encode(&block_traces);
let decoded = rlp::decode(&encoded); let decoded = ::rlp::decode(&encoded);
assert_eq!(block_traces, decoded); assert_eq!(block_traces, decoded);
} }
} }

View File

@ -17,9 +17,10 @@
//! Tracing datatypes. //! Tracing datatypes.
use util::{U256, Bytes, Address}; use util::{U256, Bytes, Address};
use util::rlp::*;
use util::sha3::Hashable; use util::sha3::Hashable;
use util::bloom::Bloomable; use util::bloom::Bloomable;
use rlp::*;
use action_params::ActionParams; use action_params::ActionParams;
use basic_types::LogBloom; use basic_types::LogBloom;
use types::executed::CallType; use types::executed::CallType;

View File

@ -18,7 +18,7 @@
use std::ops::Deref; use std::ops::Deref;
use std::cell::*; use std::cell::*;
use util::rlp::*; use rlp::*;
use util::sha3::Hashable; use util::sha3::Hashable;
use util::{H256, Address, U256, Bytes}; use util::{H256, Address, U256, Bytes};
use ethkey::{Signature, sign, Secret, recover, public_to_address, Error as EthkeyError}; use ethkey::{Signature, sign, Secret, recover, public_to_address, Error as EthkeyError};
@ -275,7 +275,7 @@ impl SignedTransaction {
match hash { match hash {
Some(h) => h, Some(h) => h,
None => { None => {
let h = self.rlp_sha3(); let h = (&*self.rlp_bytes()).sha3();
self.hash.set(Some(h)); self.hash.set(Some(h));
h h
} }

View File

@ -18,9 +18,8 @@
use ipc::binary::{BinaryConvertError, BinaryConvertable}; use ipc::binary::{BinaryConvertError, BinaryConvertable};
use error::{TransactionError, Error}; use error::{TransactionError, Error};
use util::Populatable;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// Represents the result of importing transaction. /// Represents the result of importing transaction.
pub enum TransactionImportResult { pub enum TransactionImportResult {
/// Transaction was imported to current queue. /// Transaction was imported to current queue.

View File

@ -24,6 +24,7 @@
use common::*; use common::*;
use engines::Engine; use engines::Engine;
use blockchain::*; use blockchain::*;
use rlp::{UntrustedRlp, View};
/// Preprocessed block data gathered in `verify_block_unordered` call /// Preprocessed block data gathered in `verify_block_unordered` call
pub struct PreverifiedBlock { pub struct PreverifiedBlock {
@ -240,6 +241,7 @@ mod tests {
use spec::*; use spec::*;
use transaction::*; use transaction::*;
use tests::helpers::*; use tests::helpers::*;
use rlp::View;
fn check_ok(result: Result<(), Error>) { fn check_ok(result: Result<(), Error>) {
result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e)); result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e));
@ -346,6 +348,8 @@ mod tests {
#[test] #[test]
#[cfg_attr(feature="dev", allow(similar_names))] #[cfg_attr(feature="dev", allow(similar_names))]
fn test_verify_block() { fn test_verify_block() {
use rlp::{RlpStream, Stream};
// Test against morden // Test against morden
let mut good = Header::new(); let mut good = Header::new();
let spec = Spec::new_test(); let spec = Spec::new_test();
@ -411,7 +415,7 @@ mod tests {
let mut uncles_rlp = RlpStream::new(); let mut uncles_rlp = RlpStream::new();
uncles_rlp.append(&good_uncles); uncles_rlp.append(&good_uncles);
let good_uncles_hash = uncles_rlp.as_raw().sha3(); let good_uncles_hash = uncles_rlp.as_raw().sha3();
let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| encode::<SignedTransaction>(t).to_vec()).collect()); let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| ::rlp::encode::<SignedTransaction>(t).to_vec()).collect());
let mut parent = good.clone(); let mut parent = good.clone();
parent.set_number(9); parent.set_number(9);

View File

@ -20,6 +20,7 @@ use util::*;
use header::*; use header::*;
use transaction::*; use transaction::*;
use super::{TransactionView, HeaderView}; use super::{TransactionView, HeaderView};
use rlp::{Rlp, View};
/// View onto block rlp. /// View onto block rlp.
pub struct BlockView<'a> { pub struct BlockView<'a> {

View File

@ -20,6 +20,7 @@ use util::*;
use header::*; use header::*;
use transaction::*; use transaction::*;
use super::{TransactionView, HeaderView}; use super::{TransactionView, HeaderView};
use rlp::{Rlp, View};
/// View onto block rlp. /// View onto block rlp.
pub struct BodyView<'a> { pub struct BodyView<'a> {

View File

@ -16,7 +16,8 @@
//! View onto block header rlp //! View onto block header rlp
use util::{Rlp, U256, Bytes, Hashable, H256, Address, H2048, View}; use util::{U256, Bytes, Hashable, H256, Address, H2048};
use rlp::{Rlp, View};
use header::BlockNumber; use header::BlockNumber;
/// View onto block header rlp. /// View onto block header rlp.

View File

@ -15,7 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! View onto transaction rlp //! View onto transaction rlp
use util::{Rlp, U256, Bytes, Hashable, H256, View}; use util::{U256, Bytes, Hashable, H256};
use rlp::{Rlp, View};
/// View onto transaction rlp. /// View onto transaction rlp.
pub struct TransactionView<'a> { pub struct TransactionView<'a> {

View File

@ -42,7 +42,7 @@ pub struct ModuleState {
#[derive(Ipc)] #[derive(Ipc)]
pub trait ControlService { pub trait ControlService {
fn shutdown(&self); fn shutdown(&self) -> bool;
} }
#[derive(Ipc)] #[derive(Ipc)]

View File

@ -16,7 +16,6 @@
//! Binary representation of types //! Binary representation of types
use util::bytes::Populatable;
use util::{U256, U512, H256, H2048, Address}; use util::{U256, U512, H256, H2048, Address};
use std::mem; use std::mem;
use std::collections::{VecDeque, BTreeMap}; use std::collections::{VecDeque, BTreeMap};
@ -706,14 +705,21 @@ pub fn serialize<T: BinaryConvertable>(t: &T) -> Result<Vec<u8>, BinaryError> {
#[macro_export] #[macro_export]
macro_rules! binary_fixed_size { macro_rules! binary_fixed_size {
($target_ty: ty) => { ($target_ty: ty) => {
impl BinaryConvertable for $target_ty { impl BinaryConvertable for $target_ty where $target_ty: Copy {
fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, BinaryConvertError> { fn from_bytes(bytes: &[u8], _length_stack: &mut ::std::collections::VecDeque<usize>) -> Result<Self, BinaryConvertError> {
match bytes.len().cmp(&::std::mem::size_of::<$target_ty>()) { let size = ::std::mem::size_of::<$target_ty>();
match bytes.len().cmp(&size) {
::std::cmp::Ordering::Equal => (), ::std::cmp::Ordering::Equal => (),
_ => return Err(BinaryConvertError::size(::std::mem::size_of::<$target_ty>(), bytes.len())), _ => return Err(BinaryConvertError::size(size, bytes.len())),
}; };
let mut res: Self = unsafe { ::std::mem::uninitialized() }; let res: Self = unsafe {
res.copy_raw(bytes); let mut temp = ::std::mem::zeroed();
let temp_ptr = &mut temp as *mut _ as *mut u8;
::std::ptr::copy_nonoverlapping(bytes.as_ptr(), temp_ptr, size);
temp
};
Ok(res) Ok(res)
} }
@ -731,14 +737,14 @@ macro_rules! binary_fixed_size {
} }
/// Fixed-sized version of Handshake struct /// Fixed-sized version of Handshake struct
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BinHandshake { pub struct BinHandshake {
api_version: BinVersion, api_version: BinVersion,
protocol_version: BinVersion, protocol_version: BinVersion,
} }
/// Shorten version of semver Version without `pre` and `build` information /// Shorten version of semver Version without `pre` and `build` information
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BinVersion { pub struct BinVersion {
pub major: u64, pub major: u64,
pub minor: u64, pub minor: u64,

View File

@ -61,6 +61,8 @@ pub fn setup_log(config: &Config) -> Result<Arc<RotatingLogger>, String> {
let mut builder = LogBuilder::new(); let mut builder = LogBuilder::new();
// Disable ws info logging by default. // Disable ws info logging by default.
builder.filter(Some("ws"), LogLevelFilter::Warn); builder.filter(Some("ws"), LogLevelFilter::Warn);
// Disable rustls info logging by default.
builder.filter(Some("rustls"), LogLevelFilter::Warn);
builder.filter(None, LogLevelFilter::Info); builder.filter(None, LogLevelFilter::Info);
if env::var("RUST_LOG").is_ok() { if env::var("RUST_LOG").is_ok() {

View File

@ -24,7 +24,8 @@ use std::sync::Arc;
use rustc_serialize::hex::FromHex; use rustc_serialize::hex::FromHex;
use ethcore_logger::{setup_log, Config as LogConfig}; use ethcore_logger::{setup_log, Config as LogConfig};
use io::{PanicHandler, ForwardPanic}; use io::{PanicHandler, ForwardPanic};
use util::{PayloadInfo, ToPretty}; use util::ToPretty;
use rlp::PayloadInfo;
use ethcore::service::ClientService; use ethcore::service::ClientService;
use ethcore::client::{Mode, DatabaseCompactionProfile, Switch, VMType, BlockImportError, BlockChainClient, BlockID}; use ethcore::client::{Mode, DatabaseCompactionProfile, Switch, VMType, BlockImportError, BlockChainClient, BlockID};
use ethcore::error::ImportError; use ethcore::error::ImportError;

View File

@ -42,7 +42,7 @@ pub fn host_service<T: ?Sized + Send + Sync + 'static>(addr: &str, stop_guard: A
let mut worker = nanoipc::Worker::<T>::new(&service); let mut worker = nanoipc::Worker::<T>::new(&service);
worker.add_reqrep(&socket_url).unwrap(); worker.add_reqrep(&socket_url).unwrap();
while !stop_guard.load(Ordering::Relaxed) { while !stop_guard.load(Ordering::SeqCst) {
worker.poll(); worker.poll();
} }
}); });

View File

@ -26,12 +26,8 @@ extern crate docopt;
extern crate num_cpus; extern crate num_cpus;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
#[macro_use]
extern crate ethcore_util as util;
extern crate ethcore; extern crate ethcore;
extern crate ethsync; extern crate ethsync;
#[macro_use]
extern crate log as rlog;
extern crate env_logger; extern crate env_logger;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate ctrlc; extern crate ctrlc;
@ -43,8 +39,8 @@ extern crate semver;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore_ipc as ipc; extern crate ethcore_ipc as ipc;
extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_ipc_nano as nanoipc;
#[macro_use] extern crate rlp;
extern crate hyper; // for price_info.rs
extern crate json_ipc_server as jsonipc; extern crate json_ipc_server as jsonipc;
extern crate ethcore_ipc_hypervisor as hypervisor; extern crate ethcore_ipc_hypervisor as hypervisor;
@ -52,11 +48,19 @@ extern crate ethcore_rpc;
extern crate ethcore_signer; extern crate ethcore_signer;
extern crate ansi_term; extern crate ansi_term;
#[macro_use]
extern crate lazy_static;
extern crate regex; extern crate regex;
extern crate isatty; extern crate isatty;
#[macro_use]
extern crate ethcore_util as util;
#[macro_use]
extern crate log as rlog;
#[macro_use]
extern crate hyper; // for price_info.rs
#[macro_use]
extern crate lazy_static;
#[cfg(feature="stratum")] #[cfg(feature="stratum")]
extern crate ethcore_stratum; extern crate ethcore_stratum;

View File

@ -31,9 +31,10 @@ struct SyncControlService {
} }
impl ControlService for SyncControlService { impl ControlService for SyncControlService {
fn shutdown(&self) { fn shutdown(&self) -> bool {
trace!(target: "hypervisor", "Received shutdown from control service"); trace!(target: "hypervisor", "Received shutdown from control service");
self.stop.store(true, ::std::sync::atomic::Ordering::Relaxed); self.stop.store(true, ::std::sync::atomic::Ordering::SeqCst);
true
} }
} }
@ -75,14 +76,15 @@ pub fn main() {
let control_service = Arc::new(SyncControlService::default()); let control_service = Arc::new(SyncControlService::default());
let as_control = control_service.clone() as Arc<ControlService>; let as_control = control_service.clone() as Arc<ControlService>;
let mut worker = nanoipc::Worker::<ControlService>::new(&as_control); let mut worker = nanoipc::Worker::<ControlService>::new(&as_control);
let thread_stop = control_service.stop.clone();
worker.add_reqrep( worker.add_reqrep(
&service_urls::with_base(&service_config.io_path, service_urls::SYNC_CONTROL) &service_urls::with_base(&service_config.io_path, service_urls::SYNC_CONTROL)
).unwrap(); ).unwrap();
while !control_service.stop.load(::std::sync::atomic::Ordering::Relaxed) { while !thread_stop.load(::std::sync::atomic::Ordering::SeqCst) {
worker.poll(); worker.poll();
} }
service_stop.store(true, ::std::sync::atomic::Ordering::Relaxed); service_stop.store(true, ::std::sync::atomic::Ordering::SeqCst);
hypervisor.module_shutdown(SYNC_MODULE_ID); hypervisor.module_shutdown(SYNC_MODULE_ID);
trace!(target: "hypervisor", "Sync process terminated gracefully"); trace!(target: "hypervisor", "Sync process terminated gracefully");

View File

@ -23,6 +23,7 @@ ethash = { path = "../ethash" }
ethsync = { path = "../sync" } ethsync = { path = "../sync" }
ethjson = { path = "../json" } ethjson = { path = "../json" }
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
rlp = { path = "../util/rlp" }
rustc-serialize = "0.3" rustc-serialize = "0.3"
transient-hashmap = "0.1" transient-hashmap = "0.1"
serde_macros = { version = "0.8.0", optional = true } serde_macros = { version = "0.8.0", optional = true }

View File

@ -19,15 +19,12 @@
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))] #![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))] #![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
#[macro_use]
extern crate log;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate jsonrpc_core; extern crate jsonrpc_core;
extern crate jsonrpc_http_server; extern crate jsonrpc_http_server;
#[macro_use]
extern crate ethcore_util as util;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore; extern crate ethcore;
extern crate ethkey; extern crate ethkey;
@ -37,6 +34,12 @@ extern crate transient_hashmap;
extern crate json_ipc_server as ipc; extern crate json_ipc_server as ipc;
extern crate ethcore_ipc; extern crate ethcore_ipc;
extern crate time; extern crate time;
extern crate rlp;
#[macro_use]
extern crate log;
#[macro_use]
extern crate ethcore_util as util;
#[cfg(test)] #[cfg(test)]
extern crate ethjson; extern crate ethjson;

View File

@ -15,7 +15,6 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::{Address, H256, U256, Uint}; use util::{Address, H256, U256, Uint};
use util::rlp::encode;
use util::bytes::ToPretty; use util::bytes::ToPretty;
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use ethcore::client::MiningBlockChainClient; use ethcore::client::MiningBlockChainClient;
@ -70,7 +69,7 @@ pub fn unlock_sign_and_dispatch<C, M>(client: &C, miner: &M, request: Transactio
t.with_signature(signature) t.with_signature(signature)
}; };
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty()); trace!(target: "miner", "send_transaction: dispatching tx: {}", ::rlp::encode(&signed_transaction).to_vec().pretty());
dispatch_transaction(&*client, &*miner, signed_transaction) dispatch_transaction(&*client, &*miner, signed_transaction)
} }
@ -84,7 +83,7 @@ pub fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionReques
t.with_signature(signature) t.with_signature(signature)
}; };
trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty()); trace!(target: "miner", "send_transaction: dispatching tx: {}", ::rlp::encode(&signed_transaction).to_vec().pretty());
dispatch_transaction(&*client, &*miner, signed_transaction) dispatch_transaction(&*client, &*miner, signed_transaction)
} }

View File

@ -29,8 +29,8 @@ use ethcore::miner::{MinerService, ExternalMinerService};
use jsonrpc_core::*; use jsonrpc_core::*;
use util::{H256, Address, FixedHash, U256, H64, Uint}; use util::{H256, Address, FixedHash, U256, H64, Uint};
use util::sha3::*; use util::sha3::*;
use util::rlp::{encode, decode, UntrustedRlp, View};
use util::{FromHex, Mutex}; use util::{FromHex, Mutex};
use rlp::{self, UntrustedRlp, View};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID}; use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID};
use ethcore::header::Header as BlockHeader; use ethcore::header::Header as BlockHeader;
@ -123,7 +123,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
timestamp: view.timestamp().into(), timestamp: view.timestamp().into(),
difficulty: view.difficulty().into(), difficulty: view.difficulty().into(),
total_difficulty: total_difficulty.into(), total_difficulty: total_difficulty.into(),
seal_fields: view.seal().into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), seal_fields: view.seal().into_iter().map(|f| rlp::decode(&f)).map(Bytes::new).collect(),
uncles: block_view.uncle_hashes().into_iter().map(Into::into).collect(), uncles: block_view.uncle_hashes().into_iter().map(Into::into).collect(),
transactions: match include_txs { transactions: match include_txs {
true => BlockTransactions::Full(block_view.localized_transactions().into_iter().map(Into::into).collect()), true => BlockTransactions::Full(block_view.localized_transactions().into_iter().map(Into::into).collect()),
@ -147,7 +147,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
fn uncle(&self, id: UncleID) -> Result<Value, Error> { fn uncle(&self, id: UncleID) -> Result<Value, Error> {
let client = take_weak!(self.client); let client = take_weak!(self.client);
let uncle: BlockHeader = match client.uncle(id) { let uncle: BlockHeader = match client.uncle(id) {
Some(rlp) => decode(&rlp), Some(rlp) => rlp::decode(&rlp),
None => { return Ok(Value::Null); } None => { return Ok(Value::Null); }
}; };
let parent_difficulty = match client.block_total_difficulty(BlockID::Hash(uncle.parent_hash().clone())) { let parent_difficulty = match client.block_total_difficulty(BlockID::Hash(uncle.parent_hash().clone())) {
@ -173,7 +173,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
total_difficulty: (uncle.difficulty().clone() + parent_difficulty).into(), total_difficulty: (uncle.difficulty().clone() + parent_difficulty).into(),
receipts_root: uncle.receipts_root().clone().into(), receipts_root: uncle.receipts_root().clone().into(),
extra_data: uncle.extra_data().clone().into(), extra_data: uncle.extra_data().clone().into(),
seal_fields: uncle.seal().clone().into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), seal_fields: uncle.seal().clone().into_iter().map(|f| rlp::decode(&f)).map(Bytes::new).collect(),
uncles: vec![], uncles: vec![],
transactions: BlockTransactions::Hashes(vec![]), transactions: BlockTransactions::Hashes(vec![]),
}; };
@ -566,7 +566,7 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash); trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
let miner = take_weak!(self.miner); let miner = take_weak!(self.miner);
let client = take_weak!(self.client); let client = take_weak!(self.client);
let seal = vec![encode(&mix_hash).to_vec(), encode(&nonce).to_vec()]; let seal = vec![rlp::encode(&mix_hash).to_vec(), rlp::encode(&nonce).to_vec()];
let r = miner.submit_seal(&*client, pow_hash, seal); let r = miner.submit_seal(&*client, pow_hash, seal);
Ok(to_value(&r.is_ok())) Ok(to_value(&r.is_ok()))
}) })

View File

@ -18,7 +18,7 @@
use std::sync::{Weak, Arc}; use std::sync::{Weak, Arc};
use jsonrpc_core::*; use jsonrpc_core::*;
use util::rlp::{UntrustedRlp, View}; use rlp::{UntrustedRlp, View};
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionID, TraceId}; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionID, TraceId};
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action}; use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};

View File

@ -156,7 +156,7 @@ fn eth_get_balance() {
"params": ["0xaaaf5374fce5edbc8e2a8697c15331677e6ebaaa", "latest"], "params": ["0xaaaf5374fce5edbc8e2a8697c15331677e6ebaaa", "latest"],
"id": 1 "id": 1
}"#; }"#;
let res_latest = r#"{"jsonrpc":"2.0","result":"0x09","id":1}"#.to_owned(); let res_latest = r#"{"jsonrpc":"2.0","result":"0x9","id":1}"#.to_owned();
assert_eq!(tester.handler.handle_request_sync(req_latest).unwrap(), res_latest); assert_eq!(tester.handler.handle_request_sync(req_latest).unwrap(), res_latest);
// non-existant account // non-existant account
@ -167,7 +167,7 @@ fn eth_get_balance() {
"id": 3 "id": 3
}"#; }"#;
let res_new_acc = r#"{"jsonrpc":"2.0","result":"0x00","id":3}"#.to_owned(); let res_new_acc = r#"{"jsonrpc":"2.0","result":"0x0","id":3}"#.to_owned();
assert_eq!(tester.handler.handle_request_sync(req_new_acc).unwrap(), res_new_acc); assert_eq!(tester.handler.handle_request_sync(req_new_acc).unwrap(), res_new_acc);
} }
@ -297,7 +297,7 @@ fn eth_transaction_count() {
"id": 15 "id": 15
}"#; }"#;
let res_before = r#"{"jsonrpc":"2.0","result":"0x00","id":15}"#; let res_before = r#"{"jsonrpc":"2.0","result":"0x0","id":15}"#;
assert_eq!(tester.handler.handle_request_sync(&req_before).unwrap(), res_before); assert_eq!(tester.handler.handle_request_sync(&req_before).unwrap(), res_before);
@ -308,7 +308,7 @@ fn eth_transaction_count() {
"from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"", "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"gas": "0x30000", "gas": "0x30000",
"gasPrice": "0x01", "gasPrice": "0x1",
"value": "0x9184e72a" "value": "0x9184e72a"
}], }],
"id": 16 "id": 16
@ -325,7 +325,7 @@ fn eth_transaction_count() {
"id": 17 "id": 17
}"#; }"#;
let res_after_latest = r#"{"jsonrpc":"2.0","result":"0x00","id":17}"#; let res_after_latest = r#"{"jsonrpc":"2.0","result":"0x0","id":17}"#;
assert_eq!(&tester.handler.handle_request_sync(&req_after_latest).unwrap(), res_after_latest); assert_eq!(&tester.handler.handle_request_sync(&req_after_latest).unwrap(), res_after_latest);
@ -337,7 +337,7 @@ fn eth_transaction_count() {
"id": 18 "id": 18
}"#; }"#;
let res_after_pending = r#"{"jsonrpc":"2.0","result":"0x01","id":18}"#; let res_after_pending = r#"{"jsonrpc":"2.0","result":"0x1","id":18}"#;
assert_eq!(&tester.handler.handle_request_sync(&req_after_pending).unwrap(), res_after_pending); assert_eq!(&tester.handler.handle_request_sync(&req_after_pending).unwrap(), res_after_pending);
} }
@ -365,7 +365,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
}"#; }"#;
let res = r#"{"jsonrpc":"2.0","result":""#.to_owned() let res = r#"{"jsonrpc":"2.0","result":""#.to_owned()
+ format!("0x{:02x}", count).as_ref() + format!("0x{:x}", count).as_ref()
+ r#"","id":"# + r#"","id":"#
+ format!("{}", *id).as_ref() + r#"}"#; + format!("{}", *id).as_ref() + r#"}"#;
*id += 1; *id += 1;
@ -383,7 +383,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
}"#; }"#;
let res = r#"{"jsonrpc":"2.0","result":""#.to_owned() let res = r#"{"jsonrpc":"2.0","result":""#.to_owned()
+ format!("0x{:02x}", count).as_ref() + format!("0x{:x}", count).as_ref()
+ r#"","id":"# + r#"","id":"#
+ format!("{}", *id).as_ref() + r#"}"#; + format!("{}", *id).as_ref() + r#"}"#;
*id += 1; *id += 1;
@ -425,7 +425,7 @@ fn starting_nonce_test() {
"#) "#)
).unwrap(); ).unwrap();
assert_eq!(r#"{"jsonrpc":"2.0","result":"0x0100","id":15}"#, &sample); assert_eq!(r#"{"jsonrpc":"2.0","result":"0x100","id":15}"#, &sample);
} }
register_test!(eth_transaction_count_1, verify_transaction_counts, "BlockchainTests/bcWalletTest"); register_test!(eth_transaction_count_1, verify_transaction_counts, "BlockchainTests/bcWalletTest");

View File

@ -122,7 +122,7 @@ fn rpc_eth_syncing() {
} }
} }
let true_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x03e8","highestBlock":"0x09c4","startingBlock":"0x00"},"id":1}"#; let true_res = r#"{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0"},"id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(true_res.to_owned())); assert_eq!(tester.io.handle_request_sync(request), Some(true_res.to_owned()));
{ {
@ -226,7 +226,7 @@ fn rpc_eth_mining() {
#[test] #[test]
fn rpc_eth_gas_price() { fn rpc_eth_gas_price() {
let request = r#"{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x04a817c800","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x4a817c800","id":1}"#;
assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -248,7 +248,7 @@ fn rpc_eth_block_number() {
tester.client.add_blocks(10, EachBlockWith::Nothing); tester.client.add_blocks(10, EachBlockWith::Nothing);
let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0xa","id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -264,7 +264,7 @@ fn rpc_eth_balance() {
"params": ["0x0000000000000000000000000000000000000001", "latest"], "params": ["0x0000000000000000000000000000000000000001", "latest"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x5","id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -284,7 +284,7 @@ fn rpc_eth_balance_pending() {
// the TestMinerService doesn't communicate with the the TestBlockChainClient in any way. // the TestMinerService doesn't communicate with the the TestBlockChainClient in any way.
// if this returns zero, we know that the "pending" call is being properly forwarded to the // if this returns zero, we know that the "pending" call is being properly forwarded to the
// miner. // miner.
let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x0","id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -313,7 +313,7 @@ fn rpc_eth_transaction_count() {
"params": ["0x0000000000000000000000000000000000000001", "latest"], "params": ["0x0000000000000000000000000000000000000001", "latest"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x0","id":1}"#;
assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -339,7 +339,7 @@ fn rpc_eth_transaction_count_by_number() {
"params": ["latest"], "params": ["latest"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x0","id":1}"#;
assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -352,7 +352,7 @@ fn rpc_eth_transaction_count_by_number_pending() {
"params": ["pending"], "params": ["pending"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x01","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x1","id":1}"#;
assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -364,11 +364,11 @@ fn rpc_eth_pending_transaction_by_hash() {
let tester = EthTester::default(); let tester = EthTester::default();
{ {
let tx: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); let tx: SignedTransaction = ::rlp::decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
tester.miner.pending_transactions.lock().insert(H256::zero(), tx); tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
} }
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x01","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x00","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0x0a"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0xa"},"id":1}"#;
let request = r#"{ let request = r#"{
"jsonrpc": "2.0", "jsonrpc": "2.0",
"method": "eth_getTransactionByHash", "method": "eth_getTransactionByHash",
@ -400,7 +400,7 @@ fn rpc_eth_uncle_count_by_block_number() {
"params": ["latest"], "params": ["latest"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x0","id":1}"#;
assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(EthTester::default().io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -705,7 +705,7 @@ fn rpc_eth_send_raw_transaction() {
let signature = tester.accounts_provider.sign(address, t.hash()).unwrap(); let signature = tester.accounts_provider.sign(address, t.hash()).unwrap();
let t = t.with_signature(signature); let t = t.with_signature(signature);
let rlp = ::util::rlp::encode(&t).to_vec().to_hex(); let rlp = ::rlp::encode(&t).to_vec().to_hex();
let req = r#"{ let req = r#"{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@ -758,7 +758,7 @@ fn rpc_eth_transaction_receipt() {
"params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","data":"0x","logIndex":"0x01","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","type":"mined"}],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -835,7 +835,7 @@ fn rpc_get_work_returns_correct_work_package() {
eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()); eth_tester.miner.set_author(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap());
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x01"],"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}"#;
assert_eq!(eth_tester.io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(eth_tester.io.handle_request_sync(request), Some(response.to_owned()));
} }
@ -864,7 +864,7 @@ fn rpc_get_work_should_timeout() {
// Request without providing timeout. This should work since we're disabling timeout. // Request without providing timeout. This should work since we're disabling timeout.
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
let work_response = format!( let work_response = format!(
r#"{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x01"],"id":1}}"#, r#"{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}}"#,
hash, hash,
); );
assert_eq!(eth_tester.io.handle_request_sync(request), Some(work_response.to_owned())); assert_eq!(eth_tester.io.handle_request_sync(request), Some(work_response.to_owned()));
@ -872,7 +872,7 @@ fn rpc_get_work_should_timeout() {
// Request with timeout of 0 seconds. This should work since we're disabling timeout. // Request with timeout of 0 seconds. This should work since we're disabling timeout.
let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["0"], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["0"], "id": 1}"#;
let work_response = format!( let work_response = format!(
r#"{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x01"],"id":1}}"#, r#"{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}}"#,
hash, hash,
); );
assert_eq!(eth_tester.io.handle_request_sync(request), Some(work_response.to_owned())); assert_eq!(eth_tester.io.handle_request_sync(request), Some(work_response.to_owned()));

View File

@ -104,7 +104,7 @@ fn should_post_sign_to_queue() {
], ],
"id": 1 "id": 1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":"0x01","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x1","id":1}"#;
// then // then
assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned()));

View File

@ -126,7 +126,7 @@ fn rpc_ethcore_min_gas_price() {
io.add_delegate(ethcore_client(&client, &miner, &sync, &net).to_delegate()); io.add_delegate(ethcore_client(&client, &miner, &sync, &net).to_delegate());
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#; let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":"0x01312d00","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x1312d00","id":1}"#;
assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
} }

View File

@ -86,8 +86,8 @@ fn should_return_list_of_items_to_confirm() {
let request = r#"{"jsonrpc":"2.0","method":"personal_requestsToConfirm","params":[],"id":1}"#; let request = r#"{"jsonrpc":"2.0","method":"personal_requestsToConfirm","params":[],"id":1}"#;
let response = concat!( let response = concat!(
r#"{"jsonrpc":"2.0","result":["#, r#"{"jsonrpc":"2.0","result":["#,
r#"{"id":"0x01","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x01"}}},"#, r#"{"id":"0x1","payload":{"transaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
r#"{"id":"0x02","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#, r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#,
r#"],"id":1}"# r#"],"id":1}"#
); );
@ -112,7 +112,7 @@ fn should_reject_transaction_from_queue_without_dispatching() {
assert_eq!(tester.queue.requests().len(), 1); assert_eq!(tester.queue.requests().len(), 1);
// when // when
let request = r#"{"jsonrpc":"2.0","method":"personal_rejectRequest","params":["0x01"],"id":1}"#; let request = r#"{"jsonrpc":"2.0","method":"personal_rejectRequest","params":["0x1"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
// then // then
@ -137,7 +137,7 @@ fn should_not_remove_transaction_if_password_is_invalid() {
assert_eq!(tester.queue.requests().len(), 1); assert_eq!(tester.queue.requests().len(), 1);
// when // when
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x01",{},"xxx"],"id":1}"#; let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
// then // then
@ -153,7 +153,7 @@ fn should_not_remove_sign_if_password_is_invalid() {
assert_eq!(tester.queue.requests().len(), 1); assert_eq!(tester.queue.requests().len(), 1);
// when // when
let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x01",{},"xxx"],"id":1}"#; let request = r#"{"jsonrpc":"2.0","method":"personal_confirmRequest","params":["0x1",{},"xxx"],"id":1}"#;
let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#; let response = r#"{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"#;
// then // then
@ -195,7 +195,7 @@ fn should_confirm_transaction_and_dispatch() {
let request = r#"{ let request = r#"{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"method":"personal_confirmRequest", "method":"personal_confirmRequest",
"params":["0x01", {"gasPrice":"0x1000"}, "test"], "params":["0x1", {"gasPrice":"0x1000"}, "test"],
"id":1 "id":1
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;

View File

@ -103,7 +103,7 @@ mod tests {
fn test_serialize_block_transactions() { fn test_serialize_block_transactions() {
let t = BlockTransactions::Full(vec![Transaction::default()]); let t = BlockTransactions::Full(vec![Transaction::default()]);
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x","creates":null,"raw":"0x"}]"#); assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x"}]"#);
let t = BlockTransactions::Hashes(vec![H256::default().into()]); let t = BlockTransactions::Hashes(vec![H256::default().into()]);
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
@ -136,6 +136,6 @@ mod tests {
}; };
let serialized = serde_json::to_string(&block).unwrap(); let serialized = serde_json::to_string(&block).unwrap();
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x00","gasUsed":"0x00","gasLimit":"0x00","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x00","difficulty":"0x00","totalDifficulty":"0x00","sealFields":["0x","0x"],"uncles":[],"transactions":[],"size":"0x45"}"#); assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x0","gasUsed":"0x0","gasLimit":"0x0","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x0","difficulty":"0x0","totalDifficulty":"0x0","sealFields":["0x","0x"],"uncles":[],"transactions":[],"size":"0x45"}"#);
} }
} }

View File

@ -96,7 +96,7 @@ mod tests {
// when // when
let res = serde_json::to_string(&ConfirmationRequest::from(request)); let res = serde_json::to_string(&ConfirmationRequest::from(request));
let expected = r#"{"id":"0x0f","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#; let expected = r#"{"id":"0xf","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#;
// then // then
assert_eq!(res.unwrap(), expected.to_owned()); assert_eq!(res.unwrap(), expected.to_owned());
@ -120,7 +120,7 @@ mod tests {
// when // when
let res = serde_json::to_string(&ConfirmationRequest::from(request)); let res = serde_json::to_string(&ConfirmationRequest::from(request));
let expected = r#"{"id":"0x0f","payload":{"transaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x0186a0","data":"0x010203","nonce":"0x01"}}}"#; let expected = r#"{"id":"0xf","payload":{"transaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
// then // then
assert_eq!(res.unwrap(), expected.to_owned()); assert_eq!(res.unwrap(), expected.to_owned());
@ -130,7 +130,7 @@ mod tests {
fn should_deserialize_modification() { fn should_deserialize_modification() {
// given // given
let s1 = r#"{ let s1 = r#"{
"gasPrice":"0x0ba43b7400" "gasPrice":"0xba43b7400"
}"#; }"#;
let s2 = r#"{}"#; let s2 = r#"{}"#;

View File

@ -86,7 +86,7 @@ mod tests {
#[test] #[test]
fn log_serialization() { fn log_serialization() {
let s = r#"{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","logIndex":"0x01","type":"mined"}"#; let s = r#"{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}"#;
let log = Log { let log = Log {
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(), address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),

View File

@ -98,7 +98,7 @@ mod tests {
#[test] #[test]
fn receipt_serialization() { fn receipt_serialization() {
let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","logIndex":"0x01","type":"mined"}]}"#; let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}]}"#;
let receipt = Receipt { let receipt = Receipt {
transaction_hash: Some(H256::from(0)), transaction_hash: Some(H256::from(0)),

View File

@ -70,7 +70,7 @@ mod tests {
fn test_serialize_sync_info() { fn test_serialize_sync_info() {
let t = SyncInfo::default(); let t = SyncInfo::default();
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"startingBlock":"0x00","currentBlock":"0x00","highestBlock":"0x00"}"#); assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0"}"#);
} }
#[test] #[test]
@ -88,6 +88,6 @@ mod tests {
let t = SyncStatus::Info(SyncInfo::default()); let t = SyncStatus::Info(SyncInfo::default());
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"startingBlock":"0x00","currentBlock":"0x00","highestBlock":"0x00"}"#); assert_eq!(serialized, r#"{"startingBlock":"0x0","currentBlock":"0x0","highestBlock":"0x0"}"#);
} }
} }

View File

@ -549,7 +549,7 @@ mod tests {
block_hash: H256::from(14), block_hash: H256::from(14),
}; };
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"action":{"call":{"from":"0x0000000000000000000000000000000000000004","to":"0x0000000000000000000000000000000000000005","value":"0x06","gas":"0x07","input":"0x1234","callType":"call"}},"result":{"call":{"gasUsed":"0x08","output":"0x5678"}},"traceAddress":["0x0a"],"subtraces":"0x01","transactionPosition":"0x0b","transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":"0x0d","blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#); assert_eq!(serialized, r#"{"action":{"call":{"from":"0x0000000000000000000000000000000000000004","to":"0x0000000000000000000000000000000000000005","value":"0x6","gas":"0x7","input":"0x1234","callType":"call"}},"result":{"call":{"gasUsed":"0x8","output":"0x5678"}},"traceAddress":["0xa"],"subtraces":"0x1","transactionPosition":"0xb","transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":"0xd","blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#);
} }
#[test] #[test]
@ -614,7 +614,7 @@ mod tests {
} }
]); ]);
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"0x000000000000000000000000000000000000002a":{"balance":"=","nonce":{"+":"0x01"},"code":"=","storage":{"0x000000000000000000000000000000000000000000000000000000000000002a":"="}},"0x0000000000000000000000000000000000000045":{"balance":"=","nonce":{"*":{"from":"0x01","to":"0x00"}},"code":{"-":"0x60"},"storage":{}}}"#); assert_eq!(serialized, r#"{"0x000000000000000000000000000000000000002a":{"balance":"=","nonce":{"+":"0x1"},"code":"=","storage":{"0x000000000000000000000000000000000000000000000000000000000000002a":"="}},"0x0000000000000000000000000000000000000045":{"balance":"=","nonce":{"*":{"from":"0x1","to":"0x0"}},"code":{"-":"0x60"},"storage":{}}}"#);
} }
#[test] #[test]
@ -634,7 +634,7 @@ mod tests {
})]; })];
let serialized = serde_json::to_string(&actions).unwrap(); let serialized = serde_json::to_string(&actions).unwrap();
assert_eq!(serialized, r#"[{"call":{"from":"0x0000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000002","value":"0x03","gas":"0x04","input":"0x1234","callType":"call"}},{"create":{"from":"0x0000000000000000000000000000000000000005","value":"0x06","gas":"0x07","init":"0x5678"}}]"#); assert_eq!(serialized, r#"[{"call":{"from":"0x0000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000002","value":"0x3","gas":"0x4","input":"0x1234","callType":"call"}},{"create":{"from":"0x0000000000000000000000000000000000000005","value":"0x6","gas":"0x7","init":"0x5678"}}]"#);
} }
#[test] #[test]
@ -654,6 +654,6 @@ mod tests {
]; ];
let serialized = serde_json::to_string(&results).unwrap(); let serialized = serde_json::to_string(&results).unwrap();
assert_eq!(serialized, r#"[{"call":{"gasUsed":"0x01","output":"0x1234"}},{"create":{"gasUsed":"0x02","code":"0x4556","address":"0x0000000000000000000000000000000000000003"}},"failedCall","failedCreate"]"#); assert_eq!(serialized, r#"[{"call":{"gasUsed":"0x1","output":"0x1234"}},{"create":{"gasUsed":"0x2","code":"0x4556","address":"0x0000000000000000000000000000000000000003"}},"failedCall","failedCreate"]"#);
} }
} }

View File

@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::rlp::encode;
use ethcore::contract_address; use ethcore::contract_address;
use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction}; use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction};
use v1::types::{Bytes, H160, H256, U256}; use v1::types::{Bytes, H160, H256, U256};
@ -75,7 +74,7 @@ impl From<LocalizedTransaction> for Transaction {
Action::Create => Some(contract_address(&t.sender().unwrap(), &t.nonce).into()), Action::Create => Some(contract_address(&t.sender().unwrap(), &t.nonce).into()),
Action::Call(_) => None, Action::Call(_) => None,
}, },
raw: encode(&t.signed).to_vec().into(), raw: ::rlp::encode(&t.signed).to_vec().into(),
} }
} }
} }
@ -101,7 +100,7 @@ impl From<SignedTransaction> for Transaction {
Action::Create => Some(contract_address(&t.sender().unwrap(), &t.nonce).into()), Action::Create => Some(contract_address(&t.sender().unwrap(), &t.nonce).into()),
Action::Call(_) => None, Action::Call(_) => None,
}, },
raw: encode(&t).to_vec().into(), raw: ::rlp::encode(&t).to_vec().into(),
} }
} }
} }
@ -115,7 +114,7 @@ mod tests {
fn test_transaction_serialize() { fn test_transaction_serialize() {
let t = Transaction::default(); let t = Transaction::default();
let serialized = serde_json::to_string(&t).unwrap(); let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x","creates":null,"raw":"0x"}"#); assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x"}"#);
} }
} }

View File

@ -52,7 +52,13 @@ macro_rules! impl_uint {
let mut bytes = [0u8; 8 * $size]; let mut bytes = [0u8; 8 * $size];
self.0.to_big_endian(&mut bytes); self.0.to_big_endian(&mut bytes);
let len = cmp::max((self.0.bits() + 7) / 8, 1); let len = cmp::max((self.0.bits() + 7) / 8, 1);
hex.push_str(&bytes[bytes.len() - len..].to_hex()); let bytes_hex = bytes[bytes.len() - len..].to_hex();
if bytes_hex.starts_with('0') {
hex.push_str(&bytes_hex[1..]);
} else {
hex.push_str(&bytes_hex);
}
serializer.serialize_str(&hex) serializer.serialize_str(&hex)
} }
} }
@ -87,3 +93,38 @@ macro_rules! impl_uint {
} }
impl_uint!(U256, EthU256, 4); impl_uint!(U256, EthU256, 4);
#[cfg(test)]
mod tests {
use super::U256;
use serde_json;
#[test]
fn should_serialize_u256() {
let serialized1 = serde_json::to_string(&U256(0.into())).unwrap();
let serialized2 = serde_json::to_string(&U256(1.into())).unwrap();
let serialized3 = serde_json::to_string(&U256(16.into())).unwrap();
let serialized4 = serde_json::to_string(&U256(256.into())).unwrap();
assert_eq!(serialized1, r#""0x0""#);
assert_eq!(serialized2, r#""0x1""#);
assert_eq!(serialized3, r#""0x10""#);
assert_eq!(serialized4, r#""0x100""#);
}
#[test]
fn should_deserialize_u256() {
let deserialized1: U256 = serde_json::from_str(r#""0x""#).unwrap();
let deserialized2: U256 = serde_json::from_str(r#""0x0""#).unwrap();
let deserialized3: U256 = serde_json::from_str(r#""0x1""#).unwrap();
let deserialized4: U256 = serde_json::from_str(r#""0x01""#).unwrap();
let deserialized5: U256 = serde_json::from_str(r#""0x100""#).unwrap();
assert_eq!(deserialized1, U256(0.into()));
assert_eq!(deserialized2, U256(0.into()));
assert_eq!(deserialized3, U256(1.into()));
assert_eq!(deserialized4, U256(1.into()));
assert_eq!(deserialized5, U256(256.into()));
}
}

View File

@ -2,6 +2,7 @@
export TARGETS=" export TARGETS="
-p bigint\ -p bigint\
-p rlp\
-p ethash \ -p ethash \
-p ethcore \ -p ethcore \
-p ethcore-dapps \ -p ethcore-dapps \

View File

@ -16,6 +16,7 @@ ethcore-util = { path = "../util" }
ethcore-network = { path = "../util/network" } ethcore-network = { path = "../util/network" }
ethcore-io = { path = "../util/io" } ethcore-io = { path = "../util/io" }
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
rlp = { path = "../util/rlp" }
clippy = { version = "0.0.85", optional = true} clippy = { version = "0.0.85", optional = true}
log = "0.3" log = "0.3"
env_logger = "0.3" env_logger = "0.3"

View File

@ -17,7 +17,7 @@
use std::sync::Arc; use std::sync::Arc;
use network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId, use network::{NetworkProtocolHandler, NetworkService, NetworkContext, PeerId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError}; NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, NetworkError};
use util::{U256, H256, Populatable}; use util::{U256, H256};
use io::{TimerToken}; use io::{TimerToken};
use ethcore::client::{BlockChainClient, ChainNotify}; use ethcore::client::{BlockChainClient, ChainNotify};
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
@ -32,7 +32,7 @@ use parking_lot::RwLock;
pub const ETH_PROTOCOL: &'static str = "eth"; pub const ETH_PROTOCOL: &'static str = "eth";
/// Sync configuration /// Sync configuration
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub struct SyncConfig { pub struct SyncConfig {
/// Max blocks to download ahead /// Max blocks to download ahead
pub max_download_ahead_blocks: usize, pub max_download_ahead_blocks: usize,
@ -119,6 +119,7 @@ impl NetworkProtocolHandler for SyncProtocolHandler {
fn timeout(&self, io: &NetworkContext, _timer: TimerToken) { fn timeout(&self, io: &NetworkContext, _timer: TimerToken) {
self.sync.write().maintain_peers(&mut NetSyncIo::new(io, &*self.chain)); self.sync.write().maintain_peers(&mut NetSyncIo::new(io, &*self.chain));
self.sync.write().maintain_sync(&mut NetSyncIo::new(io, &*self.chain)); self.sync.write().maintain_sync(&mut NetSyncIo::new(io, &*self.chain));
self.sync.write().propagate_new_transactions(&mut NetSyncIo::new(io, &*self.chain));
} }
} }

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use util::*; use util::*;
use rlp::*;
use network::NetworkError; use network::NetworkError;
use ethcore::header::{ Header as BlockHeader}; use ethcore::header::{ Header as BlockHeader};
@ -283,11 +284,11 @@ impl BlockCollection {
transactions_root: info.transactions_root().clone(), transactions_root: info.transactions_root().clone(),
uncles: info.uncles_hash().clone(), uncles: info.uncles_hash().clone(),
}; };
if header_id.transactions_root == rlp::SHA3_NULL_RLP && header_id.uncles == rlp::SHA3_EMPTY_LIST_RLP { if header_id.transactions_root == sha3::SHA3_NULL_RLP && header_id.uncles == sha3::SHA3_EMPTY_LIST_RLP {
// empty body, just mark as downloaded // empty body, just mark as downloaded
let mut body_stream = RlpStream::new_list(2); let mut body_stream = RlpStream::new_list(2);
body_stream.append_raw(&rlp::EMPTY_LIST_RLP, 1); body_stream.append_raw(&::rlp::EMPTY_LIST_RLP, 1);
body_stream.append_raw(&rlp::EMPTY_LIST_RLP, 1); body_stream.append_raw(&::rlp::EMPTY_LIST_RLP, 1);
block.body = Some(body_stream.out()); block.body = Some(body_stream.out());
} }
else { else {
@ -337,6 +338,7 @@ mod test {
use ethcore::views::HeaderView; use ethcore::views::HeaderView;
use ethcore::header::BlockNumber; use ethcore::header::BlockNumber;
use util::*; use util::*;
use rlp::*;
fn is_empty(bc: &BlockCollection) -> bool { fn is_empty(bc: &BlockCollection) -> bool {
bc.heads.is_empty() && bc.heads.is_empty() &&

View File

@ -88,6 +88,7 @@
/// ///
use util::*; use util::*;
use rlp::*;
use network::*; use network::*;
use std::mem::{replace}; use std::mem::{replace};
use ethcore::views::{HeaderView, BlockView}; use ethcore::views::{HeaderView, BlockView};
@ -156,7 +157,7 @@ pub enum SyncState {
} }
/// Syncing status and statistics /// Syncing status and statistics
#[derive(Clone)] #[derive(Clone, Copy)]
pub struct SyncStatus { pub struct SyncStatus {
/// State /// State
pub state: SyncState, pub state: SyncState,
@ -241,7 +242,9 @@ struct PeerInfo {
asking_hash: Option<H256>, asking_hash: Option<H256>,
/// Request timestamp /// Request timestamp
ask_time: f64, ask_time: f64,
/// Pending request is expird and result should be ignored /// Holds a set of transactions recently sent to this peer to avoid spamming.
last_sent_transactions: HashSet<H256>,
/// Pending request is expired and result should be ignored
expired: bool, expired: bool,
/// Peer fork confirmation status /// Peer fork confirmation status
confirmation: ForkConfirmation, confirmation: ForkConfirmation,
@ -406,6 +409,7 @@ impl ChainSync {
asking_blocks: Vec::new(), asking_blocks: Vec::new(),
asking_hash: None, asking_hash: None,
ask_time: 0f64, ask_time: 0f64,
last_sent_transactions: HashSet::new(),
expired: false, expired: false,
confirmation: if self.fork_block.is_none() { ForkConfirmation::Confirmed } else { ForkConfirmation::Unconfirmed }, confirmation: if self.fork_block.is_none() { ForkConfirmation::Confirmed } else { ForkConfirmation::Unconfirmed },
}; };
@ -1447,42 +1451,67 @@ impl ChainSync {
} }
/// propagates new transactions to all peers /// propagates new transactions to all peers
fn propagate_new_transactions(&mut self, io: &mut SyncIo) -> usize { pub fn propagate_new_transactions(&mut self, io: &mut SyncIo) -> usize {
// Early out of nobody to send to. // Early out of nobody to send to.
if self.peers.is_empty() { if self.peers.is_empty() {
return 0; return 0;
} }
let mut transactions = io.chain().pending_transactions(); let transactions = io.chain().pending_transactions();
if transactions.is_empty() { if transactions.is_empty() {
return 0; return 0;
} }
let mut packet = RlpStream::new_list(transactions.len()); let all_transactions_hashes = transactions.iter().map(|ref tx| tx.hash()).collect::<HashSet<H256>>();
let tx_count = transactions.len(); let all_transactions_rlp = {
for tx in transactions.drain(..) { let mut packet = RlpStream::new_list(transactions.len());
packet.append(&tx); for tx in &transactions { packet.append(tx); }
} packet.out()
let rlp = packet.out();
let lucky_peers = {
// sqrt(x)/x scaled to max u32
let fraction = (self.peers.len() as f64).powf(-0.5).mul(u32::max_value() as f64).round() as u32;
let small = self.peers.len() < MIN_PEERS_PROPAGATION;
let lucky_peers = self.peers.iter()
.filter_map(|(&p, _)| if small || ::rand::random::<u32>() < fraction { Some(p.clone()) } else { None })
.collect::<Vec<_>>();
// taking at max of MAX_PEERS_PROPAGATION
lucky_peers.iter().cloned().take(min(lucky_peers.len(), MAX_PEERS_PROPAGATION)).collect::<Vec<PeerId>>()
}; };
// sqrt(x)/x scaled to max u32
let fraction = (self.peers.len() as f64).powf(-0.5).mul(u32::max_value() as f64).round() as u32;
let small = self.peers.len() < MIN_PEERS_PROPAGATION;
let lucky_peers = self.peers.iter_mut()
.filter(|_| small || ::rand::random::<u32>() < fraction)
.take(MAX_PEERS_PROPAGATION)
.filter_map(|(peer_id, mut peer_info)| {
// Send all transactions
if peer_info.last_sent_transactions.is_empty() {
peer_info.last_sent_transactions = all_transactions_hashes.clone();
return Some((*peer_id, all_transactions_rlp.clone()));
}
// Get hashes of all transactions to send to this peer
let to_send = all_transactions_hashes.difference(&peer_info.last_sent_transactions).cloned().collect::<HashSet<_>>();
if to_send.is_empty() {
return None;
}
// Construct RLP
let mut packet = RlpStream::new_list(to_send.len());
for tx in &transactions {
if to_send.contains(&tx.hash()) {
packet.append(tx);
}
}
peer_info.last_sent_transactions = all_transactions_hashes.clone();
Some((*peer_id, packet.out()))
})
.collect::<Vec<_>>();
// Send RLPs
let sent = lucky_peers.len(); let sent = lucky_peers.len();
for peer_id in lucky_peers { if sent > 0 {
self.send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp.clone()); for (peer_id, rlp) in lucky_peers.into_iter() {
self.send_packet(io, peer_id, TRANSACTIONS_PACKET, rlp);
}
trace!(target: "sync", "Sent up to {} transactions to {} peers.", transactions.len(), sent);
} }
trace!(target: "sync", "Sent {} transactions to {} peers.", tx_count, sent);
sent sent
} }
@ -1512,16 +1541,18 @@ impl ChainSync {
self.check_resume(io); self.check_resume(io);
} }
/// called when block is imported to chain, updates transactions queue and propagates the blocks /// called when block is imported to chain - propagates the blocks and updates transactions sent to peers
pub fn chain_new_blocks(&mut self, io: &mut SyncIo, _imported: &[H256], invalid: &[H256], _enacted: &[H256], _retracted: &[H256], sealed: &[H256]) { pub fn chain_new_blocks(&mut self, io: &mut SyncIo, _imported: &[H256], invalid: &[H256], _enacted: &[H256], _retracted: &[H256], sealed: &[H256]) {
if io.is_chain_queue_empty() { if io.is_chain_queue_empty() {
// Propagate latests blocks
self.propagate_latest_blocks(io, sealed); self.propagate_latest_blocks(io, sealed);
} }
if !invalid.is_empty() { if !invalid.is_empty() {
trace!(target: "sync", "Bad blocks in the queue, restarting"); trace!(target: "sync", "Bad blocks in the queue, restarting");
self.restart_on_bad_block(io); self.restart_on_bad_block(io);
} }
for peer_info in self.peers.values_mut() {
peer_info.last_sent_transactions.clear();
}
} }
} }
@ -1531,6 +1562,7 @@ mod tests {
use super::*; use super::*;
use ::SyncConfig; use ::SyncConfig;
use util::*; use util::*;
use rlp::*;
use super::{PeerInfo, PeerAsking}; use super::{PeerInfo, PeerAsking};
use ethcore::views::BlockView; use ethcore::views::BlockView;
use ethcore::header::*; use ethcore::header::*;
@ -1548,8 +1580,8 @@ mod tests {
let mut rlp = RlpStream::new_list(3); let mut rlp = RlpStream::new_list(3);
rlp.append(&header); rlp.append(&header);
rlp.append_raw(&rlp::EMPTY_LIST_RLP, 1); rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1);
rlp.append_raw(&rlp::EMPTY_LIST_RLP, 1); rlp.append_raw(&::rlp::EMPTY_LIST_RLP, 1);
rlp.out() rlp.out()
} }
@ -1723,6 +1755,7 @@ mod tests {
asking_blocks: Vec::new(), asking_blocks: Vec::new(),
asking_hash: None, asking_hash: None,
ask_time: 0f64, ask_time: 0f64,
last_sent_transactions: HashSet::new(),
expired: false, expired: false,
confirmation: super::ForkConfirmation::Confirmed, confirmation: super::ForkConfirmation::Confirmed,
}); });
@ -1819,6 +1852,83 @@ mod tests {
assert_eq!(0x07, io.queue[0].packet_id); assert_eq!(0x07, io.queue[0].packet_id);
} }
#[test]
fn propagates_transactions() {
let mut client = TestBlockChainClient::new();
client.add_blocks(100, EachBlockWith::Uncle);
client.insert_transaction_to_queue();
let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client);
let mut queue = VecDeque::new();
let mut io = TestIo::new(&mut client, &mut queue, None);
let peer_count = sync.propagate_new_transactions(&mut io);
// Try to propagate same transactions for the second time
let peer_count2 = sync.propagate_new_transactions(&mut io);
// 1 message should be send
assert_eq!(1, io.queue.len());
// 1 peer should be updated but only once
assert_eq!(1, peer_count);
assert_eq!(0, peer_count2);
// TRANSACTIONS_PACKET
assert_eq!(0x02, io.queue[0].packet_id);
}
#[test]
fn propagates_transactions_again_after_new_block() {
let mut client = TestBlockChainClient::new();
client.add_blocks(100, EachBlockWith::Uncle);
client.insert_transaction_to_queue();
let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client);
let mut queue = VecDeque::new();
let mut io = TestIo::new(&mut client, &mut queue, None);
let peer_count = sync.propagate_new_transactions(&mut io);
sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[]);
// Try to propagate same transactions for the second time
let peer_count2 = sync.propagate_new_transactions(&mut io);
// 2 message should be send
assert_eq!(2, io.queue.len());
// 1 peer should be updated twice
assert_eq!(1, peer_count);
assert_eq!(1, peer_count2);
// TRANSACTIONS_PACKET
assert_eq!(0x02, io.queue[0].packet_id);
assert_eq!(0x02, io.queue[1].packet_id);
}
#[test]
fn propagates_transactions_without_alternating() {
let mut client = TestBlockChainClient::new();
client.add_blocks(100, EachBlockWith::Uncle);
client.insert_transaction_to_queue();
let mut sync = dummy_sync_with_peer(client.block_hash_delta_minus(1), &client);
let mut queue = VecDeque::new();
// should sent some
{
let mut io = TestIo::new(&mut client, &mut queue, None);
let peer_count = sync.propagate_new_transactions(&mut io);
assert_eq!(1, io.queue.len());
assert_eq!(1, peer_count);
}
// Insert some more
client.insert_transaction_to_queue();
let mut io = TestIo::new(&mut client, &mut queue, None);
// Propagate new transactions
let peer_count2 = sync.propagate_new_transactions(&mut io);
// And now the peer should have all transactions
let peer_count3 = sync.propagate_new_transactions(&mut io);
// 2 message should be send (in total)
assert_eq!(2, io.queue.len());
// 1 peer should be updated but only once after inserting new transaction
assert_eq!(1, peer_count2);
assert_eq!(0, peer_count3);
// TRANSACTIONS_PACKET
assert_eq!(0x02, io.queue[0].packet_id);
assert_eq!(0x02, io.queue[1].packet_id);
}
#[test] #[test]
fn handles_peer_new_block_malformed() { fn handles_peer_new_block_malformed() {
let mut client = TestBlockChainClient::new(); let mut client = TestBlockChainClient::new();

View File

@ -34,7 +34,6 @@
//! extern crate ethcore; //! extern crate ethcore;
//! extern crate ethsync; //! extern crate ethsync;
//! use std::env; //! use std::env;
//! use std::sync::Arc;
//! use io::IoChannel; //! use io::IoChannel;
//! use ethcore::client::{Client, ClientConfig}; //! use ethcore::client::{Client, ClientConfig};
//! use ethsync::{EthSync, SyncConfig, ManageNetwork, NetworkConfiguration}; //! use ethsync::{EthSync, SyncConfig, ManageNetwork, NetworkConfiguration};
@ -62,22 +61,24 @@
//! } //! }
//! ``` //! ```
#[macro_use]
extern crate log;
#[macro_use]
extern crate ethcore_util as util;
extern crate ethcore_network as network; extern crate ethcore_network as network;
extern crate ethcore_io as io; extern crate ethcore_io as io;
extern crate ethcore; extern crate ethcore;
extern crate env_logger; extern crate env_logger;
extern crate time; extern crate time;
extern crate rand; extern crate rand;
extern crate semver;
extern crate parking_lot;
extern crate rlp;
#[macro_use]
extern crate log;
#[macro_use]
extern crate ethcore_util as util;
#[macro_use] #[macro_use]
extern crate heapsize; extern crate heapsize;
#[macro_use] #[macro_use]
extern crate ethcore_ipc as ipc; extern crate ethcore_ipc as ipc;
extern crate semver;
extern crate parking_lot;
mod chain; mod chain;
mod blocks; mod blocks;

View File

@ -18,7 +18,8 @@ rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
lazy_static = "0.2" lazy_static = "0.2"
eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" } eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" }
rust-crypto = "0.2.34" rust-crypto = "0.2.34"
elastic-array = { git = "https://github.com/ethcore/elastic-array" } elastic-array = "0.5"
rlp = { path = "rlp" }
heapsize = { version = "0.3", features = ["unstable"] } heapsize = { version = "0.3", features = ["unstable"] }
itertools = "0.4" itertools = "0.4"
sha3 = { path = "sha3" } sha3 = { path = "sha3" }

View File

@ -0,0 +1,18 @@
[package]
description = "HTTPS fetching library"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "https-fetch"
version = "0.1.0"
authors = ["Ethcore <admin@ethcore.io>"]
[dependencies]
log = "0.3"
mio = { git = "https://github.com/ethcore/mio", branch = "v0.5.x" }
rustls = { git = "https://github.com/ctz/rustls" }
clippy = { version = "0.0.85", optional = true}
[features]
default = []
ca-github-only = []
dev = ["clippy"]

View File

@ -0,0 +1,15 @@
extern crate https_fetch;
use std::io;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use https_fetch::*;
fn main() {
let client = Client::new().unwrap();
let aborted = Arc::new(AtomicBool::new(false));
client.fetch(Url::new("github.com", 443, "/").unwrap(), Box::new(io::stdout()), aborted, |result| {
assert!(result.is_ok());
}).unwrap();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW
YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY
uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/
LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy
/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh
cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k
8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB
Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy
dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2
MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j
b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW
gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh
hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg
4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa
2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs
1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1
oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn
8TUoE6smftX3eg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIHeTCCBmGgAwIBAgIQC/20CQrXteZAwwsWyVKaJzANBgkqhkiG9w0BAQsFADB1
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MDMxMDAwMDAwMFoXDTE4MDUxNzEy
MDAwMFowgf0xHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF
Ewc1MTU3NTUwMSQwIgYDVQQJExs4OCBDb2xpbiBQIEtlbGx5LCBKciBTdHJlZXQx
DjAMBgNVBBETBTk0MTA3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
YTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEChMMR2l0SHViLCBJbmMu
MRMwEQYDVQQDEwpnaXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA54hc8pZclxgcupjiA/F/OZGRwm/ZlucoQGTNTKmBEgNsrn/mxhngWmPw
bAvUaLP//T79Jc+1WXMpxMiz9PK6yZRRFuIo0d2bx423NA6hOL2RTtbnfs+y0PFS
/YTpQSelTuq+Fuwts5v6aAweNyMcYD0HBybkkdosFoDccBNzJ92Ac8I5EVDUc3Or
/4jSyZwzxu9kdmBlBzeHMvsqdH8SX9mNahXtXxRpwZnBiUjw36PgN+s9GLWGrafd
02T0ux9Yzd5ezkMxukqEAQ7AKIIijvaWPAJbK/52XLhIy2vpGNylyni/DQD18bBP
T+ZG1uv0QQP9LuY/joO+FKDOTler4wIDAQABo4IDejCCA3YwHwYDVR0jBBgwFoAU
PdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFIhcSGcZzKB2WS0RecO+oqyH
IidbMCUGA1UdEQQeMByCCmdpdGh1Yi5jb22CDnd3dy5naXRodWIuY29tMA4GA1Ud
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0f
BG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy
dmVyLWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt
ZXYtc2VydmVyLWcxLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsG
AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGI
BggrBgEFBQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0
LmNvbTBSBggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp
Z2lDZXJ0U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMB
Af8EAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgCkuQmQtBhYFIe7E6LM
Z3AKPDWYBPkb37jjd80OyA3cEAAAAVNhieoeAAAEAwBHMEUCIQCHHSEY/ROK2/sO
ljbKaNEcKWz6BxHJNPOtjSyuVnSn4QIgJ6RqvYbSX1vKLeX7vpnOfCAfS2Y8lB5R
NMwk6us2QiAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVNh
iennAAAEAwBHMEUCIQDZpd5S+3to8k7lcDeWBhiJASiYTk2rNAT26lVaM3xhWwIg
NUqrkIODZpRg+khhp8ag65B8mu0p4JUAmkRDbiYnRvYAdwBWFAaaL9fC7NP14b1E
sj7HRna5vJkRXMDvlJhV1onQ3QAAAVNhieqZAAAEAwBIMEYCIQDnm3WStlvE99GC
izSx+UGtGmQk2WTokoPgo1hfiv8zIAIhAPrYeXrBgseA9jUWWoB4IvmcZtshjXso
nT8MIG1u1zF8MA0GCSqGSIb3DQEBCwUAA4IBAQCLbNtkxuspqycq8h1EpbmAX0wM
5DoW7hM/FVdz4LJ3Kmftyk1yd8j/PSxRrAQN2Mr/frKeK8NE1cMji32mJbBqpWtK
/+wC+avPplBUbNpzP53cuTMF/QssxItPGNP5/OT9Aj1BxA/NofWZKh4ufV7cz3pY
RDS4BF+EEFQ4l5GY+yp4WJA/xSvYsTHWeWxRD1/nl62/Rd9FN2NkacRVozCxRVle
FrBHTFxqIP6kDnxiLElBrZngtY07ietaYZVLQN/ETyqLQftsf8TecwTklbjvm8NT
JqbaIVifYwqwNN+4lRxS3F5lNlA/il12IOgbRioLI62o8G0DaEUQgHNf8vSG
-----END CERTIFICATE-----

View File

@ -0,0 +1,210 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::cell::RefCell;
use std::{fs, str, thread};
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::path::PathBuf;
use std::io::{self, Write};
use std::collections::HashMap;
use mio;
use tlsclient::{TlsClient, TlsClientError};
use url::Url;
#[derive(Debug)]
pub enum FetchError {
InvalidAddress,
ReadingCaCertificates,
CaCertificates(io::Error),
Io(io::Error),
Notify(mio::NotifyError<ClientMessage>),
Client(TlsClientError),
}
impl From<io::Error> for FetchError {
fn from(e: io::Error) -> Self {
FetchError::Io(e)
}
}
impl From<mio::NotifyError<ClientMessage>> for FetchError {
fn from(e: mio::NotifyError<ClientMessage>) -> Self {
FetchError::Notify(e)
}
}
impl From<TlsClientError> for FetchError {
fn from(e: TlsClientError) -> Self {
FetchError::Client(e)
}
}
pub type FetchResult = Result<(), FetchError>;
pub enum ClientMessage {
Fetch(Url, Box<io::Write + Send>, Arc<AtomicBool>, Box<FnMut(FetchResult) + Send>),
Shutdown,
}
pub struct Client {
channel: mio::Sender<ClientMessage>,
thread: Option<thread::JoinHandle<()>>,
}
impl Drop for Client {
fn drop(&mut self) {
self.close_internal();
if let Some(thread) = self.thread.take() {
thread.join().expect("Clean shutdown.");
}
}
}
impl Client {
pub fn new() -> Result<Self, FetchError> {
let mut event_loop = try!(mio::EventLoop::new());
let channel = event_loop.channel();
let thread = thread::spawn(move || {
let mut client = ClientLoop {
next_token: 0,
sessions: HashMap::new(),
};
event_loop.run(&mut client).unwrap();
});
Ok(Client {
channel: channel,
thread: Some(thread),
})
}
pub fn fetch_to_file<F: FnOnce(FetchResult) + Send + 'static>(&self, url: Url, path: PathBuf, abort: Arc<AtomicBool>, callback: F) -> Result<(), FetchError> {
let file = try!(fs::File::create(&path));
self.fetch(url, Box::new(file), abort, move |result| {
if let Err(_) = result {
// remove temporary file
let _ = fs::remove_file(&path);
}
callback(result);
})
}
pub fn fetch<F: FnOnce(FetchResult) + Send + 'static>(&self, url: Url, writer: Box<io::Write + Send>, abort: Arc<AtomicBool>, callback: F) -> Result<(), FetchError> {
let cell = RefCell::new(Some(callback));
try!(self.channel.send(ClientMessage::Fetch(url, writer, abort, Box::new(move |res| {
cell.borrow_mut().take().expect("Called only once.")(res);
}))));
Ok(())
}
pub fn close(mut self) {
self.close_internal()
}
fn close_internal(&mut self) {
if let Err(e) = self.channel.send(ClientMessage::Shutdown) {
warn!("Error while closing client: {:?}. Already stopped?", e);
}
}
}
pub struct ClientLoop {
next_token: usize,
sessions: HashMap<usize, TlsClient>,
}
impl mio::Handler for ClientLoop {
type Timeout = ();
type Message = ClientMessage;
fn ready(&mut self, event_loop: &mut mio::EventLoop<ClientLoop>, token: mio::Token, events: mio::EventSet) {
let utoken = token.as_usize();
let remove = if let Some(mut tlsclient) = self.sessions.get_mut(&utoken) {
tlsclient.ready(event_loop, token, events)
} else {
false
};
if remove {
self.sessions.remove(&utoken);
}
}
fn notify(&mut self, event_loop: &mut mio::EventLoop<Self>, msg: Self::Message) {
match msg {
ClientMessage::Shutdown => event_loop.shutdown(),
ClientMessage::Fetch(url, writer, abort, callback) => {
let token = self.next_token;
self.next_token += 1;
if let Ok(mut tlsclient) = TlsClient::new(mio::Token(token), &url, writer, abort, callback) {
let httpreq = format!(
"GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nAccept-Encoding: identity\r\n\r\n",
url.path(),
url.hostname()
);
let _ = tlsclient.write(httpreq.as_bytes());
tlsclient.register(event_loop);
self.sessions.insert(token, tlsclient);
}
}
}
}
}
#[test]
fn should_successfuly_fetch_a_page() {
use std::io::{self, Cursor};
use std::sync::{mpsc, Arc};
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
struct Writer {
wrote: Arc<AtomicUsize>,
data: Cursor<Vec<u8>>,
}
impl io::Write for Writer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let res = self.data.write(buf);
if let Ok(count) = res {
self.wrote.fetch_add(count, Ordering::Relaxed);
}
res
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
let client = Client::new().unwrap();
let wrote = Arc::new(AtomicUsize::new(0));
let writer = Writer {
wrote: wrote.clone(),
data: Cursor::new(Vec::new()),
};
let (tx, rx) = mpsc::channel();
client.fetch(Url::new("github.com", 443, "/").unwrap(), Box::new(writer), Arc::new(AtomicBool::new(false)), move |result| {
assert!(result.is_ok());
assert!(wrote.load(Ordering::Relaxed) > 0);
tx.send(result).unwrap();
}).unwrap();
let _ = rx.recv().unwrap();
}

Some files were not shown because too many files have changed in this diff Show More