Merge remote-tracking branch 'origin/master' into dapps-accounts-rpc

This commit is contained in:
Gav Wood 2016-12-15 13:28:37 +01:00
commit db73b0d66f
No known key found for this signature in database
GPG Key ID: C49C1ACA1CC9B252
1571 changed files with 11446 additions and 5308 deletions

View File

@ -231,10 +231,10 @@ linux-armv6:
stage: build stage: build
image: ethcore/rust-armv6:latest image: ethcore/rust-armv6:latest
only: only:
# - beta - beta
# - tags # - tags
# - stable # - stable
- triggers # - triggers
script: script:
- export CC=arm-linux-gnueabi-gcc - export CC=arm-linux-gnueabi-gcc
- export CXX=arm-linux-gnueabi-g++ - export CXX=arm-linux-gnueabi-g++
@ -312,8 +312,8 @@ darwin:
- stable - stable
- triggers - triggers
script: script:
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
- cargo build -j 8 --release #$CARGOFLAGS - cargo build -j 8 --release #$CARGOFLAGS
- cargo build -j 8 --release -p ethstore #$CARGOFLAGS
- rm -rf parity.md5 - rm -rf parity.md5
- md5sum target/release/parity > parity.md5 - md5sum target/release/parity > parity.md5
- packagesbuild -v mac/Parity.pkgproj - packagesbuild -v mac/Parity.pkgproj
@ -350,7 +350,7 @@ windows:
- set RUST_BACKTRACE=1 - set RUST_BACKTRACE=1
- set RUSTFLAGS=%RUSTFLAGS% - set RUSTFLAGS=%RUSTFLAGS%
- rustup default stable-x86_64-pc-windows-msvc - rustup default stable-x86_64-pc-windows-msvc
- cargo build -j 8 --release #%CARGOFLAGS% - cargo build --release #%CARGOFLAGS%
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll - curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe - curl -sL --url "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -o nsis\vc_redist.x64.exe
- signtool sign /f %keyfile% /p %certpass% target\release\parity.exe - signtool sign /f %keyfile% /p %certpass% target\release\parity.exe
@ -408,7 +408,7 @@ test-darwin:
test-windows: test-windows:
stage: test stage: test
only: only:
- triggers # - triggers
before_script: before_script:
- git submodule update --init --recursive - git submodule update --init --recursive
script: script:
@ -422,14 +422,10 @@ test-rust-stable:
image: ethcore/rust:stable image: ethcore/rust:stable
before_script: before_script:
- git submodule update --init --recursive - git submodule update --init --recursive
- export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v ^js/ | wc -l) - export RUST_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep -v -e ^js -e ^\\. -e ^LICENSE -e ^README.md -e ^appveyor.yml -e ^test.sh -e ^windows/ -e ^scripts/ -e^mac/ -e ^nsis/ | wc -l)
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
- echo "rust/js modified: $RUST_FILES_MODIFIED / $JS_FILES_MODIFIED"
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
script: script:
- export RUST_BACKTRACE=1 - export RUST_BACKTRACE=1
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi - if [ $RUST_FILES_MODIFIED -eq 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
- if [ "$RUST_FILES_MODIFIED" = 0 ]; then echo "Skipping Rust tests since no Rust files modified."; else ./test.sh $CARGOFLAGS; fi
tags: tags:
- rust - rust
- rust-stable - rust-stable
@ -439,12 +435,9 @@ js-test:
before_script: before_script:
- git submodule update --init --recursive - git submodule update --init --recursive
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
- echo $JS_FILES_MODIFIED - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
script: script:
- export RUST_BACKTRACE=1 - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi
- echo $JS_FILES_MODIFIED
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS lint since no JS files modified."; else ./js/scripts/lint.sh && ./js/scripts/test.sh && ./js/scripts/build.sh; fi
tags: tags:
- rust - rust
- rust-stable - rust-stable
@ -487,9 +480,9 @@ js-release:
before_script: before_script:
- export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l) - export JS_FILES_MODIFIED=$(git --no-pager diff --name-only $CI_BUILD_REF^ $CI_BUILD_REF | grep ^js/ | wc -l)
- echo $JS_FILES_MODIFIED - echo $JS_FILES_MODIFIED
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS deps install since no JS files modified."; else ./js/scripts/install-deps.sh;fi
script: script:
- echo $JS_FILES_MODIFIED - echo $JS_FILES_MODIFIED
- if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi - if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi
tags: tags:
- javascript - javascript

35
Cargo.lock generated
View File

