Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e810e79327 | ||
|
|
10e17a5009 | ||
|
|
96f68b5130 | ||
|
|
0c6670d918 | ||
|
|
abf60cdf31 | ||
|
|
d229fd4c95 | ||
|
|
1b36add0c6 | ||
|
|
b22ff1ad03 | ||
|
|
9f0ba42f25 | ||
|
|
a3992dd347 | ||
|
|
b94fc2ed62 | ||
|
|
7d38fcaab9 | ||
|
|
be920b490f | ||
|
|
2467408a30 | ||
|
|
a71766db8f | ||
|
|
2dc9c23d07 | ||
|
|
e152d012b4 |
@@ -1,2 +0,0 @@
|
||||
[target.armv7-unknown-linux-gnueabihf]
|
||||
linker= "arm-linux-gnueabihf-gcc"
|
||||
@@ -43,6 +43,41 @@ linux-stable:
|
||||
paths:
|
||||
- target/release/parity
|
||||
name: "stable-x86_64-unknown-linux-gnu_parity"
|
||||
linux-stable-debian:
|
||||
stage: build
|
||||
image: ethcore/rust-debian:latest
|
||||
only:
|
||||
- beta
|
||||
- tags
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- cargo build -j $(nproc) --release $CARGOFLAGS
|
||||
- strip target/release/parity
|
||||
- export SHA3=$(target/release/parity tools hash target/release/parity)
|
||||
- md5sum target/release/parity > parity.md5
|
||||
- sh scripts/deb-build.sh amd64
|
||||
- cp target/release/parity deb/usr/bin/parity
|
||||
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
|
||||
- dpkg-deb -b deb "parity_"$VER"_amd64.deb"
|
||||
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity --body target/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/parity.md5 --body parity.md5
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/"parity_"$VER"_amd64.deb" --body "parity_"$VER"_amd64.deb"
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu/"parity_"$VER"_amd64.deb.md5" --body "parity_"$VER"_amd64.deb.md5"
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
- curl --data "commit=$CI_BUILD_REF&sha3=$SHA3&filename=parity&secret=$RELEASES_SECRET" http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/x86_64-unknown-debian-gnu
|
||||
tags:
|
||||
- rust
|
||||
- rust-debian
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity
|
||||
name: "stable-x86_64-unknown-debian-gnu_parity"
|
||||
linux-beta:
|
||||
stage: build
|
||||
image: ethcore/rust:beta
|
||||
@@ -227,41 +262,6 @@ linux-arm:
|
||||
- target/arm-unknown-linux-gnueabihf/release/parity
|
||||
name: "arm-unknown-linux-gnueabihf_parity"
|
||||
allow_failure: true
|
||||
linux-armv6:
|
||||
stage: build
|
||||
image: ethcore/rust-armv6:latest
|
||||
only:
|
||||
- beta
|
||||
- tags
|
||||
- stable
|
||||
- triggers
|
||||
script:
|
||||
- export CC=arm-linux-gnueabi-gcc
|
||||
- export CXX=arm-linux-gnueabi-g++
|
||||
- export HOST_CC=gcc
|
||||
- export HOST_CXX=g++
|
||||
- rm -rf .cargo
|
||||
- mkdir -p .cargo
|
||||
- echo "[target.arm-unknown-linux-gnueabi]" >> .cargo/config
|
||||
- echo "linker= \"arm-linux-gnueabi-gcc\"" >> .cargo/config
|
||||
- cat .cargo/config
|
||||
- cargo build --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
|
||||
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
|
||||
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
|
||||
- aws configure set aws_access_key_id $s3_key
|
||||
- aws configure set aws_secret_access_key $s3_secret
|
||||
- if [[ $CI_BUILD_REF_NAME =~ ^(master|beta|stable)$ ]]; then export S3_BUCKET=builds-parity-published; else export S3_BUCKET=builds-parity; fi
|
||||
- aws s3 rm --recursive s3://$S3_BUCKET/$CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity --body target/arm-unknown-linux-gnueabi/release/parity
|
||||
- aws s3api put-object --bucket $S3_BUCKET --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity.md5 --body parity.md5
|
||||
tags:
|
||||
- rust
|
||||
- rust-arm
|
||||
artifacts:
|
||||
paths:
|
||||
- target/arm-unknown-linux-gnueabi/release/parity
|
||||
name: "arm-unknown-linux-gnueabi_parity"
|
||||
allow_failure: true
|
||||
linux-aarch64:
|
||||
stage: build
|
||||
image: ethcore/rust-aarch64:latest
|
||||
@@ -399,18 +399,19 @@ windows:
|
||||
- zip win-installer.zip InstallParity.exe InstallParity.exe.md5
|
||||
- md5sums win-installer.zip > win-installer.zip.md5
|
||||
- cd ..\target\release\
|
||||
- md5sums parity.exe parity.pdb > parity.md5
|
||||
- md5sums parity.exe > parity.md5
|
||||
- md5sums parity.exe > parity.exe.md5
|
||||
- zip parity.zip parity.exe parity.pdb parity.md5
|
||||
- zip parity.zip parity.exe parity.md5
|
||||
- md5sums parity.zip > parity.zip.md5
|
||||
- cd ..\..
|
||||
- aws configure set aws_access_key_id %s3_key%
|
||||
- aws configure set aws_secret_access_key %s3_secret%
|
||||
- echo %CI_BUILD_REF_NAME%
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published || set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "master" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "beta" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %CI_BUILD_REF_NAME% | findstr /R "stable" >nul 2>&1 && set S3_BUCKET=builds-parity-published|| set S3_BUCKET=builds-parity
|
||||
- echo %S3_BUCKET%
|
||||
- echo s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc
|
||||
- aws s3 rm --recursive s3://%S3_BUCKET%/%CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe --body target\release\parity.exe
|
||||
- aws s3api put-object --bucket %S3_BUCKET% --key %CI_BUILD_REF_NAME%/x86_64-pc-windows-msvc/parity.exe.md5 --body target\release\parity.exe.md5
|
||||
@@ -425,9 +426,22 @@ windows:
|
||||
artifacts:
|
||||
paths:
|
||||
- target/release/parity.exe
|
||||
- target/release/parity.pdb
|
||||
- nsis/InstallParity.exe
|
||||
name: "x86_64-pc-windows-msvc_parity"
|
||||
docker-build:
|
||||
stage: build
|
||||
only:
|
||||
- tags
|
||||
before_script:
|
||||
- docker info
|
||||
script:
|
||||
- cd docker/hub
|
||||
- if [ "$CI_BUILD_REF_NAME" == "nightly" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
|
||||
- docker login -u $Docker_Hub_User -p $Docker_Hub_Pass
|
||||
- docker build --no-cache=true --tag ethcore/parity:$DOCKER_TAG .
|
||||
- docker push ethcore/parity:$DOCKER_TAG
|
||||
tags:
|
||||
- docker
|
||||
test-darwin:
|
||||
stage: test
|
||||
only:
|
||||
|
||||
30
Cargo.lock
generated
30
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
||||
[root]
|
||||
name = "parity"
|
||||
version = "1.4.8"
|
||||
version = "1.4.12"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -21,7 +21,7 @@ dependencies = [
|
||||
"ethcore-rpc 1.4.0",
|
||||
"ethcore-signer 1.4.0",
|
||||
"ethcore-stratum 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"ethsync 1.4.0",
|
||||
"fdlimit 0.1.0",
|
||||
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -289,7 +289,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.4.0",
|
||||
"ethcore-ipc-codegen 1.4.0",
|
||||
"ethcore-ipc-nano 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"ethstore 0.1.0",
|
||||
@@ -336,7 +336,7 @@ dependencies = [
|
||||
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.4.0",
|
||||
"ethcore-rpc 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"fetch 0.1.0",
|
||||
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
|
||||
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -381,7 +381,7 @@ name = "ethcore-ipc"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"ethcore-devtools 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -428,7 +428,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.4.0",
|
||||
"ethcore-ipc-codegen 1.4.0",
|
||||
"ethcore-ipc-nano 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -439,7 +439,7 @@ name = "ethcore-logger"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -455,7 +455,7 @@ dependencies = [
|
||||
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-devtools 1.4.0",
|
||||
"ethcore-io 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -482,7 +482,7 @@ dependencies = [
|
||||
"ethcore-devtools 1.4.0",
|
||||
"ethcore-io 1.4.0",
|
||||
"ethcore-ipc 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"ethcrypto 0.1.0",
|
||||
"ethjson 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
@@ -511,7 +511,7 @@ dependencies = [
|
||||
"ethcore-devtools 1.4.0",
|
||||
"ethcore-io 1.4.0",
|
||||
"ethcore-rpc 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -530,7 +530,7 @@ dependencies = [
|
||||
"ethcore-ipc 1.4.0",
|
||||
"ethcore-ipc-codegen 1.4.0",
|
||||
"ethcore-ipc-nano 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"json-tcp-server 0.1.0 (git+https://github.com/ethcore/json-tcp-server)",
|
||||
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -541,7 +541,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-util"
|
||||
version = "1.4.8"
|
||||
version = "1.4.12"
|
||||
dependencies = [
|
||||
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -590,7 +590,7 @@ dependencies = [
|
||||
name = "ethjson"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -643,7 +643,7 @@ dependencies = [
|
||||
"ethcore-ipc-codegen 1.4.0",
|
||||
"ethcore-ipc-nano 1.4.0",
|
||||
"ethcore-network 1.4.0",
|
||||
"ethcore-util 1.4.8",
|
||||
"ethcore-util 1.4.12",
|
||||
"heapsize 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.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1249,7 +1249,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#b2c6ed0ad2d92901bb95ac9203632ffc86bbda24"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#8ac9a3a3fc5a26e7f43fd0535018cc263cdfde64"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
description = "Ethcore client."
|
||||
name = "parity"
|
||||
version = "1.4.8"
|
||||
version = "1.4.12"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
78
docker/hub/Dockerfile
Normal file
78
docker/hub/Dockerfile
Normal file
@@ -0,0 +1,78 @@
|
||||
FROM ubuntu:14.04
|
||||
MAINTAINER Parity Technologies <devops@parity.io>
|
||||
WORKDIR /build
|
||||
# install tools and dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --force-yes --no-install-recommends \
|
||||
# make
|
||||
build-essential \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
make \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
g++ \
|
||||
gcc \
|
||||
libc6 \
|
||||
libc6-dev \
|
||||
binutils \
|
||||
file \
|
||||
openssl \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
dpkg-dev \
|
||||
# evmjit dependencies
|
||||
zlib1g-dev \
|
||||
libedit-dev \
|
||||
libudev-dev &&\
|
||||
# cmake and llvm ppa's. then update ppa's
|
||||
add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||
apt-get update && \
|
||||
apt-get install -y --force-yes cmake llvm-3.7-dev && \
|
||||
# install evmjit
|
||||
git clone https://github.com/debris/evmjit && \
|
||||
cd evmjit && \
|
||||
mkdir build && cd build && \
|
||||
cmake .. && make && make install && cd && \
|
||||
# install rustup
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y && \
|
||||
# rustup directory
|
||||
PATH=/root/.cargo/bin:$PATH && \
|
||||
# show backtraces
|
||||
RUST_BACKTRACE=1 && \
|
||||
# build parity
|
||||
cd /build&&git clone https://github.com/ethcore/parity && \
|
||||
cd parity && \
|
||||
git pull&& \
|
||||
git checkout $CI_BUILD_REF_NAME && \
|
||||
cargo build --verbose --release && \
|
||||
#ls /build/parity/target/release/parity && \
|
||||
strip /build/parity/target/release/parity && \
|
||||
file /build/parity/target/release/parity&&mkdir -p /parity&& cp /build/parity/target/release/parity /parity&&\
|
||||
#cleanup Docker image
|
||||
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
|
||||
apt-get purge -y \
|
||||
# make
|
||||
build-essential \
|
||||
# add-apt-repository
|
||||
software-properties-common \
|
||||
make \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
g++ \
|
||||
gcc \
|
||||
binutils \
|
||||
file \
|
||||
pkg-config \
|
||||
dpkg-dev \
|
||||
# evmjit dependencies
|
||||
zlib1g-dev \
|
||||
libedit-dev \
|
||||
cmake llvm-3.7-dev&&\
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
# setup ENTRYPOINT
|
||||
EXPOSE 8080 8545 8180
|
||||
ENTRYPOINT ["/parity/parity"]
|
||||
@@ -14,7 +14,8 @@
|
||||
"eip155Transition": 10,
|
||||
"eip160Transition": 10,
|
||||
"eip161abcTransition": 10,
|
||||
"eip161dTransition": 10
|
||||
"eip161dTransition": 10,
|
||||
"maxCodeSize": 24576
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@ use evm::Schedule;
|
||||
use ethjson;
|
||||
use rlp::{self, UntrustedRlp, View};
|
||||
|
||||
/// Parity tries to round block.gas_limit to multiple of this constant
|
||||
pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]);
|
||||
|
||||
/// Ethash params.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct EthashParams {
|
||||
@@ -176,16 +179,25 @@ impl Engine for Ethash {
|
||||
let gas_limit = {
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
|
||||
if gas_limit < gas_floor_target {
|
||||
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
|
||||
let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into();
|
||||
let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into();
|
||||
let gas_limit = if gas_limit < gas_floor_target {
|
||||
let gas_limit = min(gas_floor_target, upper_limit);
|
||||
round_block_gas_limit(gas_limit, lower_limit, upper_limit)
|
||||
} else if gas_limit > gas_ceil_target {
|
||||
max(gas_ceil_target, gas_limit - gas_limit / bound_divisor + 1.into())
|
||||
let gas_limit = max(gas_ceil_target, lower_limit);
|
||||
round_block_gas_limit(gas_limit, lower_limit, upper_limit)
|
||||
} else {
|
||||
min(gas_ceil_target,
|
||||
max(gas_floor_target,
|
||||
gas_limit - gas_limit / bound_divisor + 1.into() +
|
||||
(header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor))
|
||||
}
|
||||
let total_lower_limit = max(lower_limit, gas_floor_target);
|
||||
let total_upper_limit = min(upper_limit, gas_ceil_target);
|
||||
let gas_limit = max(gas_floor_target, min(total_upper_limit,
|
||||
lower_limit + (header.gas_used().clone() * 6.into() / 5.into()) / bound_divisor));
|
||||
round_block_gas_limit(gas_limit, total_lower_limit, total_upper_limit)
|
||||
};
|
||||
// ensure that we are not violating protocol limits
|
||||
debug_assert!(gas_limit >= lower_limit);
|
||||
debug_assert!(gas_limit <= upper_limit);
|
||||
gas_limit
|
||||
};
|
||||
header.set_difficulty(difficulty);
|
||||
header.set_gas_limit(gas_limit);
|
||||
@@ -327,7 +339,24 @@ impl Engine for Ethash {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self
|
||||
// Try to round gas_limit a bit so that:
|
||||
// 1) it will still be in desired range
|
||||
// 2) it will be a nearest (with tendency to increase) multiple of PARITY_GAS_LIMIT_DETERMINANT
|
||||
fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256) -> U256 {
|
||||
let increased_gas_limit = gas_limit + (PARITY_GAS_LIMIT_DETERMINANT - gas_limit % PARITY_GAS_LIMIT_DETERMINANT);
|
||||
if increased_gas_limit > upper_limit {
|
||||
let decreased_gas_limit = increased_gas_limit - PARITY_GAS_LIMIT_DETERMINANT;
|
||||
if decreased_gas_limit < lower_limit {
|
||||
gas_limit
|
||||
} else {
|
||||
decreased_gas_limit
|
||||
}
|
||||
} else {
|
||||
increased_gas_limit
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
||||
impl Ethash {
|
||||
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
||||
const EXP_DIFF_PERIOD: u64 = 100000;
|
||||
@@ -432,11 +461,12 @@ mod tests {
|
||||
use util::*;
|
||||
use block::*;
|
||||
use tests::helpers::*;
|
||||
use engines::Engine;
|
||||
use env_info::EnvInfo;
|
||||
use error::{BlockError, Error};
|
||||
use header::Header;
|
||||
use super::super::{new_morden, new_homestead_test};
|
||||
use super::{Ethash, EthashParams};
|
||||
use super::{Ethash, EthashParams, PARITY_GAS_LIMIT_DETERMINANT};
|
||||
use rlp;
|
||||
|
||||
#[test]
|
||||
@@ -776,4 +806,65 @@ mod tests {
|
||||
ethash.calculate_difficulty(&header, &parent_header)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gas_limit_is_multiple_of_determinant() {
|
||||
let spec = new_homestead_test();
|
||||
let ethash = Ethash::new(spec.params, get_default_ethash_params(), BTreeMap::new());
|
||||
let mut parent = Header::new();
|
||||
let mut header = Header::new();
|
||||
header.set_number(1);
|
||||
|
||||
// this test will work for this constant only
|
||||
assert_eq!(PARITY_GAS_LIMIT_DETERMINANT, U256::from(37));
|
||||
|
||||
// when parent.gas_limit < gas_floor_target:
|
||||
parent.set_gas_limit(U256::from(50_000));
|
||||
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||
assert_eq!(*header.gas_limit(), U256::from(50_024));
|
||||
|
||||
// when parent.gas_limit > gas_ceil_target:
|
||||
parent.set_gas_limit(U256::from(250_000));
|
||||
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||
assert_eq!(*header.gas_limit(), U256::from(249_787));
|
||||
|
||||
// when parent.gas_limit is in miner's range
|
||||
header.set_gas_used(U256::from(150_000));
|
||||
parent.set_gas_limit(U256::from(150_000));
|
||||
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(200_000));
|
||||
assert_eq!(*header.gas_limit(), U256::from(150_035));
|
||||
|
||||
// when parent.gas_limit is in miner's range
|
||||
// && we can NOT increase it to be multiple of constant
|
||||
header.set_gas_used(U256::from(150_000));
|
||||
parent.set_gas_limit(U256::from(150_000));
|
||||
ethash.populate_from_parent(&mut header, &parent, U256::from(100_000), U256::from(150_002));
|
||||
assert_eq!(*header.gas_limit(), U256::from(149_998));
|
||||
|
||||
// when parent.gas_limit is in miner's range
|
||||
// && we can NOT increase it to be multiple of constant
|
||||
// && we can NOT decrease it to be multiple of constant
|
||||
header.set_gas_used(U256::from(150_000));
|
||||
parent.set_gas_limit(U256::from(150_000));
|
||||
ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002));
|
||||
assert_eq!(*header.gas_limit(), U256::from(150_002));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficulty_max_timestamp() {
|
||||
let spec = new_homestead_test();
|
||||
let ethparams = get_default_ethash_params();
|
||||
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
|
||||
|
||||
let mut parent_header = Header::default();
|
||||
parent_header.set_number(1000000);
|
||||
parent_header.set_difficulty(U256::from_str("b69de81a22b").unwrap());
|
||||
parent_header.set_timestamp(1455404053);
|
||||
let mut header = Header::default();
|
||||
header.set_number(parent_header.number() + 1);
|
||||
header.set_timestamp(u64::max_value());
|
||||
|
||||
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
|
||||
assert_eq!(U256::from(12543204905719u64), difficulty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ impl Decodable for Header {
|
||||
number: try!(r.val_at(8)),
|
||||
gas_limit: try!(r.val_at(9)),
|
||||
gas_used: try!(r.val_at(10)),
|
||||
timestamp: try!(r.val_at(11)),
|
||||
timestamp: min(try!(r.val_at::<U256>(11)), u64::max_value().into()).as_u64(),
|
||||
extra_data: try!(r.val_at(12)),
|
||||
seal: vec![],
|
||||
hash: RefCell::new(Some(r.as_raw().sha3())),
|
||||
|
||||
@@ -150,7 +150,7 @@ impl GasPriceCalibrator {
|
||||
if Instant::now() >= self.next_calibration {
|
||||
let usd_per_tx = self.options.usd_per_tx;
|
||||
trace!(target: "miner", "Getting price info");
|
||||
if let Ok(_) = PriceInfo::get(move |price: PriceInfo| {
|
||||
PriceInfo::get(move |price: PriceInfo| {
|
||||
trace!(target: "miner", "Price info arrived: {:?}", price);
|
||||
let usd_per_eth = price.ethusd;
|
||||
let wei_per_usd: f32 = 1.0e18 / usd_per_eth;
|
||||
@@ -158,11 +158,9 @@ impl GasPriceCalibrator {
|
||||
let wei_per_gas: f32 = wei_per_usd * usd_per_tx / gas_per_tx;
|
||||
info!(target: "miner", "Updated conversion rate to Ξ1 = {} ({} wei/gas)", Colour::White.bold().paint(format!("US${}", usd_per_eth)), Colour::Yellow.bold().paint(format!("{}", wei_per_gas)));
|
||||
set_price(U256::from(wei_per_gas as u64));
|
||||
}) {
|
||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||
} else {
|
||||
warn!(target: "miner", "Unable to update Ether price.");
|
||||
}
|
||||
});
|
||||
|
||||
self.next_calibration = Instant::now() + self.options.recalibration_period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::time::Duration;
|
||||
use std::str::FromStr;
|
||||
use std::sync::mpsc;
|
||||
use hyper::client::{Handler, Request, Response, Client};
|
||||
use hyper::{Next, Encoder, Decoder};
|
||||
use hyper::{Url, Next, Encoder, Decoder};
|
||||
use hyper::net::HttpStream;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -29,12 +29,12 @@ pub struct PriceInfo {
|
||||
pub ethusd: f32,
|
||||
}
|
||||
|
||||
pub struct SetPriceHandler<F: Fn(PriceInfo) + Sync + Send + 'static> {
|
||||
pub struct SetPriceHandler<F> {
|
||||
set_price: F,
|
||||
channel: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
impl<F: Fn(PriceInfo) + Sync + Send + 'static> Drop for SetPriceHandler<F> {
|
||||
impl<F> Drop for SetPriceHandler<F> {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.channel.send(());
|
||||
}
|
||||
@@ -47,37 +47,61 @@ impl<F: Fn(PriceInfo) + Sync + Send + 'static> Handler<HttpStream> for SetPriceH
|
||||
|
||||
fn on_response_readable(&mut self, r: &mut Decoder<HttpStream>) -> Next {
|
||||
let mut body = String::new();
|
||||
let _ = r.read_to_string(&mut body).ok()
|
||||
.and_then(|_| Json::from_str(&body).ok())
|
||||
.and_then(|json| json.find_path(&["result", "ethusd"])
|
||||
.and_then(|obj| match *obj {
|
||||
Json::String(ref s) => Some((self.set_price)(PriceInfo {
|
||||
ethusd: FromStr::from_str(s)
|
||||
.expect("Etherscan API will always return properly formatted price; qed")
|
||||
})),
|
||||
_ => None,
|
||||
}));
|
||||
let info = r.read_to_string(&mut body)
|
||||
.map_err(|e| format!("Unable to read response: {:?}", e))
|
||||
.and_then(|_| self.process_response(&body));
|
||||
|
||||
if let Err(e) = info {
|
||||
warn!("Failed to auto-update latest ETH price: {:?}", e);
|
||||
}
|
||||
Next::end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Fn(PriceInfo) + Sync + Send + 'static> SetPriceHandler<F> {
|
||||
fn process_response(&self, body: &str) -> Result<(), String> {
|
||||
let json = Json::from_str(body).map_err(|e| format!("Invalid JSON returned: {:?}", e))?;
|
||||
let obj = json.find_path(&["result", "ethusd"]).ok_or("USD price not found".to_owned())?;
|
||||
let ethusd = match *obj {
|
||||
Json::String(ref s) => FromStr::from_str(s).ok(),
|
||||
_ => None,
|
||||
}.ok_or("Unexpected price format.".to_owned())?;
|
||||
|
||||
(self.set_price)(PriceInfo {
|
||||
ethusd: ethusd,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PriceInfo {
|
||||
pub fn get<F: Fn(PriceInfo) + Sync + Send + 'static>(set_price: F) -> Result<(), ()> {
|
||||
// TODO: Handle each error type properly
|
||||
let client = try!(Client::new().map_err(|_| ()));
|
||||
pub fn get<F: Fn(PriceInfo) + Sync + Send + 'static>(set_price: F) {
|
||||
thread::spawn(move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let url = FromStr::from_str("http://api.etherscan.io/api?module=stats&action=ethprice")
|
||||
.expect("string known to be a valid URL; qed");
|
||||
let _ = client.request(
|
||||
url,
|
||||
SetPriceHandler {
|
||||
set_price: set_price,
|
||||
channel: tx,
|
||||
}).ok().and_then(|_| rx.recv().ok());
|
||||
client.close();
|
||||
|
||||
if let Err(e) = Self::request(url, set_price) {
|
||||
warn!("Failed to auto-update latest ETH price: {:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn request<F: Fn(PriceInfo) + Send + Sync + 'static>(url: Url, set_price: F) -> Result<(), String> {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let client = Client::new().map_err(|e| format!("Unable to start client: {:?}", e))?;
|
||||
|
||||
client.request(
|
||||
url,
|
||||
SetPriceHandler {
|
||||
set_price: set_price,
|
||||
channel: tx,
|
||||
},
|
||||
).map_err(|_| "Request failed.".to_owned())?;
|
||||
|
||||
// Wait for exit
|
||||
let _ = rx.recv().map_err(|e| format!("Request interrupted: {:?}", e))?;
|
||||
client.close();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -93,7 +117,7 @@ fn should_get_price_info() {
|
||||
let done = Arc::new((Mutex::new(PriceInfo { ethusd: 0f32 }), Condvar::new()));
|
||||
let rdone = done.clone();
|
||||
|
||||
PriceInfo::get(move |price| { let mut p = rdone.0.lock(); *p = price; rdone.1.notify_one(); }).unwrap();
|
||||
PriceInfo::get(move |price| { let mut p = rdone.0.lock(); *p = price; rdone.1.notify_one(); });
|
||||
let mut p = done.0.lock();
|
||||
let t = done.1.wait_for(&mut p, Duration::from_millis(10000));
|
||||
assert!(!t.timed_out());
|
||||
|
||||
@@ -186,7 +186,7 @@ pub mod headers {
|
||||
type Verified = Header;
|
||||
|
||||
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error> {
|
||||
verify_header_params(&input, engine).map(|_| input)
|
||||
verify_header_params(&input, engine, true).map(|_| input)
|
||||
}
|
||||
|
||||
fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> {
|
||||
|
||||
@@ -97,7 +97,6 @@ pub struct VerificationQueue<K: Kind> {
|
||||
engine: Arc<Engine>,
|
||||
more_to_verify: Arc<SCondvar>,
|
||||
verification: Arc<Verification<K>>,
|
||||
verifiers: Vec<JoinHandle<()>>,
|
||||
deleting: Arc<AtomicBool>,
|
||||
ready_signal: Arc<QueueSignal>,
|
||||
empty: Arc<SCondvar>,
|
||||
@@ -105,6 +104,7 @@ pub struct VerificationQueue<K: Kind> {
|
||||
max_queue_size: usize,
|
||||
max_mem_use: usize,
|
||||
total_difficulty: RwLock<U256>,
|
||||
verifier_handles: Vec<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
struct QueueSignal {
|
||||
@@ -186,7 +186,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
let empty = Arc::new(SCondvar::new());
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
|
||||
let mut verifiers: Vec<JoinHandle<()>> = Vec::new();
|
||||
let mut verifier_handles: Vec<JoinHandle<()>> = Vec::new();
|
||||
let thread_count = max(::num_cpus::get(), 3) - 2;
|
||||
for i in 0..thread_count {
|
||||
let verification = verification.clone();
|
||||
@@ -196,7 +196,7 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
let empty = empty.clone();
|
||||
let deleting = deleting.clone();
|
||||
let panic_handler = panic_handler.clone();
|
||||
verifiers.push(
|
||||
verifier_handles.push(
|
||||
thread::Builder::new()
|
||||
.name(format!("Verifier #{}", i))
|
||||
.spawn(move || {
|
||||
@@ -213,13 +213,13 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
ready_signal: ready_signal.clone(),
|
||||
more_to_verify: more_to_verify.clone(),
|
||||
verification: verification.clone(),
|
||||
verifiers: verifiers,
|
||||
deleting: deleting.clone(),
|
||||
processing: RwLock::new(HashMap::new()),
|
||||
empty: empty.clone(),
|
||||
max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
||||
max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT),
|
||||
total_difficulty: RwLock::new(0.into()),
|
||||
verifier_handles: verifier_handles,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,8 +531,15 @@ impl<K: Kind> Drop for VerificationQueue<K> {
|
||||
trace!(target: "shutdown", "[VerificationQueue] Closing...");
|
||||
self.clear();
|
||||
self.deleting.store(true, AtomicOrdering::Release);
|
||||
self.more_to_verify.notify_all();
|
||||
for t in self.verifiers.drain(..) {
|
||||
|
||||
// acquire this lock to force threads to reach the waiting point
|
||||
// if they're in-between the exit check and the more_to_verify wait.
|
||||
{
|
||||
let _more = self.verification.more_to_verify.lock().unwrap();
|
||||
self.more_to_verify.notify_all();
|
||||
}
|
||||
|
||||
for t in self.verifier_handles.drain(..) {
|
||||
t.join().unwrap();
|
||||
}
|
||||
trace!(target: "shutdown", "[VerificationQueue] Closed.");
|
||||
|
||||
@@ -29,6 +29,7 @@ use header::{BlockNumber, Header};
|
||||
use rlp::{UntrustedRlp, View};
|
||||
use transaction::SignedTransaction;
|
||||
use views::BlockView;
|
||||
use time::get_time;
|
||||
|
||||
/// Preprocessed block data gathered in `verify_block_unordered` call
|
||||
pub struct PreverifiedBlock {
|
||||
@@ -50,12 +51,12 @@ impl HeapSizeOf for PreverifiedBlock {
|
||||
|
||||
/// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block
|
||||
pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> {
|
||||
try!(verify_header_params(&header, engine));
|
||||
try!(verify_header_params(&header, engine, true));
|
||||
try!(verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash()));
|
||||
try!(engine.verify_block_basic(&header, Some(bytes)));
|
||||
for u in try!(UntrustedRlp::new(bytes).at(2)).iter().map(|rlp| rlp.as_val::<Header>()) {
|
||||
let u = try!(u);
|
||||
try!(verify_header_params(&u, engine));
|
||||
try!(verify_header_params(&u, engine, false));
|
||||
try!(engine.verify_block_basic(&u, None));
|
||||
}
|
||||
// Verify transactions.
|
||||
@@ -194,7 +195,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
|
||||
}
|
||||
|
||||
/// Check basic header parameters.
|
||||
pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Error> {
|
||||
pub fn verify_header_params(header: &Header, engine: &Engine, is_full: bool) -> Result<(), Error> {
|
||||
if header.number() >= From::from(BlockNumber::max_value()) {
|
||||
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number() })))
|
||||
}
|
||||
@@ -209,6 +210,12 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro
|
||||
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
|
||||
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
|
||||
}
|
||||
if is_full {
|
||||
let max_time = get_time().sec as u64 + 30;
|
||||
if header.timestamp() > max_time {
|
||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@
|
||||
<key>GID</key>
|
||||
<integer>0</integer>
|
||||
<key>PATH</key>
|
||||
<string>../target/release/deps/ethstore</string>
|
||||
<string>../target/release/ethstore</string>
|
||||
<key>PATH_TYPE</key>
|
||||
<integer>3</integer>
|
||||
<key>PERMISSIONS</key>
|
||||
@@ -578,7 +578,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.4.8</string>
|
||||
<string>1.4.12</string>
|
||||
</dict>
|
||||
<key>UUID</key>
|
||||
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
|
||||
!define VERSIONMAJOR 1
|
||||
!define VERSIONMINOR 4
|
||||
!define VERSIONBUILD 8
|
||||
!define VERSIONBUILD 12
|
||||
!define ARGS "--warp"
|
||||
!define FIRST_START_ARGS "ui --warp --mode=passive"
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
643e43dbaf3050e8e22479a4112e4e79 target/release/parity
|
||||
@@ -1 +0,0 @@
|
||||
81fb6415b884badc17c15534271a457129a78564
|
||||
@@ -1 +0,0 @@
|
||||
7abf0c0c0f47873be9c1c4859d083ff4 parity_1.4.0_amd64.deb
|
||||
@@ -1 +0,0 @@
|
||||
34a11190d1457c0d32175c939cd43b9b9563b6f5
|
||||
@@ -1,2 +0,0 @@
|
||||
1f98044f343dd17447c4d73f00248bef parity_1.4.0_armhf.deb
|
||||
0e2dad031c1b2586bf21adecbf65bfea parity_1.4.0_armhf.deb
|
||||
@@ -566,7 +566,7 @@ impl ChainSync {
|
||||
if let (Some(ancient_block_hash), Some(ancient_block_number)) = (chain.ancient_block_hash, chain.ancient_block_number) {
|
||||
|
||||
trace!(target: "sync", "Downloading old blocks from {:?} (#{}) till {:?} (#{:?})", ancient_block_hash, ancient_block_number, chain.first_block_hash, chain.first_block_number);
|
||||
let mut downloader = BlockDownloader::new(true, &ancient_block_hash, ancient_block_number, pruning.history_size);
|
||||
let mut downloader = BlockDownloader::new(true, &ancient_block_hash, ancient_block_number, None);
|
||||
if let Some(hash) = chain.first_block_hash {
|
||||
trace!(target: "sync", "Downloader target set to {:?}", hash);
|
||||
downloader.set_target(&hash);
|
||||
@@ -1854,11 +1854,10 @@ impl ChainSync {
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn select_random_lagging_peers(&mut self, peers: &[PeerId]) -> Vec<PeerId> {
|
||||
use rand::Rng;
|
||||
fn select_random_peers(peers: &[PeerId]) -> Vec<PeerId> {
|
||||
// take sqrt(x) peers
|
||||
let mut peers = peers.to_vec();
|
||||
let mut count = (self.peers.len() as f64).powf(0.5).round() as usize;
|
||||
let mut count = (peers.len() as f64).powf(0.5).round() as usize;
|
||||
count = min(count, MAX_PEERS_PROPAGATION);
|
||||
count = max(count, MIN_PEERS_PROPAGATION);
|
||||
random::new().shuffle(&mut peers);
|
||||
@@ -1984,7 +1983,7 @@ impl ChainSync {
|
||||
let mut peers = self.get_lagging_peers(&chain_info, io);
|
||||
if sealed.is_empty() {
|
||||
let hashes = self.propagate_new_hashes(&chain_info, io, &peers);
|
||||
peers = self.select_random_lagging_peers(&peers);
|
||||
peers = ChainSync::select_random_peers(&peers);
|
||||
let blocks = self.propagate_blocks(&chain_info, io, sealed, &peers);
|
||||
if blocks != 0 || hashes != 0 {
|
||||
trace!(target: "sync", "Sent latest {} blocks and {} hashes to peers.", blocks, hashes);
|
||||
@@ -2018,19 +2017,13 @@ impl ChainSync {
|
||||
self.restart(io);
|
||||
}
|
||||
|
||||
if !is_syncing && !enacted.is_empty() {
|
||||
// Select random peers to re-broadcast transactions to.
|
||||
let mut random = random::new();
|
||||
let len = self.peers.len();
|
||||
let peers = random.gen_range(0, min(len, 3));
|
||||
trace!(target: "sync", "Re-broadcasting transactions to {} random peers.", peers);
|
||||
|
||||
for _ in 0..peers {
|
||||
let peer = random.gen_range(0, len);
|
||||
self.peers.values_mut().nth(peer).map(|mut peer_info| {
|
||||
peer_info.last_sent_transactions.clear()
|
||||
});
|
||||
}
|
||||
if !is_syncing && !enacted.is_empty() && !self.peers.is_empty() {
|
||||
// Select random peer to re-broadcast transactions to.
|
||||
let peer = random::new().gen_range(0, self.peers.len());
|
||||
trace!(target: "sync", "Re-broadcasting transactions to a random peer.");
|
||||
self.peers.values_mut().nth(peer).map(|mut peer_info|
|
||||
peer_info.last_sent_transactions.clear()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2392,6 +2385,26 @@ mod tests {
|
||||
assert_eq!(0x02, io.queue[0].packet_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_fail_for_no_peers() {
|
||||
let mut client = TestBlockChainClient::new();
|
||||
client.add_blocks(100, EachBlockWith::Uncle);
|
||||
client.insert_transaction_to_queue();
|
||||
// Sync with no peers
|
||||
let mut sync = ChainSync::new(SyncConfig::default(), &client);
|
||||
let mut queue = VecDeque::new();
|
||||
let ss = TestSnapshotService::new();
|
||||
let mut io = TestIo::new(&mut client, &ss, &mut queue, None);
|
||||
let peer_count = sync.propagate_new_transactions(&mut io);
|
||||
sync.chain_new_blocks(&mut io, &[], &[], &[], &[], &[]);
|
||||
// Try to propagate same transactions for the second time
|
||||
let peer_count2 = sync.propagate_new_transactions(&mut io);
|
||||
|
||||
assert_eq!(0, io.queue.len());
|
||||
assert_eq!(0, peer_count);
|
||||
assert_eq!(0, peer_count2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagates_transactions_without_alternating() {
|
||||
let mut client = TestBlockChainClient::new();
|
||||
|
||||
@@ -3,7 +3,7 @@ description = "Ethcore utility library"
|
||||
homepage = "http://ethcore.io"
|
||||
license = "GPL-3.0"
|
||||
name = "ethcore-util"
|
||||
version = "1.4.8"
|
||||
version = "1.4.12"
|
||||
authors = ["Ethcore <admin@ethcore.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@@ -158,8 +158,8 @@ impl<Socket: GenericSocket> GenericConnection<Socket> {
|
||||
}
|
||||
if self.send_queue.is_empty() {
|
||||
self.interest.remove(Ready::writable());
|
||||
try!(io.update_registration(self.token));
|
||||
}
|
||||
try!(io.update_registration(self.token));
|
||||
Ok(r)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ pub fn version() -> String {
|
||||
let date_dash = if commit_date.is_empty() { "" } else { "-" };
|
||||
let env = Target::env();
|
||||
let env_dash = if env.is_empty() { "" } else { "-" };
|
||||
format!("Parity/v{}-beta{}{}{}{}/{}-{}{}{}/rustc{}", env!("CARGO_PKG_VERSION"), sha3_dash, sha3, date_dash, commit_date, Target::arch(), Target::os(), env_dash, env, rustc_version())
|
||||
format!("Parity/v{}-stable{}{}{}{}/{}-{}{}{}/rustc{}", env!("CARGO_PKG_VERSION"), sha3_dash, sha3, date_dash, commit_date, Target::arch(), Target::os(), env_dash, env, rustc_version())
|
||||
}
|
||||
|
||||
/// Get the standard version data for this software.
|
||||
|
||||
@@ -23,7 +23,7 @@ const SNAPPY_OK: c_int = 0;
|
||||
const SNAPPY_INVALID_INPUT: c_int = 1;
|
||||
const SNAPPY_BUFFER_TOO_SMALL: c_int = 2;
|
||||
|
||||
#[link(name = "snappy")]
|
||||
#[link(name = "snappy", kind = "static")]
|
||||
extern {
|
||||
fn snappy_compress(
|
||||
input: *const c_char,
|
||||
@@ -154,4 +154,4 @@ pub fn decompress_into(input: &[u8], output: &mut Vec<u8>) -> Result<usize, Inva
|
||||
pub fn validate_compressed_buffer(input: &[u8]) -> bool {
|
||||
let status = unsafe { snappy_validate_compressed_buffer(input.as_ptr() as *const c_char, input.len() as size_t )};
|
||||
status == SNAPPY_OK
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user