@ -530,6 +530,7 @@ dependencies = [
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
"jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)",
"jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)",
"jsonrpc-macros 0.1.0 (git+https://github.com/ethcore/jsonrpc.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", "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)",
@ -860,10 +861,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "jsonrpc-core" name = "jsonrpc-core"
version = "4.0.0" version = "4.0.0"
source = "git+https://github.com/ethcore/jsonrpc.git#1500da1b9613a0a17fc0109d825f3ccc60199a53" source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
dependencies = [ 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.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.5 (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)",
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -872,7 +873,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-http-server" name = "jsonrpc-http-server"
version = "6.1.1" version = "6.1.1"
source = "git+https://github.com/ethcore/jsonrpc.git#1500da1b9613a0a17fc0109d825f3ccc60199a53" source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
dependencies = [ dependencies = [
"hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)", "hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)",
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
@ -883,7 +884,7 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc-ipc-server" name = "jsonrpc-ipc-server"
version = "0.2.4" version = "0.2.4"
source = "git+https://github.com/ethcore/jsonrpc.git#1500da1b9613a0a17fc0109d825f3ccc60199a53" source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
dependencies = [ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.3.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)",
@ -895,10 +896,19 @@ dependencies = [
"slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "jsonrpc-macros"
version = "0.1.0"
source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
dependencies = [
"jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "jsonrpc-tcp-server" name = "jsonrpc-tcp-server"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/ethcore/jsonrpc.git#1500da1b9613a0a17fc0109d825f3ccc60199a53" source = "git+https://github.com/ethcore/jsonrpc.git#33262d626a294a00c20435dec331058ba65e224a"
dependencies = [ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.3.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)",
@ -1290,22 +1300,11 @@ dependencies = [
[[package]] [[package]]
name = "parity-ui-precompiled" name = "parity-ui-precompiled"
version = "1.4.0" version = "1.4.0"
source = "git+https://github.com/ethcore/js-precompiled.git#3d3b2f9e8e8b0fd62c172240bfd001a317cf2979" source = "git+https://github.com/ethcore/js-precompiled.git#175003ae159b126302fd1a90dd875dc86d7adba0"
dependencies = [ dependencies = [
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "parking_lot"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.3.5" version = "0.3.5"
@ -2065,6 +2064,7 @@ dependencies = [
"checksum jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>" "checksum jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
"checksum jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>" "checksum jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
"checksum jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>" "checksum jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
"checksum jsonrpc-macros 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
"checksum jsonrpc-tcp-server 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>" "checksum jsonrpc-tcp-server 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
@ -2107,7 +2107,6 @@ dependencies = [
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7" "checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab" "checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>" "checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
"checksum parking_lot 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "968f685642555d2f7e202c48b8b11de80569e9bfea817f7f12d7c61aac62d4e6"
"checksum parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc5847584161f273e69edc63c1a86254a22f570a0b5dd87aa6f9773f6f7d125" "checksum parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc5847584161f273e69edc63c1a86254a22f570a0b5dd87aa6f9773f6f7d125"
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068" "checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
"checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026" "checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026"

View File

@ -3,7 +3,7 @@ description = "Ethcore client."
name = "parity" name = "parity"
version = "1.5.0" version = "1.5.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -3,7 +3,7 @@ description = "Parity Dapps crate"
name = "ethcore-dapps" name = "ethcore-dapps"
version = "1.5.0" version = "1.5.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[lib] [lib]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -3,7 +3,7 @@ description = "Base Package for all Parity built-in dapps"
name = "parity-dapps-glue" name = "parity-dapps-glue"
version = "1.5.0" version = "1.5.0"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Ethcore Parity UI" description = "Ethcore Parity UI"
homepage = "http://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "parity-ui" name = "parity-ui"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[build-dependencies] [build-dependencies]
rustc_version = "0.1" rustc_version = "0.1"

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Ethcore Database" description = "Ethcore Database"
homepage = "http://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore-db" name = "ethcore-db"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Ethcore development/test/build tools" description = "Ethcore development/test/build tools"
homepage = "http://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore-devtools" name = "ethcore-devtools"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
rand = "0.3" rand = "0.3"

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ethash" name = "ethash"
version = "1.5.0" version = "1.5.0"
authors = ["arkpar <arkadiy@ethcore.io"] authors = ["Parity Technologies <admin@parity.io>"]
[lib] [lib]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Ethcore library" description = "Ethcore library"
homepage = "http://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore" name = "ethcore"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Fetching hash-addressed content." description = "Fetching hash-addressed content."
homepage = "https://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore-hash-fetch" name = "ethcore-hash-fetch"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
log = "0.3" log = "0.3"

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,10 +1,10 @@
[package] [package]
description = "Parity LES primitives" description = "Parity LES primitives"
homepage = "https://ethcore.io" homepage = "http://parity.io"
license = "GPL-3.0" license = "GPL-3.0"
name = "ethcore-light" name = "ethcore-light"
version = "1.5.0" version = "1.5.0"
authors = ["Ethcore <admin@ethcore.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -14,13 +14,12 @@
// 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/>.
//! Light client implementation. Used for raw data queries as well as the header //! Light client implementation. Stores data from light sync
//! sync.
use std::sync::Arc; use std::sync::Arc;
use ethcore::engines::Engine; use ethcore::engines::Engine;
use ethcore::ids::BlockID; use ethcore::ids::BlockId;
use ethcore::service::ClientIoMessage; use ethcore::service::ClientIoMessage;
use ethcore::block_import_error::BlockImportError; use ethcore::block_import_error::BlockImportError;
use ethcore::block_status::BlockStatus; use ethcore::block_status::BlockStatus;
@ -29,7 +28,7 @@ use ethcore::transaction::SignedTransaction;
use ethcore::blockchain_info::BlockChainInfo; use ethcore::blockchain_info::BlockChainInfo;
use io::IoChannel; use io::IoChannel;
use util::hash::H256; use util::hash::{H256, H256FastMap};
use util::{Bytes, Mutex}; use util::{Bytes, Mutex};
use provider::Provider; use provider::Provider;
@ -37,9 +36,10 @@ use request;
/// Light client implementation. /// Light client implementation.
pub struct Client { pub struct Client {
engine: Arc<Engine>, _engine: Arc<Engine>,
header_queue: HeaderQueue, header_queue: HeaderQueue,
message_channel: Mutex<IoChannel<ClientIoMessage>>, _message_channel: Mutex<IoChannel<ClientIoMessage>>,
tx_pool: Mutex<H256FastMap<SignedTransaction>>,
} }
impl Client { impl Client {
@ -51,17 +51,22 @@ impl Client {
} }
/// Whether the block is already known (but not necessarily part of the canonical chain) /// Whether the block is already known (but not necessarily part of the canonical chain)
pub fn is_known(&self, _id: BlockID) -> bool { pub fn is_known(&self, _id: BlockId) -> bool {
false false
} }
/// Import a local transaction.
pub fn import_own_transaction(&self, tx: SignedTransaction) {
self.tx_pool.lock().insert(tx.hash(), tx);
}
/// Fetch a vector of all pending transactions. /// Fetch a vector of all pending transactions.
pub fn pending_transactions(&self) -> Vec<SignedTransaction> { pub fn pending_transactions(&self) -> Vec<SignedTransaction> {
vec![] self.tx_pool.lock().values().cloned().collect()
} }
/// Inquire about the status of a given block. /// Inquire about the status of a given block (or header).
pub fn status(&self, _id: BlockID) -> BlockStatus { pub fn status(&self, _id: BlockId) -> BlockStatus {
BlockStatus::Unknown BlockStatus::Unknown
} }

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -28,8 +28,7 @@
//! It starts by performing a header-only sync, verifying random samples //! It starts by performing a header-only sync, verifying random samples
//! of members of the chain to varying degrees. //! of members of the chain to varying degrees.
// TODO: remove when integrating with the rest of parity. #![deny(missing_docs)]
#![allow(dead_code)]
pub mod client; pub mod client;
pub mod net; pub mod net;

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -16,7 +16,7 @@
//! I/O and event context generalizations. //! I/O and event context generalizations.
use network::{NetworkContext, PeerId}; use network::{NetworkContext, PeerId, NodeId};
use super::{Announcement, LightProtocol, ReqId}; use super::{Announcement, LightProtocol, ReqId};
use super::error::Error; use super::error::Error;
@ -26,95 +26,113 @@ use request::Request;
/// disconnecting peers. This is used as a generalization of the portions /// disconnecting peers. This is used as a generalization of the portions
/// of a p2p network which the light protocol structure makes use of. /// of a p2p network which the light protocol structure makes use of.
pub trait IoContext { pub trait IoContext {
/// Send a packet to a specific peer. /// Send a packet to a specific peer.
fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>); fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>);
/// Respond to a peer's message. Only works if this context is a byproduct /// Respond to a peer's message. Only works if this context is a byproduct
/// of a packet handler. /// of a packet handler.
fn respond(&self, packet_id: u8, packet_body: Vec<u8>); fn respond(&self, packet_id: u8, packet_body: Vec<u8>);
/// Disconnect a peer. /// Disconnect a peer.
fn disconnect_peer(&self, peer: PeerId); fn disconnect_peer(&self, peer: PeerId);
/// Disable a peer -- this is a disconnect + a time-out. /// Disable a peer -- this is a disconnect + a time-out.
fn disable_peer(&self, peer: PeerId); fn disable_peer(&self, peer: PeerId);
/// Get a peer's protocol version. /// Get a peer's protocol version.
fn protocol_version(&self, peer: PeerId) -> Option<u8>; fn protocol_version(&self, peer: PeerId) -> Option<u8>;
/// Persistent peer id
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
} }
impl<'a> IoContext for NetworkContext<'a> { impl<'a> IoContext for NetworkContext<'a> {
fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>) { fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.send(peer, packet_id, packet_body) { if let Err(e) = self.send(peer, packet_id, packet_body) {
debug!(target: "les", "Error sending packet to peer {}: {}", peer, e); debug!(target: "les", "Error sending packet to peer {}: {}", peer, e);
} }
} }
fn respond(&self, packet_id: u8, packet_body: Vec<u8>) { fn respond(&self, packet_id: u8, packet_body: Vec<u8>) {
if let Err(e) = self.respond(packet_id, packet_body) { if let Err(e) = self.respond(packet_id, packet_body) {
debug!(target: "les", "Error responding to peer message: {}", e); debug!(target: "les", "Error responding to peer message: {}", e);
} }
} }
fn disconnect_peer(&self, peer: PeerId) { fn disconnect_peer(&self, peer: PeerId) {
NetworkContext::disconnect_peer(self, peer); NetworkContext::disconnect_peer(self, peer);
} }
fn disable_peer(&self, peer: PeerId) { fn disable_peer(&self, peer: PeerId) {
NetworkContext::disable_peer(self, peer); NetworkContext::disable_peer(self, peer);
} }
fn protocol_version(&self, peer: PeerId) -> Option<u8> { fn protocol_version(&self, peer: PeerId) -> Option<u8> {
self.protocol_version(self.subprotocol_name(), peer) self.protocol_version(self.subprotocol_name(), peer)
} }
fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId> {
self.session_info(peer).and_then(|info| info.id)
}
} }
/// Context for a protocol event. /// Context for a protocol event.
pub trait EventContext { pub trait EventContext {
/// Get the peer relevant to the event e.g. message sender, /// Get the peer relevant to the event e.g. message sender,
/// disconnected/connected peer. /// disconnected/connected peer.
fn peer(&self) -> PeerId; fn peer(&self) -> PeerId;
/// Make a request from a peer. /// Returns the relevant's peer persistent Id (aka NodeId).
fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error>; fn persistent_peer_id(&self, peer: PeerId) -> Option<NodeId>;
/// Make an announcement of new capabilities to the rest of the peers. /// Make a request from a peer.
// TODO: maybe just put this on a timer in LightProtocol? fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error>;
fn make_announcement(&self, announcement: Announcement);
/// Disconnect a peer. /// Make an announcement of new capabilities to the rest of the peers.
fn disconnect_peer(&self, peer: PeerId); // TODO: maybe just put this on a timer in LightProtocol?
fn make_announcement(&self, announcement: Announcement);
/// Disable a peer. /// Disconnect a peer.
fn disable_peer(&self, peer: PeerId); fn disconnect_peer(&self, peer: PeerId);
/// Disable a peer.
fn disable_peer(&self, peer: PeerId);
} }
/// Concrete implementation of `EventContext` over the light protocol struct and /// Concrete implementation of `EventContext` over the light protocol struct and
/// an io context. /// an io context.
pub struct Ctx<'a> { pub struct Ctx<'a> {
/// Io context to enable immediate response to events. /// Io context to enable immediate response to events.
pub io: &'a IoContext, pub io: &'a IoContext,
/// Protocol implementation. /// Protocol implementation.
pub proto: &'a LightProtocol, pub proto: &'a LightProtocol,
/// Relevant peer for event. /// Relevant peer for event.
pub peer: PeerId, pub peer: PeerId,
} }
impl<'a> EventContext for Ctx<'a> { impl<'a> EventContext for Ctx<'a> {
fn peer(&self) -> PeerId { self.peer } fn peer(&self) -> PeerId {
fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error> { self.peer
self.proto.request_from(self.io, &peer, request) }
}
fn make_announcement(&self, announcement: Announcement) { fn persistent_peer_id(&self, id: PeerId) -> Option<NodeId> {
self.proto.make_announcement(self.io, announcement); self.io.persistent_peer_id(id)
} }
fn disconnect_peer(&self, peer: PeerId) { fn request_from(&self, peer: PeerId, request: Request) -> Result<ReqId, Error> {
self.io.disconnect_peer(peer); self.proto.request_from(self.io, &peer, request)
} }
fn disable_peer(&self, peer: PeerId) { fn make_announcement(&self, announcement: Announcement) {
self.io.disable_peer(peer); self.proto.make_announcement(self.io, announcement);
} }
fn disconnect_peer(&self, peer: PeerId) {
self.io.disconnect_peer(peer);
}
fn disable_peer(&self, peer: PeerId) {
self.io.disable_peer(peer);
}
} }

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -34,7 +34,7 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use provider::Provider; use provider::Provider;
use request::{self, Request}; use request::{self, HashOrNumber, Request};
use self::buffer_flow::{Buffer, FlowParams}; use self::buffer_flow::{Buffer, FlowParams};
use self::context::Ctx; use self::context::Ctx;
@ -57,13 +57,13 @@ const TIMEOUT_INTERVAL_MS: u64 = 1000;
// minimum interval between updates. // minimum interval between updates.
const UPDATE_INTERVAL_MS: i64 = 5000; const UPDATE_INTERVAL_MS: i64 = 5000;
// Supported protocol versions. /// Supported protocol versions.
pub const PROTOCOL_VERSIONS: &'static [u8] = &[1]; pub const PROTOCOL_VERSIONS: &'static [u8] = &[1];
// Max protocol version. /// Max protocol version.
pub const MAX_PROTOCOL_VERSION: u8 = 1; pub const MAX_PROTOCOL_VERSION: u8 = 1;
// Packet count for LES. /// Packet count for LES.
pub const PACKET_COUNT: u8 = 15; pub const PACKET_COUNT: u8 = 15;
// packet ID definitions. // packet ID definitions.
@ -102,6 +102,18 @@ mod packet {
pub const HEADER_PROOFS: u8 = 0x0e; pub const HEADER_PROOFS: u8 = 0x0e;
} }
// timeouts for different kinds of requests. all values are in milliseconds.
// TODO: variable timeouts based on request count.
mod timeout {
pub const HANDSHAKE: i64 = 2500;
pub const HEADERS: i64 = 5000;
pub const BODIES: i64 = 5000;
pub const RECEIPTS: i64 = 3500;
pub const PROOFS: i64 = 4000;
pub const CONTRACT_CODES: i64 = 5000;
pub const HEADER_PROOFS: i64 = 3500;
}
/// A request id. /// A request id.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ReqId(usize); pub struct ReqId(usize);
@ -111,7 +123,6 @@ pub struct ReqId(usize);
struct PendingPeer { struct PendingPeer {
sent_head: H256, sent_head: H256,
last_update: SteadyTime, last_update: SteadyTime,
proto_version: u8,
} }
// data about each peer. // data about each peer.
@ -122,7 +133,6 @@ struct Peer {
remote_flow: Option<(Buffer, FlowParams)>, remote_flow: Option<(Buffer, FlowParams)>,
sent_head: H256, // last head we've given them. sent_head: H256, // last head we've given them.
last_update: SteadyTime, last_update: SteadyTime,
proto_version: u8,
} }
impl Peer { impl Peer {
@ -443,17 +453,54 @@ impl LightProtocol {
} }
}; };
// if something went wrong, figure out how much to punish the peer.
if let Err(e) = res { if let Err(e) = res {
match e.punishment() { punish(*peer, io, e);
Punishment::None => {} }
Punishment::Disconnect => { }
debug!(target: "les", "Disconnecting peer {}: {}", peer, e);
io.disconnect_peer(*peer) // check timeouts and punish peers.
} fn timeout_check(&self, io: &IoContext) {
Punishment::Disable => { let now = SteadyTime::now();
debug!(target: "les", "Disabling peer {}: {}", peer, e);
io.disable_peer(*peer) // handshake timeout
{
let mut pending = self.pending_peers.write();
let slowpokes: Vec<_> = pending.iter()
.filter(|&(_, ref peer)| {
peer.last_update + Duration::milliseconds(timeout::HANDSHAKE) <= now
})
.map(|(&p, _)| p)
.collect();
for slowpoke in slowpokes {
debug!(target: "les", "Peer {} handshake timed out", slowpoke);
pending.remove(&slowpoke);
io.disconnect_peer(slowpoke);
}
}
// request timeouts
{
for r in self.pending_requests.read().values() {
let kind_timeout = match r.request.kind() {
request::Kind::Headers => timeout::HEADERS,
request::Kind::Bodies => timeout::BODIES,
request::Kind::Receipts => timeout::RECEIPTS,
request::Kind::StateProofs => timeout::PROOFS,
request::Kind::Codes => timeout::CONTRACT_CODES,
request::Kind::HeaderProofs => timeout::HEADER_PROOFS,
};
if r.timestamp + Duration::milliseconds(kind_timeout) <= now {
debug!(target: "les", "Request for {:?} from peer {} timed out",
r.request.kind(), r.peer_id);
// keep the request in the `pending` set for now so
// on_disconnect will pass unfulfilled ReqIds to handlers.
// in the case that a response is received after this, the
// disconnect won't be cancelled but the ReqId won't be
// marked as abandoned.
io.disconnect_peer(r.peer_id);
} }
} }
} }
@ -463,19 +510,37 @@ impl LightProtocol {
impl LightProtocol { impl LightProtocol {
// called when a peer connects. // called when a peer connects.
fn on_connect(&self, peer: &PeerId, io: &IoContext) { fn on_connect(&self, peer: &PeerId, io: &IoContext) {
let peer = *peer; let proto_version = match io.protocol_version(*peer).ok_or(Error::WrongNetwork) {
Ok(pv) => pv,
Err(e) => { punish(*peer, io, e); return }
};
trace!(target: "les", "Peer {} connecting", peer); if PROTOCOL_VERSIONS.iter().find(|x| **x == proto_version).is_none() {
punish(*peer, io, Error::UnsupportedProtocolVersion(proto_version));
match self.send_status(peer, io) { return;
Ok(pending_peer) => {
self.pending_peers.write().insert(peer, pending_peer);
}
Err(e) => {
trace!(target: "les", "Error while sending status: {}", e);
io.disconnect_peer(peer);
}
} }
let chain_info = self.provider.chain_info();
let status = Status {
head_td: chain_info.total_difficulty,
head_hash: chain_info.best_block_hash,
head_num: chain_info.best_block_number,
genesis_hash: chain_info.genesis_hash,
protocol_version: proto_version as u32, // match peer proto version
network_id: self.network_id,
last_head: None,
};
let capabilities = self.capabilities.read().clone();
let status_packet = status::write_handshake(&status, &capabilities, Some(&self.flow_params));
self.pending_peers.write().insert(*peer, PendingPeer {
sent_head: chain_info.best_block_hash,
last_update: SteadyTime::now(),
});
io.send(*peer, packet::STATUS, status_packet);
} }
// called when a peer disconnects. // called when a peer disconnects.
@ -508,38 +573,6 @@ impl LightProtocol {
} }
} }
// send status to a peer.
fn send_status(&self, peer: PeerId, io: &IoContext) -> Result<PendingPeer, Error> {
let proto_version = try!(io.protocol_version(peer).ok_or(Error::WrongNetwork));
if PROTOCOL_VERSIONS.iter().find(|x| **x == proto_version).is_none() {
return Err(Error::UnsupportedProtocolVersion(proto_version));
}
let chain_info = self.provider.chain_info();
let status = Status {
head_td: chain_info.total_difficulty,
head_hash: chain_info.best_block_hash,
head_num: chain_info.best_block_number,
genesis_hash: chain_info.genesis_hash,
protocol_version: proto_version as u32, // match peer proto version
network_id: self.network_id,
last_head: None,
};
let capabilities = self.capabilities.read().clone();
let status_packet = status::write_handshake(&status, &capabilities, Some(&self.flow_params));
io.send(peer, packet::STATUS, status_packet);
Ok(PendingPeer {
sent_head: chain_info.best_block_hash,
last_update: SteadyTime::now(),
proto_version: proto_version,
})
}
// Handle status message from peer. // Handle status message from peer.
fn status(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> { fn status(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> {
let pending = match self.pending_peers.write().remove(peer) { let pending = match self.pending_peers.write().remove(peer) {
@ -570,7 +603,6 @@ impl LightProtocol {
remote_flow: remote_flow, remote_flow: remote_flow,
sent_head: pending.sent_head, sent_head: pending.sent_head,
last_update: pending.last_update, last_update: pending.last_update,
proto_version: pending.proto_version,
})); }));
for handler in &self.handlers { for handler in &self.handlers {
@ -645,18 +677,21 @@ impl LightProtocol {
let mut peer = peer.lock(); let mut peer = peer.lock();
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let data = try!(data.at(1));
let block = { let start_block = {
let rlp = try!(data.at(1)); if try!(data.at(0)).size() == 32 {
(try!(rlp.val_at(0)), try!(rlp.val_at(1))) HashOrNumber::Hash(try!(data.val_at(0)))
} else {
HashOrNumber::Number(try!(data.val_at(0)))
}
}; };
let req = request::Headers { let req = request::Headers {
block_num: block.0, start: start_block,
block_hash: block.1, max: ::std::cmp::min(MAX_HEADERS, try!(data.val_at(1))),
max: ::std::cmp::min(MAX_HEADERS, try!(data.val_at(2))), skip: try!(data.val_at(2)),
skip: try!(data.val_at(3)), reverse: try!(data.val_at(3)),
reverse: try!(data.val_at(4)),
}; };
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Headers, req.max)); let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Headers, req.max));
@ -667,8 +702,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::BLOCK_HEADERS, { io.respond(packet::BLOCK_HEADERS, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for header in response { for header in response {
stream.append_raw(&header, 1); stream.append_raw(&header, 1);
@ -683,7 +718,7 @@ impl LightProtocol {
// Receive a response for block headers. // Receive a response for block headers.
fn block_headers(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { fn block_headers(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
let req_id = try!(self.pre_verify_response(peer, request::Kind::Headers, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::Headers, &raw));
let raw_headers: Vec<_> = raw.iter().skip(2).map(|x| x.as_raw().to_owned()).collect(); let raw_headers: Vec<_> = try!(raw.at(2)).iter().map(|x| x.as_raw().to_owned()).collect();
for handler in &self.handlers { for handler in &self.handlers {
handler.on_block_headers(&Ctx { handler.on_block_headers(&Ctx {
@ -713,7 +748,7 @@ impl LightProtocol {
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let req = request::Bodies { let req = request::Bodies {
block_hashes: try!(data.iter().skip(1).take(MAX_BODIES).map(|x| x.as_val()).collect()) block_hashes: try!(try!(data.at(1)).iter().take(MAX_BODIES).map(|x| x.as_val()).collect())
}; };
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Bodies, req.block_hashes.len())); let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Bodies, req.block_hashes.len()));
@ -726,8 +761,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::BLOCK_BODIES, { io.respond(packet::BLOCK_BODIES, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for body in response { for body in response {
stream.append_raw(&body, 1); stream.append_raw(&body, 1);
@ -742,7 +777,7 @@ impl LightProtocol {
// Receive a response for block bodies. // Receive a response for block bodies.
fn block_bodies(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { fn block_bodies(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
let req_id = try!(self.pre_verify_response(peer, request::Kind::Bodies, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::Bodies, &raw));
let raw_bodies: Vec<Bytes> = raw.iter().skip(2).map(|x| x.as_raw().to_owned()).collect(); let raw_bodies: Vec<Bytes> = try!(raw.at(2)).iter().map(|x| x.as_raw().to_owned()).collect();
for handler in &self.handlers { for handler in &self.handlers {
handler.on_block_bodies(&Ctx { handler.on_block_bodies(&Ctx {
@ -772,7 +807,7 @@ impl LightProtocol {
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let req = request::Receipts { let req = request::Receipts {
block_hashes: try!(data.iter().skip(1).take(MAX_RECEIPTS).map(|x| x.as_val()).collect()) block_hashes: try!(try!(data.at(1)).iter().take(MAX_RECEIPTS).map(|x| x.as_val()).collect())
}; };
let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Receipts, req.block_hashes.len())); let max_cost = try!(peer.deduct_max(&self.flow_params, request::Kind::Receipts, req.block_hashes.len()));
@ -785,8 +820,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::RECEIPTS, { io.respond(packet::RECEIPTS, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for receipts in response { for receipts in response {
stream.append_raw(&receipts, 1); stream.append_raw(&receipts, 1);
@ -801,9 +836,8 @@ impl LightProtocol {
// Receive a response for receipts. // Receive a response for receipts.
fn receipts(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { fn receipts(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
let req_id = try!(self.pre_verify_response(peer, request::Kind::Receipts, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::Receipts, &raw));
let raw_receipts: Vec<Vec<Receipt>> = try!(raw let raw_receipts: Vec<Vec<Receipt>> = try!(try!(raw.at(2))
.iter() .iter()
.skip(2)
.map(|x| x.as_val()) .map(|x| x.as_val())
.collect()); .collect());
@ -835,7 +869,7 @@ impl LightProtocol {
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let req = { let req = {
let requests: Result<Vec<_>, Error> = data.iter().skip(1).take(MAX_PROOFS).map(|x| { let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_PROOFS).map(|x| {
Ok(request::StateProof { Ok(request::StateProof {
block: try!(x.val_at(0)), block: try!(x.val_at(0)),
key1: try!(x.val_at(1)), key1: try!(x.val_at(1)),
@ -859,8 +893,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::PROOFS, { io.respond(packet::PROOFS, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for proof in response { for proof in response {
stream.append_raw(&proof, 1); stream.append_raw(&proof, 1);
@ -876,8 +910,7 @@ impl LightProtocol {
fn proofs(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { fn proofs(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
let req_id = try!(self.pre_verify_response(peer, request::Kind::StateProofs, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::StateProofs, &raw));
let raw_proofs: Vec<Vec<Bytes>> = raw.iter() let raw_proofs: Vec<Vec<Bytes>> = try!(raw.at(2)).iter()
.skip(2)
.map(|x| x.iter().map(|node| node.as_raw().to_owned()).collect()) .map(|x| x.iter().map(|node| node.as_raw().to_owned()).collect())
.collect(); .collect();
@ -909,7 +942,7 @@ impl LightProtocol {
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let req = { let req = {
let requests: Result<Vec<_>, Error> = data.iter().skip(1).take(MAX_CODES).map(|x| { let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_CODES).map(|x| {
Ok(request::ContractCode { Ok(request::ContractCode {
block_hash: try!(x.val_at(0)), block_hash: try!(x.val_at(0)),
account_key: try!(x.val_at(1)), account_key: try!(x.val_at(1)),
@ -931,8 +964,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::CONTRACT_CODES, { io.respond(packet::CONTRACT_CODES, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for code in response { for code in response {
stream.append(&code); stream.append(&code);
@ -948,7 +981,7 @@ impl LightProtocol {
fn contract_code(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { fn contract_code(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> {
let req_id = try!(self.pre_verify_response(peer, request::Kind::Codes, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::Codes, &raw));
let raw_code: Vec<Bytes> = try!(raw.iter().skip(2).map(|x| x.as_val()).collect()); let raw_code: Vec<Bytes> = try!(try!(raw.at(2)).iter().map(|x| x.as_val()).collect());
for handler in &self.handlers { for handler in &self.handlers {
handler.on_code(&Ctx { handler.on_code(&Ctx {
@ -978,7 +1011,7 @@ impl LightProtocol {
let req_id: u64 = try!(data.val_at(0)); let req_id: u64 = try!(data.val_at(0));
let req = { let req = {
let requests: Result<Vec<_>, Error> = data.iter().skip(1).take(MAX_PROOFS).map(|x| { let requests: Result<Vec<_>, Error> = try!(data.at(1)).iter().take(MAX_PROOFS).map(|x| {
Ok(request::HeaderProof { Ok(request::HeaderProof {
cht_number: try!(x.val_at(0)), cht_number: try!(x.val_at(0)),
block_number: try!(x.val_at(1)), block_number: try!(x.val_at(1)),
@ -1001,8 +1034,8 @@ impl LightProtocol {
let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost); let cur_buffer = peer.refund(&self.flow_params, max_cost - actual_cost);
io.respond(packet::HEADER_PROOFS, { io.respond(packet::HEADER_PROOFS, {
let mut stream = RlpStream::new_list(response.len() + 2); let mut stream = RlpStream::new_list(3);
stream.append(&req_id).append(&cur_buffer); stream.append(&req_id).append(&cur_buffer).begin_list(response.len());
for proof in response { for proof in response {
stream.append_raw(&proof, 1); stream.append_raw(&proof, 1);
@ -1023,9 +1056,8 @@ impl LightProtocol {
)) ))
} }
let req_id = try!(self.pre_verify_response(peer, request::Kind::HeaderProofs, &raw)); let req_id = try!(self.pre_verify_response(peer, request::Kind::HeaderProofs, &raw));
let raw_proofs: Vec<_> = try!(raw.iter().skip(2).map(decode_res).collect()); let raw_proofs: Vec<_> = try!(try!(raw.at(2)).iter().map(decode_res).collect());
for handler in &self.handlers { for handler in &self.handlers {
handler.on_header_proofs(&Ctx { handler.on_header_proofs(&Ctx {
@ -1058,6 +1090,21 @@ impl LightProtocol {
} }
} }
// if something went wrong, figure out how much to punish the peer.
fn punish(peer: PeerId, io: &IoContext, e: Error) {
match e.punishment() {
Punishment::None => {}
Punishment::Disconnect => {
debug!(target: "les", "Disconnecting peer {}: {}", peer, e);
io.disconnect_peer(peer)
}
Punishment::Disable => {
debug!(target: "les", "Disabling peer {}: {}", peer, e);
io.disable_peer(peer)
}
}
}
impl NetworkProtocolHandler for LightProtocol { impl NetworkProtocolHandler for LightProtocol {
fn initialize(&self, io: &NetworkContext) { fn initialize(&self, io: &NetworkContext) {
io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS).expect("Error registering sync timer."); io.register_timer(TIMEOUT, TIMEOUT_INTERVAL_MS).expect("Error registering sync timer.");
@ -1075,11 +1122,9 @@ impl NetworkProtocolHandler for LightProtocol {
self.on_disconnect(*peer, io); self.on_disconnect(*peer, io);
} }
fn timeout(&self, _io: &NetworkContext, timer: TimerToken) { fn timeout(&self, io: &NetworkContext, timer: TimerToken) {
match timer { match timer {
TIMEOUT => { TIMEOUT => self.timeout_check(io),
// broadcast transactions to peers.
}
_ => warn!(target: "les", "received timeout on unknown token {}", timer), _ => warn!(target: "les", "received timeout on unknown token {}", timer),
} }
} }
@ -1089,20 +1134,24 @@ impl NetworkProtocolHandler for LightProtocol {
fn encode_request(req: &Request, req_id: usize) -> Vec<u8> { fn encode_request(req: &Request, req_id: usize) -> Vec<u8> {
match *req { match *req {
Request::Headers(ref headers) => { Request::Headers(ref headers) => {
let mut stream = RlpStream::new_list(5); let mut stream = RlpStream::new_list(2);
stream.append(&req_id).begin_list(4);
match headers.start {
HashOrNumber::Hash(ref hash) => stream.append(hash),
HashOrNumber::Number(ref num) => stream.append(num),
};
stream stream
.append(&req_id)
.begin_list(2)
.append(&headers.block_num)
.append(&headers.block_hash)
.append(&headers.max) .append(&headers.max)
.append(&headers.skip) .append(&headers.skip)
.append(&headers.reverse); .append(&headers.reverse);
stream.out() stream.out()
} }
Request::Bodies(ref request) => { Request::Bodies(ref request) => {
let mut stream = RlpStream::new_list(request.block_hashes.len() + 1); let mut stream = RlpStream::new_list(2);
stream.append(&req_id); stream.append(&req_id).begin_list(request.block_hashes.len());
for hash in &request.block_hashes { for hash in &request.block_hashes {
stream.append(hash); stream.append(hash);
@ -1111,8 +1160,8 @@ fn encode_request(req: &Request, req_id: usize) -> Vec<u8> {
stream.out() stream.out()
} }
Request::Receipts(ref request) => { Request::Receipts(ref request) => {
let mut stream = RlpStream::new_list(request.block_hashes.len() + 1); let mut stream = RlpStream::new_list(2);
stream.append(&req_id); stream.append(&req_id).begin_list(request.block_hashes.len());
for hash in &request.block_hashes { for hash in &request.block_hashes {
stream.append(hash); stream.append(hash);
@ -1121,8 +1170,8 @@ fn encode_request(req: &Request, req_id: usize) -> Vec<u8> {
stream.out() stream.out()
} }
Request::StateProofs(ref request) => { Request::StateProofs(ref request) => {
let mut stream = RlpStream::new_list(request.requests.len() + 1); let mut stream = RlpStream::new_list(2);
stream.append(&req_id); stream.append(&req_id).begin_list(request.requests.len());
for proof_req in &request.requests { for proof_req in &request.requests {
stream.begin_list(4) stream.begin_list(4)
@ -1140,8 +1189,8 @@ fn encode_request(req: &Request, req_id: usize) -> Vec<u8> {
stream.out() stream.out()
} }
Request::Codes(ref request) => { Request::Codes(ref request) => {
let mut stream = RlpStream::new_list(request.code_requests.len() + 1); let mut stream = RlpStream::new_list(2);
stream.append(&req_id); stream.append(&req_id).begin_list(request.code_requests.len());
for code_req in &request.code_requests { for code_req in &request.code_requests {
stream.begin_list(2) stream.begin_list(2)
@ -1152,8 +1201,8 @@ fn encode_request(req: &Request, req_id: usize) -> Vec<u8> {
stream.out() stream.out()
} }
Request::HeaderProofs(ref request) => { Request::HeaderProofs(ref request) => {
let mut stream = RlpStream::new_list(request.requests.len() + 1); let mut stream = RlpStream::new_list(2);
stream.append(&req_id); stream.append(&req_id).begin_list(request.requests.len());
for proof_req in &request.requests { for proof_req in &request.requests {
stream.begin_list(3) stream.begin_list(3)

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -19,9 +19,9 @@
use ethcore::blockchain_info::BlockChainInfo; use ethcore::blockchain_info::BlockChainInfo;
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient}; use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
use ethcore::ids::BlockID; use ethcore::ids::BlockId;
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use network::PeerId; use network::{PeerId, NodeId};
use net::buffer_flow::FlowParams; use net::buffer_flow::FlowParams;
use net::context::IoContext; use net::context::IoContext;
@ -68,6 +68,10 @@ impl IoContext for Expect {
fn protocol_version(&self, _peer: PeerId) -> Option<u8> { fn protocol_version(&self, _peer: PeerId) -> Option<u8> {
Some(super::MAX_PROTOCOL_VERSION) Some(super::MAX_PROTOCOL_VERSION)
} }
fn persistent_peer_id(&self, _peer: PeerId) -> Option<NodeId> {
None
}
} }
// can't implement directly for Arc due to cross-crate orphan rules. // can't implement directly for Arc due to cross-crate orphan rules.
@ -91,22 +95,33 @@ impl Provider for TestProvider {
} }
fn block_headers(&self, req: request::Headers) -> Vec<Bytes> { fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
let best_num = self.0.client.chain_info().best_block_number; use request::HashOrNumber;
let start_num = req.block_num; use ethcore::views::HeaderView;
match self.0.client.block_hash(BlockID::Number(req.block_num)) { let best_num = self.chain_info().best_block_number;
Some(hash) if hash == req.block_hash => {} let start_num = match req.start {
_=> { HashOrNumber::Number(start_num) => start_num,
trace!(target: "les_provider", "unknown/non-canonical start block in header request: {:?}", (req.block_num, req.block_hash)); HashOrNumber::Hash(hash) => match self.0.client.block_header(BlockId::Hash(hash)) {
return vec![] None => {
return Vec::new();
}
Some(header) => {
let num = HeaderView::new(&header).number();
if req.max == 1 || self.0.client.block_hash(BlockId::Number(num)) != Some(hash) {
// Non-canonical header or single header requested.
return vec![header];
}
num
}
} }
} };
(0u64..req.max as u64) (0u64..req.max as u64)
.map(|x: u64| x.saturating_mul(req.skip + 1)) .map(|x: u64| x.saturating_mul(req.skip + 1))
.take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num >= *x }) .take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num >= *x })
.map(|x| if req.reverse { start_num - x } else { start_num + x }) .map(|x| if req.reverse { start_num - x } else { start_num + x })
.map(|x| self.0.client.block_header(BlockID::Number(x))) .map(|x| self.0.client.block_header(BlockId::Number(x)))
.take_while(|x| x.is_some()) .take_while(|x| x.is_some())
.flat_map(|x| x) .flat_map(|x| x)
.collect() .collect()
@ -114,7 +129,7 @@ impl Provider for TestProvider {
fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> { fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
req.block_hashes.into_iter() req.block_hashes.into_iter()
.map(|hash| self.0.client.block_body(BlockID::Hash(hash))) .map(|hash| self.0.client.block_body(BlockId::Hash(hash)))
.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) .map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec()))
.collect() .collect()
} }
@ -250,8 +265,7 @@ fn buffer_overflow() {
// 1000 requests is far too many for the default flow params. // 1000 requests is far too many for the default flow params.
let request = encode_request(&Request::Headers(Headers { let request = encode_request(&Request::Headers(Headers {
block_num: 1, start: 1.into(),
block_hash: provider.client.chain_info().genesis_hash,
max: 1000, max: 1000,
skip: 0, skip: 0,
reverse: false, reverse: false,
@ -284,8 +298,7 @@ fn get_block_headers() {
} }
let request = Headers { let request = Headers {
block_num: 1, start: 1.into(),
block_hash: provider.client.block_hash(BlockID::Number(1)).unwrap(),
max: 10, max: 10,
skip: 0, skip: 0,
reverse: false, reverse: false,
@ -294,14 +307,14 @@ fn get_block_headers() {
let request_body = encode_request(&Request::Headers(request.clone()), req_id); let request_body = encode_request(&Request::Headers(request.clone()), req_id);
let response = { let response = {
let headers: Vec<_> = (0..10).map(|i| provider.client.block_header(BlockID::Number(i + 1)).unwrap()).collect(); let headers: Vec<_> = (0..10).map(|i| provider.client.block_header(BlockId::Number(i + 1)).unwrap()).collect();
assert_eq!(headers.len(), 10); assert_eq!(headers.len(), 10);
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10); let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10);
let mut response_stream = RlpStream::new_list(12); let mut response_stream = RlpStream::new_list(3);
response_stream.append(&req_id).append(&new_buf); response_stream.append(&req_id).append(&new_buf).begin_list(10);
for header in headers { for header in headers {
response_stream.append_raw(&header, 1); response_stream.append_raw(&header, 1);
} }
@ -334,21 +347,21 @@ fn get_block_bodies() {
} }
let request = request::Bodies { let request = request::Bodies {
block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(), block_hashes: (0..10).map(|i| provider.client.block_hash(BlockId::Number(i)).unwrap()).collect(),
}; };
let req_id = 111; let req_id = 111;
let request_body = encode_request(&Request::Bodies(request.clone()), req_id); let request_body = encode_request(&Request::Bodies(request.clone()), req_id);
let response = { let response = {
let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockID::Number(i + 1)).unwrap()).collect(); let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockId::Number(i + 1)).unwrap()).collect();
assert_eq!(bodies.len(), 10); assert_eq!(bodies.len(), 10);
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10); let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10);
let mut response_stream = RlpStream::new_list(12); let mut response_stream = RlpStream::new_list(3);
response_stream.append(&req_id).append(&new_buf); response_stream.append(&req_id).append(&new_buf).begin_list(10);
for body in bodies { for body in bodies {
response_stream.append_raw(&body, 1); response_stream.append_raw(&body, 1);
} }
@ -382,7 +395,7 @@ fn get_block_receipts() {
// find the first 10 block hashes starting with `f` because receipts are only provided // find the first 10 block hashes starting with `f` because receipts are only provided
// by the test client in that case. // by the test client in that case.
let block_hashes: Vec<_> = (0..1000).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()) let block_hashes: Vec<_> = (0..1000).map(|i| provider.client.block_hash(BlockId::Number(i)).unwrap())
.filter(|hash| format!("{}", hash).starts_with("f")).take(10).collect(); .filter(|hash| format!("{}", hash).starts_with("f")).take(10).collect();
let request = request::Receipts { let request = request::Receipts {
@ -399,9 +412,9 @@ fn get_block_receipts() {
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len()); let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len());
let mut response_stream = RlpStream::new_list(2 + receipts.len()); let mut response_stream = RlpStream::new_list(3);
response_stream.append(&req_id).append(&new_buf); response_stream.append(&req_id).append(&new_buf).begin_list(receipts.len());
for block_receipts in receipts { for block_receipts in receipts {
response_stream.append_raw(&block_receipts, 1); response_stream.append_raw(&block_receipts, 1);
} }
@ -448,9 +461,9 @@ fn get_state_proofs() {
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2); let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2);
let mut response_stream = RlpStream::new_list(4); let mut response_stream = RlpStream::new_list(3);
response_stream.append(&req_id).append(&new_buf); response_stream.append(&req_id).append(&new_buf).begin_list(2);
for proof in proofs { for proof in proofs {
response_stream.append_raw(&proof, 1); response_stream.append_raw(&proof, 1);
} }
@ -497,9 +510,9 @@ fn get_contract_code() {
let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Codes, 2); let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Codes, 2);
let mut response_stream = RlpStream::new_list(4); let mut response_stream = RlpStream::new_list(3);
response_stream.append(&req_id).append(&new_buf); response_stream.append(&req_id).append(&new_buf).begin_list(2);
for code in codes { for code in codes {
response_stream.append(&code); response_stream.append(&code);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -20,7 +20,7 @@
use ethcore::blockchain_info::BlockChainInfo; use ethcore::blockchain_info::BlockChainInfo;
use ethcore::client::{BlockChainClient, ProvingBlockChainClient}; use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
use ethcore::transaction::SignedTransaction; use ethcore::transaction::SignedTransaction;
use ethcore::ids::BlockID; use ethcore::ids::BlockId;
use util::{Bytes, H256}; use util::{Bytes, H256};
@ -97,22 +97,34 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
} }
fn block_headers(&self, req: request::Headers) -> Vec<Bytes> { fn block_headers(&self, req: request::Headers) -> Vec<Bytes> {
let best_num = self.chain_info().best_block_number; use request::HashOrNumber;
let start_num = req.block_num; use ethcore::views::HeaderView;
match self.block_hash(BlockID::Number(req.block_num)) { let best_num = self.chain_info().best_block_number;
Some(hash) if hash == req.block_hash => {} let start_num = match req.start {
_=> { HashOrNumber::Number(start_num) => start_num,
trace!(target: "les_provider", "unknown/non-canonical start block in header request: {:?}", (req.block_num, req.block_hash)); HashOrNumber::Hash(hash) => match self.block_header(BlockId::Hash(hash)) {
return vec![] None => {
trace!(target: "les_provider", "Unknown block hash {} requested", hash);
return Vec::new();
}
Some(header) => {
let num = HeaderView::new(&header).number();
if req.max == 1 || self.block_hash(BlockId::Number(num)) != Some(hash) {
// Non-canonical header or single header requested.
return vec![header];
}
num
}
} }
} };
(0u64..req.max as u64) (0u64..req.max as u64)
.map(|x: u64| x.saturating_mul(req.skip + 1)) .map(|x: u64| x.saturating_mul(req.skip + 1))
.take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num >= *x }) .take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num >= *x })
.map(|x| if req.reverse { start_num - x } else { start_num + x }) .map(|x| if req.reverse { start_num - x } else { start_num + x })
.map(|x| self.block_header(BlockID::Number(x))) .map(|x| self.block_header(BlockId::Number(x)))
.take_while(|x| x.is_some()) .take_while(|x| x.is_some())
.flat_map(|x| x) .flat_map(|x| x)
.collect() .collect()
@ -120,7 +132,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> { fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> {
req.block_hashes.into_iter() req.block_hashes.into_iter()
.map(|hash| self.block_body(BlockID::Hash(hash))) .map(|hash| self.block_body(BlockId::Hash(hash)))
.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) .map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec()))
.collect() .collect()
} }
@ -139,8 +151,8 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
for request in req.requests { for request in req.requests {
let proof = match request.key2 { let proof = match request.key2 {
Some(key2) => self.prove_storage(request.key1, key2, request.from_level, BlockID::Hash(request.block)), Some(key2) => self.prove_storage(request.key1, key2, request.from_level, BlockId::Hash(request.block)),
None => self.prove_account(request.key1, request.from_level, BlockID::Hash(request.block)), None => self.prove_account(request.key1, request.from_level, BlockId::Hash(request.block)),
}; };
let mut stream = RlpStream::new_list(proof.len()); let mut stream = RlpStream::new_list(proof.len());
@ -157,7 +169,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> { fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> {
req.code_requests.into_iter() req.code_requests.into_iter()
.map(|req| { .map(|req| {
self.code_by_hash(req.account_key, BlockID::Hash(req.block_hash)) self.code_by_hash(req.account_key, BlockId::Hash(req.block_hash))
}) })
.collect() .collect()
} }

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -18,15 +18,34 @@
use util::H256; use util::H256;
/// Either a hash or a number.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "ipc", derive(Binary))]
pub enum HashOrNumber {
/// Block hash variant.
Hash(H256),
/// Block number variant.
Number(u64),
}
impl From<H256> for HashOrNumber {
fn from(hash: H256) -> Self {
HashOrNumber::Hash(hash)
}
}
impl From<u64> for HashOrNumber {
fn from(num: u64) -> Self {
HashOrNumber::Number(num)
}
}
/// A request for block headers. /// A request for block headers.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "ipc", derive(Binary))] #[cfg_attr(feature = "ipc", derive(Binary))]
pub struct Headers { pub struct Headers {
/// Starting block number /// Starting block number or hash.
pub block_num: u64, pub start: HashOrNumber,
/// Starting block hash. This and number could be combined but IPC codegen is
/// not robust enough to support it.
pub block_hash: H256,
/// The maximum amount of headers which can be returned. /// The maximum amount of headers which can be returned.
pub max: usize, pub max: usize,
/// The amount of headers to skip between each response entry. /// The amount of headers to skip between each response entry.

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -21,8 +21,9 @@
}, },
"genesis": { "genesis": {
"seal": { "seal": {
"generic": { "authority_round": {
"rlp": "0xc28080" "step": "0x0",
"signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
} }
}, },
"difficulty": "0x20000", "difficulty": "0x20000",

View File

@ -17,10 +17,7 @@
}, },
"genesis": { "genesis": {
"seal": { "seal": {
"generic": { "generic": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
"fields": 1,
"rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
}
}, },
"difficulty": "0x20000", "difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000", "author": "0x0000000000000000000000000000000000000000",

View File

@ -10,14 +10,15 @@
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000", "blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x118c30", "homesteadTransition": 1150000,
"eip150Transition": "0x2625a0", "eip150Transition": 2500000,
"eip155Transition": "0x7fffffffffffffff", "eip155Transition": 3000000,
"eip160Transition": "0x7fffffffffffffff", "eip160Transition": 3000000,
"ecip1010PauseTransition": 3000000,
"ecip1010ContinueTransition": 5000000,
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff", "eip161dTransition": "0x7fffffffffffffff"
"ecip1010PauseTransition": "0x2dc6c0",
"ecip1010ContinueTransition": "0x4c4b40"
} }
} }
}, },

View File

@ -170,9 +170,6 @@
"enode://cadc6e573b6bc2a9128f2f635ac0db3353e360b56deef239e9be7e7fce039502e0ec670b595f6288c0d2116812516ad6b6ff8d5728ff45eba176989e40dead1e@37.128.191.230:30303", "enode://cadc6e573b6bc2a9128f2f635ac0db3353e360b56deef239e9be7e7fce039502e0ec670b595f6288c0d2116812516ad6b6ff8d5728ff45eba176989e40dead1e@37.128.191.230:30303",
"enode://595a9a06f8b9bc9835c8723b6a82105aea5d55c66b029b6d44f229d6d135ac3ecdd3e9309360a961ea39d7bee7bac5d03564077a4e08823acc723370aace65ec@46.20.235.22:30303", "enode://595a9a06f8b9bc9835c8723b6a82105aea5d55c66b029b6d44f229d6d135ac3ecdd3e9309360a961ea39d7bee7bac5d03564077a4e08823acc723370aace65ec@46.20.235.22:30303",
"enode://029178d6d6f9f8026fc0bc17d5d1401aac76ec9d86633bba2320b5eed7b312980c0a210b74b20c4f9a8b0b2bf884b111fa9ea5c5f916bb9bbc0e0c8640a0f56c@216.158.85.185:30303", "enode://029178d6d6f9f8026fc0bc17d5d1401aac76ec9d86633bba2320b5eed7b312980c0a210b74b20c4f9a8b0b2bf884b111fa9ea5c5f916bb9bbc0e0c8640a0f56c@216.158.85.185:30303",
"enode://84f5d5957b4880a8b0545e32e05472318898ad9fc8ebe1d56c90c12334a98e12351eccfdf3a2bf72432ac38b57e9d348400d17caa083879ade3822390f89773f@10.1.52.78:30303",
"enode://f90dc9b9bf7b8db97726b7849e175f1eb2707f3d8f281c929336e398dd89b0409fc6aeceb89e846278e9d3ecc3857cebfbe6758ff352ece6fe5d42921ee761db@10.1.173.87:30303",
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@10.3.149.199:30303",
"enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303", "enode://fdd1b9bb613cfbc200bba17ce199a9490edc752a833f88d4134bf52bb0d858aa5524cb3ec9366c7a4ef4637754b8b15b5dc913e4ed9fdb6022f7512d7b63f181@212.47.247.103:30303",
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303", "enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",

View File

@ -9,12 +9,15 @@
"durationLimit": "0x0d", "durationLimit": "0x0d",
"blockReward": "0x4563918244F40000", "blockReward": "0x4563918244F40000",
"registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d", "registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d",
"homesteadTransition": "0x789b0", "homesteadTransition": 494000,
"eip150Transition": "0x1b34d8", "eip150Transition": 1783000,
"eip155Transition": 1885000, "eip155Transition": 1915000,
"eip160Transition": 1885000, "eip160Transition": 1915000,
"eip161abcTransition": 1885000, "ecip1010PauseTransition": 1915000,
"eip161dTransition": 1885000 "ecip1010ContinueTransition": 3415000,
"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
} }
} }
}, },

@ -1 +1 @@
Subproject commit e8f4624b7f1a15c63674eecf577c7ab76c3b16be Subproject commit 9028c4801fd39fbb71a9796979182549a24e81c8

View File

@ -4,29 +4,27 @@
"InstantSeal": null "InstantSeal": null
}, },
"params": { "params": {
"accountStartNonce": "0x0100000", "accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20", "maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388", "minGasLimit": "0x1388",
"networkID" : "0x2" "networkID" : "0x11"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
"generic": { "generic": "0x0"
"rlp": "0x0"
}
}, },
"difficulty": "0x20000", "difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000", "author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00", "timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x", "extraData": "0x",
"gasLimit": "0x2fefd8" "gasLimit": "0x5B8D80"
}, },
"accounts": { "accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"0x00a329c0648769a73afac7f9381e08fb43dbea72": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } "0x00a329c0648769a73afac7f9381e08fb43dbea72": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
} }
} }

View File

@ -0,0 +1,40 @@
{
"name": "TestBFT",
"engine": {
"Tendermint": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"authorities" : [
"0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1",
"0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e"
]
}
}
},
"params": {
"accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2323"
},
"genesis": {
"seal": {
"generic": {
"rlp": "f88980b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f843b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -23,9 +23,9 @@ use self::stores::{AddressBook, DappsSettingsStore, NewDappsPolicy};
use std::fmt; use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use util::{Mutex, RwLock}; use util::RwLock;
use ethstore::{SecretStore, Error as SSError, SafeAccount, EthStore}; use ethstore::{SimpleSecretStore, SecretStore, Error as SSError, EthStore, EthMultiStore, random_string};
use ethstore::dir::{KeyDirectory}; use ethstore::dir::MemoryDirectory;
use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator}; use ethstore::ethkey::{Address, Message, Public, Secret, Random, Generator};
use ethjson::misc::AccountMeta; use ethjson::misc::AccountMeta;
pub use ethstore::ethkey::Signature; pub use ethstore::ethkey::Signature;
@ -73,58 +73,47 @@ impl From<SSError> for Error {
} }
} }
#[derive(Default)]
struct NullDir {
accounts: RwLock<HashMap<Address, SafeAccount>>,
}
impl KeyDirectory for NullDir {
fn load(&self) -> Result<Vec<SafeAccount>, SSError> {
Ok(self.accounts.read().values().cloned().collect())
}
fn insert(&self, account: SafeAccount) -> Result<SafeAccount, SSError> {
self.accounts.write().insert(account.address.clone(), account.clone());
Ok(account)
}
fn remove(&self, address: &Address) -> Result<(), SSError> {
self.accounts.write().remove(address);
Ok(())
}
}
/// Dapp identifier /// Dapp identifier
pub type DappId = String; pub type DappId = String;
fn transient_sstore() -> EthMultiStore {
EthMultiStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")
}
type AccountToken = String;
/// Account management. /// Account management.
/// Responsible for unlocking accounts. /// Responsible for unlocking accounts.
pub struct AccountProvider { pub struct AccountProvider {
unlocked: Mutex<HashMap<Address, AccountData>>, unlocked: RwLock<HashMap<Address, AccountData>>,
sstore: Box<SecretStore>,
address_book: RwLock<AddressBook>, address_book: RwLock<AddressBook>,
dapps_settings: RwLock<DappsSettingsStore>, dapps_settings: RwLock<DappsSettingsStore>,
/// Accounts on disk
sstore: Box<SecretStore>,
/// Accounts unlocked with rolling tokens
transient_sstore: EthMultiStore,
} }
impl AccountProvider { impl AccountProvider {
/// Creates new account provider. /// Creates new account provider.
pub fn new(sstore: Box<SecretStore>) -> Self { pub fn new(sstore: Box<SecretStore>) -> Self {
AccountProvider { AccountProvider {
unlocked: Mutex::new(HashMap::new()), unlocked: RwLock::new(HashMap::new()),
address_book: RwLock::new(AddressBook::new(sstore.local_path().into())), address_book: RwLock::new(AddressBook::new(sstore.local_path().into())),
dapps_settings: RwLock::new(DappsSettingsStore::new(sstore.local_path().into())), dapps_settings: RwLock::new(DappsSettingsStore::new(sstore.local_path().into())),
sstore: sstore, sstore: sstore,
transient_sstore: transient_sstore(),
} }
} }
/// Creates not disk backed provider. /// Creates not disk backed provider.
pub fn transient_provider() -> Self { pub fn transient_provider() -> Self {
AccountProvider { AccountProvider {
unlocked: Mutex::new(HashMap::new()), unlocked: RwLock::new(HashMap::new()),
address_book: RwLock::new(AddressBook::transient()), address_book: RwLock::new(AddressBook::transient()),
dapps_settings: RwLock::new(DappsSettingsStore::transient()), dapps_settings: RwLock::new(DappsSettingsStore::transient()),
sstore: Box::new(EthStore::open(Box::new(NullDir::default())) sstore: Box::new(EthStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")),
.expect("NullDir load always succeeds; qed")) transient_sstore: transient_sstore(),
} }
} }
@ -252,7 +241,7 @@ impl AccountProvider {
Ok(AccountMeta { Ok(AccountMeta {
name: try!(self.sstore.name(&account)), name: try!(self.sstore.name(&account)),
meta: try!(self.sstore.meta(&account)), meta: try!(self.sstore.meta(&account)),
uuid: self.sstore.uuid(&account).ok().map(Into::into), // allowed to not have a UUID uuid: self.sstore.uuid(&account).ok().map(Into::into), // allowed to not have a Uuid
}) })
} }
@ -270,11 +259,8 @@ impl AccountProvider {
/// Returns `true` if the password for `account` is `password`. `false` if not. /// Returns `true` if the password for `account` is `password`. `false` if not.
pub fn test_password(&self, account: &Address, password: &str) -> Result<bool, Error> { pub fn test_password(&self, account: &Address, password: &str) -> Result<bool, Error> {
match self.sstore.sign(account, password, &Default::default()) { self.sstore.test_password(account, password)
Ok(_) => Ok(true), .map_err(Into::into)
Err(SSError::InvalidPassword) => Ok(false),
Err(e) => Err(Error::SStore(e)),
}
} }
/// Permanently removes an account. /// Permanently removes an account.
@ -295,7 +281,7 @@ impl AccountProvider {
let _ = try!(self.sstore.sign(&account, &password, &Default::default())); let _ = try!(self.sstore.sign(&account, &password, &Default::default()));
// check if account is already unlocked pernamently, if it is, do nothing // check if account is already unlocked pernamently, if it is, do nothing
let mut unlocked = self.unlocked.lock(); let mut unlocked = self.unlocked.write();
if let Some(data) = unlocked.get(&account) { if let Some(data) = unlocked.get(&account) {
if let Unlock::Perm = data.unlock { if let Unlock::Perm = data.unlock {
return Ok(()) return Ok(())
@ -312,7 +298,7 @@ impl AccountProvider {
} }
fn password(&self, account: &Address) -> Result<String, Error> { fn password(&self, account: &Address) -> Result<String, Error> {
let mut unlocked = self.unlocked.lock(); let mut unlocked = self.unlocked.write();
let data = try!(unlocked.get(account).ok_or(Error::NotUnlocked)).clone(); let data = try!(unlocked.get(account).ok_or(Error::NotUnlocked)).clone();
if let Unlock::Temp = data.unlock { if let Unlock::Temp = data.unlock {
unlocked.remove(account).expect("data exists: so key must exist: qed"); unlocked.remove(account).expect("data exists: so key must exist: qed");
@ -343,7 +329,7 @@ impl AccountProvider {
/// Checks if given account is unlocked /// Checks if given account is unlocked
pub fn is_unlocked(&self, account: Address) -> bool { pub fn is_unlocked(&self, account: Address) -> bool {
let unlocked = self.unlocked.lock(); let unlocked = self.unlocked.read();
unlocked.get(&account).is_some() unlocked.get(&account).is_some()
} }
@ -353,6 +339,48 @@ impl AccountProvider {
Ok(try!(self.sstore.sign(&account, &password, &message))) Ok(try!(self.sstore.sign(&account, &password, &message)))
} }
/// Signs given message with supplied token. Returns a token to use in next signing within this session.
pub fn sign_with_token(&self, account: Address, token: AccountToken, message: Message) -> Result<(Signature, AccountToken), Error> {
let is_std_password = try!(self.sstore.test_password(&account, &token));
let new_token = random_string(16);
let signature = if is_std_password {
// Insert to transient store
try!(self.sstore.copy_account(&self.transient_sstore, &account, &token, &new_token));
// sign
try!(self.sstore.sign(&account, &token, &message))
} else {
// check transient store
try!(self.transient_sstore.change_password(&account, &token, &new_token));
// and sign
try!(self.transient_sstore.sign(&account, &new_token, &message))
};
Ok((signature, new_token))
}
/// Decrypts a message with given token. Returns a token to use in next operation for this account.
pub fn decrypt_with_token(&self, account: Address, token: AccountToken, shared_mac: &[u8], message: &[u8])
-> Result<(Vec<u8>, AccountToken), Error>
{
let is_std_password = try!(self.sstore.test_password(&account, &token));
let new_token = random_string(16);
let message = if is_std_password {
// Insert to transient store
try!(self.sstore.copy_account(&self.transient_sstore, &account, &token, &new_token));
// decrypt
try!(self.sstore.decrypt(&account, &token, shared_mac, message))
} else {
// check transient store
try!(self.transient_sstore.change_password(&account, &token, &new_token));
// and decrypt
try!(self.transient_sstore.decrypt(&account, &token, shared_mac, message))
};
Ok((message, new_token))
}
/// Decrypts a message. If password is not provided the account must be unlocked. /// Decrypts a message. If password is not provided the account must be unlocked.
pub fn decrypt(&self, account: Address, password: Option<String>, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> { pub fn decrypt(&self, account: Address, password: Option<String>, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
let password = try!(password.map(Ok).unwrap_or_else(|| self.password(&account))); let password = try!(password.map(Ok).unwrap_or_else(|| self.password(&account)));
@ -409,10 +437,26 @@ mod tests {
assert!(ap.unlock_account_timed(kp.address(), "test1".into(), 60000).is_err()); assert!(ap.unlock_account_timed(kp.address(), "test1".into(), 60000).is_err());
assert!(ap.unlock_account_timed(kp.address(), "test".into(), 60000).is_ok()); assert!(ap.unlock_account_timed(kp.address(), "test".into(), 60000).is_ok());
assert!(ap.sign(kp.address(), None, Default::default()).is_ok()); assert!(ap.sign(kp.address(), None, Default::default()).is_ok());
ap.unlocked.lock().get_mut(&kp.address()).unwrap().unlock = Unlock::Timed(Instant::now()); ap.unlocked.write().get_mut(&kp.address()).unwrap().unlock = Unlock::Timed(Instant::now());
assert!(ap.sign(kp.address(), None, Default::default()).is_err()); assert!(ap.sign(kp.address(), None, Default::default()).is_err());
} }
#[test]
fn should_sign_and_return_token() {
// given
let kp = Random.generate().unwrap();
let ap = AccountProvider::transient_provider();
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
// when
let (_signature, token) = ap.sign_with_token(kp.address(), "test".into(), Default::default()).unwrap();
// then
ap.sign_with_token(kp.address(), token.clone(), Default::default())
.expect("First usage of token should be correct.");
assert!(ap.sign_with_token(kp.address(), token, Default::default()).is_err(), "Second usage of the same token should fail.");
}
#[test] #[test]
fn should_set_dapps_addresses() { fn should_set_dapps_addresses() {
// given // given

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify
@ -266,7 +266,8 @@ impl<'x> OpenBlock<'x> {
r.block.base.header.set_extra_data(extra_data); r.block.base.header.set_extra_data(extra_data);
r.block.base.header.note_dirty(); r.block.base.header.note_dirty();
engine.populate_from_parent(&mut r.block.base.header, parent, gas_range_target.0, gas_range_target.1); let gas_floor_target = ::std::cmp::max(gas_range_target.0, engine.params().min_gas_limit);
engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target, gas_range_target.1);
engine.on_new_block(&mut r.block); engine.on_new_block(&mut r.block);
Ok(r) Ok(r)
} }

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. // Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity. // This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify // Parity is free software: you can redistribute it and/or modify

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