Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
491f17f149 | ||
|
aad068d2c6 | ||
|
bee2cb8fb4 | ||
|
18ddd7c249 | ||
|
d35f4c1f0d | ||
|
52fe28a052 | ||
|
8e347b2602 | ||
|
a5dcaf7d21 | ||
|
cb09330cb3 | ||
|
363ad10906 | ||
|
d147700046 |
294
.gitlab-ci.yml
294
.gitlab-ci.yml
@ -1,37 +1,22 @@
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- package
|
||||
- publish
|
||||
- docs
|
||||
- optional
|
||||
|
||||
image: parity/rust:gitlab-ci
|
||||
|
||||
variables:
|
||||
CI_SERVER_NAME: "GitLab CI"
|
||||
CARGO_HOME: "${CI_PROJECT_DIR}/cargo"
|
||||
|
||||
BUILD_TARGET: ubuntu
|
||||
BUILD_ARCH: amd64
|
||||
CARGO_HOME: "${CI_PROJECT_DIR}/.cargo"
|
||||
CARGO_TARGET: x86_64-unknown-linux-gnu
|
||||
|
||||
cache:
|
||||
key: "${CI_JOB_NAME}"
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/target/
|
||||
- ${CI_PROJECT_DIR}/cargo/
|
||||
|
||||
.releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries")
|
||||
only: &releaseable_branches
|
||||
- master
|
||||
- stable
|
||||
- beta
|
||||
- tags
|
||||
|
||||
.publishable_branches: # list of git refs for publishing builds to the "production" locations
|
||||
only: &publishable_branches
|
||||
- nightly # Our nightly builds from schedule, on `master`
|
||||
- "v2*" # Our version tags
|
||||
- schedules
|
||||
|
||||
.collect_artifacts: &collect_artifacts
|
||||
artifacts:
|
||||
@ -41,68 +26,24 @@ cache:
|
||||
paths:
|
||||
- artifacts/
|
||||
|
||||
.determine_version:
|
||||
before_script: &determine_version
|
||||
- >
|
||||
VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' < Cargo.toml)";
|
||||
if [ "${CI_COMMIT_REF_NAME}" = "nightly" ]; then
|
||||
COMMIT_REF_SHORT="echo ${CI_COMMIT_REF} | grep -oE '^.{7}')";
|
||||
DATE_STRING="$(date +%Y%m%d)";
|
||||
export VERSION="${VERSION}-${COMMIT_REF_SHORT}-${DATE_STRING}";
|
||||
fi;
|
||||
export VERSION;
|
||||
echo "Version: $VERSION"
|
||||
.determine_version: &determine_version
|
||||
- VERSION="$(sed -r -n '1,/^version/s/^version = "([^"]+)".*$/\1/p' Cargo.toml)"
|
||||
- DATE_STR="$(date +%Y%m%d)"
|
||||
- ID_SHORT="$(echo ${CI_COMMIT_SHA} | cut -c 1-7)"
|
||||
- test "${CI_COMMIT_REF_NAME}" = "nightly" && VERSION="${VERSION}-${ID_SHORT}-${DATE_STR}"
|
||||
- export VERSION
|
||||
- echo "Version = ${VERSION}"
|
||||
|
||||
|
||||
#### stage: test
|
||||
|
||||
test-rust-stable: &test
|
||||
test-linux:
|
||||
stage: test
|
||||
variables:
|
||||
RUN_TESTS: all
|
||||
script:
|
||||
- scripts/gitlab/test.sh stable
|
||||
- scripts/gitlab/test-all.sh stable
|
||||
tags:
|
||||
- rust-stable
|
||||
|
||||
.optional_test: &optional_test
|
||||
<<: *test
|
||||
allow_failure: true
|
||||
only:
|
||||
- master
|
||||
|
||||
test-rust-beta:
|
||||
<<: *optional_test
|
||||
script:
|
||||
- scripts/gitlab/test.sh beta
|
||||
|
||||
test-rust-nightly:
|
||||
<<: *optional_test
|
||||
script:
|
||||
- scripts/gitlab/test.sh nightly
|
||||
|
||||
test-lint-rustfmt:
|
||||
<<: *optional_test
|
||||
script:
|
||||
- scripts/gitlab/rustfmt.sh
|
||||
|
||||
test-lint-clippy:
|
||||
<<: *optional_test
|
||||
script:
|
||||
- scripts/gitlab/clippy.sh
|
||||
|
||||
test-coverage-kcov:
|
||||
stage: test
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- scripts/gitlab/coverage.sh
|
||||
tags:
|
||||
- shell
|
||||
allow_failure: true
|
||||
|
||||
|
||||
#### stage: build
|
||||
|
||||
build-linux-ubuntu-amd64: &build
|
||||
build-linux:
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
variables:
|
||||
@ -112,59 +53,23 @@ build-linux-ubuntu-amd64: &build
|
||||
<<: *collect_artifacts
|
||||
tags:
|
||||
- rust-stable
|
||||
allow_failure: true
|
||||
|
||||
build-linux-ubuntu-i386:
|
||||
<<: *build
|
||||
image: parity/rust-i686:gitlab-ci
|
||||
variables:
|
||||
CARGO_TARGET: i686-unknown-linux-gnu
|
||||
tags:
|
||||
- rust-i686
|
||||
|
||||
build-linux-ubuntu-arm64:
|
||||
<<: *build
|
||||
image: parity/rust-arm64:gitlab-ci
|
||||
variables:
|
||||
CARGO_TARGET: aarch64-unknown-linux-gnu
|
||||
tags:
|
||||
- rust-arm
|
||||
|
||||
build-linux-ubuntu-armhf:
|
||||
<<: *build
|
||||
image: parity/rust-armv7:gitlab-ci
|
||||
variables:
|
||||
CARGO_TARGET: armv7-unknown-linux-gnueabihf
|
||||
tags:
|
||||
- rust-arm
|
||||
|
||||
build-linux-android-armhf:
|
||||
<<: *build
|
||||
image: parity/rust-android:gitlab-ci
|
||||
variables:
|
||||
CARGO_TARGET: armv7-linux-androideabi
|
||||
tags:
|
||||
- rust-arm
|
||||
|
||||
build-darwin-macos-x86_64:
|
||||
<<: *build
|
||||
build-darwin:
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-apple-darwin
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
script:
|
||||
- scripts/gitlab/build-unix.sh
|
||||
tags:
|
||||
- osx
|
||||
- rust-osx
|
||||
<<: *collect_artifacts
|
||||
|
||||
build-windows-msvc-x86_64:
|
||||
build-windows:
|
||||
stage: build
|
||||
only: *releaseable_branches
|
||||
cache:
|
||||
key: "%CI_JOB_NAME%"
|
||||
paths:
|
||||
- "%CI_PROJECT_DIR%/target/"
|
||||
- "%CI_PROJECT_DIR%/cargo/"
|
||||
# No cargo caching, since fetch-locking on Windows gets stuck
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-pc-windows-msvc
|
||||
script:
|
||||
@ -173,131 +78,74 @@ build-windows-msvc-x86_64:
|
||||
- rust-windows
|
||||
<<: *collect_artifacts
|
||||
|
||||
|
||||
#### stage: package
|
||||
|
||||
package-linux-snap-amd64: &package_snap
|
||||
stage: package
|
||||
publish-docker:
|
||||
stage: publish
|
||||
only: *releaseable_branches
|
||||
cache: {}
|
||||
before_script: *determine_version
|
||||
variables:
|
||||
CARGO_TARGET: x86_64-unknown-linux-gnu
|
||||
dependencies:
|
||||
- build-linux-ubuntu-amd64
|
||||
script:
|
||||
- scripts/gitlab/package-snap.sh
|
||||
tags:
|
||||
- rust-stable
|
||||
<<: *collect_artifacts
|
||||
|
||||
package-linux-snap-i386:
|
||||
<<: *package_snap
|
||||
variables:
|
||||
BUILD_ARCH: i386
|
||||
CARGO_TARGET: i686-unknown-linux-gnu
|
||||
dependencies:
|
||||
- build-linux-ubuntu-i386
|
||||
|
||||
package-linux-snap-arm64:
|
||||
<<: *package_snap
|
||||
variables:
|
||||
BUILD_ARCH: arm64
|
||||
CARGO_TARGET: aarch64-unknown-linux-gnu
|
||||
dependencies:
|
||||
- build-linux-ubuntu-arm64
|
||||
|
||||
package-linux-snap-armhf:
|
||||
<<: *package_snap
|
||||
variables:
|
||||
BUILD_ARCH: armhf
|
||||
CARGO_TARGET: armv7-unknown-linux-gnueabihf
|
||||
dependencies:
|
||||
- build-linux-ubuntu-armhf
|
||||
|
||||
|
||||
#### stage: publish
|
||||
|
||||
publish-linux-snap-amd64: &publish_snap
|
||||
stage: publish
|
||||
only: *publishable_branches
|
||||
image: snapcore/snapcraft:stable
|
||||
cache: {}
|
||||
before_script: *determine_version
|
||||
variables:
|
||||
BUILD_ARCH: amd64
|
||||
dependencies:
|
||||
- package-linux-snap-amd64
|
||||
script:
|
||||
- scripts/gitlab/publish-snap.sh
|
||||
tags:
|
||||
- rust-stable
|
||||
|
||||
publish-linux-snap-i386:
|
||||
<<: *publish_snap
|
||||
variables:
|
||||
BUILD_ARCH: i386
|
||||
dependencies:
|
||||
- package-linux-snap-i386
|
||||
|
||||
publish-linux-snap-arm64:
|
||||
<<: *publish_snap
|
||||
variables:
|
||||
BUILD_ARCH: arm64
|
||||
dependencies:
|
||||
- package-linux-snap-arm64
|
||||
|
||||
publish-linux-snap-armhf:
|
||||
<<: *publish_snap
|
||||
variables:
|
||||
BUILD_ARCH: armhf
|
||||
dependencies:
|
||||
- package-linux-snap-armhf
|
||||
|
||||
publish-docker-parity-amd64: &publish_docker
|
||||
stage: publish
|
||||
only: *publishable_branches
|
||||
cache: {}
|
||||
dependencies:
|
||||
- build-linux-ubuntu-amd64
|
||||
- build-linux
|
||||
tags:
|
||||
- shell
|
||||
allow_failure: true
|
||||
script:
|
||||
- scripts/gitlab/publish-docker.sh parity
|
||||
|
||||
publish-docker-parityevm-amd64:
|
||||
<<: *publish_docker
|
||||
script:
|
||||
- scripts/gitlab/publish-docker.sh parity-evm
|
||||
|
||||
publish-github-and-s3:
|
||||
publish-awss3:
|
||||
stage: publish
|
||||
only: *publishable_branches
|
||||
only: *releaseable_branches
|
||||
cache: {}
|
||||
dependencies:
|
||||
- build-linux-ubuntu-amd64
|
||||
- build-linux-ubuntu-i386
|
||||
- build-linux-ubuntu-armhf
|
||||
- build-linux-ubuntu-arm64
|
||||
- build-darwin-macos-x86_64
|
||||
- build-windows-msvc-x86_64
|
||||
- build-linux
|
||||
- build-darwin
|
||||
- build-windows
|
||||
before_script: *determine_version
|
||||
script:
|
||||
- scripts/gitlab/push.sh
|
||||
- scripts/gitlab/publish-awss3.sh
|
||||
tags:
|
||||
- shell
|
||||
allow_failure: true
|
||||
|
||||
|
||||
####stage: docs
|
||||
|
||||
docs-rpc-json:
|
||||
stage: docs
|
||||
docs-jsonrpc:
|
||||
stage: optional
|
||||
only:
|
||||
- tags
|
||||
except:
|
||||
- nightly
|
||||
cache: {}
|
||||
script:
|
||||
- scripts/gitlab/rpc-docs.sh
|
||||
- scripts/gitlab/docs-jsonrpc.sh
|
||||
tags:
|
||||
- shell
|
||||
|
||||
cargo-audit:
|
||||
stage: optional
|
||||
script:
|
||||
- scripts/gitlab/cargo-audit.sh
|
||||
tags:
|
||||
- rust-stable
|
||||
|
||||
build-android:
|
||||
stage: optional
|
||||
image: parity/rust-android:gitlab-ci
|
||||
variables:
|
||||
CARGO_TARGET: armv7-linux-androideabi
|
||||
script:
|
||||
- scripts/gitlab/build-unix.sh
|
||||
tags:
|
||||
- rust-arm
|
||||
|
||||
test-beta:
|
||||
stage: optional
|
||||
variables:
|
||||
RUN_TESTS: cargo
|
||||
script:
|
||||
- scripts/gitlab/test-all.sh beta
|
||||
tags:
|
||||
- rust-beta
|
||||
|
||||
test-nightly:
|
||||
stage: optional
|
||||
variables:
|
||||
RUN_TESTS: all
|
||||
script:
|
||||
- scripts/gitlab/test-all.sh nightly
|
||||
tags:
|
||||
- rust-nightly
|
||||
|
664
Cargo.lock
generated
664
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity-ethereum"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "2.1.0"
|
||||
version = "2.1.6"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
|
28
README.md
28
README.md
@ -4,9 +4,7 @@
|
||||
|
||||
<p align="center"><strong><a href="https://github.com/paritytech/parity-ethereum/releases/latest">» Download the latest release «</a></strong></p>
|
||||
|
||||
<p align="center"><a href="https://gitlab.parity.io/parity/parity/commits/master" target="_blank"><img src="https://gitlab.parity.io/parity/parity/badges/master/build.svg" /></a>
|
||||
<a href="https://codecov.io/gh/paritytech/parity-ethereum" target="_blank"><img src="https://codecov.io/gh/paritytech/parity-ethereum/branch/master/graph/badge.svg" /></a>
|
||||
<a href="https://build.snapcraft.io/user/paritytech/parity" target="_blank"><img src="https://build.snapcraft.io/badge/paritytech/parity.svg" /></a>
|
||||
<p align="center"><a href="https://gitlab.parity.io/parity/parity-ethereum/commits/master" target="_blank"><img src="https://gitlab.parity.io/parity/parity-ethereum/badges/master/build.svg" /></a>
|
||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank"><img src="https://img.shields.io/badge/license-GPL%20v3-green.svg" /></a></p>
|
||||
|
||||
**Built for mission-critical use**: Miners, service providers, and exchanges need fast synchronisation and maximum uptime. Parity Ethereum provides the core infrastructure essential for speedy and reliable services.
|
||||
@ -25,11 +23,11 @@ By default, Parity Ethereum runs a JSON-RPC HTTP server on port `:8545` and a We
|
||||
|
||||
If you run into problems while using Parity Ethereum, check out the [wiki for documentation](https://wiki.parity.io/), feel free to [file an issue in this repository](https://github.com/paritytech/parity-ethereum/issues/new), or hop on our [Gitter](https://gitter.im/paritytech/parity) or [Riot](https://riot.im/app/#/group/+parity:matrix.parity.io) chat room to ask a question. We are glad to help! **For security-critical issues**, please refer to the security policy outlined in [SECURITY.md](SECURITY.md).
|
||||
|
||||
Parity Ethereum's current beta-release is 2.0. You can download it at [the releases page](https://github.com/paritytech/parity-ethereum/releases) or follow the instructions below to build from source. Please, mind the [CHANGELOG.md](CHANGELOG.md) for a list of all changes between different versions.
|
||||
Parity Ethereum's current beta-release is 2.1. You can download it at [the releases page](https://github.com/paritytech/parity-ethereum/releases) or follow the instructions below to build from source. Please, mind the [CHANGELOG.md](CHANGELOG.md) for a list of all changes between different versions.
|
||||
|
||||
## Build Dependencies
|
||||
|
||||
Parity Ethereum requires **Rust version 1.28.x** to build.
|
||||
Parity Ethereum requires **Rust version 1.29.x** to build.
|
||||
|
||||
We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have `rustup`, you can install it like this:
|
||||
|
||||
@ -60,26 +58,6 @@ Once you have `rustup` installed, then you need to install:
|
||||
|
||||
Make sure that these binaries are in your `PATH`. After that, you should be able to build Parity Ethereum from source.
|
||||
|
||||
## Install from the Snapcraft Store
|
||||
|
||||
In any of the [supported Linux distros](https://snapcraft.io/docs/core/install):
|
||||
|
||||
```bash
|
||||
sudo snap install parity
|
||||
```
|
||||
|
||||
Alternatively, if you want to contribute testing the upcoming release:
|
||||
|
||||
```bash
|
||||
sudo snap install parity --beta
|
||||
```
|
||||
|
||||
Moreover, to test the latest code from the master branch:
|
||||
|
||||
```bash
|
||||
sudo snap install parity --edge
|
||||
```
|
||||
|
||||
## Build from Source Code
|
||||
|
||||
```bash
|
||||
|
@ -1,61 +0,0 @@
|
||||
FROM ubuntu:xenial
|
||||
LABEL maintainer="Parity Technologies <devops@parity.io>"
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -yq sudo curl file build-essential wget git g++ cmake pkg-config bison flex \
|
||||
unzip lib32stdc++6 lib32z1 python autotools-dev automake autoconf libtool \
|
||||
gperf xsltproc docbook-xsl
|
||||
|
||||
# Rust & Cargo
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
ENV PATH /root/.cargo/bin:$PATH
|
||||
RUN rustup toolchain install stable
|
||||
RUN rustup target add --toolchain stable arm-linux-androideabi
|
||||
RUN rustup target add --toolchain stable armv7-linux-androideabi
|
||||
|
||||
# Android NDK and toolchain
|
||||
RUN cd /usr/local && \
|
||||
wget -q https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip && \
|
||||
unzip -q android-ndk-r16b-linux-x86_64.zip && \
|
||||
rm android-ndk-r16b-linux-x86_64.zip
|
||||
ENV NDK_HOME /usr/local/android-ndk-r16b
|
||||
RUN /usr/local/android-ndk-r16b/build/tools/make-standalone-toolchain.sh \
|
||||
--arch=arm --install-dir=/opt/ndk-standalone --stl=libc++ --platform=android-26
|
||||
ENV PATH $PATH:/opt/ndk-standalone/bin
|
||||
|
||||
# Compiling libudev for Android
|
||||
# This is the most hacky part of the process, as we need to apply a patch and pass specific
|
||||
# options that the compiler environment doesn't define.
|
||||
RUN cd /root && \
|
||||
git clone https://github.com/gentoo/eudev.git
|
||||
ADD libudev.patch /root
|
||||
RUN cd /root/eudev && \
|
||||
git checkout 83d918449f22720d84a341a05e24b6d109e6d3ae && \
|
||||
./autogen.sh && \
|
||||
./configure --disable-introspection --disable-programs --disable-hwdb \
|
||||
--host=arm-linux-androideabi --prefix=/opt/ndk-standalone/sysroot/usr/ \
|
||||
--enable-shared=false CC=arm-linux-androideabi-clang \
|
||||
CFLAGS="-D LINE_MAX=2048 -D RLIMIT_NLIMITS=15 -D IPTOS_LOWCOST=2 -std=gnu99" \
|
||||
CXX=arm-linux-androideabi-clang++ && \
|
||||
git apply - < /root/libudev.patch && \
|
||||
make && \
|
||||
make install
|
||||
RUN rm -rf /root/eudev
|
||||
RUN rm /root/libudev.patch
|
||||
|
||||
# Rust-related configuration
|
||||
ADD cargo-config.toml /root/.cargo/config
|
||||
ENV ARM_LINUX_ANDROIDEABI_OPENSSL_DIR /opt/ndk-standalone/sysroot/usr
|
||||
ENV ARMV7_LINUX_ANDROIDEABI_OPENSSL_DIR /opt/ndk-standalone/sysroot/usr
|
||||
ENV CC_arm_linux_androideabi arm-linux-androideabi-clang
|
||||
ENV CC_armv7_linux_androideabi arm-linux-androideabi-clang
|
||||
ENV CXX_arm_linux_androideabi arm-linux-androideabi-clang++
|
||||
ENV CXX_armv7_linux_androideabi arm-linux-androideabi-clang++
|
||||
ENV AR_arm_linux_androideabi arm-linux-androideabi-ar
|
||||
ENV AR_armv7_linux_androideabi arm-linux-androideabi-ar
|
||||
ENV CFLAGS_arm_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID
|
||||
ENV CFLAGS_armv7_linux_androideabi -std=gnu11 -fPIC -D OS_ANDROID
|
||||
ENV CXXFLAGS_arm_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID
|
||||
ENV CXXFLAGS_armv7_linux_androideabi -std=gnu++11 -fPIC -fexceptions -frtti -static-libstdc++ -D OS_ANDROID
|
||||
ENV CXXSTDLIB_arm_linux_androideabi ""
|
||||
ENV CXXSTDLIB_armv7_linux_androideabi ""
|
@ -1,9 +0,0 @@
|
||||
[target.armv7-linux-androideabi]
|
||||
linker = "arm-linux-androideabi-clang"
|
||||
ar = "arm-linux-androideabi-ar"
|
||||
rustflags = ["-C", "link-arg=-lc++_static", "-C", "link-arg=-lc++abi", "-C", "link-arg=-landroid_support"]
|
||||
|
||||
[target.arm-linux-androideabi]
|
||||
linker = "arm-linux-androideabi-clang"
|
||||
ar = "arm-linux-androideabi-ar"
|
||||
rustflags = ["-C", "link-arg=-lc++_static", "-C", "link-arg=-lc++abi", "-C", "link-arg=-landroid_support"]
|
@ -1,216 +0,0 @@
|
||||
diff --git a/src/collect/collect.c b/src/collect/collect.c
|
||||
index 2cf1f00..b24f26b 100644
|
||||
--- a/src/collect/collect.c
|
||||
+++ b/src/collect/collect.c
|
||||
@@ -84,7 +84,7 @@ static void usage(void)
|
||||
" invoked for each ID in <idlist>) collect returns 0, the\n"
|
||||
" number of missing IDs otherwise.\n"
|
||||
" On error a negative number is returned.\n\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/src/scsi_id/scsi_id.c b/src/scsi_id/scsi_id.c
|
||||
index 8b76d87..7bf3948 100644
|
||||
--- a/src/scsi_id/scsi_id.c
|
||||
+++ b/src/scsi_id/scsi_id.c
|
||||
@@ -321,7 +321,7 @@ static void help(void) {
|
||||
" -u --replace-whitespace Replace all whitespace by underscores\n"
|
||||
" -v --verbose Verbose logging\n"
|
||||
" -x --export Print values as environment keys\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
|
||||
}
|
||||
|
||||
diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h
|
||||
index a03ee58..a7c2005 100644
|
||||
--- a/src/shared/hashmap.h
|
||||
+++ b/src/shared/hashmap.h
|
||||
@@ -98,10 +98,7 @@ extern const struct hash_ops uint64_hash_ops;
|
||||
#if SIZEOF_DEV_T != 8
|
||||
unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
|
||||
int devt_compare_func(const void *a, const void *b) _pure_;
|
||||
-extern const struct hash_ops devt_hash_ops = {
|
||||
- .hash = devt_hash_func,
|
||||
- .compare = devt_compare_func
|
||||
-};
|
||||
+extern const struct hash_ops devt_hash_ops;
|
||||
#else
|
||||
#define devt_hash_func uint64_hash_func
|
||||
#define devt_compare_func uint64_compare_func
|
||||
diff --git a/src/shared/log.c b/src/shared/log.c
|
||||
index 4a40996..1496984 100644
|
||||
--- a/src/shared/log.c
|
||||
+++ b/src/shared/log.c
|
||||
@@ -335,7 +335,7 @@ static int write_to_syslog(
|
||||
|
||||
IOVEC_SET_STRING(iovec[0], header_priority);
|
||||
IOVEC_SET_STRING(iovec[1], header_time);
|
||||
- IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
|
||||
+ IOVEC_SET_STRING(iovec[2], "parity");
|
||||
IOVEC_SET_STRING(iovec[3], header_pid);
|
||||
IOVEC_SET_STRING(iovec[4], buffer);
|
||||
|
||||
@@ -383,7 +383,7 @@ static int write_to_kmsg(
|
||||
char_array_0(header_pid);
|
||||
|
||||
IOVEC_SET_STRING(iovec[0], header_priority);
|
||||
- IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
|
||||
+ IOVEC_SET_STRING(iovec[1], "parity");
|
||||
IOVEC_SET_STRING(iovec[2], header_pid);
|
||||
IOVEC_SET_STRING(iovec[3], buffer);
|
||||
IOVEC_SET_STRING(iovec[4], "\n");
|
||||
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
|
||||
index 6af7163..3271e56 100644
|
||||
--- a/src/udev/udevadm-control.c
|
||||
+++ b/src/udev/udevadm-control.c
|
||||
@@ -41,7 +41,7 @@ static void print_help(void) {
|
||||
" -p --property=KEY=VALUE Set a global property for all events\n"
|
||||
" -m --children-max=N Maximum number of children\n"
|
||||
" --timeout=SECONDS Maximum time to block for a reply\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int adm_control(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
|
||||
index 0aec976..a31ac02 100644
|
||||
--- a/src/udev/udevadm-info.c
|
||||
+++ b/src/udev/udevadm-info.c
|
||||
@@ -279,7 +279,7 @@ static void help(void) {
|
||||
" -P --export-prefix Export the key name with a prefix\n"
|
||||
" -e --export-db Export the content of the udev database\n"
|
||||
" -c --cleanup-db Clean up the udev database\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int uinfo(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
|
||||
index 15ded09..b58dd08 100644
|
||||
--- a/src/udev/udevadm-monitor.c
|
||||
+++ b/src/udev/udevadm-monitor.c
|
||||
@@ -73,7 +73,7 @@ static void help(void) {
|
||||
" -u --udev Print udev events\n"
|
||||
" -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
|
||||
" -t --tag-match=TAG Filter events by tag\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
|
||||
index 33597bc..b36a504 100644
|
||||
--- a/src/udev/udevadm-settle.c
|
||||
+++ b/src/udev/udevadm-settle.c
|
||||
@@ -43,7 +43,7 @@ static void help(void) {
|
||||
" --version Show package version\n"
|
||||
" -t --timeout=SECONDS Maximum time to wait for events\n"
|
||||
" -E --exit-if-exists=FILE Stop waiting if file exists\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int adm_settle(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
|
||||
index baaeca9..50ed812 100644
|
||||
--- a/src/udev/udevadm-test-builtin.c
|
||||
+++ b/src/udev/udevadm-test-builtin.c
|
||||
@@ -39,7 +39,7 @@ static void help(struct udev *udev) {
|
||||
" -h --help Print this message\n"
|
||||
" --version Print version of the program\n\n"
|
||||
"Commands:\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
|
||||
udev_builtin_list(udev);
|
||||
}
|
||||
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
|
||||
index 47fd924..a855412 100644
|
||||
--- a/src/udev/udevadm-test.c
|
||||
+++ b/src/udev/udevadm-test.c
|
||||
@@ -39,7 +39,7 @@ static void help(void) {
|
||||
" --version Show package version\n"
|
||||
" -a --action=ACTION Set action string\n"
|
||||
" -N --resolve-names=early|late|never When to resolve names\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int adm_test(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
|
||||
index 4dc756a..67787d3 100644
|
||||
--- a/src/udev/udevadm-trigger.c
|
||||
+++ b/src/udev/udevadm-trigger.c
|
||||
@@ -92,7 +92,7 @@ static void help(void) {
|
||||
" -y --sysname-match=NAME Trigger devices with this /sys path\n"
|
||||
" --name-match=NAME Trigger devices with this /dev name\n"
|
||||
" -b --parent-match=NAME Trigger devices with that parent device\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
||||
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
|
||||
index 3e57cf6..b03dfaa 100644
|
||||
--- a/src/udev/udevadm.c
|
||||
+++ b/src/udev/udevadm.c
|
||||
@@ -62,7 +62,7 @@ static int adm_help(struct udev *udev, int argc, char *argv[]) {
|
||||
printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
|
||||
"Send control commands or test the device manager.\n\n"
|
||||
"Commands:\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
|
||||
if (udevadm_cmds[i]->help != NULL)
|
||||
@@ -128,7 +128,7 @@ int main(int argc, char *argv[]) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
- fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
|
||||
+ fprintf(stderr, "%s: missing or unknown command\n", "parity");
|
||||
rc = 2;
|
||||
out:
|
||||
mac_selinux_finish();
|
||||
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
|
||||
index cf826c6..4eec0af 100644
|
||||
--- a/src/udev/udevd.c
|
||||
+++ b/src/udev/udevd.c
|
||||
@@ -1041,7 +1041,7 @@ static void help(void) {
|
||||
" -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
|
||||
" -N --resolve-names=early|late|never\n"
|
||||
" When to resolve users and groups\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
diff --git a/src/v4l_id/v4l_id.c b/src/v4l_id/v4l_id.c
|
||||
index 1dce0d5..f65badf 100644
|
||||
--- a/src/v4l_id/v4l_id.c
|
||||
+++ b/src/v4l_id/v4l_id.c
|
||||
@@ -49,7 +49,7 @@ int main(int argc, char *argv[]) {
|
||||
printf("%s [-h,--help] <device file>\n\n"
|
||||
"Video4Linux device identification.\n\n"
|
||||
" -h Print this message\n"
|
||||
- , program_invocation_short_name);
|
||||
+ , "parity");
|
||||
return 0;
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
|
||||
index 0744563..7151356 100644
|
||||
--- a/src/shared/path-util.c
|
||||
+++ b/src/shared/path-util.c
|
||||
@@ -109,7 +109,7 @@ char *path_make_absolute_cwd(const char *p) {
|
||||
if (path_is_absolute(p))
|
||||
return strdup(p);
|
||||
|
||||
- cwd = get_current_dir_name();
|
||||
+ cwd = getcwd(malloc(128), 128);
|
||||
if (!cwd)
|
||||
return NULL;
|
||||
|
@ -18,7 +18,7 @@ ethcore-bloom-journal = { path = "../util/bloom" }
|
||||
parity-bytes = "0.1"
|
||||
hashdb = "0.2.1"
|
||||
memorydb = "0.2.1"
|
||||
patricia-trie = "0.2.1"
|
||||
patricia-trie = "0.2"
|
||||
patricia-trie-ethereum = { path = "../util/patricia-trie-ethereum" }
|
||||
parity-crypto = "0.1"
|
||||
error-chain = { version = "0.12", default-features = false }
|
||||
|
@ -176,9 +176,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
||||
Request::GasMem(default_gas, mem_needed(stack.peek(0), stack.peek(1))?)
|
||||
},
|
||||
instructions::SHA3 => {
|
||||
let w = overflowing!(add_gas_usize(Gas::from_u256(*stack.peek(1))?, 31));
|
||||
let words = w >> 5;
|
||||
let gas = Gas::from(schedule.sha3_gas) + (Gas::from(schedule.sha3_word_gas) * words);
|
||||
let words = overflowing!(to_word_size(Gas::from_u256(*stack.peek(1))?));
|
||||
let gas = overflowing!(Gas::from(schedule.sha3_gas).overflow_add(overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(words))));
|
||||
Request::GasMem(gas, mem_needed(stack.peek(0), stack.peek(1))?)
|
||||
},
|
||||
instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => {
|
||||
@ -231,13 +230,24 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
||||
|
||||
Request::GasMemProvide(gas, mem, Some(requested))
|
||||
},
|
||||
instructions::CREATE | instructions::CREATE2 => {
|
||||
instructions::CREATE => {
|
||||
let start = stack.peek(1);
|
||||
let len = stack.peek(2);
|
||||
|
||||
let gas = Gas::from(schedule.create_gas);
|
||||
let mem = match instruction {
|
||||
instructions::CREATE => mem_needed(stack.peek(1), stack.peek(2))?,
|
||||
instructions::CREATE2 => mem_needed(stack.peek(2), stack.peek(3))?,
|
||||
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
|
||||
};
|
||||
let mem = mem_needed(start, len)?;
|
||||
|
||||
Request::GasMemProvide(gas, mem, None)
|
||||
},
|
||||
instructions::CREATE2 => {
|
||||
let start = stack.peek(1);
|
||||
let len = stack.peek(2);
|
||||
|
||||
let base = Gas::from(schedule.create_gas);
|
||||
let word = overflowing!(to_word_size(Gas::from_u256(*len)?));
|
||||
let word_gas = overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(word));
|
||||
let gas = overflowing!(base.overflow_add(word_gas));
|
||||
let mem = mem_needed(start, len)?;
|
||||
|
||||
Request::GasMemProvide(gas, mem, None)
|
||||
},
|
||||
@ -287,8 +297,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
||||
},
|
||||
Request::GasMemCopy(gas, mem_size, copy) => {
|
||||
let (mem_gas_cost, new_mem_gas, new_mem_size) = self.mem_gas_cost(schedule, current_mem_size, &mem_size)?;
|
||||
let copy = overflowing!(add_gas_usize(copy, 31)) >> 5;
|
||||
let copy_gas = Gas::from(schedule.copy_gas) * copy;
|
||||
let copy = overflowing!(to_word_size(copy));
|
||||
let copy_gas = overflowing!(Gas::from(schedule.copy_gas).overflow_mul(copy));
|
||||
let gas = overflowing!(gas.overflow_add(copy_gas));
|
||||
let gas = overflowing!(gas.overflow_add(mem_gas_cost));
|
||||
|
||||
@ -315,7 +325,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
||||
};
|
||||
|
||||
let current_mem_size = Gas::from(current_mem_size);
|
||||
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5;
|
||||
let req_mem_size_rounded = overflowing!(to_word_size(*mem_size)) << 5;
|
||||
|
||||
let (mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size {
|
||||
let new_mem_gas = gas_for_mem(req_mem_size_rounded)?;
|
||||
@ -347,6 +357,16 @@ fn add_gas_usize<Gas: evm::CostType>(value: Gas, num: usize) -> (Gas, bool) {
|
||||
value.overflow_add(Gas::from(num))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_word_size<Gas: evm::CostType>(value: Gas) -> (Gas, bool) {
|
||||
let (gas, overflow) = add_gas_usize(value, 31);
|
||||
if overflow {
|
||||
return (gas, overflow);
|
||||
}
|
||||
|
||||
(gas >> 5, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, original: &U256, current: &U256, new: &U256) -> Gas {
|
||||
Gas::from(
|
||||
@ -383,7 +403,7 @@ fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, origina
|
||||
}
|
||||
|
||||
pub fn handle_eip1283_sstore_clears_refund(ext: &mut vm::Ext, original: &U256, current: &U256, new: &U256) {
|
||||
let sstore_clears_schedule = U256::from(ext.schedule().sstore_refund_gas);
|
||||
let sstore_clears_schedule = ext.schedule().sstore_refund_gas;
|
||||
|
||||
if current == new {
|
||||
// 1. If current value equals new value (this is a no-op), 200 gas is deducted.
|
||||
@ -418,11 +438,11 @@ pub fn handle_eip1283_sstore_clears_refund(ext: &mut vm::Ext, original: &U256, c
|
||||
// 2.2.2. If original value equals new value (this storage slot is reset)
|
||||
if original.is_zero() {
|
||||
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter.
|
||||
let refund = U256::from(ext.schedule().sstore_set_gas - ext.schedule().sload_gas);
|
||||
let refund = ext.schedule().sstore_set_gas - ext.schedule().sload_gas;
|
||||
ext.add_sstore_refund(refund);
|
||||
} else {
|
||||
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
|
||||
let refund = U256::from(ext.schedule().sstore_reset_gas - ext.schedule().sload_gas);
|
||||
let refund = ext.schedule().sstore_reset_gas - ext.schedule().sload_gas;
|
||||
ext.add_sstore_refund(refund);
|
||||
}
|
||||
}
|
||||
|
@ -306,8 +306,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
match result {
|
||||
InstructionResult::JumpToPosition(position) => {
|
||||
if self.valid_jump_destinations.is_none() {
|
||||
let code_hash = self.params.code_hash.clone().unwrap_or_else(|| keccak(self.reader.code.as_ref()));
|
||||
self.valid_jump_destinations = Some(self.cache.jump_destinations(&code_hash, &self.reader.code));
|
||||
self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code));
|
||||
}
|
||||
let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
|
||||
let pos = self.verify_jump(position, jump_destinations)?;
|
||||
@ -634,7 +633,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
||||
gasometer::handle_eip1283_sstore_clears_refund(ext, &original_val, ¤t_val, &val);
|
||||
} else {
|
||||
if !current_val.is_zero() && val.is_zero() {
|
||||
let sstore_clears_schedule = U256::from(ext.schedule().sstore_refund_gas);
|
||||
let sstore_clears_schedule = ext.schedule().sstore_refund_gas;
|
||||
ext.add_sstore_refund(sstore_clears_schedule);
|
||||
}
|
||||
}
|
||||
|
@ -50,17 +50,22 @@ impl SharedCache {
|
||||
}
|
||||
|
||||
/// Get jump destinations bitmap for a contract.
|
||||
pub fn jump_destinations(&self, code_hash: &H256, code: &[u8]) -> Arc<BitSet> {
|
||||
if code_hash == &KECCAK_EMPTY {
|
||||
return Self::find_jump_destinations(code);
|
||||
}
|
||||
pub fn jump_destinations(&self, code_hash: &Option<H256>, code: &[u8]) -> Arc<BitSet> {
|
||||
if let Some(ref code_hash) = code_hash {
|
||||
if code_hash == &KECCAK_EMPTY {
|
||||
return Self::find_jump_destinations(code);
|
||||
}
|
||||
|
||||
if let Some(d) = self.jump_destinations.lock().get_mut(code_hash) {
|
||||
return d.0.clone();
|
||||
if let Some(d) = self.jump_destinations.lock().get_mut(code_hash) {
|
||||
return d.0.clone();
|
||||
}
|
||||
}
|
||||
|
||||
let d = Self::find_jump_destinations(code);
|
||||
self.jump_destinations.lock().insert(code_hash.clone(), Bits(d.clone()));
|
||||
|
||||
if let Some(ref code_hash) = code_hash {
|
||||
self.jump_destinations.lock().insert(*code_hash, Bits(d.clone()));
|
||||
}
|
||||
|
||||
d
|
||||
}
|
||||
|
@ -716,7 +716,7 @@ fn test_jumps(factory: super::Factory) {
|
||||
test_finalize(vm.exec(&mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(ext.sstore_clears, U256::from(ext.schedule().sstore_refund_gas));
|
||||
assert_eq!(ext.sstore_clears, ext.schedule().sstore_refund_gas as i128);
|
||||
assert_store(&ext, 0, "0000000000000000000000000000000000000000000000000000000000000000"); // 5!
|
||||
assert_store(&ext, 1, "0000000000000000000000000000000000000000000000000000000000000078"); // 5!
|
||||
assert_eq!(gas_left, U256::from(54_117));
|
||||
|
@ -13,7 +13,7 @@ parity-bytes = "0.1"
|
||||
ethcore-transaction = { path = "../transaction" }
|
||||
ethereum-types = "0.4"
|
||||
memorydb = "0.2.1"
|
||||
patricia-trie = "0.2.1"
|
||||
patricia-trie = "0.2"
|
||||
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
|
@ -26,7 +26,7 @@ heapsize = "0.4"
|
||||
keccak-hash = "0.1.2"
|
||||
log = "0.4"
|
||||
parking_lot = "0.6"
|
||||
patricia-trie = "0.2.1"
|
||||
patricia-trie = "0.2"
|
||||
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
|
||||
rand = "0.3"
|
||||
rlp = { version = "0.2.4", features = ["ethereum"] }
|
||||
|
@ -3068,17 +3068,18 @@
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
"enode://e809c4a2fec7daed400e5e28564e23693b23b2cc5a019b612505631bbe7b9ccf709c1796d2a3d29ef2b045f210caf51e3c4f5b6d3587d43ad5d6397526fa6179@174.112.32.157:30303",
|
||||
"enode://6e538e7c1280f0a31ff08b382db5302480f775480b8e68f8febca0ceff81e4b19153c6f8bf60313b93bef2cc34d34e1df41317de0ce613a201d1660a788a03e2@52.206.67.235:30303",
|
||||
"enode://efd48ad0879eeb7f9cb5e50f33f7bc21e805a72e90361f145baaa22dd75d111e7cd9c93f1b7060dcb30aa1b3e620269336dbf32339fea4c18925a4c15fe642df@18.205.66.229:30303",
|
||||
"enode://5fbfb426fbb46f8b8c1bd3dd140f5b511da558cd37d60844b525909ab82e13a25ee722293c829e52cb65c2305b1637fa9a2ea4d6634a224d5f400bfe244ac0de@162.243.55.45:30303",
|
||||
"enode://42d8f29d1db5f4b2947cd5c3d76c6d0d3697e6b9b3430c3d41e46b4bb77655433aeedc25d4b4ea9d8214b6a43008ba67199374a9b53633301bca0cd20c6928ab@104.155.176.151:30303",
|
||||
"enode://814920f1ec9510aa9ea1c8f79d8b6e6a462045f09caa2ae4055b0f34f7416fca6facd3dd45f1cf1673c0209e0503f02776b8ff94020e98b6679a0dc561b4eba0@104.154.136.117:30303",
|
||||
"enode://72e445f4e89c0f476d404bc40478b0df83a5b500d2d2e850e08eb1af0cd464ab86db6160d0fde64bd77d5f0d33507ae19035671b3c74fec126d6e28787669740@104.198.71.200:30303",
|
||||
"enode://39abab9d2a41f53298c0c9dc6bbca57b0840c3ba9dccf42aa27316addc1b7e56ade32a0a9f7f52d6c5db4fe74d8824bcedfeaecf1a4e533cacb71cf8100a9442@144.76.238.49:30303",
|
||||
"enode://f50e675a34f471af2438b921914b5f06499c7438f3146f6b8936f1faeb50b8a91d0d0c24fb05a66f05865cd58c24da3e664d0def806172ddd0d4c5bdbf37747e@144.76.238.49:30306",
|
||||
"enode://83b33409349ffa25e150555f7b4f8deebc68f3d34d782129dc3c8ba07b880c209310a4191e1725f2f6bef59bce9452d821111eaa786deab08a7e6551fca41f4f@159.89.223.6:30303",
|
||||
"enode://5cd218959f8263bc3721d7789070806b0adff1a0ed3f95ec886fb469f9362c7507e3b32b256550b9a7964a23a938e8d42d45a0c34b332bfebc54b29081e83b93@35.187.57.94:30303",
|
||||
"enode://6dd3ac8147fa82e46837ec8c3223d69ac24bcdbab04b036a3705c14f3a02e968f7f1adfcdb002aacec2db46e625c04bf8b5a1f85bb2d40a479b3cc9d45a444af@104.237.131.102:30303"
|
||||
"enode://6dd3ac8147fa82e46837ec8c3223d69ac24bcdbab04b036a3705c14f3a02e968f7f1adfcdb002aacec2db46e625c04bf8b5a1f85bb2d40a479b3cc9d45a444af@104.237.131.102:30303",
|
||||
"enode://b9e893ea9cb4537f4fed154233005ae61b441cd0ecd980136138c304fefac194c25a16b73dac05fc66a4198d0c15dd0f33af99b411882c68a019dfa6bb703b9d@18.130.93.66:30303",
|
||||
"enode://3fe9705a02487baea45c1ffebfa4d84819f5f1e68a0dbc18031553242a6a08e39499b61e361a52c2a92f9553efd63763f6fdd34692be0d4ba6823bb2fc346009@178.62.238.75:30303",
|
||||
"enode://d50facc65e46bda6ff594b6e95491efa16e067de41ae96571d9f3cb853d538c44864496fa5e4df10115f02bbbaf47853f932e110a44c89227da7c30e96840596@188.166.163.187:30303",
|
||||
"enode://a0d5c589dc02d008fe4237da9877a5f1daedee0227ab612677eabe323520f003eb5e311af335de9f7964c2092bbc2b3b7ab1cce5a074d8346959f0868b4e366e@46.101.78.44:30303",
|
||||
"enode://c071d96b0c0f13006feae3977fb1b3c2f62caedf643df9a3655bc1b60f777f05e69a4e58bf3547bb299210092764c56df1e08380e91265baa845dca8bc0a71da@68.183.99.5:30303",
|
||||
"enode://83b33409349ffa25e150555f7b4f8deebc68f3d34d782129dc3c8ba07b880c209310a4191e1725f2f6bef59bce9452d821111eaa786deab08a7e6551fca41f4f@206.189.68.191:30303",
|
||||
"enode://0daae2a30f2c73b0b257746587136efb8e3479496f7ea1e943eeb9a663b72dd04582f699f7010ee02c57fc45d1f09568c20a9050ff937f9139e2973ddd98b87b@159.89.169.103:30303",
|
||||
"enode://50808461dd73b3d70537e4c1e5fafd1132b3a90f998399af9205f8889987d62096d4e853813562dd43e7270a71c9d9d4e4dd73a534fdb22fbac98c389c1a7362@178.128.55.119:30303",
|
||||
"enode://5cd218959f8263bc3721d7789070806b0adff1a0ed3f95ec886fb469f9362c7507e3b32b256550b9a7964a23a938e8d42d45a0c34b332bfebc54b29081e83b93@35.187.57.94:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
|
@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "Byzantium (Test)",
|
||||
"name": "Constantinople (test)",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x29A2241AF62C0000",
|
||||
"blockReward": "0x1BC16D674EC80000",
|
||||
"homesteadTransition": "0x0",
|
||||
"eip100bTransition": "0x0",
|
||||
"difficultyBombDelays": {
|
||||
"0": 3000000
|
||||
"0": 5000000
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,11 +30,13 @@
|
||||
"eip161abcTransition": "0x0",
|
||||
"eip161dTransition": "0x0",
|
||||
"eip140Transition": "0x0",
|
||||
"eip210Transition": "0x0",
|
||||
"eip211Transition": "0x0",
|
||||
"eip214Transition": "0x0",
|
||||
"eip155Transition": "0x0",
|
||||
"eip658Transition": "0x0",
|
||||
"eip145Transition": "0x0",
|
||||
"eip1014Transition": "0x0",
|
||||
"eip1052Transition": "0x0",
|
||||
"eip1283Transition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
|
54
ethcore/res/ethereum/eip210_test.json
Normal file
54
ethcore/res/ethereum/eip210_test.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "EIP210 (test)",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"homesteadTransition": "0x0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x1",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
"eip98Transition": "0xffffffffffffffff",
|
||||
"eip150Transition": "0x0",
|
||||
"eip160Transition": "0x0",
|
||||
"eip161abcTransition": "0x0",
|
||||
"eip161dTransition": "0x0",
|
||||
"eip210Transition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x400000000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||
"gasLimit": "0x1388"
|
||||
},
|
||||
"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 } } } },
|
||||
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": "0x00", "pricing": { "modexp": { "divisor": 100 } } } },
|
||||
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": "0x00", "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": "0x00", "pricing": { "linear": { "base": 2000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x00", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
|
||||
}
|
||||
}
|
@ -177,8 +177,8 @@
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f9020ba0c7139a7f4b14c2e12dbe34aeb92711b37747bf8698ecdd6f2c3b1f5f3840e288a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479452e44f279f4203dcf680395379e5f9990a69f13ca06e817f8a9b206f93a393da76a3ece2a74b98eaecc4dae0cfa8f409455e88ccb4a0d739197170d2bc6bbb24fac0ce695982090702082fe1541bb7634f018dfe87b3a038503b7299fb1c113a78b4a3a5dfd997ef32e7fbf722fc178dfcb21e1af1f7f5b9010000020000000000000008000000000010000000000000000000000000000200000002000000000008000000000000000000000000000000000000000000000000000000000000000001004008000000000000000000000000000080000000000008000000080000000000008000000000000000000000000000040210004000000010000000400000000001040000000200000000000000440008000000040000000000000000000000000010000000000000000000000000000000800000000000100002000000000000000000002000000000000000000000000000000000000080000000100000000000000000040400000000000000004000000000000000870c90e059b181c6835ee8018379fb9583065150845b833d198a7777772e62772e636f6da0171fc2d066507ea10c8c2d7bedd5ccc3f0dfb4d590a3998a614013326c0b213a88b4fd884826187393",
|
||||
"totalDifficulty": "6255555800944520547241",
|
||||
"header": "f90210a0b5950d9087e0e1d3dfc18cae9388fc798d9b3932a6efb4fc073081f5561adc8da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794829bd824b016326a401d083b33d092293333a830a00caa3307575bbbe59bb8f8a89f115ccb864866c2591d8d3ec3bffa6231532e52a024278597d4fddf58a4b55fe6a8bb7bf0e6cf1c6e75158b3d0d0b1bb9bb16647da01ba199a450390854e88ea5504144be61dd681e805aed7a1cc8bea61d5b61194bb901001902100820000000020110010418b02612064240040a4051001001a0024400e2484001141a422e56073887504031028220080010040501800000080080268040050018400100cc4710800419088000005a840a201c09011040086001260040000021004842021800024204400204a8a1180a8a0002164400202000115420602005512a20410088002248c000020e801803c051202030000420810912000401010604000801543084004414c051048082100000221684005c8015a40100040170025040132500014054900482500403088004000821194124a0b20000200229b9601c230180400802020800000408e49314200190121404002080218814a08085870ac84878814c3083662001837a2147837a050f845be9e82d8fe4b883e5bda9e7a59ee4bb99e9b1bca05714f772f5e2fa3a41a8c7435407b579b7c16397cf08eca605eadd9e63db7f6a88315d0b500d2cb0a8",
|
||||
"totalDifficulty": "7772265011609637471285",
|
||||
"CHTs": [
|
||||
"0x0eb474b7721727204978e92e27d31cddff56471911e424a4c8271c35f9c982cc",
|
||||
"0xe10e94515fb5ffb7ffa9bf50db4a959b3f50c2ff75e0b8bd5f5e038749e52a11",
|
||||
@ -3216,7 +3216,238 @@
|
||||
"0xf344c0cf6516f0fa6617e48076726aefbdaaf5a31f67ad8199bc3f6e426bf904",
|
||||
"0x3f3d2d33f36ba9009e9a72f3f5bbcb5df5392a19fc7afc8d37823aaf52b03477",
|
||||
"0x346a89411f090d559ff90e670bf0a385b1b09f117fc9ffa18b09d3b6d5d8e45c",
|
||||
"0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357"
|
||||
"0x5bc5689e2b4572b8ceea472cc7827e22cbfd018920beebf5c5b25f65f5cd5357",
|
||||
"0xda418efcaa0076f77e4d2f0c57fc32fa67179a5631d9df52d56497113d0e87af",
|
||||
"0x5a8050832e835202695129f6f384652827e61ea5f1be7ff300183201d8bd6b4d",
|
||||
"0xd9f444c382da42c310bd2f05955187163ae7b224e5efd44ab95af332e197d374",
|
||||
"0x9ef2c5bad361117eedbc2adcb72a2ef5eba4caf3a99a0cbb2a65a94d185e48ae",
|
||||
"0x7e3e089bc46b00a4174d90003379c382ab5bd84d092b9c4db3189d2bdc24f00b",
|
||||
"0x94f50fb12eed909d251fe69adb1a1f214776cb029d487360b55c3a2abb663d7e",
|
||||
"0xd3e1f4244dea40d0741255db2dae72103e263390e0ccfdefcbb2da59ecc5ec9f",
|
||||
"0x6808bf0cb7d4b677527de762b6db8ddf74a1b272349f34f44505912bd95d62f3",
|
||||
"0xbf7672ac474b5b849bc086ff8455216f015c8fc7660436dee153522ef6991c04",
|
||||
"0xe79d27a369cdd5455ddbc6bd9158cd1870aa895b3c3971d07f1555b95ed02ac3",
|
||||
"0xfa9e20a36c11b0dfbf7e9c62872a6423f5460dfd18e447481461a41176678262",
|
||||
"0xaafb6c407910341bedc82c0f260cdef75ce5653f644b93a465cb990247a32986",
|
||||
"0x5058e655e0c179e6c20f48fbd08c2f34f9341f6c07972ff40f55bfabbc783b12",
|
||||
"0x28d2e7c852de8602a764ff693b6881af18ddadd67fc7eff481f48ac20ebf32f6",
|
||||
"0xf82e09e7916f61b5cfdc3dcf193bf9d535f2b33f93a06c90fbdc78b3aac6b7ef",
|
||||
"0x626f3cca9e1a9e5e123e34485c8697c758ffc32213a727665065dd6abd2babe5",
|
||||
"0xb7f1c07f673d903daa61dec649eb12286a7a0568ee36ecfb1023ec41427c8dd0",
|
||||
"0x8d1d42bfe88dbe4c621cf68d380dc57e7768121a815546bb4aab29b7486da9ee",
|
||||
"0x79835acd7266bce85978f481aa3c58f3bab9106d72892df8579e472dc95c6899",
|
||||
"0x0911c9c804bbe9be0aebab6c92f5b71a893f72a9d0cd35a51b0e8cd19ab0c02a",
|
||||
"0x7fd2eff10936d8d12fd9a1c6d27e77cbec4e48253465eb7e65876134ff60c8ec",
|
||||
"0xc739ad4255415e2831c6996673f3d02dc79f6e6d6822f7dee23bff5b94833c3a",
|
||||
"0x2559faafbae0852fe5a1c924f0e4f6ccdf4fd22f483148b3672a3e7b3692b669",
|
||||
"0xca37f0aa3d375dbddc0b426c9564fe68f10b0a4cbbf1ab87f97b27b44878f2fb",
|
||||
"0x00ba40205d1bd46ad5b5e73cd5b1f3418bd892586d5a4647ac9a6d158f15bd93",
|
||||
"0xfa6d25c829299535e6b80af81a2416d10ed6903117e73c656b979a5f5abe3ee0",
|
||||
"0xfd82d8944315cfb228a8fa416c18ff82cbd8869c3babbd3389dca6dd66797785",
|
||||
"0xd8834cc29788cb40ec901725419df8c031a13e190756a6352696de870eaf4671",
|
||||
"0xdf6843a52bf55e0f4404e7bdf144bb17d5c47a72ef9482e712090ac9730a7f52",
|
||||
"0x4c2c562f835966c72985f7cca89a3b1a7b0d4cb04623dc96e337daa35a2f5925",
|
||||
"0x49d2afd87e83a04059dbf3ef4e2598b8d0c495ab1cf91ed3004e16a608e910c2",
|
||||
"0x5be64774739c001c239efae1ce9f2a5706cc6e3054ddf24b03c09358f2f4852f",
|
||||
"0x678f789dc8c409653b36f4d2015338165d3bc6a73f2a77ebfe438676b8412d7a",
|
||||
"0xf87c8fbf02d8e84cf72680e6b9a8b8be39fbae9f1eb1047c536d77535494a301",
|
||||
"0xe2428b952d2c6d60d4925f56b3d8227cd6bc608da2c1b20264befd8b1ad89454",
|
||||
"0x561a95eb50c663462bb8af3aab336bd745b0571746b10fefa791bc11be777763",
|
||||
"0x6945f40e3499d2769ceecf499c701015d93fddb607720b18dbbd5a6a2aa46639",
|
||||
"0x9c35b0367a2b82270d64f11c5299336b21b9f454077dcf7af3b2e434677a31b6",
|
||||
"0x454dc6bb2443509381e478f1836cb36808e2ecd1a9944072056c292b710072f4",
|
||||
"0x0c80566f34a46477592560a883a9c01fa393f7a2c9dbb28a54e46a5c017e8596",
|
||||
"0xeff6a1255090509eccfdea2e591516886c91191f1f02eaae4808ac95009086fc",
|
||||
"0x37cf60888e5ec75841e7f0533feef7200185a1c9f3253073216d83923c864829",
|
||||
"0xb169ebb9e418809a96529835bc293782e4fc6310dba450afe3e95a7abdf7cc01",
|
||||
"0xa3c8d5c71ce0477a247f56bfe95272ea07f0b7f10a8526b6e3ff9a8de8faa9ab",
|
||||
"0x2bf18db4ee84bafbbabaf05d1d4d383c0d5fc91be6ae902334496996eb3a8e48",
|
||||
"0x6c116f0d5809a2c28351a737ef3dbd1808685e1fd656e37df6b6e524aa82c918",
|
||||
"0x21e2c8e019c687fdb360c9bdd4e3a5133488cd2e0365aee3b823120734aa6f27",
|
||||
"0x20c9a1db9de894ab4f576265da25f391b32c0805c3da76fbfdd0aaf300f88a39",
|
||||
"0x23ef1f43af87be7396449fc1f89d9766c59e8adf2660812293c65a27482ddb8e",
|
||||
"0x04a82d3a4a5e7f2507688ecdcdc300d7fb97aa8be92a671d7d42c0b60fa4532b",
|
||||
"0x99e204c42afd6d4040faad384517d99bd0e077b03310d32223234d2251d6a07c",
|
||||
"0xe342c0c4295665b9e25773fc9998e18c460e723d0a14efdb59c19b27b9c7011b",
|
||||
"0xb654b1b8ede0d54a605cda54b4635d2b3c2bb8efd01ebd416e52cc87b590d4f3",
|
||||
"0x5daabc41eeb6de98336411a03ec0323995e81549941cf32b7e15c765d1b7b39e",
|
||||
"0x5103fc7f0fc6df43fb081b580bb01476f2b1cbde73e4d0f9d1fa6d8427fae789",
|
||||
"0xe2ecf5daba51d2f7b22106033fc43f956bd1db0c5ad02bd941bd3d2b96ca21c5",
|
||||
"0xf152bce5c6d1efb7e22cde72d6b8ca37f556ffb686a13770c5fab46e04837c92",
|
||||
"0x306007d8091caa5baaa78643307f5abf9a5f03996fc072a9016ba6b487b2017c",
|
||||
"0xf57308d0c02c6b8e2416c070554c7e29911fa84ef4cf2d934e2322ca262e987c",
|
||||
"0xb234fe7433d7fd71fe0c6dfc834e4bcbf84a261b95760a6c4eb67d222b9ff392",
|
||||
"0x753059f3405f60da3aa7cd1aa0cbcfa4d5ef4f2a6ed34b853b2c5ab2181fd383",
|
||||
"0x096c6630e821816d9f4bd83fbe0ccfd223282f34aae5a49f969ba30b98c324c3",
|
||||
"0xd3eec9dedb057fbc839c474fc99cb54d89f3f47d896e06e758c98f1cd194b61f",
|
||||
"0x0d44cb2a83b9a3fa18daac280cf08b46cc637d705488fd9400cd7300475d0a1c",
|
||||
"0x2e37a3036db99c4cb1c135f5ca6b527fa13b2e80ee421805b7be5d8b16983602",
|
||||
"0x381e0ca505308b7d3a083e60b0f9cb44c89f84942430ec9e4c5571796ab6a8eb",
|
||||
"0x90b04d35906c6f5a59c266c3bce7c2b63cea1486f714e272592ef9ecab25b0ee",
|
||||
"0x9cbea70e760f2ee97537d058d57f395886a2c3a6e769ccd3433b797b8716517b",
|
||||
"0x4e2167846e8d6f0f6495b5f1443f59bea143b63f242e40186fc6429434d1136e",
|
||||
"0xcaa0512739d000bb9783fceb46d0427098886e2b7f2e1140855f1a91f843d5b3",
|
||||
"0xc14df4e379e84591f618e60b5953aa6764146c7822aa1f0e3c2287e20753985a",
|
||||
"0xf4443154c04fd378b2c3812fee84b774b37d6e12778674403fb5c995379df866",
|
||||
"0x1a501c2733cc138fb6ff3716899e08dbcd4d75edc18af8972e8a749e45eaf67a",
|
||||
"0xfc8cb80bb0d0fb490f29aae3067641eef72e9225c558e7e299e0796a2086969d",
|
||||
"0x2b7895550febf03070485c02d521e7ddd80b94b7fe33a60b7d7ea3545b13e7dd",
|
||||
"0xfc4137c3cccd45050b5770a40b2f38c43c62b70b07d17bb6d762b405f3d753dc",
|
||||
"0x86ed22bbbb9fc6600112b91601af4fff56d0ecbe9b3099f91d4477cab8e300f5",
|
||||
"0x2273a60405ffb04bd024d880c79010f18d58e3c8ca0dc82795a0125364679fa6",
|
||||
"0x00dfbfe7be3bb2116d9a603a01ac428c0088a2c1477810cd5d3be0d1bd86beab",
|
||||
"0x7acfb03315585c79e2a47dbe847d24cab0785791f6af7f179fea4f9d6ecb0e0f",
|
||||
"0xbf6a2e20ee1da5eec12b792bbaec2531e20766ba54bac423011c1057215851db",
|
||||
"0xb5e94d1e3ba7363d1d79fb62dedd0b6c26b0485052dd64a7093d41ad2d41b890",
|
||||
"0x9b0cc26f08708814960de8f280ac26d8ed5089a19bcbd2d765059306da22c196",
|
||||
"0x22d8af121d3e395d3cb4f6ee43c06e6292f1b5ffda672d2e40dba69a2885f5ac",
|
||||
"0x04bc174272a57189d76aa17de0f76806e8481f4903575ed8c4df12b042637e0e",
|
||||
"0x06ebd2b6ec4b80280969a92726df5f9cb12d4288b60af617b7040876116656d3",
|
||||
"0x0e9430513e63b5173271c89b1c91af0b4818d5d14a3034e1228c56c94186a109",
|
||||
"0x8dc5422ba98d9e58112b052a00d4b82b1db32e22dd7ff2d845619899bd47f277",
|
||||
"0xde513d40bdbb1e4956b468cece598d77134626a900066b92fb2ecd6fcb5f81c2",
|
||||
"0x90746299ec75af1eb444ad14ac666ee444aa020fac3fb57796516d8772ec8f45",
|
||||
"0xaa91c30c62b24f943ee1eec7586b682289541c0355c2726e44424da8686ca24d",
|
||||
"0x76eb68baae9fb7ed126097f93842dcadfe6e7188d61549d9c0922a9b3ef8e80a",
|
||||
"0x5aa5b4045e7fe71559a6e93f4a89b135eaef38b9a7f3a84e383ab1ff902ceca9",
|
||||
"0x504b78f8fc3646e9722e96a5e97d99f2560d4fa3337fa5faf1cc8c8a05f3520d",
|
||||
"0xffd7a5d7c3b21e8144f7678a9ddc039cf85eb32b09000a600c9f12aa7d6083ed",
|
||||
"0xcbb4010000e96ff0b50b9627dae032bd50782ccbd51af8af7cfcd6cd184675f7",
|
||||
"0xb96fabbdd02371bf4a6a0dc00e3874cf43d47246e27163c910c141b6759a4249",
|
||||
"0x7358419f4e994ff296a37f2e88b238b3de6ba73062073c9467dec52a2df64422",
|
||||
"0xca90be9f190a1fd0548becfa719a6e4763e92de0e4da4283a33b5f7d2886b425",
|
||||
"0xa629364f7d6329b008d9c6a0262327bcc12953aa515cdb7b8817e7fe1d746d46",
|
||||
"0xc5167bd8cac1ea6d14f305c9d4fe075e1875d96353e5236473b6daca5ae9b4fe",
|
||||
"0xaf4ce2490e9504172a4393cf14e691e947c86a0ec7b53416384a5832b213d6c5",
|
||||
"0xbfa4853ef2eecc5d99a90e1abfef37ca10c1f823c1d0ad59a1bb19339861241f",
|
||||
"0xbb5a6584cdc7e4d06ec5fc1514233cc42970f6c332c3a9590978dc9908e58c0a",
|
||||
"0xe69d7a0766db411e504f09a8f39f0583b2869016bbe95f21dba432bbe8b88442",
|
||||
"0x89cf4caaaf200881779f5fa6da8ae91ff1c962045dd0622b5ca65c830d3a9d4f",
|
||||
"0x82d66c631f4c4167e5301d896dbdfe24d8245b1de041fc85eaeb6e35117ed9a0",
|
||||
"0x957907bc93879681d8682a188622f9bf2c7d2595dbe3e2e34bb01711cc4124d1",
|
||||
"0xccb3a3380550586696abd3ac267e85c7516b2b682b3c48f66aca94d57500f3b3",
|
||||
"0xaf56d4650406e70748dc860a7879d8d522599081f8e7011056c976b860703e43",
|
||||
"0x5d96ac1d2dff8a054d880a44f5d45a1bd18aba29085fcd633b0608351ff1876c",
|
||||
"0xe051736dad8b9f93a8f1c13031c2b63249925e152685a2e7ec188ee089861b20",
|
||||
"0x0db8987339e1fae41af5f08e6fa15da5fd80de3431b54e82cf8edbdc792f870e",
|
||||
"0xcc99097678110af2be8dc07da8d642dce928b7d9e2728fe6fef1fe2eaa81a72a",
|
||||
"0x2428c1f94ca57c7913b011a68281eee9ee4855e4ed2c97e34a370e649b21acb1",
|
||||
"0x501ee9580c89b1f67c5b3b69ae5fd1f83852a2f9330f53565bcd04d8a7c0b776",
|
||||
"0x16ae47cfa19e8046f93a579fa2557b17aeca7892fc7a82b6d539930c8b7c95c9",
|
||||
"0xda62590043ca70c1cdfc7969cdfa853bddbcef0ef62aabb9f372805322511014",
|
||||
"0x481b4aeaaa60504c94dcfea966840b381db85183c34cd25b4857300b5c189003",
|
||||
"0x035dcc47f8670a9f648bcb0232e42fd4876243a7a3bf737b88d723ba187929a7",
|
||||
"0xebe9bf09e3577865aeb341a06f67bb6e607f10b04ed9f9d733492a9d0e9ceb1a",
|
||||
"0xad5d85b58af6aef7f81bd6b2407c6e4884ec82b2ae2aeaa24e379a3d35902375",
|
||||
"0x0f0dd63d7c6c284659283825624140b31a3adaf7cdbb2255faca443e52ebfe84",
|
||||
"0x40079be1c9394e95b4823895ed380d79333ca2085aed2abd0d766f84d21b7b42",
|
||||
"0x7cc40ed01b436ce225a3f9c5c2bc7f6f81aee40bb83a54bca2fe899b15f3e2b6",
|
||||
"0x1b6356e1a83ca5b0eefda1fd62fa959b118d2a19a6a90f182a53414b3fc7f9f0",
|
||||
"0xae4a71712cc96a5b30b45e3b92c339c2e975e4ed683f4d1fcadcdc121ff7c6bf",
|
||||
"0x226f6d8c71ec32c5eaab6b01c0fc1d00ae95e60b383d09560e90549b79eb1447",
|
||||
"0xf3dec779841c9384df93bcefbba8700a292b570b29d286a7c9c5a442b4788a20",
|
||||
"0x63ef48e80efa45383857adcb0f31076393260cbad058d1938345ad13faae50b4",
|
||||
"0x7ba213077278bd01ff874e760c3a0bfd4e5cf65bb18eed8b0f8076d81e16d05b",
|
||||
"0x92eace1cff535745aae658d9ad90c372d41ce318a20716ae3b2c0958bdb48b33",
|
||||
"0x76b2607fae8dbe532d8516c4c33e309f2c0a963bb68035f4361a2859d62d2daf",
|
||||
"0xfb0c46a588438f4f217e183ef7772b649b5a45a318253496b01676253dedb568",
|
||||
"0xd6dba12c700a0c5ca59b9d17f628066405de8e4399f92472cccce2e25e70ba4d",
|
||||
"0x2390984444cbc9de301adaf0853f4f6ed2fb56fefeabce717306cf1e40da9618",
|
||||
"0xa6992b0db82c50ce623febc7f16c8a316ce262255de11ad1914316b3d986fe66",
|
||||
"0x96787cf8e0a70ffe5b84151ae8219362ba6d9465223c23c135590fe4cb9ab592",
|
||||
"0x0b4e7fba24f6bed3790b8fc289e2715d9a3f4235c9316dd9d4f889f710a65ae4",
|
||||
"0x49585a7af98ad032371df01c458fab933ac399ff4d2d35731a2d86fc136b5eb8",
|
||||
"0x517947f22d8d56466dbb496f3e98fcd01864176af19be2112f2260e55bddbd58",
|
||||
"0xbc0aa38cbc79c3557fa81e446071e6d531989d088c6311060bff971e430fa36b",
|
||||
"0x5a0a88750db7ad3190dcaaf5bde2649e6fd99cc5b05979fff84ae689ed47b51b",
|
||||
"0x9ad902d6abe59faabfa5fde485c2fe16f6f3e2c41aa8bdaba021e94a3c292dc8",
|
||||
"0xbd6e7bf8b466940b9f619e3f433fb68c68d344974798996e454c925e2628b1b2",
|
||||
"0x112b5e9d438eb79aa9d7b4488b6aa9f7edf7599dce805d8781510302da45e9a2",
|
||||
"0x881255ae2cab543ee6b429e1b201c197cb35051d53f881cb51fc58f9c760e51d",
|
||||
"0xcf56a4ed6b771e4905e6ba888390526eba8ba3483ead7585dee00c0eaea58cbc",
|
||||
"0x12705d1609ee34bce0c82bab9da730452db57863371f5b84de84c4c135537237",
|
||||
"0xa9abc081a75bfcde86ea830483be240cb3bcfa72ae34a16dfc35cb964dd7a457",
|
||||
"0x65cf0c91f8567d8567ac3f00ddc19da0b916179266c7e42768fd5d7271e91092",
|
||||
"0x07f15ccc91a47edfe9b67a79d05ed1da1410e3ac16e4a4c2147c3ef0de26ae62",
|
||||
"0xb44eb7db9e4dbe8901bfac43ad54ef27576a3ac0c78218138715e03b3f9a782e",
|
||||
"0x9ef66d20aeccdea66ade0fe8ccc0a85dbe9498305509c8919b670ae8e854a450",
|
||||
"0xb10a7dbd4857f910ae8cca5d1b7a85923adaad65c4b00d1255813efef00c646f",
|
||||
"0x20410bc64b58a1c221f7b38f293700591692c73a785d94a5548b336bd5db10da",
|
||||
"0xed7176f398eb75ae6c1d4348d3882aade99573f8369ef00e809b1ff91b5a9191",
|
||||
"0x35f06785e1f7e362682e969586322b1588624f6025692ca87db21cb199c382f4",
|
||||
"0x9a6b06141660e2bd106f6d46afd2f3e64d72711ffe6a9c495887bc3932f7934e",
|
||||
"0xd64e602a976e86d3948d0f4cf0b8f13a63558d5bdea5affb36eeb91007a653b3",
|
||||
"0x71050553ca1da7234764a5486e4647fdad00652560eb47102c1d0fc039b4b63e",
|
||||
"0x53ba43f79de58a957e8ac0d998ecb4999c68f423b1769d9e8df2405259dcdaa6",
|
||||
"0x17b33d269609bd90fac57eaeb298bf489a3b8a985cfd9998d297c7e0628bc84c",
|
||||
"0x9b47bba7ff6b283e76100e36246c0dcad836ff29a674fbb1c6d2f58e38e29f92",
|
||||
"0x262f8387628500fa26e2cdca6b5938262c8fa81888daed41a09d880df136167f",
|
||||
"0xb6c6d0ed2824a9818fa9476c99a810cf33a0c1fd3f2fb6b7a44603f2442525e7",
|
||||
"0x6f3437e677dcc60cb587f6100eaa2e7ef5c76b57023b63ae61a6a8ed2750512d",
|
||||
"0x4bb5aad759b0c6390cf4dbc6c32e78f2721c2be3f40ca3d11de880fbe90e456a",
|
||||
"0xfbeced3e048769a07bfd50010de59cd24f2c534234abc1ee7f3fe9d7e3d9f482",
|
||||
"0xbe871fdd431974370e8156fb9347377d1bb07990ff60296abbaaf2c38b4059d0",
|
||||
"0xcbdf566fceb5adc33608a847c77b6f3501cdc4182ba98e04e1f7e8b8ae66ba5b",
|
||||
"0xa06a5de4aeafdb5981ae02004a38c524116ebe557dda83abdf03141e4dfbd4cd",
|
||||
"0x73660bb361b94287b85b6c41394bea5447e8e3ccffaba1772a765a8fc0fa9b27",
|
||||
"0xf80439908d6173fe4fea42aeb07ddea2c644e581373dbe9dbb9d092f12fd2125",
|
||||
"0x32d935f078bdbb9ae693bef4ab8316e7da701edf42f156568b639193b0ea24bf",
|
||||
"0x8ef0b9f247b5b9d9e5a813877d03a518d1f06900e2fdf5743feda3537ab3777d",
|
||||
"0x59f92f14340a77b94839b6ea61389691a6fa5bb2ddc5b2241e873b066d37fc61",
|
||||
"0x0288bdae302901b701df46263f4b12bdd6bd76436c3ae1626936e1b4bb631ca7",
|
||||
"0x2fcfd5a54d6bbe07d4063ef64fe4b164bd8cb89a8e03cb5fabee98bfef280e43",
|
||||
"0xd8d1169b3a9aca48f167cd43e9617d3ecc74658ea61ace251beb370d3c05f86c",
|
||||
"0xdb2c3ef7b8a8a18ad3a8ce7cb8a6be2e1ef2cd694fb3f1b2e0732f2e27c758cb",
|
||||
"0xfbffbf26f4756bcf1cd217686597ffe9c1282a70b279c8b01ee5076ec31b1c2c",
|
||||
"0x2cf1404cc8482698eccde40185740753c47319b1aa30d9204fe53922feaae9b8",
|
||||
"0x553a9e079d09d3f8251947ab37891027fc3d041246f2e43f01321fc3523b508f",
|
||||
"0x35954f131f276933c7ef3938f35c6011806c7dd637fa249451379003d740cbaa",
|
||||
"0x1ee7a658e8a2368391810667c35b8b0e321d381907e2312e7789a3cc7b0341aa",
|
||||
"0x4cb3c908526bc6ccbdd39d855b3b3649e59eec4322bf48f07598d98240101d0c",
|
||||
"0x996eb99b0cb27fb5ec07873af17933f377ed2c131f02926bab74341c475a95a9",
|
||||
"0x68a90de2c8ea439db0417b77a23eb66e7421268335be7e4f593a52b1093681fa",
|
||||
"0x4325afa26bf545951a73c016d866f1c71a5855ef52202b7ad0c54dc23906936d",
|
||||
"0xaf5111b606b0e6d699bb4fb61c8a0592af7eb45dd7357b3e896ebc3e798919ad",
|
||||
"0x4de03498b2d532a8eb01a12edea2a15b8a907d6d23ccfc380507a5d294abce99",
|
||||
"0x5d642ba55dc046ef1b84fe594ae2e46b844cc6590d580e2591ba9c0c1c942c24",
|
||||
"0x8477bb69d6d23ae4f45e56c372d66f42ba7417cf5107136081b5ccdd208b1545",
|
||||
"0x924f641a7cea7cf76ad8920b9ee7c39e74304169571b028fbe40e6ed255a90f4",
|
||||
"0x4b39dbfae8635f286284009a0213c6d267d5f48485a25f2df855c5cac5e7d6ca",
|
||||
"0x61827bf3a120a079111665f78ba2e5ad15943492e4ffdfc708e235f44ce92842",
|
||||
"0xdc0c0dafc340277058a6f8e03bf4e5e733e05fa638e2a8c4ebe4521960bbdc20",
|
||||
"0x7038c52c4e92d6ed20b19481ed63d432325f94ee2a3ad4c0d5e25fafe5b32bd6",
|
||||
"0xe1f5a1123679ce45005d53672018e16648fd44c4a2251802f295d29ed876a0db",
|
||||
"0x173a332438a181f6cf1773b2603556d229254861534f34ad65b2170b0cf47fb5",
|
||||
"0x22a19ab1d828b5d05057f40f5cf798e27ec068fc584968987b7bbe440f52ac84",
|
||||
"0x15b3e3b6e1de6b8a407ad7e325c53c4bfa9e73f23c6f3acedcdf68d759f73860",
|
||||
"0x0347a8e310cbc921daf829002ba0c44399c4dd7c930ac1fca203272949e09dc9",
|
||||
"0x9babeec2d3003ddb15fdcb89ec7b61c0d7f795145b58f55a17810447d5afe5be",
|
||||
"0x62c14ff2ed414ede1e3fa7fc2fccbab0b8f284b9f38127823c3dc9eb55a08b44",
|
||||
"0xb301a7c865abe0f42d9444b5c3b775dc6ab4c99effbe8d54cec29745ff4af01d",
|
||||
"0x3fabed16363d78f34a13ca6b99cfc592671668d4281c5eb3ab07f4b9017a4ebc",
|
||||
"0xb14af7c7331f7b5518e04bc31c8c2b63d9d497acac405bc22e1ab2431105b867",
|
||||
"0xb7b90e8852ae132f858cb98635fd6e1267b141de7da6773ec4092d5c83def42b",
|
||||
"0x1a5c8bed811fc72de8146516cc4d668fc4557baf48082503a2a5cc0e473b6e08",
|
||||
"0x0060158b427095081a18fc57c4f56290873188960dc0e4d2b16cdd57b5761100",
|
||||
"0x2f0dd546f4982d47b6e04ce282b19be8e165b5c89b5f03c1ac8c6d8be2af2b4f",
|
||||
"0x229d31a50f46afeda23a2535c8b011a827383c981e7e59f67622359e4b307a10",
|
||||
"0x10da7b2e78954845b506b9672ff93d3a617f187521116d442b364a1178f10f08",
|
||||
"0x511325c034c772ff3a61b1c8d94e3c13f19cf1e93523a8924666833bc1e5b0ba",
|
||||
"0x3a8b0251b2f7c99774d0a7863388422723b5405fd1db035ec5e30df90306e251",
|
||||
"0x885c3b0507dcdd6e1cec187cf3d97ee12ce101ccf63d99c1c7fc77dd57ee0439",
|
||||
"0xa76f1fdcf546ccb62f86ec7b85bd8eb662f696d7aed2f2ed2b3c769af90897b2",
|
||||
"0xbec073b15a35de54487b60f92615cd44dbcb5a5fa9d1bcca2ea31437b2e45756",
|
||||
"0x662013eba4201630ccc4a9b6fb1dac36f439cc6cd2b6f295c0260713d075108e",
|
||||
"0x81b0148f7e690088330650b01c52831d50f3d30ba2fd2074bca5513c179ad30a",
|
||||
"0x01614cb8f2f2bd6794a20513fffe99a36eee526b7145405db15f9c2ede980093",
|
||||
"0xd3d8664a5464c8f681e37265948c4046e373843e602bee66c8583277397db258",
|
||||
"0xdaf61a9e7157100cce6ea5bc405926fd4190fda7354edaafad9b6e468bb24422",
|
||||
"0xeb05144e032621f7b1792dacbdc79c044a268442a9a9284ef1b2d1d60cadb29f",
|
||||
"0xb1916e802e8e3eca2570d1a190d317cf38cf9f6b58119b65ed0d60b9749461ad",
|
||||
"0x17e103cb26e7c5c7678a523f99f90387490bcca00916190e7e1b38274c52a375",
|
||||
"0x105b8126ef037364f46a44fdca4fea1ec4c099de5a05918688249fb8844dfea0",
|
||||
"0x7ca09f536bb9f0d7b3809c086918ba4750722edfd47153a8412fc761eb4783c8",
|
||||
"0xc988cc2d92dcb85eaff8cf2f70ca49646cc5aff6c8e10b43a0581193137d3b92"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
|
@ -43,7 +43,13 @@
|
||||
"eip211Transition": 5067000,
|
||||
"eip214Transition": 5067000,
|
||||
"eip658Transition": 5067000,
|
||||
"wasmActivationTransition": 6600000
|
||||
"wasmActivationTransition": 6600000,
|
||||
"eip145Transition": 9200000,
|
||||
"eip1014Transition": 9200000,
|
||||
"eip1052Transition": 9200000,
|
||||
"eip1283Transition": 9200000,
|
||||
"kip4Transition": 9200000,
|
||||
"kip6Transition": 9200000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@ -56,8 +62,8 @@
|
||||
"gasLimit": "0x5B8D80"
|
||||
},
|
||||
"hardcodedSync": {
|
||||
"header": "f9023ea00861b3771ffb84fce48b8ba3c54a09f81e91ccb38c401261f06d370098889a43a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479400e6d2b931f55a3f1701c7389d592a7778897879a071cc81d58cdd21d1e17f7389e55c530cd9f94cc15bb32af6477320682327dcffa06090021a7c09ae5e75e443410ebdb76de04f1eafb0ab910daae96ee6eec560eaa032510bf257dd03b11f3b4761b94b495a5b5a18cd6eb17c77785e0f46e2ffc882b901000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffd8381e001837a12008306697a845b83bd6096d583010b068650617269747986312e32372e30826c698416e0ef58b841117e2088e2835bf2afcd5d48f42b3bf2a1f33435f21f089ead2a6bae7d01c1486e645b460bb3c726a827ff1eb50e0579f3410563bae090fc256cf1d8d594b82100",
|
||||
"totalDifficulty": "2845866505151538604560067685603735513869853136",
|
||||
"header": "f90247a0434ba1ebe3bc9d9d12886f616afee0eb785dd00d78aa64502045b249c8a3cc33a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940010f94b296a852aaac52ea6c5ac72e03afd032da0d1c1137be913218840c44bdb8f5709a59d8608b05be0dc2401402e11ff1bf2ada0eb50a864e57e19bd4c8499725a6a3841f706ff5d743e64f1d06db903aca62eaba0d4d77727f7253c109e6f048fa5b1583b6c2911ad77f7d59d8947d38a96a67729b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090fffffffffffffffffffffffffffffffe838ee001837a120083013502845bea4f689fde830200088f5061726974792d457468657265756d86312e32392e30826c698416fa93dab841c80b3e34bacdc91e01f6a76c64a920a65edfea86b84e0fd59c6d8dbd7758f2dc4e3cb446de8dc07f3d8cb71375a6315f401cd1ce54c56694e4e01f7e774555e701",
|
||||
"totalDifficulty": "3135776192732436705400032023148164213445066062",
|
||||
"CHTs": [
|
||||
"0xdb9557458495268ddd69409fc1f66631ed5ff9bf6c479be6eabe5d83a460acac",
|
||||
"0xd413800c22172be6e0b7a36348c90098955991f119ddad32c5b928e8db4deb02",
|
||||
@ -4214,7 +4220,423 @@
|
||||
"0x3ef50c81169af169c100f58f3afcb8e2f926d957b2adbaca8787be5d4e8d7233",
|
||||
"0x8783eaeb56ca2d7fec84e0e272b77271fdfd6c14452a2e1dd83de770c5d99a1a",
|
||||
"0x861024460895378ba100c5d0c05e62bb6cac8b21ae529ab5cab39eb6c6cabd90",
|
||||
"0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b"
|
||||
"0x1c741ed9eda60e5ac585e2f48f06fb988367c2c40a0d8111bb04b260fe44ec6b",
|
||||
"0x6051d77e0596a911bce132c4bc12be2ae5cf29d113dd52a41b3bc166861149ce",
|
||||
"0x92c049df5ddb238644015d4e039e169614ed1d926de070952f2407912906cb4b",
|
||||
"0xa897567fc1ee9437f2876deb3de2b11b8fc00aa07340564031573f0351ec556d",
|
||||
"0x3e54a8e15218db168960d28369003cdb1a76f8db19384e9e2696ae66a6693d6e",
|
||||
"0xc5db7ade97cf28f8b61f2c63a0773201ba64f37dadc19c03943b6772aa7a1a50",
|
||||
"0xda784d1bf64b7efd06558b90cd2436f3e61dc0f7a8370ff92516ed062f461091",
|
||||
"0xa1d10b0a36ec5169d2df740878d051bf4d38ebc5dc04ae5558daaabc2bfa1471",
|
||||
"0xcc89a8be2ff74a7bb9e967cfea3cac067aa84cc455a2fdd5449577b52a2b4ff3",
|
||||
"0xbd23a3e6d3198d81d798c2851c36b954fa6f359bc8fc6e04a0b757e3d0ba053a",
|
||||
"0x74640f825b9d9f95be69763845aaa0269d3a6ed5aaec88bfd9b5c4139ba7ef41",
|
||||
"0xc01a29e41af3cc0d0a13ea83f131f3e4828ec3e83dd2fdf9739c139938dfc2b3",
|
||||
"0x832509e705972acc7efe91475e8d76ac00a12750e194847093825e6c4db9e83b",
|
||||
"0x63139d1224766ada1318613b9ec5894308efa2473e809d9e37c8305c6965f2cc",
|
||||
"0x76547e54dc59473093c3fcca1166307cc7d0f4f0e8a35d850507bec216b76476",
|
||||
"0x3a6a14785272391982cfa690762f5b2aeccc1dc0bb13eab6b9fcfd056f40703a",
|
||||
"0x603e32b52795c04416d800b6a936343aaaa09898fa97cadc2b157eeaaf3bd6f7",
|
||||
"0xf241102a3d3f3a9fdc5a1a586b16fdce4280c6c6da04290541eb3cb9c28c7325",
|
||||
"0x6db6de041bcc7c00104a21bbd487a1e1ddd5e4953f7a503aa992d68a8a7bbc43",
|
||||
"0x8377d795c55eac07c0acca674e775ed7d8eea35867990c8a776f40965c9ddc68",
|
||||
"0x48d62d562279641043e405f4d7fbd76050d773103871c5de2c8acc25992db502",
|
||||
"0xa9ef42d314e15c419537e022753ab46d41318f1fa8784e4363494f395eb6d236",
|
||||
"0x99572f567eb602a1d9839bd23b41562bb3782eccf9a8893e54b002e685ab378c",
|
||||
"0xd8cf2fa2291efed46c1a36e1b8837be62e86caacc380aa6397792ae8baf8f3a1",
|
||||
"0xed2e800df1acb7bba5ee6251592c397a604debd7b0bfc28c8b0002dc40faa8bf",
|
||||
"0x9ccece195d9e67e318f6d2952bca9486d09f4207c6d8be266cc0eebe41290920",
|
||||
"0xb20580a5c96c25bb59e1bae6ced3ea5cb69d903f64e648bcb38b799141b3cd5b",
|
||||
"0x1488647e697452306d2744ca6c709007cf75e2e37da3c7c05006211ba0720824",
|
||||
"0x009c3dfc5494962c77900fb8da67d7bf2a2f4b855c521b9d50c4aafb1e0735bb",
|
||||
"0x482428835dfff3ee1da335b36ba3aa1969fa35e89150e5b3c1991f28272d14f5",
|
||||
"0x6a972044f2076e98833b243c9ed18162d96b46823170ef7c20b1a02d8bbd48c5",
|
||||
"0x676242effe0fae84110c4933beecfe5ff549b439e54ff5a588add229329e5365",
|
||||
"0x2441bce77589ebf8019fa8ae870a8529479c6eaa0fed7e0fbd3cc7439dbd4a09",
|
||||
"0x0b20c25d2c6897c1a8dc9ea1364d3c72d33c97b4d70b9176c3f0a1e3b6ce08a7",
|
||||
"0x685aa4e279118f8326a90c78e9896e40d9baa62144e2425887dcc704106979c3",
|
||||
"0xabcab60973f6bc9ec3b596452e7434c4dc89c55c8eea925fc0092d1103c6f86b",
|
||||
"0xcbf44f106f3f2c0050906b5e344ad22f0e0034067d35402d447311d254516dd0",
|
||||
"0xcaa67796a8ac69283d7b6304181a988992130ad8441d47b4fdaf236686dc1caa",
|
||||
"0xad06e6db230bd0bfaa0df59d1ae517ced29d5f11b34f76ef9bb6a73407128b59",
|
||||
"0x93ef56a4951e4e5c19230918b1219c1f07e9356363503c1410e71486ed338f87",
|
||||
"0xc6fef02b5bdd4909906c40cf5b999fe9e08e4c0d8bfe59d3c9aa99011136f780",
|
||||
"0xfed633749700ffdeb0921a537a215ae31c25b85e4f80727376e50c247b4c5a38",
|
||||
"0xc39d8cc15f4331fb7db2c24ee1163bd164e81ad2ebc43271f841fb25d03835c6",
|
||||
"0xb13962dcb364ee49e2d0a34dd1a555fa8df363041504ef1e987ce78646d64146",
|
||||
"0x97e0d3047e2151d53cbd1358da627453558362c6a830910b33f241848b20cffc",
|
||||
"0x587ea98cbd1da50c0af1986f6ee5e676658c06442e893304708db831fec8e804",
|
||||
"0x0a1d21212d9bd85a1a39e046c897d1dafb496bfd80762beda2fd3eb1cdc72eb9",
|
||||
"0x46aad83612f04e7a51fd642de742f713601992e58de4daf24148a3e6f3318aa2",
|
||||
"0xa65a8a9ed4fb28fcab6ee3af5df4647083c2e735fc652568759fe0426e9a294e",
|
||||
"0xacd7ed5525cad187f053ba98487cc4abf24f76c8c0e97e71a696d553a3a41b7f",
|
||||
"0xdcbdcfbaee764bb404bfa5261b5037b9c7ce567a3c1aa9f7280071990320da18",
|
||||
"0xf195aae79a232b2170a98602efaa2efbdebb3c40d2438e63bf0954e4dc779cb0",
|
||||
"0xfbb2675a62e2e67baf85e56fcd4cdf2bf89ff7905952155d3cfd4e625fb674d9",
|
||||
"0x5b955473a35f6b0d24fa8be8009734ecee62f6c4bcf0cafc2335f07c51752fb1",
|
||||
"0x66f37b268338f4ba1e21eef6884aef245bc36935be1f5eb14ee1d23618f00f5b",
|
||||
"0xaab809ee86773263043201b83bd445d98a634d8a6da4c389b2336f68381dd481",
|
||||
"0x509fc38118491458e45c7e8ab1d60c687f50d85fc1c0bf104b531a3b352198ea",
|
||||
"0x20d1e4f38e83b27b77d55281af40e9f96be098fdbb90730170638c88ab7e435a",
|
||||
"0xb33711864d62709a98f81d9c5f0a301bd5808d0e8ecef1063c97347af754c8c2",
|
||||
"0xd69fd6c0fea478bb380b948f5b054f91831cf26d304991d40ebdf0b00a97503c",
|
||||
"0x87157d452bf57e617ac1dd2372438b0777b83f6087d8223008d823652c634882",
|
||||
"0x9c54b0172ae0223e6b23f7e000cb6887144e615efb02c74596002dc26d43eb5c",
|
||||
"0x5b0f87baa8e40f0a2bbc1a76afbe0b21b5e8aae1443f0d38c3ac55c5f942db42",
|
||||
"0xeb68d93e19860fb9fb76847080edc345972e29ab1ffd417ae5727d3cec79c0eb",
|
||||
"0xd27026033bba2557c79c4babaf669a399fbc72a2a5cc06c707e24eaacee83bce",
|
||||
"0x420d887bd82cccac29711c52f4d362b6a7d854e694f8d597d208d0a094fbad8e",
|
||||
"0x02ff085c6c3c47879a91f511ea4c54a214af8160e07dce8e82a6be9e8299e237",
|
||||
"0x1f0384e0afaf47ba59aff9f224905950768674c48de0fb0312749b16edb0a347",
|
||||
"0x55cefaac814e132ff335882a366ea6173bc21fa713e93d8ad92260c84cfd2d85",
|
||||
"0x58a8dd6e036a05a937a7053be916c0e7f719f2a1905186e7586a9d2dafd5a1a4",
|
||||
"0x8714d03549461e32a467cefdad60a96788c97172db05c18eb9debf6e6a4d39e8",
|
||||
"0xd141656c1f57c12feed31dbff3817e1d2af4e1b5cf6aa75d1bb29ea2c0a3ae69",
|
||||
"0x5ec365177e19fca3c1063e65a9342008aff04ba9d03d53837b598b143504b97a",
|
||||
"0xc620e23ae73d423bf2628a3de70b1a1f915d80173e0c8d1443a44b91400c5a8a",
|
||||
"0xc72c2356ed53eae5a4a56bc248d9d2f4e9154f1404780b84781f357cbc7ad2d2",
|
||||
"0xe60bfe30e5a1a9457ccca65810675e129948b474f391ce64d270200be7ea6beb",
|
||||
"0xf679887baad8f8e497d60b015156f194b94fc30c6cb1f83fbc4575e99b95a8d5",
|
||||
"0x654463146799fcfa18a74ffe4f2423fa04c8747c16b789dd24da26d0338d381c",
|
||||
"0xe8b5406278d9e4622d088976af8b5e6b14cc146a9530c862a42fa5566a247355",
|
||||
"0x8ecb4735132f769663781f96fb531115190e68390c54e33b250db874e90aebaa",
|
||||
"0xef13bf38c2ba993c9dea5777e5db348339273d0e6dd1f41867d3b258f24ac4d4",
|
||||
"0xbbbbeedf7276a857c513f4ebce88e3b531c99cf206eacd1c6c29d3cabab45df4",
|
||||
"0x89cd50cde2de3ef40de7502241b78e664de53dd4a5e2ed85db62c55be0a4d8a4",
|
||||
"0x0da2cae061e7dff539c7e39b0b9f63af3217f1a51bc597db957b6a3972cf7186",
|
||||
"0x57aa87a6daab3c65519de7c1c1360ab33b830d46f169d4e0d3c38e7dadef289b",
|
||||
"0x85fb1241c4110b4f3a6c197450af8ac47bb24d531219f6cefcc079717b208c84",
|
||||
"0x52194cfba6bd7d5eb8b438054fbaf5fef387cdb8b1a7ebafe44cdcf4da47b1dd",
|
||||
"0x7d24eb47a1310f7f4244e825847f634fd4a4224f695a3609c5250dc6052de6d4",
|
||||
"0x38edeacb93b10653624f77dc05063499daa770b74d6b63ebe656be5a3630b7b8",
|
||||
"0x4e050f7b9d73c1aea3ce60c8eae8e46b55b6d4c1cd1eae22faf982895871dcd1",
|
||||
"0xf22b284ed4d97b7d3553600388748721a328052daaf92a58ed5403fd4020a496",
|
||||
"0xc5fcf858d9a9748045fa0ca1271ba5af780a788c51d693815e0490671be3885b",
|
||||
"0x2342efdb88226e68173ef84060a0d4dc6c8aa9c9431883beef4a5588f3157fae",
|
||||
"0xe1599bf452eaacb8dcd51ff835a9ef5761dbce83cfc719813d6a10772ca5fdb3",
|
||||
"0xb754797393b3216778ea6389361ca5951f365ae4e7ed99ed4cd4c9c76ff442d3",
|
||||
"0x3fb5f9f3754764155296c6ff4c469109512264c603ece7c78c1231942bb8ac35",
|
||||
"0xbb347d23c7d703cd2801e2763f1a6c375b5cb2a666ba137c4d6442c3f94688dc",
|
||||
"0xed3806645b55fd7027dfb7f5f796933049ae558d26ca695a01e1b11333f5e453",
|
||||
"0xeadb7740432ede4f90c0bc490c15fb377b68de0fc1ee3a56e87e21e7771211fe",
|
||||
"0xa8c0e907e0b544e7fc3116d47e4cdfc8e8688f5cc4a67cdf600f74be6b79775a",
|
||||
"0xc6f6b94f2fb4c56066e3c722123b8e85f80ce8baa0427b62c5a2ff937702c481",
|
||||
"0xfff0b94553a7daaee58a7e15daf9845d1a3ad4917d81d4f23dad27d0262b48ec",
|
||||
"0xb9084676613e1a063c2b491bef1b984acfbd2dce60a8ed970688239524e31962",
|
||||
"0x196af717eab2cf09b47db13605ca4864cb0c4189d40c9b618d8a7d3f92831d78",
|
||||
"0x4fac369653dcfe74d86b7422354d68f7580b1ae0ab359a8b8f8be8582590ea7a",
|
||||
"0x035ff04f84478354706945480266321d31790f5445028f3e964801fd9a16c78c",
|
||||
"0x63df70a24370a408bffabbe1c7a4c9b9e40be1cb326ab10d63fe54bb9de50d34",
|
||||
"0x37b5c558d31128595425ca68deddf5ae7539abc6da838837eb1e0457e092d9ea",
|
||||
"0x41a9ce82ab27afbc84669368c2e75a15e6386b77034ec316795a896ef9de577d",
|
||||
"0x08bc6cc18842df4130280823f7676f418f4797d3ddfc544e54267e6456cfac68",
|
||||
"0xeabc09ffceeb35cc4ec18518d4920bea2f43bf746f23b5524fa405bd874e9d34",
|
||||
"0x40336744dcfe6f312e17eea83f53538f9999864c41bec43576cfcbef68d12e7d",
|
||||
"0x3e780dc9c8f2b708527f1eebca75d18507e00e226a00e1b1ddd0b715aa8dd561",
|
||||
"0xfd6a3c50c4a4d6e1a6fe27fa96f6aa2654573cbb9b839ce8e09a75993e2bf8e5",
|
||||
"0x166c03d381d6ab94666099024adc95de0ecc9818e5ceb49965767682ca0c73fe",
|
||||
"0x9805810b802a51a3ae18ce44f6b2c68abfccef2119df2430e4693e291059e222",
|
||||
"0x353ecd1a0922e819ffdcd634385ebbdb674d247c4fe75e2d5437b659c98424a4",
|
||||
"0xe75fb8682b706ed6596699d6151db4dcb19f6e71a3b6e34aabc3508c919f5c17",
|
||||
"0x6e9bab64b10a2341f49e81d862ef3322d3117842e3f1aabc8b774c68484a2a31",
|
||||
"0x82b5e79ee8d72c3613458c975530bcbba359734a4e9f07015686dfc521230329",
|
||||
"0x86d48d57ccbe1f1986a4043748b1a0d8d76fd56bc74e7c48c6fd742affa0ee11",
|
||||
"0x46ee65b9c2fa3e69aa1cd6ba5aaafa7f7aef59224098b60e22994996c927c9c4",
|
||||
"0xb6983761b177e21899799410dc018f1acd3d417fe35943fbe57207f9f799a100",
|
||||
"0x594057a8386db6e159d43d136c464c5e3980eae75a73900f7a84ba94803fc6c4",
|
||||
"0x53c78073c4a4c44d17db85be06f38ab47ecbb7f36ffa87b9db707fd2bc87f391",
|
||||
"0x4a976673044732e3e8a0987fc8f3c36375e3c4fb3722fcde5259af492ec458c7",
|
||||
"0x1e2fc8db341a4d9e123ae4ff4f4d8096d8afef47c5d2915c665922bd1de3b00c",
|
||||
"0x565cd8eb410c6e0b4d67b54d37ff42f6189095965896b0f81566ca502bea34e3",
|
||||
"0x32d030e4ff6b2f5a560cb7525b5e66ab1f34a1e06531f9b81c48b8a257bd5637",
|
||||
"0x25a91d756023bb9ae538034bd39b6e698d05fb1393d1328c4fc7e5c14209cce1",
|
||||
"0x8036f74c4cbaff3bd98820ddd84bc093c95e88d357b341154a3189715225d068",
|
||||
"0x8bc6bc61f7a57a145b8d728f583e027c8630f0c07e003b189f390ffd11d6f150",
|
||||
"0xfbeb53fa167d067c9b0a2c0710f7f5931484f7dd90b9456c52c578a15f402d9b",
|
||||
"0x8d355b208a16b8aa3f7bc5d8864dc7d6a1c4917a97c523274b86e82998d60b63",
|
||||
"0xc94e45da800d7b56456d55a9aa36ddf9df45e9cfeeacb1116b8c51a0cea34ebd",
|
||||
"0x81761ec04a8d219aedb2f58aee529e876043b0a476e771957bc03fef9f0780de",
|
||||
"0x29264094c720151f7448cae053a403aa86fc20649bcf383517e214d1677e893e",
|
||||
"0x9ac97c7eef9b69dcd73ec7144a0cddfbf0973791beed405202fb4c2d932ec59e",
|
||||
"0x89611f8e2f9e2e1629f83ec14aaec1656876718c05088e5087887c87b8414c39",
|
||||
"0x67244fcdba97905472631378fa3a228b649880c2efdd57e5a6c95e9b70ad8456",
|
||||
"0x0d554cfc4df02560c3e76159d1964c69c39f5df9489bba5516f28a32a4be202e",
|
||||
"0xce9274a36a0f25a13edef679a5b286bf91a9dc5274354bb6f1ce0ac52557e650",
|
||||
"0x6017e68689d9f6dca78f42b93a224b445c18b70288a6e4c0d6cc295627dbb1b9",
|
||||
"0x76791c90f887355878d0a4d8c84ec3990a3159933ecc8d868d196b363153bd5f",
|
||||
"0xacb6a6c9ec937b3d5cedba26ab6d581fc41cf9a58b0867232e2c8c73d9978cc3",
|
||||
"0x89f17989ef556a0562c2aa5a2a1d71e5132b89d656bead1ef88ad31073b80cd1",
|
||||
"0x06efcf8dbadaf28ee719a5b9c017a093fde84a7f4b9966fe3052c0b2fe410ea6",
|
||||
"0xce16909616f1d97e5853818938b4798030259ddd41e3468f35b940ca901d6817",
|
||||
"0xd3ff9e9ad14a605a94bdf05dd2639b6fbda28ccf7b2b228f064b0de52410df5b",
|
||||
"0xb3e8ca9ee88d4c3ce347d82e8f22793ba22b7adc350fd694b1b00b0764c584f9",
|
||||
"0xe690268a4ec089aced00f9654aa95acb7a8d7270d9428205b103c30a08d142eb",
|
||||
"0xd685e1460799c51f14273361e31b9739e5212fa538fb8dfbb8e81e8b1d329bbe",
|
||||
"0x664c293680fb7c5a89ff3c31e81ec8d0c30a6274ef44e4e76bdb9bba83f3c0b3",
|
||||
"0x44027fd23526685d920d37b032f912159e308286eaac018244006690b4191d4e",
|
||||
"0x7ea934c3d75a9ecb6a2055dcd5feaf2d4c851eaf360a648d5d87ef40fba2fbd0",
|
||||
"0xfd97fc801315e5be630ccb3dc983c409a58fc1fc307adc1e4a48fc60c89ea40f",
|
||||
"0x15aa0c3c732a2c6684d521729dfeb93f62e22e155d85d20e5488e2c86b043142",
|
||||
"0xba235420ac54100da28cd6f30ff64b8594e73c42f45ca8494fb3d3c4d66651a9",
|
||||
"0x9948e8489cd94bed4b8e90a8bd35e01ffe38e7c077f587c6c1949caa99cc98e0",
|
||||
"0xcf66ccdfa85655d7d4c94cffd41f499afdfa2bbddcdaac547223e6ac4d1f9cf1",
|
||||
"0x7e5382881f710530720b420a3f3ac08211565ecc8fead8ec649cea11f9385c3d",
|
||||
"0x104576fbb1760c16ce85c3e5757832d53bda83d618500ef677a6a192ff14a5fb",
|
||||
"0x9e4689bb1ee34635e1106e38ca41833d2dbc1cfacb7635ede5761048a8637c7c",
|
||||
"0xc8c7f7ac271015da443320f4af650fc71ea0914f4c41252a5b7ec76f329d5268",
|
||||
"0x46a93ae992001a54119c8d27788e3ef8927dee0a9949b22ece0196a90932c1da",
|
||||
"0xa69467f9944f1a5e3a46718a99d3cb14930cab6d971baa37bb774cc757e55c2b",
|
||||
"0x33f7272fdbfb91428a1344df5867300e256fc3cc2e439c777c3feae1cb27b781",
|
||||
"0x0aaa367f4c7f399edc64ac1754f47aa5c28b0fa208238276de6bd9e424021ce3",
|
||||
"0xf5f363c3bfa4a23bf221951f4b53a77b27613938babe40f0832d05fdfd252233",
|
||||
"0xec315af99bdfdcb3cab1f1dcaa5b42ef53f4e3fcf4d921578892a5896fa20e9c",
|
||||
"0xb580a8e51e875446d7096a20801dded1f7e5b5fac9f47e9361dfc9dd80214013",
|
||||
"0xb877df38d8f4cebdfb89f26868bdb97ef945da187b44e1cbeafc1d4b7059d713",
|
||||
"0x78613b9d2d6b639a54ecf1d50a56af80560b436fa632ae636cf354d4a6dd4af8",
|
||||
"0x80a9d0a5e43558f1d24256baa6940c0074fa84d4b8e7e236054943f9ad5fbe2b",
|
||||
"0x60f79f699ba1a740c9784f2a8f1b652d4e695ad2d230b110472b95914fd35c8d",
|
||||
"0xae20de288eb7362a36a1ff236faaed6ddaacf58783d098118bc9fe66b8780651",
|
||||
"0xcd08003531d6094cabdbe4d971a01b41552784c246bd2a2f749ee9947d1394d6",
|
||||
"0x676720accf739c380f64748390c1acd2f88d454539866f7326a517c9b629b545",
|
||||
"0x086b71ac681c0ea369c16b22ca49753b2083ec25b46ba659206433eb060d98c3",
|
||||
"0x78910ab7d67e67da722ad53b669d8c3a312de3cf362c6254c09581088e920acb",
|
||||
"0x5bc6e98a830c114cb432091679ac5b3efd25c362d6f99585ce3a027dff95e524",
|
||||
"0x8d0daff5a97327b615d1535fea44fa33610fd645d93035e1e5e2bb49d4dcef24",
|
||||
"0xbb46662b884bc6676d98ebf3f2a35ff9190339b72d68520fe40100b4eafaa2a2",
|
||||
"0x9aa8faaf935c95a60ffae0487844860084a963792ae0bb90a831f825339810ac",
|
||||
"0xfd77b5d6b6b87bfb0ddcad7b0ed3992e5fe897b16db06b118230b2d292e317e9",
|
||||
"0xc465a3384c694bc50cbe97ce9f3bc364884651a97a491f7f64e65dc319d1c9f0",
|
||||
"0xc4634431867d7a302be79e83fb50d01df7f3b950aeede21fcb59b883399b06e4",
|
||||
"0xfd524c29525cb97a89026ff68048ca6e2a9f522791eadd74447a6c278151d7df",
|
||||
"0xc7df516c295a58cf4cd5614eee3d2f773a412dcd4926eadad7e935ecae6d8907",
|
||||
"0xfb915abde0108d6e84354e21a513fa564f5201277e060bb916a9153537fba1f7",
|
||||
"0x1d3c6a780f1b259e096f4a141ab83cb6bd035407421e2468e743daec211e536f",
|
||||
"0xb2f47534f060c70f61a7c16f920d0e11b957bb3ef912ed9292f35b8ceda2acea",
|
||||
"0x03e0ebe6e9992f6921362d463b68f91518d91079c001c6bea7b3452879fdc29c",
|
||||
"0xd9a7de173a1617ad813a554a56d7c7d2f010ac78d7782e524b35b5c676cb72dc",
|
||||
"0x90d05d99167e53d34a02c5b66ed6920190370656905465f20efe56499aa0ba6b",
|
||||
"0x17702606dc895aae35aef034fddf8f7235efcc66e5c9d252347063209c2177b0",
|
||||
"0x3c416492193d81fc03b5c1964989a314e5ee6d689c638c996f6761b4d7acd6be",
|
||||
"0x3c6c1162ea9b277f831989ea26e14bb23ce4d72bb9c865e354992559266ceb16",
|
||||
"0x96de93f849613bb2ffc117bf111d4798b9252649f94f21187da324a3fe363833",
|
||||
"0x91e50fc6e564cb9d6b7aab3a6e93f6b32944d5a781196a9a8b12ac7f6f527565",
|
||||
"0xdbefa2bb2ee620d75295d0f3103e06b428f955dba1a792421e435051c46f7933",
|
||||
"0x78f29df98ef7dce9fe7b4414da90fb4df5d99231ab0a3b7a3e70659986580fe4",
|
||||
"0x56cf56899c2388d55eb1496ccbe62041d14cf655c9dbc53984d86c22ed281acd",
|
||||
"0x099f52c675171088550a9e93e1ab17f003190fa3388d956724d422e5925c4813",
|
||||
"0x9913e4ad8405b8a60fa512fb616c544c6cdc415cb1023aad0669d58cc3810161",
|
||||
"0xbf5d51369b2510bb57f8fc8e9342890e8bb37049079dc79ab97afc0bcbf3cbf2",
|
||||
"0x3a012d45d250c818b641fb18b71b622f5bdf0b7a541e0d8de54f61e516ee3ce7",
|
||||
"0x0233833414d2cff3da0326f7baccf1bd522db5fee290ab4fc0a976934a20358e",
|
||||
"0x38a0978c955f20cdc32e2013a5373efbfc50924e45e9c4c756291a903f4162b4",
|
||||
"0x4107f33a14052662a0469ddd646ab6659006df131c4b0f6b0e6cfd331b46fea2",
|
||||
"0x8074fb5054c755c912bc68b1dc22ae40ba13c06912c8af1c12652eb4d84c6503",
|
||||
"0xf6d151b8f9c26c3a31366d967dd7338e80e8107b9b81da0a98faf16df9cbc91a",
|
||||
"0xcebb0256d0a8a4b22d2341ec7c48292c3226caf4aeaa2003ee36dde25cff833b",
|
||||
"0x5fa9ac499a2642b0cb7ca365062c02588f9c555bcdf584f533ee8e8544b9928d",
|
||||
"0x800c7f04db30247318b8d4c11d575dca66bf615674fbeb9e8c20f387d907c8e2",
|
||||
"0xb0a43de06c9d48afefd5411d759e3c6293cbea4a7c6d862b119182ea02af81b7",
|
||||
"0xb6e7ca0075d28959cf87d716fea885e9e3a0062fc7da1b6e06089c808a632b8a",
|
||||
"0x734c1b19f0b5972b5215f675cf60c68c12cf6d6bda7b5a95ee9a781482e68365",
|
||||
"0x1995b08fffb20dedbef592ac23a81d87129ceb396e065265dd4a6cb876beaf09",
|
||||
"0x051082047a6b579684b5444ce5b75bc630277ec06b0087779387b9d7fcd18fec",
|
||||
"0x4aabfe145c368e6878e2ccbdfbecf2f1db5c9078650696bb3a584c14fe17177f",
|
||||
"0x42811ab68b304ce30fe896c52b53d861abc3c8b5e4e740fa97b1695db9a6691f",
|
||||
"0xd90cdb12ad64f86b2aa7afb781c00301f50206b05f1543b111c2b971ed209c94",
|
||||
"0x385435507c2ef42b5f1760b97497e8a02a4b5ec4926c3cce8569fc0f4be59ce8",
|
||||
"0x2d7a4908350c9cf022920cc51e0cad9c3c05d1d14a92d72310b52f984c857101",
|
||||
"0xceea9c58106f4f806a256f64dc04e1c4b53e6cc5eb048f3df7a14f8de3506e96",
|
||||
"0x7032f864eb3eae8d198c3f8edd9cc2dfe88b9971cd01b33318dcba004f9b044b",
|
||||
"0x71bfeb4c183b20fba60e225524c809b0864fa14f5c0137accc36649ed0712e5c",
|
||||
"0xef0ec5a2761c46827110c20e14fc4aecadc2407541ea046de09a58cda3b2e839",
|
||||
"0x5e6debf328055c9413fc3eeca28583f917b361a5b5bda9af4306929931a4116a",
|
||||
"0x1aab81df07eab969189333e5b2930fcc1b88a525ec5bc6af6626fdcb202b8f34",
|
||||
"0xbdbf97e1558711d4872821b9400e03a811c61096bb838d3126b1c2154f8fb776",
|
||||
"0x7d8aaee482933ffaa97777af3e4bf69ce7d99afb24e546d2e365d445d3d0190d",
|
||||
"0x9da421621b14164582b2b877090c9a956f3a7c917031bf743a9ce457b6292369",
|
||||
"0x050d717f0433a72b17a0e9a1340f26aed5bf17f90c08a5b73e675860ac9c24de",
|
||||
"0x80551d3ff835aaf987b9ec056a73a3890985ef551431daa9d4aca10c81cac7fd",
|
||||
"0x625a5b5aed2660d32d2fd8c4d1bfc248365a5cddaf9b5695e3f131629739ec60",
|
||||
"0x7d86bc2dc5914d16b3d0d882a5db0230b4b688cbd8c81098d2efc5080e589646",
|
||||
"0xfe42cd832cdffe56426031ba7d837c56d86be72b89ca9f5474bd08db80cfe903",
|
||||
"0x0ca30e1fd3bf3e16a0e295ecbb442757248b2ad47baf88fc37d6c55901e709f6",
|
||||
"0x2a83ed111b99844e17fb7aa69854525958255ffea04e0bfdc365264e72b349db",
|
||||
"0x709779de19590b69864f5b9228b3a1c334724e20be006ef5ae38f8c05eb6f37e",
|
||||
"0xf09c664d0e2e88ad5418d14481fefdc9e9c46158bc5439ffe0bf6d6d5ecb2eda",
|
||||
"0xf350785dd3617ef73b0a5bf439ce5c49adca0c041b6b5047a664e5e33967ddf7",
|
||||
"0x8fcf87571154dc4eb0a73c6ee31cc0db5f4e064cf23a255a408b2f2c7cc9c0e9",
|
||||
"0x75801fc8867ce7c75b3148c6c022d7702143b93d93c1fc2349e3e969d0179cae",
|
||||
"0xf14c18bf68ae881d3fb07f631340b00557a83860d0ba0efbfe55fe199176aff6",
|
||||
"0xbe48c727fb6a32242229eaa09146c76522dcf6bed6d1c6fc1bebf86b5e4ccdb4",
|
||||
"0x8487b971e383272df82cd812a0bf3a2026b85bc3897b4ce9ce48afa00849fe00",
|
||||
"0x60d18b465172f59c0d71594b5273a90cb41db24a5d4c9fc37020f9d8c467a4a2",
|
||||
"0xab4e36d9f17c748c87d89c23b667e3f4e3265e77b62dbd9c92659026f8a53d12",
|
||||
"0x2c711e8eec1be3caef6e16a03dcca83dac3a565c93327c67f4e8ea9f2697d9e9",
|
||||
"0x21d7a9a3f22a163767075aa693d82a962e4458b074bd8f3485c4ded1e47c1172",
|
||||
"0x1509cac83867db4b888107974d5c8547dc4aa1db3b8e886291f0f9eb6bd7af58",
|
||||
"0xa555eb6001982080479c9bdd3da9e8668bf90ca9538f16f27a45ae698ec85fb7",
|
||||
"0x1d1f4019fa3ea7ec85ee0a411560738791f2d45fe5fe6242d07267183a852b96",
|
||||
"0x2a8994caa5a27eb3081cc749cda5694da7ed3fbb8a1b4c67d7e92306cbd3c6ab",
|
||||
"0x8389736ba114022ea97a6b3e755d75e74c3c370e9eb916c0f2d73a46a6f6c396",
|
||||
"0x6a2e5d08ea64195a4153fc7bf26b7a99dcc9d31d8f58faa07510a1e87fb1ade4",
|
||||
"0x78b66b38fd9b9cd3a5bc9c91c6f816153c2c28c1055f7ac9ad12ab61f9464850",
|
||||
"0xb2f77834f7a88c4354763a28080d95be44dcb380d01f09292e679a6ed274b179",
|
||||
"0x2070456b2bff0c30ae26b2435af82e153094aeea8102a75541e02a39e9ebe717",
|
||||
"0x4e3bb2fbdc71602a62f0c423aa45398af09cf3ad24f0437027b4590e7056b882",
|
||||
"0xe877208750e7569ce78215659ef78c1656e98b63ab6cc3e1381d7581afbea99f",
|
||||
"0x8c9d8132d01b83cffd1a1fd9d19a3d2fb3a58a0a28602018db44f8b6dd5fe1aa",
|
||||
"0xcece8a371b72873a660f4077f98b04d6a3cde1a150852db3a194a293e6a08b72",
|
||||
"0xe72c8c7211acf2d67bf904cb3428c6fd69c8bd679d52deb3b2e749d5a3124b86",
|
||||
"0x504f53693e747fbba7475dff1aad887ad0124d48cc7892ec488fda56e31e0de5",
|
||||
"0xddb3ce7ac0c7e2d141df857e9e5c083d66f4a62ead742bf6631756a72fb643e3",
|
||||
"0xdc1c6a45dd8308ea319671732de7578a65a025852a3cbe88aa9c5d770d662990",
|
||||
"0xb6a9df772bdb5e7cdff569bb9d3078c081ed53e870f9171a5b0369d84fe6ce50",
|
||||
"0x1b436a7d8c9af357c8175430e1d0d3057096c92bd8bd24fe285fa55673c68b72",
|
||||
"0xa57ce7fed7521e26a908ead89253bc57939459b4c34fba583eececd0f9104e2a",
|
||||
"0xb16c4f6bdce8de6657d049e2e41f91a1cef8623671eacb9ab02fff45cee7c0c3",
|
||||
"0x8d23f3ea29767da41a2090cfceb56a65236a405031b69e614c78fb79c1847651",
|
||||
"0x33149d4876fa24dea4e872ad1da120e01b14e8f9f8270611fced328a36df25ca",
|
||||
"0x266c558486a85de2536e8849d49443e7d39797a6ed817ad7217633c28166bf06",
|
||||
"0x2073a22a1f157025228f8fc82bdaff48d3cb1c9b004ac2cb867c2cbbe7cafd95",
|
||||
"0xcf643d70f96101c99cedcc2d169b0196c564e7a8b235ae093ad25b1ba8981d01",
|
||||
"0x1489101bebc1b60e4c0fa37a94bb946f1b51ba284c667e4b2f3270ef9d264d41",
|
||||
"0xd2eceef739e2601390d872bdbb58f8d67864b000f7fbab07b0354c44279379e8",
|
||||
"0xf67a02d7e7e6da127015e5137f90e30ab43c2e828e62c3f8fe68ad5a0a3011fb",
|
||||
"0x01fe94220a07efc2bde2404c584f67e9b06e47eba05e50e71ad59710d9d6a9fd",
|
||||
"0x509bc80d1a464116b4f234001c3f2d7aac7772cd6ec5fa6ef9606ab8ab273127",
|
||||
"0xea497db1233691b3b86d8fc80ebffe28e6863f445a0b352a1286412a94ad2f6f",
|
||||
"0x80074f0e2cb668b6a8e5b454db4ae5cf2482894f3ccb7648cfa26b3365a0a54b",
|
||||
"0x56c8cd15e5e1a21c6f32f7211d18e1e56c89da688cf11b80c9e55718514eab24",
|
||||
"0x6705989758f03a8c4ee93d44f53b4114a10337694197186b62ac2220188a6879",
|
||||
"0x7581fbe2b0ae6e0a61d073fd1700c3111d2e3e8d9342d50800ba05d026c9edd6",
|
||||
"0x254548091369ad8e0abbd2eb4e31e2c08c8e9dc0256fd0097e50e75831946924",
|
||||
"0xac3119a5ba40f303a9a70ecdef9b6d4722c6adb6592a0cf52e5a312a1a0819c2",
|
||||
"0xbdf30bc3cd852b882c5d410e6d4419e0f36ed17b761b58fe58ded980829d1cf8",
|
||||
"0xebaeb5965563f6fa71006d8c2d285e093a167630c319cee2dfa961c4a583b60b",
|
||||
"0x6cd6717885bd50263a97574e8a56a3ccbca88229bce595b38a454c1184ea94d5",
|
||||
"0xc9bba3a4a72f0f08663e3af36e2bac2d4c8422b2e3c3bd29705e5b86e7c42a20",
|
||||
"0xcc442230a4b6aed5a1eb2b8744a09aefe3cfb9e477816edfa829dfbd3f7c2bc7",
|
||||
"0x4ee48471e3326144c7a48b15fa5f39691ad9f24b82430ca281eb961b18019e02",
|
||||
"0x35016779dd877530f99b1d3372a0a77eff7ae831208d2bdfcd0979b838190acd",
|
||||
"0xe3e9b2a4adc4b4e167376b33b8bf2a00bd64d52f66f4e7b291ade123e8c04402",
|
||||
"0x5a7d1466e2538b62ceada9577079248788e912e23c4cbc52d7b82a1afbf28ec7",
|
||||
"0xb8529c5a2b2dbfb72e70165b9c9291e7c02b43f157092a9b59f3b4cad85fb587",
|
||||
"0x55e90fb666a950f38ae41732269cb69afca8643b75a99bce508a16e06685fc03",
|
||||
"0x651f45996ed080d8a8dcb78550089331ad67c2df33330d1871dff956463aed3e",
|
||||
"0x9c6b4a961663c59dde3a4f0fdf7b68b0b5f049719ba0d10d841855cffc7ee166",
|
||||
"0x15c4d98e0ee4fa1535f83625a20bf1a491852884f8fe608eae6b9bde45986779",
|
||||
"0xc7891cf34fcc61935a43f37bd7f23b674c785ef3b2718358fb627364f3d8b09b",
|
||||
"0x8105fb76c9e1281f0f0d7c520dc6cd1d546d1b4b29cfa398eecd7965af57f408",
|
||||
"0x2a141f1c4e1f1e7be5d10c444dde3d1b5fe1a69f23506d5ed1842957375a1208",
|
||||
"0x9d2313d34a5a6873f2ae1e2684db00e3b693ba962796fe7e78d26a2c49104471",
|
||||
"0x84d0245b1537ec1fae89fd39741d3b6427ceda3933f750befe4e2d8ec022fc1b",
|
||||
"0x93d281ff6bfefc7f94058a0d87cb826b97728c9593ef4876b88c35d26b2163bf",
|
||||
"0x9018a352b09cb36311d0b54bd83a33dcd5dca5ae7032f1d399fec3a0e5a9cb7a",
|
||||
"0xf01486ea17dca0bb45c245c9ba76d20d1a2f4eb718b7d07fb5183736e5cd08c5",
|
||||
"0xf797fec0a8cddb31ace66223e1355211e41211c4bfd33a416c8a1a86e497f630",
|
||||
"0xf24aef69daf4e2b90b4f3bdedddbabbae86a7fd1182947da7306c8145f82cc88",
|
||||
"0xdd14e34cd000ddb6ae6426dcd78cabbf6bfbe5b3ecd7553c4989b3891e506257",
|
||||
"0xc01ece645c7430801ee26b20ad215e221f7de0e060fe004b450b372a6c4438a9",
|
||||
"0x64c836653383bcb165207b80ee8f9377ad25ef1bcd6cf7ba166cca78419898ed",
|
||||
"0x6b1cdfa195df272d7e35ccd843191d5725919c0d8b71f1abf4b950a954770503",
|
||||
"0xebe51f94a9f445d83180c4f075d944fa2f05b5b784b7e3cb4bc1544020bd35cf",
|
||||
"0x7007f6b2c04420d390fbdb6a9fc21edd3249c1a098f8a9383131b8be50c6f975",
|
||||
"0x6b7e93d96f74fc2b068104a017fa5fa74836e8be5599865309361ad9305d9bb9",
|
||||
"0xcccf2dc238c68464f3b0446e06fc48fedf202e366ace5734cdac5a7fe7c43342",
|
||||
"0xfec77750c277cd6bb0937d25d7f598d07cbffb1117b6232e932a296f32b45ce5",
|
||||
"0xb04e6883c11ba3f2b7f0301936c3dcb622f6f78b3d3d57e48c6dcba063038d6e",
|
||||
"0x23fe83ea2f197cb97a3ce5f2afd75652cae993f30bc627e8b9572a0069ae088b",
|
||||
"0x44cc6bf2cee513c826ecc0c130a32b61b0153129721ad2a70d4503b71c128247",
|
||||
"0xb1a11be5f9b37faf1901b1405494af32084641dc02685ec33be7f6e82e360a42",
|
||||
"0x284bdf9a6aa0ac964b0f5e72d0d47c713c919d72fa9e24f42b65d749efb6e2c3",
|
||||
"0x96a0a0e92ed87946a322c9bca6c0ebf70e51e0e825e2ede85b975349f9bb2caa",
|
||||
"0xd73becb6a3d9a155d46a96d17412cf015724a79b166d2961d24125d92e355947",
|
||||
"0xd87f142746611ce081945999f42b8da49cbda03a10bf953ba043417861e27c77",
|
||||
"0x4af010485b5385579a534693bd21ef3768c8920c5b5dc6f9ddf722cc68fd6550",
|
||||
"0x65a2f4ec5cf3b37530fe0672418214618393db47ad1185f285b445cf5f53cf26",
|
||||
"0x1d208df2a2785599565a40d934eb2c0cc1673c1dd43d11685d698122ecf24d6f",
|
||||
"0x046b7211427f0027ed4b69b06cb43986d3cd53d1579a2e078f6904a06ee6587d",
|
||||
"0x053fb3ccc35edc1a1623f8652dd8c239045b02b58ffe7d51337950ae43365990",
|
||||
"0x0721f82b52ff87272e1b0af5f4dc16b90dfaaaf3ba56b91bef555d283c98a8ae",
|
||||
"0x26e93e4e2d0df49a857bfcede7e6ac234d75b71617b561ce39c3db130449e4fb",
|
||||
"0x5ed6d53c35a0aa52d9dd0a244f31be00426292c11676737c7283f567ba485dbc",
|
||||
"0x047add17bd1601a06a32b721165ecb2afb55290e025a828696f234b95c52eae3",
|
||||
"0x6f9e6884745cad7091646f7767a6b17ebffb6482ee4726f5c1f3b9e02d26b77f",
|
||||
"0xab29ed5be2938fb19614da621ea9828eb338514309b3d56efc6f19b57b8f4f6a",
|
||||
"0xd5f14043479e8e37c6545527b2e93a76763a654661af9a25adae2b37dac40672",
|
||||
"0xc43635c1489c3cf3aa231419bfcf7bcb2455a812e4781e5947bb76cf0219d1e4",
|
||||
"0x72117c92f8bab83ccc7fbe5fc6cd931c765238ebd67ad8c4fcf1353eb78c8df2",
|
||||
"0x5deed7df3559ed75d7c2388a6e583067222684741143350f85d236bc5fb4075f",
|
||||
"0x655bbc0590587c030902e32d88cc9113fcbdd5c3371820868768abaeacecb79c",
|
||||
"0x1641c875e8e44b1fa71badcbb4f724a71e2f916d9cd212f09e9039ef41b1242f",
|
||||
"0x40bacdc3f0b53522cdf2aefafa2bbd9c8e9f8fd25b4b33bc19a87d72a5de293d",
|
||||
"0xc35c6cffaf93170662a6f3d4a0152c988b0f4916a33d037801f6f589a6140d08",
|
||||
"0xd4e37125c0ca7844e048bac4e4c6069ec24b0493e4547f53679fc8df2a1e0d66",
|
||||
"0x34c6bcf0e01dd55a1d3a82df0a2edcb2caccbc4be93fdfde32c7718276e59bbd",
|
||||
"0x78e50d394d9d42ca8aae3f4dfccfb32fc3923073a6643c010fd49ec3897c4fe5",
|
||||
"0xeba75c237fb213e893083c5ed0e28dde3ec1f5f1b60edfdddc17a54de9cdfaf3",
|
||||
"0x4f35b9a67fc66492fea331378c479eba921fe0a6f0589b5ac07a44b1ea9b4995",
|
||||
"0xbb4d09d98b27d672259b608f5075575cca49f87cce0519813c1ba4a614d369ee",
|
||||
"0x805550ff80be2d3a543d5076961442f70dcd86e82762149c125d2ce371a32f69",
|
||||
"0x7d81d766cc2d6c66c7bf07be0a416f2a4c0dd2bd94026270a410ea6a051dd4aa",
|
||||
"0x30edcef101041c0e0acecb8d6c15a28c70b8894e56196cddefb5fb6b39658ceb",
|
||||
"0xe5e8d21a00ccabb5cb50b4d04ee1dcc217fb9908e72bf0efab69d4ce7a0b7eab",
|
||||
"0x3793f78e2e582b56fb3d24e3bd4aa69db4741e768795f9681285b0fd34ebd602",
|
||||
"0x4a9378b4ad76df084739b2a63459ac67abf8eff7499210936fb9e6644265054a",
|
||||
"0x2e47b62375a267e104ad2f8bfaf5c985fa7c6f4c438739810517e41141a825bd",
|
||||
"0x73dd638affe08c104b37d53e6cb7884b8a9b4cd4afa4bbec6ef608bab4559dd9",
|
||||
"0xc566dce73da1cc0d069a032045c44ac4ac86b145efd2cb1c363a2d403fd8d7cd",
|
||||
"0xa1a04d193c5408d0edf85e771c6976c5dc8de08c87d906b6c9de1efa4b4fcbca",
|
||||
"0x3245d987f205b01c54448d9a9d76bc7e4174c1021726a68f5feb6748ac373f8d",
|
||||
"0x1f963274b936dde92281f2acd47d3685261b03845efc7d10ab8b02500c239af0",
|
||||
"0xa1e6d69b28aea5d24c3dc301dfb0d6df8ee8fe693d1d0f419cde3b4d20d22a89",
|
||||
"0x31b0711795c77cae9e1b62b87244a5eafa4b1764aa1620d53be7e779db060984",
|
||||
"0xea141234dd00c54ec7912c80baca591b53a058b81fed1673317fa4ec37c2c715",
|
||||
"0xc5902f3941d647da304e94062951b09f4d6da5bcff71517c7a35e8b49c6ac569",
|
||||
"0x54c5677af7e31b84010f8b2941ffed5080e9b4d18b608fcbd230f163a5e04ba5",
|
||||
"0x1a12c56542a01bc58288a58e8e526f2b2c81a5238c83bbfe4808d206b3b9d0e4",
|
||||
"0xa398984bab81b7640674893496b2346eaa8257aad4cc8bb52474f7162fb6fa2d",
|
||||
"0xf454a592314f1b7459d21eeb6ffe54c96ae2e25a7051dab1f8129518d3788cd2",
|
||||
"0x12964f85bcc410fb40e89f518d749c7dc2be7546a960849dcf560eea2ec3d333",
|
||||
"0xb176775c2ff94aedef2c099b936468986874d17eb563086215525acbee2fdbd1",
|
||||
"0x250de6e94d60125bb680e862fcb70823d06e4f27308ea1ecea8a465d5febc860",
|
||||
"0x731cc6817fec665290d7637c67fdbc72bbebae70a13f9346f47f3b368eb1e4a5",
|
||||
"0x489e955cc77f16d8aa16bada320127380315eac978f0fd1033baa04911123332",
|
||||
"0xa88623d9f89221dce46b55ca7248581b4e3ace94a7cccc9fd44a3b03412fa729",
|
||||
"0x4a65c1808d79577b36dfb5fa74d0deb96e90d0105ee373d552685cc4f73d35d8",
|
||||
"0x7aa8228e6f8fb98a23e1599e12ecd84c879475a23f10660e763e338a347c9002",
|
||||
"0xa825d02023ab76478b83a2a61dcc5cf6c05ca741b960043adba3f13d1c99612a",
|
||||
"0xd3c90e414048510d9594ae7a593e25641b6baf93f9625cc4a3caade094f02e07",
|
||||
"0x4d631d9024a4e75111189835b4ec0007a6951d710512dd7b91a8d56da95e57b2",
|
||||
"0x0158c7f49affa675f04aa4ebdf11e88bab8c6dc0abfecc0100d32489b0d59f1a",
|
||||
"0x4ec96496694ef53e17b11b3122cc45cce3a4fe1a252fe9c0d379b302db1318ac",
|
||||
"0xeec44b94d9f6c7359047d257ffd5f1f5cee87b3ebd6845dc1fe48be686a9ba69",
|
||||
"0xe24c7b667382186196e5da605ce75a5cd9c7e4803fb2e268b4de5848737db026",
|
||||
"0x14a551850f945f02fa2ab84c6ffe3d17930c81f5b15e94ce92342c3646b8cd9a",
|
||||
"0x7e9a72469a52662bbcacd449dc7df8fa75e5cd1480dac3b635148a34e0f9e375",
|
||||
"0x2dd4fd0394574c5d8c9272c42175e3a88d8501753bb25a77fa937123d0c2538d",
|
||||
"0x6f044eb54fd2b8e51d89f6db2ee6e654b144d9e69cddf79b7899e06af5bf39f5",
|
||||
"0x091d894513fca5d2239f6b5ce73737aa2657c90c2af196b2b893ba0b0205859c",
|
||||
"0x78b9ca580e3eca0808e60420ead000365eeafa60c6394e055a653a7f536c8b6d",
|
||||
"0x595cfe325aa600ef0d7de6b2eb717b33c92dfbb1e3ecb9487fe332c878e9f121",
|
||||
"0xe1dcc22aa44a0243f67dcb0aef7e0eb1ceee269b0faa67633698f8ee29155115",
|
||||
"0xddd3354d4167161c6b18173ae24fffac2cff12a8bcb3ddf1d964907716685cb3",
|
||||
"0x55c02c02eb758f8c9aab60a2432d29e73b567e3e3d0148611ce4569fa074c5d9",
|
||||
"0x5d07d5a7d45fe16a0521c55b3dd898b922c619e5b938535e2f974f11b4edfdc7",
|
||||
"0xf75100a1a2f8d6daf0dc36569cbf579ed6e52838b163fe50b5deaad8fe7bd07d",
|
||||
"0xb6391d028fbc88825eabf1dc4566e58112e6d3b7cfe6d387d0fa58df387df78f",
|
||||
"0x8a58fab34ada4d30eecbad64a001015c91e446cf14e95c9d7a3d894530787b03",
|
||||
"0xac13b36d0eb0483ab8cf21f49c78f9e32092c74c878ff520ed3a3c0080fdf5fd",
|
||||
"0x358c1021fbdf028ec82b811cdeb504adc2611a1ab477e8a191f780592d598361",
|
||||
"0x6a7af25eb6d089ad63712187d1414e8bd04fb6bfbac26e6086b1a3e2d66f6f7e",
|
||||
"0x6bebf617fe66129dc8c9dadef1a74df05567ed2fc89f4e5c4dd36327d6b0a5e5",
|
||||
"0xc658d76eb9f3fb91327c64668b08d3e9bfbbb2099bf5d9aeb6a61b8e4f893c39",
|
||||
"0xfe68ecc66eaa625842068f8b5ad4bdf5cbce0c82ecfafa4bf48b08de49c58595",
|
||||
"0x26eba0a168f2e5f3ffcb37955839d37432b39f2f447497854d42d802826fb1ee",
|
||||
"0x8b4f8964062d0f00e40a41d21852a2e22abba1f4cf75f594797e368e4df21f7d",
|
||||
"0x916993123d91b181d145e2668efed6eae3845fd76d4765df3a04d8adde8c7142",
|
||||
"0x21b91051b5c5fbd22164a655de8485cfc2a9eff58ed09d6fbbb454560898daed",
|
||||
"0xb52ca76065bcf43f06335977ab87d6c809dcf4e6cdfc452ac2018b77c64089a5"
|
||||
]
|
||||
},
|
||||
"accounts": {
|
||||
|
@ -15,9 +15,14 @@
|
||||
},
|
||||
"772000": {
|
||||
"safeContract": "0x83451c8bc04d4ee9745ccc58edfab88037bc48cc"
|
||||
},
|
||||
"5329160": {
|
||||
"safeContract": "0xa105Db0e6671C7B5f4f350ff1Af6460E6C696e71"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"blockRewardContractAddress": "0x4d0153D434384128D17243409e02fca1B3EE21D6",
|
||||
"blockRewardContractTransition": 5761140
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18,9 +18,14 @@
|
||||
},
|
||||
"509355": {
|
||||
"safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038"
|
||||
},
|
||||
"4622420": {
|
||||
"safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D",
|
||||
"blockRewardContractTransition": 4639000
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,12 +9,14 @@
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": {
|
||||
"0": "0x4563918244F40000",
|
||||
"1700000": "0x29A2241AF62C0000"
|
||||
"1700000": "0x29A2241AF62C0000",
|
||||
"4230000": "0x1BC16D674EC80000"
|
||||
},
|
||||
"homesteadTransition": 0,
|
||||
"eip100bTransition": 1700000,
|
||||
"difficultyBombDelays": {
|
||||
"1700000": 3000000
|
||||
"1700000": 3000000,
|
||||
"4230000": 2000000
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,8 +28,8 @@
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x3",
|
||||
"forkBlock": 3383558,
|
||||
"forkCanonHash": "0x6b4b80d65951375a70bc1ecf9a270d152dd355454d57869abbae2e42c213e0f3",
|
||||
"forkBlock": "0x40E80F",
|
||||
"forkCanonHash": "0x3e12d5c0f8d63fbc5831cc7f7273bd824fa4d0a9a4102d65d99a7ea5604abc00",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": 10,
|
||||
"eip150Transition": 0,
|
||||
@ -39,7 +41,11 @@
|
||||
"eip140Transition": 1700000,
|
||||
"eip211Transition": 1700000,
|
||||
"eip214Transition": 1700000,
|
||||
"eip658Transition": 1700000
|
||||
"eip658Transition": 1700000,
|
||||
"eip145Transition": 4230000,
|
||||
"eip1014Transition": 4230000,
|
||||
"eip1052Transition": 4230000,
|
||||
"eip1283Transition": 4230000
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@ -56,8 +62,8 @@
|
||||
"gasLimit": "0x1000000"
|
||||
},
|
||||
"hardcodedSync":{
|
||||
"header": "f9020fa0a415a8dcd55fe9c93372da415ff6897036e48cd3c1a5ff8ffe119eea1096ecd6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479443d58f2096e015db88e44346e73d8c59cb1753bda0100f05d66d36782b7c061c724d8d07619cc61053eda41badc8d2cb9292898ebaa00a60317b490365f40f0528e1f559b0f49facb6638c82a9490d368e963647c704a0118b536c3bdabf90273d527dfc26914c7878176fff16cee8fbb150e00ffcdd29b9010000000000000000040000002040000000000000000000000000000000000000000040020000000000010800000000000010000000000200000800000000600400000000080100c000004002080000000045000000008000080000000020000200404010010200010004000000000008020000008000000000000000108010440000800080000400010000080010820008000410800000100000000000000000000240244000000010000000000010010000000000002000000000000000000004000000020000001000002000000000000000013000000100000800008000200000104000000000000080000080200402010000000000000000001020000008008501602a8414833bc8018347b7a983476d40845b838083904d696e656420627920416e74506f6f6ca0f540bc9cfa258b97576bfb9a79518b2c07ed73a98bc6baa61cf7af4b40ad5b6988965658a406315a8a",
|
||||
"totalDifficulty": "9811143388018700",
|
||||
"header": "f90205a0cd611d63e443c91cba1dc259c71fdb96bb70a1b78639166f7aa2a09b36843f7da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940d85c541489b4c67df516b86898e1ed59c8d639aa039cdbfba9ee1e91d15fead004292a7df0865204ee878daab2375683cc527df2ca0ebf5b5fe0ef82be8bda42e6767ad7881269cefe650c3a899f38f5ed1c05cad8da0578f443c4b0d0bd89e42a855436258f1b19d1a018f6769c5be7aca0679ce6008b90100000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000800000000000000008501856ef4de83436801837a121d830e1038845bea0191864b564f544845a08dcfeee7d79d54276d8bc35765ade21a51d277540a3d7a8e17fc26b6324487e488d70f2a90307e2ae3",
|
||||
"totalDifficulty": "14549054591321060",
|
||||
"CHTs": [
|
||||
"0x614648fc0a459451850bdfe353a932b5ff824e1b568478394f78b3ed5427e37a",
|
||||
"0x1eae561c582dbb7f4e041998e084e165d0332c915d3a6da367638a8d24f3fafc",
|
||||
@ -1971,14 +1977,259 @@
|
||||
"0xb652952de1bf9e1174e5f6a37b069b437792672a37a9e0159c4f36b6e64306b4",
|
||||
"0xb72dd6cb5df1b00dbbd84e097e2da79af2ce60559697ab4c93b0a8b85b2ee406",
|
||||
"0xb96fd4a94ac30c10f757691f7f06f25a4900fe424f4eb7ccf322e2f95249b914",
|
||||
"0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8"
|
||||
"0x99fd442599036f161ccef1ae8088c5ef694c1819f5b76d9d2fa8f979935f69f8",
|
||||
"0x3e53574f6ae31a45ef928f9c37bea6c61e6d728a5ade9851567d3167f5ca3314",
|
||||
"0xd7e3d08c5b71a7ad8338e8b51ec54cb11ad4d643d129a371af07376f8c47c1d4",
|
||||
"0x1033c8aed4ec46377f75cc9a6b3297e1da0a7d1e74df20bae9fdf6d037afdc28",
|
||||
"0x924d621544f3301f9e212fbb95872fce9eb4a4172a11693674de733bfc2b0018",
|
||||
"0x7f61884149ea4def1444a70c022da1c23f31ecc51bb175905b492236a57c7fde",
|
||||
"0x40c50785bc0665ab4eb3cec95405e17510c571570a5859ead804530dbcbd1387",
|
||||
"0xf806491cf778f4796c0f73428e6eaf237da8488af99e9b61d72c56fa03e7051c",
|
||||
"0x7a9670842dcb12c66f11e357a84849cee227ea5a7351e7c6c9370e9ef2560129",
|
||||
"0x1c974da4e1073157c10deac8b256c8ced77a030e0500b2b8a90b6ca1d32ab4fa",
|
||||
"0x97ebcc81ba9c1e04865ee4617daa967dec39f65501be21fbbe929db869d57dd8",
|
||||
"0xa36e4506065d8b9c662697b18ffe50ed2f6ccfe6d07a065bdad048778cc53668",
|
||||
"0xb9d5566eb0d40bbb03114d333d1d1dc85b0e780ec63229f3b93b2c84af5f9509",
|
||||
"0xcd16693573724880c3c83834d516be65c35a861b76b43878e28aa7fcbc961361",
|
||||
"0x4f60ecd7811acc087fc4557fdfaa1a0b522fe30da1cbae5e7740eec3cff04c00",
|
||||
"0x9e58573b152bf5008e0ea3fc0d64573211916521a62fb08ba0f1b44c5da12e7d",
|
||||
"0x2c6693cfd7e5bf9a3d8cef9e186b3da25d07af983564ced6238f9191b020f105",
|
||||
"0x8cc6149caeafef85ec7b2456f33530459c52b30a5365a2a0022b1c308357f7b4",
|
||||
"0x6f66863bd9909f687523128569cd0894c4cf41e2eddd5cd9c20d30c446b1711b",
|
||||
"0x402317752053e7b6d7e2d5512d6397112d80ace0873f5f9d32c023a402ec03b3",
|
||||
"0x2fcd50a79495057908bd34875e3531e6298488f0d06d043fb6fb0b140895d379",
|
||||
"0x533ba9669dcee2c6e35713c7eca3bca168a326a36b0e39fcde76cbd35ab3d99d",
|
||||
"0xdc2e86503e8066bc5fac91fe63544e33568a3c744967b9360458101c3d9df096",
|
||||
"0xf994b38ba312d8bfb00d428b13a088738d93965b525eae81b45b9be344f99fd2",
|
||||
"0x0721f3f772958d6a58dba638453b8d004e0c76dc8b4cf6d595b712edddcf002f",
|
||||
"0x3c650c2c7ebbe7879a15882c3157552e8ae1adebea8f0c65a2dda272cc4ed838",
|
||||
"0x649fe38e87546703245a7adf5925e8c7a07942750e14d39553a56ca3fcbd8c65",
|
||||
"0xad204bf42d2a444faa864df8e9d023483a6b6daaa8001e00bb5373a45ed064a3",
|
||||
"0x2c5cdc73d8ddef2e5c0d47358ac180043e7e246e590a7e8ad2b0a3f9b4e9375d",
|
||||
"0xf38f6c364bbbbe626e849ca9bb9324c54cf0ba8dfc0b2741a3ff87ce7734adbc",
|
||||
"0x317efc1cea774849d6219d31c8464a15956da4f3810bf15d4353443f79d98e75",
|
||||
"0xb6796dccdf4d3cab16b5ec9567237cb988ee94131f3262c2a581180b775e76de",
|
||||
"0x1fde3fdf2303d080d400c43345a424f50f6551a6a06ad50c6e277d49e8034df3",
|
||||
"0x4d7bc44a3b56f5e69fd3e5e8c0cd8f5f839a775c4ee381b4b1d0a36656cf91cc",
|
||||
"0x6051b60fdced0c51aa6a1cab2418c8f21c5d174109d514a4c6de758b2056611b",
|
||||
"0x3c2f7be830078af3c2c6d1557b3da74d1d5bbfd8094f98886a959aa71ce70b15",
|
||||
"0x8f296b90a0ece0a3dbec19a801072497c5840f9c0491062cd402db00c2b69f2a",
|
||||
"0x6c14c4697f8291dbdfdbfea5522798e3f8b17204f80d8370e6d379e6ee659e77",
|
||||
"0x4e98f63afaa50f8a30b0d352eb5fcb5403c635cf54b41545aa8b48465d23fb1d",
|
||||
"0xad3059433e981ff12cd0d7dbc11a8d92a65cb39c6e936e9c7db5934d45806492",
|
||||
"0x1cbb21f28ad2d191d6850c97487e5a733306f2f6ba370723fd5ed37cf6c880a0",
|
||||
"0x82a0010a1b20d383bff0e5d7ba3751bc0d9161a4817554432558c5c2825babb3",
|
||||
"0x33e54e93443e87c003d582dc51d0b9981ddcaeac4df0993877739651cbf52a58",
|
||||
"0x1de8bc150f4142cd45b5d0784e5952abd8de7cba9654af959498c0fd0bcac404",
|
||||
"0x3ee852f48a1a930d671e53c9c8d8c3c38353ee1737c093960c3f841e6c682e94",
|
||||
"0xa9c6e05ec91e2a2f2f003419063fe033e37e5353c6e233706e29c08693e35eb8",
|
||||
"0x649f7328064c55c03249d527dadaedcdbb4cb0e939d94c866844192d99469e05",
|
||||
"0x3a407d00efcd5fe7bb765347b1a3f231b744349269b3aeb44099f4bdd068eb9e",
|
||||
"0xa1a20af2f7e61082810ce7e7afe6118bc0ad95e9641e6129027f46af28048107",
|
||||
"0x0d68fc5e58cacb2d16d99a0e9e612d674754ea51cbee2c68a21f4b0aa926688c",
|
||||
"0x9b3e58144c014343271c9dc90daa8d2f642954b3eda223d64bbb0ac41380e512",
|
||||
"0xd3de08b676d4f06bbf4322ed4340caab76e6ab7144c97af91c2bc9c749e65b38",
|
||||
"0x21d626c9c38087aac6262b64f09398be6e4cbf246100d8c2416cab57e9ac1b68",
|
||||
"0x563a450e35f40279f5946641a823f596ef3ad22a45b8ec280128546aeb0faf14",
|
||||
"0xadd9c7128e14e670c7d21d6dfa5c09a11dfd237e90709b087e3329d3cd89b5fd",
|
||||
"0x258cc0f845d8e7438a707f590f55203c6c51302cef4cfbf788b1c7054688da14",
|
||||
"0x4309676aa14fa8244e0a089c7013b89c9adf57fa952295b8ddb23fc6545c9870",
|
||||
"0x5db769765dfb41aefc0f40f06f3d005b30ce1f14f04f653e0c5500f651cd61cb",
|
||||
"0xbef131c9f19572b05d295d7122fd1a09fe4a8afd4e20c5a0f3cd2785b7eb9882",
|
||||
"0x3f235228ea537332a041ec75cc6cb5663edaa1c2ed1c1700273af73a5d49bf1c",
|
||||
"0xc081811bb077c6ebe224b560eb6b81f3f813b26789cb06d96110071ffc25fcb4",
|
||||
"0x912444c19a5e458b79c89969ed5336f2873267baf2fe729b6f218b74d269b797",
|
||||
"0x5846fc726eb9627e9d070041b92d76191c4b32e315d33ad18121b8acd01634fd",
|
||||
"0xc899f45494660034d343670856c13a32b230d047434a4d54a772132ddfe3e182",
|
||||
"0x11a699c18b04e8cdcd96a43b7465f7bd81f8f64d7ebe79dcaf9201cc897f2746",
|
||||
"0x8e09b134dc8a1735c060175e9688fd001974bf2e3baa5a8e88dc4c87365e0e07",
|
||||
"0xa086797ebca0a1d446a9289b7eda920b926e1b595c288a9dea31ad225e6de86f",
|
||||
"0x0cc04369b6036dff78a9856a5173bb2dde380359a8dbe0126e06d6e763a01c36",
|
||||
"0x4b5efcac86e03d1f67774769b8bcc5d131c181cd4fa297eaa6cea5ec0cdfaa6f",
|
||||
"0x47272a21a07ad5e14e3f97b237dab7e33344da4db5b2d31bc7cd0cc2d2c9f1db",
|
||||
"0x9540755fd321d125b73cb6f1884c2f0b2a821d29362194f5029a5e7ba2d3ed44",
|
||||
"0x229b88922fe52a78090673775f264cd665fe222002d6add2ed29b7ffd98de717",
|
||||
"0x8fa2d755d5cc0efb01d9fd6f5ae1f7864404ae111d8ba17e23686ea9b6566336",
|
||||
"0x33a8f2e0775fd19b1302b985bd6c29d4ab5fc63060bcf3df2c3685ab1b19ce67",
|
||||
"0xf6d6bebb541ef9b84d779c62adb76774bb38a8eba3823e74e0790dc7401bebbc",
|
||||
"0xa1f421108d49ed23996e55012613fc05e0f86e00f17251b1ff1e0824d35befc7",
|
||||
"0x2cc572ed83dc6c604bb455ab050c550184a923f4b13815f06d10ef19dffb3c7a",
|
||||
"0x28220e7d1a9583d68656f03ef4d6fa3e249c71d1b42698f87ba1fc582493e194",
|
||||
"0xe8aa37b3214abb1bc167fdb6f10119a4019541f31c76b3b3f8c363bb138bd09e",
|
||||
"0x825189c2c836dda454b457a03ff83d422bf78df1f368434768690fa7f51c57e0",
|
||||
"0x5dad65d275e69478c81ecaec5b872660205735d9649ac020f65f5ea6ae972dda",
|
||||
"0x84a1184d8f94fab280e0593479179348f9184d6fe5a2b2ea9697894c42574473",
|
||||
"0xbef5a05bc7e1fb94465570144499672d95f31fa241b4c510011f6677e2bf72fb",
|
||||
"0xd08235ebe6d79a8549bcd3d2414cd8afd2a3e2ca22ced226c60aacad1361ff89",
|
||||
"0xbab5204ad45ec52860023e7474579e7c95397f3c4ac01db7e446e92c19dceef0",
|
||||
"0x6c81acf2ff161d423a904c457166ff454ef41571d01e73d56bf9ab892790248d",
|
||||
"0xaf4a603b808e3ddece42e3e123ea02defb9f8ef2546a95c5a617b6ecdb89c306",
|
||||
"0xeecdbda25b04eb764e322d9a1e5eefad399c9ced8c77b1e4ecfbefcc90bb403d",
|
||||
"0x9463f4677a2039ca372b61b16d5bcb7c043b26af04aea4d3f0dcdec7bd222070",
|
||||
"0x27bfd92799b4cf9699d2bfcb158f6727bb986fc0dee780fc1052366ebc4e6364",
|
||||
"0x63c3faa1a8fc0d531261cd241b1299d4fc13629abb4cd357eeb130505fbddf94",
|
||||
"0x9a4535b07ff68862f3396b14b88fa07cff7abdd5744775aeeec6868606eb4712",
|
||||
"0xae59e7c3e0a1df32f6e027da2983d3c55b4ba4d99e85329361561bd7f13ac629",
|
||||
"0xcc5dc26b9be8fd8432537d967afe12fc668949e4fcf72d97a40f9214975fa57a",
|
||||
"0x8f11634c83c7a43be8b98335ba617a64c6379f5f92664055c5e1620791134ddb",
|
||||
"0x14ce2a69d844e6a46aa244c5aca9fb74c127f2151c7c16f4611ca030df365d8b",
|
||||
"0xb06f220566a5e62570b9e9e49a8b9d5663501ba145b12260fbf9d4a18a4b19e3",
|
||||
"0x6274f3cf553c45e6ba7ef644d75bf208e08a8c6325e336aefd35dda9cca3c4d2",
|
||||
"0xd0d685497c2f2b923d0b9f1590a748da8c684a915a470db58c3105c83d8304e7",
|
||||
"0xf37fab515f96e655f182f0b6e6aa3602f2cd74773329094772151e8c33d1f9a4",
|
||||
"0xf6efd731481e8553f1d18b5735166499e787009b484b0dfbe4d35e7930f0d837",
|
||||
"0xc96132b510863e553e08c54e98b5e9c0067f26e421980a6a3bfd4f07480c4396",
|
||||
"0xdca9d8182c573871b6d6a184cb9819256398080bcb7fd765e6c69cd972a28d8d",
|
||||
"0xd632ca6f5d45646726ecd2977ffea5c71a867890633f571b359657c0d096f840",
|
||||
"0xfe3884dbca6bd3b0087466b04e6a5857ad59d7a25021e1d994d059d20005185b",
|
||||
"0x7f40eb6fb94b05bb43873a98e9d4eb5f7ac90fb8913240bc0909c6be42922b30",
|
||||
"0x5113a0808666815cfc52b8ed63c649d96f35c365def36ae623f536241b163c3f",
|
||||
"0x8e6dbacfb5c593d7d7c2650d3d0115c3702cbb55f73011823a202e69ca33cc70",
|
||||
"0x8f069ac7caa48bce09fe93f4aaef6784d8a6f7a3a09edb82c7512ec18acc3ab9",
|
||||
"0xa5525e51fd789c59d3b208efffe09abca47cfd6981d36ab44084b86706c69888",
|
||||
"0xcb4a7e60d5e8b9d22887ef1e8ce339cfcea0ae1fcbfa9adb766ad05d84182de7",
|
||||
"0x0a14f23f9066ebdb67df31e66f6b8ab1c089025c0ba56ea56d15f73749f47cb7",
|
||||
"0x0963e3eba12e41d21af7625b8dc487b637b1789a6ac05fb23062e0166942df68",
|
||||
"0xcb7ec271b2f42cae0027d22b688b19b9288f2b5d9c43bc5b1ea23b35f5542828",
|
||||
"0x9b97e6f4b2eeee29ecccf9584dc020c8caa3cae51c82f5b58d279eaf0c6ab4e3",
|
||||
"0xad7f1963ce9993e6172c2ae90c6e1d4d3d3c52e14284fcc1b1e9a56776afb97e",
|
||||
"0x52ef2ad7bc2921742dcbac9772f13d5c31be938eb1ad6aceb2fa8a163389cefa",
|
||||
"0x369ead6d900e64ae0b5028df8574e59b67c61dca418c87ce6461eb4c8535fd30",
|
||||
"0x7e1a18f6199f05f21f9eb5463e9ffd87637d2fd24a23047fe095895c533cb6a5",
|
||||
"0xe1b8813a95e511aaec9b358d515e624fbc20e551c56328f843ae90b3c895d3a2",
|
||||
"0xc2ea59f3d1e7bbe115390a4c210142fe9f9dcb1959764450f5b5292ad90e0fcf",
|
||||
"0x97d235c3f18e6819c08dab4efe66d0f11f0d06f8ffc9686e3f28400e057e6f4a",
|
||||
"0xea64f817770252b77b08ca2f579b440ec02e833fc88af7c9c96a8e1e07b2cb2c",
|
||||
"0x185f5fd1f7001b533dc01783c83b7ab0828a4e2f188cc4e26768c515b4c421f6",
|
||||
"0x0c9de9844e856a1e4340bf54dcaf9dc66b489304765b5c3c6ca20284f5a0dca6",
|
||||
"0x4dd1d52da1d260d1f0f63bafc4c816b30cea8ec3434e7d4b63a0eff86997254c",
|
||||
"0x0b3eb94aa246f7c8c871535ae2d3abe5c1b951e76b77510140ef52d5ea2457ee",
|
||||
"0x27102708eea5d715799642f213049d8ac9abc3b12c76d147ce443dab28af96d8",
|
||||
"0x81fb3c4e8dc6c658af2901b7aebf7467b9ae045dd0f58fe8d77f8770ac517fb6",
|
||||
"0xf68dba4eee635d7494bae6fb9f0c44e739b3121d4bc6f6f21b495a716af3cf52",
|
||||
"0xcf87b723dc473d313bf9ddfa233056036c5658777e831796f1f56647cd040c8d",
|
||||
"0x49927c2100039ac496d9c16dd12f0a05c9441b8616c69c726fd2e79ae65e130c",
|
||||
"0x088195c7251f6b9fa2105e77df5620211b8ca783a77f1a98de6752fc442c26c7",
|
||||
"0x604de480bcb88e908b90451c4142b99b9cbb479167473befca7bea9b4ca427a3",
|
||||
"0x642fdaf6bc1abbf261a9480fcf9bb48cf03fb80bdd434c6ab63401856c74fa39",
|
||||
"0xe6b596393fce7a3023a316ac34a1fac18e18779ca5983791866f857f257592e1",
|
||||
"0x40384a52564fae5df8c3e41827cdf584e38f3f555a54ca749b7b516619071d85",
|
||||
"0xe52f7c17a4106594563ae7b724e5613e87d8442177f39a36b946b0e335be0e5b",
|
||||
"0x7726202a7c255a9d7be47af6f3b44c1e379cda61237866554396fb6ec043482c",
|
||||
"0x665da353f296cde80e3cbcb9c7f93b107d5676e5cd694b0bd33334d74789beb9",
|
||||
"0xa1157fb181aaa945793b029d3915b37103d050f1f695862d9cda90df4755c189",
|
||||
"0x449c9daae1c38b3d3f6861b63dc611f147b8a29029927f85c32b5e549df8ee9d",
|
||||
"0x5739fcf908f960416e5227ff6f95aeb00696f8eb7192968239458a0aebf42533",
|
||||
"0xfaa6017362d6e64f9ae1b6d11764ddba77cd980261acb5bdbb17b7cdee2d3024",
|
||||
"0x97fee586909cf8b3cfb2f2dd4e251cb642eb551f1e5d9fa557a21dcb66f430c0",
|
||||
"0x9934d90e0b4ec5900107784116323b0f76d1d71491cf9c619520478b6eb97ded",
|
||||
"0x8f5afe4fefb0de810442e27b2bce63e3a424f9e339a0e1f46f6ed26617a4a404",
|
||||
"0xcd12ed1b75e624f93d9e4fe7dc65407b6d7963196e4082fb459ce354977355a1",
|
||||
"0x6858ff0c07de87aa2a88498ae948efe6cffade00f3f21086f0a71b8364090846",
|
||||
"0xaca944e99122e4fe41c62b88e67940332483c8aae2a3a615508f848ceb1c044e",
|
||||
"0xa8bd3a6b9197bec8849737e6771f563d14d7415707776ce4bed9460588c55c9a",
|
||||
"0x20e5f18e795844cfcf2326f52ab1e56f4a53a1ce405fd355e0d37de5f6d552ee",
|
||||
"0x038821cd156d2d9e2aff1ce3525726c42f581ca3e9e2cc75df524a3dbdfe0feb",
|
||||
"0xb79bd23e10d1e6c7ae749cecaa732966ce3c2e2ea8b640d43638f14d7b78a21c",
|
||||
"0x2c4d3bcae4a76ffe6924555b320847211367ee37899b187d8fd4358d91264c2e",
|
||||
"0x0896db7657d2aa8d02166bd4ceba7515b24147fcf0aa34223590fb80db64f848",
|
||||
"0x95f3b077d9cff92709d46185a7dc5d723f257fb77641e436b0f1bf07947844a1",
|
||||
"0x6fdd931a93229698b92e6419074bc308a372e0923b35321b725916c1c151cae0",
|
||||
"0x8c337c36c2027d0f2fb96405f76d3190cdd01237f6a602e07976e09c4a2339e4",
|
||||
"0x8091a859cf86c1e2c22c870ebc10334f50e05bac2a41153102bf3f698bf5156b",
|
||||
"0x382435cc836bf1873e489cb4d42d1c1673c5d1b452ba2d16dbd1ca77b7b87a8c",
|
||||
"0xac5a288b16ed708b00cbe956a14e2a64b321f40851ea25ab1aded7b096822ec6",
|
||||
"0xee95229b736827a21e0b7154873da3da59e38a1ba3e3b1770de2ed973495ce23",
|
||||
"0x5168b6e3b5274054fec17b94a82931bc229d0270e5e4c9aeb61539fe8ba4f4a3",
|
||||
"0x588c6144dfbb33922873946a44f03092bd65d2f89a01b3973002ed38f48917bc",
|
||||
"0x6c51a964953dc036043b6e8c7fba4a3f6e83295306767bcc3562d9a8cdb04497",
|
||||
"0x2cfdde11cc2669c5b504c4a82c31ff03e3f0b3aff044519b44bc39405bbf3c9b",
|
||||
"0xd93200e550400a7179ac7afc394b22b7c710192eadbf429389450e7167191fdb",
|
||||
"0x5e32f497c606c01c9be8ce1cca5f3cf475f62cf38b2195244a7c93df7d064dde",
|
||||
"0xb0b74e34fd3983aef31a0584b6a7483ee936622b5fffbdce1411a9db6171c685",
|
||||
"0x69d0a96a2eca8d6a5c32e700d3f910330930a3348e98e5b276013fcf70c0fe5f",
|
||||
"0xf49cbb26f2463d38fde553e483de2d4bc6dd85efe2d0e56a2a79810df6af6db9",
|
||||
"0xe58aa167a26eadf11257f1fcb5da7eef50f9985b590320cc6c015176965ea58e",
|
||||
"0x582f08d14023a661a9d9dfd1db8324be88fc631cb9136e92f379ad7703584414",
|
||||
"0xb9c5e584f5e231c2c41b41799a945d60b7ec22487e587ef55e2d9710489c3c00",
|
||||
"0xd8b70c6657a5bf1fa4b67c4fc046c1eda284d677c610dbacaf0d2d84e4d782dd",
|
||||
"0x1e29fb536e468abf66b59dd6f48d177a5100a192f1807afc12bb5c97368b8c95",
|
||||
"0x595ac042acdb51370bf6bfd2b2058dda4781dd7ec330474defb2d5dd00e7f50e",
|
||||
"0x3d00887c6509b148c5fadde21014aae94924fef363fd5723d80d6a2028df1de5",
|
||||
"0x9632d419c9fdc7e676b130806cb9c86631aade0adc6a129d3769908ff97e7ef3",
|
||||
"0x2f91c7ce1158228c8264a6147c6ca396b0d536cdde997a922cde2772b786743f",
|
||||
"0xf4c731ac2e2612b7e7afcf3ba5911a58a03ef075133923218f54a736b25acb81",
|
||||
"0x6748a5143ad25f0a461257a47eeab8f057782a438274ced580ca2bd3725d6be3",
|
||||
"0x05a113b04baf81b6396dd32d59a53908d07a374ebdf17314ec334b3330a16697",
|
||||
"0xb1bafaef874da14b8a9f883f89a896ec37d9af1b0958f5a3867780278bfe940d",
|
||||
"0xd93c67d29befe531330c37dfa8b64db7339c8ac35b8cb674d741a414d90d77ef",
|
||||
"0xb4319281a05f00968367a349e626ec63227412193c30aaface14ac6f7a480024",
|
||||
"0xf6dce891724a49024535047bee44f889d5228066a931a8f40c18c7efed60f31b",
|
||||
"0xccdeb308e3402c7dc72588871c23fb4f6fdc60e2a63230f628c5a2951878535b",
|
||||
"0x90958033b917eea42ffb8bf077ccab8b19c2448113e8a128815ab3441846404b",
|
||||
"0xed3436553039948094f33cffaff91a7e2b1eab86b638de5c8eb09538c8df0a8e",
|
||||
"0x0910ba3093e37abaf70ffc0ef6a3b9b82e8c5f7ae497eec14b753f23d0a25343",
|
||||
"0xdc78d9fceec3add33b92e1a0ee402b80cd87946e0def46f284d26eac46be6bcd",
|
||||
"0x1d71a82b8d4b89f73747d8073a36acf8496757d35bb452e9cfd74d758774f492",
|
||||
"0x5399612937722b6fbcb90c1768a92bb35acd4da6168814c1d9deb6156cf35134",
|
||||
"0xc7156ee3591ab91824b2d4868d28baf11855a63a801b3793f99fdde7867eac7f",
|
||||
"0xd25b288f3333ea8e33b33f42edf7b64976281e4840599aa49b07da39f895073a",
|
||||
"0xc6596a87c544e84cfaa2baaa4fb0a93f3fa9d1e6938426ea05a418568a1589b0",
|
||||
"0xdbf30aa7f1cb3a6d7661934d7ea2ec0665843ea1ec9b05fddd77fdb33fa7d834",
|
||||
"0xfac2628cb5d70c177e8defbf62b0448297ecb13962638b9a26c5d05203cb2937",
|
||||
"0xe8c5a65edee74d59e7b9e2fb4779485958d95303fff95bfebc0c1f4bf24ef9bf",
|
||||
"0x67d21b95f40ca7c991f37981393dcec3218e70d5402d82ecbfcb21ae532872bb",
|
||||
"0xba19c10601ed47bffb755f791325c50af9229d5c25294f315116fdb3640ca35a",
|
||||
"0xf4c026f65e31d4606541c4e679d30d7336cfeeb81e9893465eb08c310792c061",
|
||||
"0x5425ff602e06947bda22cfb687ace85c10896b5d48de144149cba26bac9a35ae",
|
||||
"0xe11f82e350c209213da7d977e2de5199559ad3793a24a226cb4be367c0aa3c4a",
|
||||
"0x13fb0194f473a4af296184d3293005dffcd28f1cf4b986bdaacede4a0a096fa6",
|
||||
"0x3dab80c9fc23caf409e38791f07e107da3b5d0d9d4a64f87164e6d455660591b",
|
||||
"0x5901803b234ef0445acfcd884baf0777970d3b600b80ab137dc1015a5b790885",
|
||||
"0x3735e2d0ac017cd2c0570830615ed9eb642183fee5b2c2155e5fefc1d4de2561",
|
||||
"0xea9030afc249a1e4f6c86f4b19660ea63783824e8d1c3de30e38802f1aea9d12",
|
||||
"0x9def3e76927de026a1a76f39c242263ffbf94b3ef42fb6e98626b67ec3d8a308",
|
||||
"0x504886149f29d5eb02412202f04b45f23cc97a82206bdf237c433e83c52e386b",
|
||||
"0xc84d3b9e84727c2d9279dfebcdf8104762e3b101dd9f39c9482a456f87bcf976",
|
||||
"0xf4737cd864b198c8049ece5a4f18eea18b48a649997c42504b560188adfb6f2b",
|
||||
"0x410894a208ff99bd3ec5f925aa7ff6932c4404390df9e337601fa7b7251d09ff",
|
||||
"0xe6e7e7e2b54bcbe37eb7066b9a3c9b01b632d228c8ed5ef8f1871d9b7235a55b",
|
||||
"0x8af02fe4657f956a9ede1a9b0a83d67367b43a8f5efdf6bd753d09f428b58960",
|
||||
"0xdd056794fcb6f5b694934b17ef35577dbec8d04159fe447e0eba02e4ff4e9d96",
|
||||
"0xef94a3289e9e197b04c17886373adbe66a451efe052fb419846006b5f659b91a",
|
||||
"0x5558e5612dc3c222d76e7190409fc5d38479e08f6fdf4b7df299e6da968c2811",
|
||||
"0x5f38cc5046a503d424c4b63cb060956babe0c1de050517d0067eccfa23cb664d",
|
||||
"0x4c6a04827f46e51378e9ff3b811c878dead62da3ae20ef7d392c57512a09a719",
|
||||
"0x68fd9806bea1d937063778b245a6788cd992e4fc614d5bce1ffe06e125f67701",
|
||||
"0x0751a79f86c4220e81bbf6b4692976ed4c315f9b62937b23083f4db2370f04eb",
|
||||
"0x5651840a2065a3468d97bf824e78455eb5e22b82b45fde7bb69b297c4c40e853",
|
||||
"0x959d277feeb492ed3393fcd5774f1dde27c6018b07cc4fc93b937ee266ae12ea",
|
||||
"0xa145f2ed353350a89de97e83433188adbd14107c16c654c131203442c34f2899",
|
||||
"0xf888fc918eab6f88a5f6c6545d47a32dd558f10d00e86a9949cb3f144b7264e2",
|
||||
"0x2fef7f5f1c149c87602cbe38766631abc992efaee26dd5b59e5bc361f6901cf4",
|
||||
"0x5e0735a9be3eb97e790a93502a6f138a8863b0f0c20905bee0ac14d5aff4206a",
|
||||
"0x9c40cbdab8e769c2c6f9de57c23621c5d8a25adaedd1ba9df17fa1680cd4e63f",
|
||||
"0x995e6a00f5bc63f0a5d837a6671260771f12995b82da19c72a9546ae7b93f38f",
|
||||
"0x10f647c754615b475543fca5ed9a4491503867fae619513dad966af63cb7ed2b",
|
||||
"0x7e45b18bd06e946d20bc3807aa926aa5c0a10555b9dc18f9574136969b8f48d5",
|
||||
"0x8a419fcb515eef5a139a37241872c095818fd276f77e6388c74b82ae49e6386f",
|
||||
"0x2cb2d82e278d8ba47830ed3dbd6edf69d2e49721182488ffe0a01698071e7d40",
|
||||
"0x1e9e5cb7a68e7a2decef900bd250bd31c1f024ddd240799327263c72940c7e59",
|
||||
"0x3904821c4388b16e9851e3a7318f4177102da38525cd3e5e5708430a243470a1",
|
||||
"0x7785b9d9ff6dfa45d945aaa393270bf8b62bbde46e941aa068606c173963e518",
|
||||
"0xbff782fbbadfc752f5c2a239e49ab13200fc35cfba29a5332fe936a0367d336c",
|
||||
"0x294a3fd73f102c7017c9208857dfb91ec7c323916dd1bb3c9f1fac2c7d952b4b",
|
||||
"0x3a9fe3685814b6cff7a918e514a9d5375a1fc8268a48d5b78da93dfda115332f",
|
||||
"0xc033a1836983d485e28e5a0825c953a76d4c7f4a8ec5f7eb0b11baf5ae2beb79",
|
||||
"0xb088df91127cad5d72f8db96d7ea86dfdef55374bf982222a45df7d2b631ceb6"
|
||||
]
|
||||
},
|
||||
"nodes": [
|
||||
"enode://6332792c4a00e3e4ee0926ed89e0d27ef985424d97b6a45bf0f23e51f0dcb5e66b875777506458aea7af6f9e4ffb69f43f3778ee73c81ed9d34c51c4b16b0b0f@52.232.243.152:30303",
|
||||
"enode://94c15d1b9e2fe7ce56e458b9a3b672ef11894ddedd0c6f247e0f1d3487f52b66208fb4aeb8179fce6e3a749ea93ed147c37976d67af557508d199d9594c35f09@192.81.208.223:30303",
|
||||
"enode://30b7ab30a01c124a6cceca36863ece12c4f5fa68e3ba9b0b51407ccc002eeed3b3102d20a88f1c1d3c3154e2449317b8ef95090e77b312d5cc39354f86d5d606@52.176.7.10:30303",
|
||||
"enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303"
|
||||
"enode://865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303",
|
||||
"enode://691907d5a7dee24884b791e799183e5db01f4fe0b6e9b795ffaf5cf85a3023a637f2abadc82fc0da168405092df869126377c5f190794cd2d1c067245ae2b1ce@13.125.237.43:30303"
|
||||
],
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000000": { "balance": "1" },
|
||||
|
468
ethcore/res/ethereum/tests-issues/currents.json
Normal file
468
ethcore/res/ethereum/tests-issues/currents.json
Normal file
@ -0,0 +1,468 @@
|
||||
{ "block":
|
||||
[
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stCreateTest",
|
||||
"subtests": [
|
||||
"CreateOOGafterInitCodeReturndata2_d0g1v0_Constantinople"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stCreate2",
|
||||
"subtests": [
|
||||
"RevertDepthCreateAddressCollision_d0g1v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d1g1v1_Constantinople",
|
||||
"CREATE2_Suicide_d5g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d7g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedOOG_d2g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedOOG_d2g0v0_Constantinople",
|
||||
"create2collisionNonce_d1g0v0_Byzantium",
|
||||
"create2collisionNonce_d1g0v0_Constantinople",
|
||||
"CreateMessageRevertedOOGInInit_d0g1v0_Constantinople",
|
||||
"create2callPrecompiles_d3g0v0_Constantinople",
|
||||
"create2collisionCode_d1g0v0_Byzantium",
|
||||
"create2collisionCode_d1g0v0_Constantinople",
|
||||
"create2collisionStorage_d0g0v0_Byzantium",
|
||||
"create2collisionStorage_d0g0v0_Constantinople",
|
||||
"create2callPrecompiles_d4g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedRevert_d0g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedRevert_d0g0v0_Constantinople",
|
||||
"CreateMessageReverted_d0g1v0_Constantinople",
|
||||
"RevertOpcodeCreate_d0g1v0_Constantinople",
|
||||
"CREATE2_Suicide_d11g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d5g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedOOG_d1g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedOOG_d1g0v0_Constantinople",
|
||||
"returndatacopy_following_create_d1g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d1g1v1_Constantinople",
|
||||
"create2collisionSelfdestructed_d2g0v0_Byzantium",
|
||||
"create2collisionSelfdestructed_d2g0v0_Constantinople",
|
||||
"create2callPrecompiles_d2g0v0_Constantinople",
|
||||
"create2InitCodes_d2g0v0_Constantinople",
|
||||
"create2collisionNonce_d2g0v0_Byzantium",
|
||||
"create2collisionNonce_d2g0v0_Constantinople",
|
||||
"create2collisionCode_d0g0v0_Byzantium",
|
||||
"create2collisionCode_d0g0v0_Constantinople",
|
||||
"CREATE2_Bounds_d0g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d0g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d1g0v0_Constantinople",
|
||||
"CREATE2_Bounds3_d0g1v0_Constantinople",
|
||||
"create2collisionStorage_d2g0v0_Byzantium",
|
||||
"create2collisionStorage_d2g0v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d0g0v1_Constantinople",
|
||||
"create2callPrecompiles_d5g0v0_Constantinople",
|
||||
"create2collisionCode2_d0g0v0_Byzantium",
|
||||
"create2collisionCode2_d0g0v0_Constantinople",
|
||||
"create2noCash_d0g0v0_Byzantium",
|
||||
"create2noCash_d0g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d7g0v0_Constantinople",
|
||||
"create2SmartInitCode_d1g0v0_Constantinople",
|
||||
"create2InitCodes_d6g0v0_Constantinople",
|
||||
"create2noCash_d1g0v0_Byzantium",
|
||||
"create2noCash_d1g0v0_Constantinople",
|
||||
"CREATE2_ContractSuicideDuringInit_ThenStoreThenReturn_d0g0v0_Constantinople",
|
||||
"RevertOpcodeInCreateReturns_d0g0v0_Constantinople",
|
||||
"create2collisionStorage_d1g0v0_Byzantium",
|
||||
"create2collisionStorage_d1g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d3g0v0_Constantinople",
|
||||
"create2collisionBalance_d0g0v0_Byzantium",
|
||||
"create2collisionBalance_d0g0v0_Constantinople",
|
||||
"create2collisionSelfdestructed2_d0g0v0_Constantinople",
|
||||
"create2InitCodes_d3g0v0_Constantinople",
|
||||
"create2collisionCode2_d1g0v0_Byzantium",
|
||||
"create2collisionCode2_d1g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d1g0v0_Constantinople",
|
||||
"create2collisionBalance_d1g0v0_Byzantium",
|
||||
"create2collisionBalance_d1g0v0_Constantinople",
|
||||
"CREATE2_Bounds3_d0g2v0_Constantinople",
|
||||
"create2callPrecompiles_d6g0v0_Constantinople",
|
||||
"Create2Recursive_d0g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedOOG_d0g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedOOG_d0g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d3g0v0_Constantinople",
|
||||
"returndatacopy_following_create_d0g0v0_Constantinople",
|
||||
"create2InitCodes_d8g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d0g0v1_Constantinople",
|
||||
"create2checkFieldsInInitcode_d2g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d1g0v1_Constantinople",
|
||||
"Create2OnDepth1024_d0g0v0_Constantinople",
|
||||
"create2collisionSelfdestructed2_d1g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedRevert_d2g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedRevert_d2g0v0_Constantinople",
|
||||
"create2callPrecompiles_d0g0v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d0g1v1_Constantinople",
|
||||
"create2collisionSelfdestructed_d1g0v0_Byzantium",
|
||||
"create2collisionSelfdestructed_d1g0v0_Constantinople",
|
||||
"call_outsize_then_create2_successful_then_returndatasize_d0g0v0_Byzantium",
|
||||
"call_outsize_then_create2_successful_then_returndatasize_d0g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeRevert_d0g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndata3_d0g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndataSize_d0g0v0_Constantinople",
|
||||
"create2InitCodes_d7g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d10g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d0g1v0_Constantinople",
|
||||
"create2InitCodes_d5g0v0_Constantinople",
|
||||
"create2collisionSelfdestructedRevert_d1g0v0_Byzantium",
|
||||
"create2collisionSelfdestructedRevert_d1g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d1g1v0_Constantinople",
|
||||
"create2collisionSelfdestructed_d0g0v0_Byzantium",
|
||||
"create2collisionSelfdestructed_d0g0v0_Constantinople",
|
||||
"create2noCash_d2g0v0_Byzantium",
|
||||
"create2noCash_d2g0v0_Constantinople",
|
||||
"CREATE2_Bounds3_d0g0v0_Constantinople",
|
||||
"create2collisionNonce_d0g0v0_Byzantium",
|
||||
"create2collisionNonce_d0g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d2g0v0_Constantinople",
|
||||
"Create2OOGafterInitCode_d0g0v0_Constantinople",
|
||||
"call_then_create2_successful_then_returndatasize_d0g0v0_Byzantium",
|
||||
"call_then_create2_successful_then_returndatasize_d0g0v0_Constantinople",
|
||||
"create2collisionBalance_d2g0v0_Byzantium",
|
||||
"create2collisionBalance_d2g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d6g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d0g1v1_Constantinople",
|
||||
"returndatacopy_afterFailing_create_d0g0v0_Constantinople",
|
||||
"returndatacopy_following_revert_in_create_d0g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d9g0v0_Constantinople",
|
||||
"create2callPrecompiles_d7g0v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d1g0v1_Constantinople",
|
||||
"create2InitCodes_d1g0v0_Constantinople",
|
||||
"CREATE2_Bounds_d0g1v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndata_d0g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d4g0v0_Constantinople",
|
||||
"CreateMessageRevertedOOGInInit_d0g0v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d1g1v0_Constantinople",
|
||||
"returndatacopy_following_successful_create_d0g0v0_Constantinople",
|
||||
"create2checkFieldsInInitcode_d0g0v0_Constantinople",
|
||||
"CreateMessageReverted_d0g0v0_Constantinople",
|
||||
"create2SmartInitCode_d0g0v0_Constantinople",
|
||||
"CREATE2_Bounds2_d0g0v0_Constantinople",
|
||||
"returndatasize_following_successful_create_d0g0v0_Constantinople",
|
||||
"CREATE2_Bounds2_d0g1v0_Constantinople",
|
||||
"returndatacopy_0_0_following_successful_create_d0g0v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d0g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d0g0v0_Constantinople",
|
||||
"create2InitCodes_d0g0v0_Constantinople",
|
||||
"Create2OnDepth1023_d0g0v0_Constantinople",
|
||||
"create2InitCodes_d4g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndata2_d0g0v0_Constantinople",
|
||||
"create2collisionBalance_d3g0v0_Byzantium",
|
||||
"create2collisionBalance_d3g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d4g0v0_Constantinople",
|
||||
"Create2OOGafterInitCode_d0g1v0_Constantinople",
|
||||
"RevertDepthCreateAddressCollision_d1g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeRevert2_d0g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndata_d0g1v0_Constantinople",
|
||||
"Create2Recursive_d0g1v0_Constantinople",
|
||||
"create2collisionCode_d2g0v0_Byzantium",
|
||||
"create2collisionCode_d2g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d6g0v0_Constantinople",
|
||||
"CREATE2_Suicide_d8g0v0_Constantinople",
|
||||
"RevertOpcodeCreate_d0g0v0_Constantinople",
|
||||
"Create2OOGafterInitCodeReturndata2_d0g1v0_Constantinople",
|
||||
"create2callPrecompiles_d1g0v0_Constantinople",
|
||||
"RevertInCreateInInit_d0g0v0_Constantinople",
|
||||
"RevertDepthCreate2OOG_d1g0v0_Constantinople"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "bcStateTest",
|
||||
"subtests": [
|
||||
"suicideStorageCheck_Byzantium",
|
||||
"suicideStorageCheck_Constantinople",
|
||||
"suicideStorageCheckVCreate2_Byzantium",
|
||||
"suicideStorageCheckVCreate2_Constantinople",
|
||||
"create2collisionwithSelfdestructSameBlock_Constantinople",
|
||||
"blockhashNonConstArg_Constantinople",
|
||||
"suicideThenCheckBalance_Constantinople",
|
||||
"suicideThenCheckBalance_Homestead",
|
||||
"suicideStorageCheckVCreate_Byzantium",
|
||||
"suicideStorageCheckVCreate_Constantinople"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stEIP158Specific",
|
||||
"subtests": [
|
||||
"callToEmptyThenCallError_d0g0v0_Byzantium",
|
||||
"callToEmptyThenCallError_d0g0v0_Constantinople",
|
||||
"callToEmptyThenCallError_d0g0v0_EIP158"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stPreCompiledContracts",
|
||||
"subtests": [
|
||||
"identity_to_smaller_d0g0v0_Constantinople",
|
||||
"identity_to_bigger_d0g0v0_Constantinople"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stReturnDataTest",
|
||||
"subtests": [
|
||||
"modexp_modsize0_returndatasize_d0g1v0_Constantinople",
|
||||
"modexp_modsize0_returndatasize_d0g2v0_Constantinople",
|
||||
"modexp_modsize0_returndatasize_d0g3v0_Constantinople"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stSpecialTest",
|
||||
"subtests": [
|
||||
"push32withoutByte_d0g0v0_Constantinople"
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
"state":
|
||||
[
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stCreateTest",
|
||||
"subtests": {
|
||||
"CreateOOGafterInitCodeReturndata2": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stCreate2Test",
|
||||
"subtests": {
|
||||
"RevertInCreateInInit": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stEIP150Specific",
|
||||
"subtests": {
|
||||
"NewGasPriceForCodes": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stInitCodeTest",
|
||||
"subtests": {
|
||||
"OutOfGasContractCreation": {
|
||||
"subnumbers": ["4"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stPreCompiledContracts",
|
||||
"subtests": {
|
||||
"modexp": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stRevertTest",
|
||||
"subtests": {
|
||||
"LoopCallsDepthThenRevert3": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertOpcodeCreate": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertSubCallStorageOOG2": {
|
||||
"subnumbers": ["1","3"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertDepthCreateOOG": {
|
||||
"subnumbers": ["3","4"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertOpcodeMultipleSubCalls": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertOpcodeDirectCall": {
|
||||
"subnumbers": ["1","2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"LoopCallsDepthThenRevert2": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertDepth2": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertRemoteSubCallStorageOOG2": {
|
||||
"subnumbers": ["1","2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertDepthCreateAddressCollision": {
|
||||
"subnumbers": ["3","4"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stStaticCall",
|
||||
"subtests": {
|
||||
"static_RevertDepth2": {
|
||||
"subnumbers": ["1","3"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"static_CheckOpcodes4": {
|
||||
"subnumbers": ["3"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"static_CheckOpcodes3": {
|
||||
"subnumbers": ["5","6","7","8"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"static_callBasic": {
|
||||
"subnumbers": ["1","2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"static_CheckOpcodes2": {
|
||||
"subnumbers": ["5","6","7","8"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"static_callCreate": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "https://github.com/ethereum/tests/issues/512",
|
||||
"failing": "stZeroKnowledge",
|
||||
"subtests": {
|
||||
"pointAddTrunc": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"pointAdd": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"pointMulAdd": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"pointMulAdd2": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"reference": "9590",
|
||||
"failing": "stCreate2Test",
|
||||
"subtests": {
|
||||
"call_then_create2_successful_then_returndatasize": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"returndatacopy_afterFailing_create": {
|
||||
"subnumbers": ["1"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2checkFieldsInInitcode": {
|
||||
"subnumbers": ["1","2","3","5","6","7"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2Recursive": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2collisionBalance": {
|
||||
"subnumbers": ["2","3"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2InitCodes": {
|
||||
"subnumbers": ["1","5","6","7","8","9"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2OOGafterInitCode": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"CreateMessageRevertedOOGInInit": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"returndatacopy_following_revert_in_create": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2collisionSelfdestructed": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"returndatacopy_0_0_following_successful_create": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2OnDepth1023": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2OOGafterInitCodeReturndata2": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"RevertOpcodeInCreateReturns": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"CREATE2_ContractSuicideDuringInit_ThenStoreThenReturn": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"returndatasize_following_successful_create": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"call_outsize_then_create2_successful_then_returndatasize": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"CreateMessageReverted": {
|
||||
"subnumbers": ["2"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"CREATE2_Suicide": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2OOGafterInitCodeRevert": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"Create2OnDepth1024": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2collisionStorage": {
|
||||
"subnumbers": ["2","3"],
|
||||
"chain": "Constantinople (test)"
|
||||
},
|
||||
"create2callPrecompiles": {
|
||||
"subnumbers": ["*"],
|
||||
"chain": "Constantinople (test)"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -52,7 +52,7 @@ use encoded;
|
||||
use engines::{EthEngine, EpochTransition, ForkChoice};
|
||||
use error::{
|
||||
ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult,
|
||||
QueueError, QueueErrorKind, Error as EthcoreError
|
||||
QueueError, QueueErrorKind, Error as EthcoreError, EthcoreResult,
|
||||
};
|
||||
use vm::{EnvInfo, LastHashes};
|
||||
use evm::Schedule;
|
||||
@ -296,7 +296,6 @@ impl Importer {
|
||||
continue;
|
||||
}
|
||||
|
||||
let raw = block.bytes.clone();
|
||||
match self.check_and_lock_block(block, client) {
|
||||
Ok(closed_block) => {
|
||||
if self.engine.is_proposal(&header) {
|
||||
@ -314,8 +313,8 @@ impl Importer {
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
self.bad_blocks.report(raw, format!("{:?}", err));
|
||||
invalid_blocks.insert(header.hash());
|
||||
self.bad_blocks.report(bytes, format!("{:?}", err));
|
||||
invalid_blocks.insert(hash);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -356,7 +355,7 @@ impl Importer {
|
||||
imported
|
||||
}
|
||||
|
||||
fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> Result<LockedBlock, ()> {
|
||||
fn check_and_lock_block(&self, block: PreverifiedBlock, client: &Client) -> EthcoreResult<LockedBlock> {
|
||||
let engine = &*self.engine;
|
||||
let header = block.header.clone();
|
||||
|
||||
@ -364,7 +363,7 @@ impl Importer {
|
||||
let best_block_number = client.chain.read().best_block_number();
|
||||
if client.pruning_info().earliest_state > header.number() {
|
||||
warn!(target: "client", "Block import failed for #{} ({})\nBlock is ancient (current best block: #{}).", header.number(), header.hash(), best_block_number);
|
||||
return Err(());
|
||||
bail!("Block is ancient");
|
||||
}
|
||||
|
||||
// Check if parent is in chain
|
||||
@ -372,7 +371,7 @@ impl Importer {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
warn!(target: "client", "Block import failed for #{} ({}): Parent not found ({}) ", header.number(), header.hash(), header.parent_hash());
|
||||
return Err(());
|
||||
bail!("Parent not found");
|
||||
}
|
||||
};
|
||||
|
||||
@ -391,13 +390,13 @@ impl Importer {
|
||||
|
||||
if let Err(e) = verify_family_result {
|
||||
warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
bail!(e);
|
||||
};
|
||||
|
||||
let verify_external_result = self.verifier.verify_block_external(&header, engine);
|
||||
if let Err(e) = verify_external_result {
|
||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
bail!(e);
|
||||
};
|
||||
|
||||
// Enact Verified Block
|
||||
@ -417,9 +416,13 @@ impl Importer {
|
||||
&mut chain.ancestry_with_metadata_iter(*header.parent_hash()),
|
||||
);
|
||||
|
||||
let mut locked_block = enact_result.map_err(|e| {
|
||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
})?;
|
||||
let mut locked_block = match enact_result {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
bail!(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Strip receipts for blocks before validate_receipts_transition,
|
||||
// if the expected receipts root header does not match.
|
||||
@ -433,7 +436,7 @@ impl Importer {
|
||||
// Final Verification
|
||||
if let Err(e) = self.verifier.verify_block_final(&header, locked_block.block().header()) {
|
||||
warn!(target: "client", "Stage 5 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||
return Err(());
|
||||
bail!(e);
|
||||
}
|
||||
|
||||
Ok(locked_block)
|
||||
@ -443,7 +446,7 @@ impl Importer {
|
||||
///
|
||||
/// The block is guaranteed to be the next best blocks in the
|
||||
/// first block sequence. Does no sealing or transaction validation.
|
||||
fn import_old_block(&self, unverified: Unverified, receipts_bytes: &[u8], db: &KeyValueDB, chain: &BlockChain) -> Result<(), ::error::Error> {
|
||||
fn import_old_block(&self, unverified: Unverified, receipts_bytes: &[u8], db: &KeyValueDB, chain: &BlockChain) -> EthcoreResult<()> {
|
||||
let receipts = ::rlp::decode_list(receipts_bytes);
|
||||
let _import_lock = self.import_lock.lock();
|
||||
|
||||
@ -1153,7 +1156,8 @@ impl Client {
|
||||
},
|
||||
};
|
||||
|
||||
snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hashdb(), writer, p)?;
|
||||
let processing_threads = self.config.snapshot.processing_threads;
|
||||
snapshot::take_snapshot(&*self.engine, &self.chain.read(), start_hash, db.as_hashdb(), writer, p, processing_threads)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1491,7 +1495,7 @@ impl Call for Client {
|
||||
let sender = t.sender();
|
||||
let options = || TransactOptions::with_tracing().dont_check_nonce();
|
||||
|
||||
let cond = |gas| {
|
||||
let exec = |gas| {
|
||||
let mut tx = t.as_unsigned().clone();
|
||||
tx.gas = gas;
|
||||
let tx = tx.fake_sign(sender);
|
||||
@ -1499,22 +1503,28 @@ impl Call for Client {
|
||||
let mut clone = state.clone();
|
||||
let machine = self.engine.machine();
|
||||
let schedule = machine.schedule(env_info.number);
|
||||
Ok(Executive::new(&mut clone, &env_info, &machine, &schedule)
|
||||
Executive::new(&mut clone, &env_info, &machine, &schedule)
|
||||
.transact_virtual(&tx, options())
|
||||
.ok()
|
||||
.map(|r| r.exception.is_none())
|
||||
.unwrap_or(false))
|
||||
};
|
||||
|
||||
if !cond(upper)? {
|
||||
let cond = |gas| exec(gas).unwrap_or(false);
|
||||
|
||||
if !cond(upper) {
|
||||
upper = max_upper;
|
||||
if !cond(upper)? {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
|
||||
return Err(err.into())
|
||||
match exec(upper) {
|
||||
Some(false) => return Err(CallError::Exceptional),
|
||||
None => {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
|
||||
return Err(err.into())
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
let lower = t.gas_required(&self.engine.schedule(env_info.number)).into();
|
||||
if cond(lower)? {
|
||||
if cond(lower) {
|
||||
trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower);
|
||||
return Ok(lower)
|
||||
}
|
||||
@ -1523,12 +1533,12 @@ impl Call for Client {
|
||||
/// Returns the lowest value between `lower` and `upper` for which `cond` returns true.
|
||||
/// We assert: `cond(lower) = false`, `cond(upper) = true`
|
||||
fn binary_chop<F, E>(mut lower: U256, mut upper: U256, mut cond: F) -> Result<U256, E>
|
||||
where F: FnMut(U256) -> Result<bool, E>
|
||||
where F: FnMut(U256) -> bool
|
||||
{
|
||||
while upper - lower > 1.into() {
|
||||
let mid = (lower + upper) / 2;
|
||||
trace!(target: "estimate_gas", "{} .. {} .. {}", lower, mid, upper);
|
||||
let c = cond(mid)?;
|
||||
let c = cond(mid);
|
||||
match c {
|
||||
true => upper = mid,
|
||||
false => lower = mid,
|
||||
@ -2352,14 +2362,13 @@ impl ProvingBlockChainClient for Client {
|
||||
env_info.gas_limit = transaction.gas.clone();
|
||||
let mut jdb = self.state_db.read().journal_db().boxed_clone();
|
||||
|
||||
state::prove_transaction(
|
||||
state::prove_transaction_virtual(
|
||||
jdb.as_hashdb_mut(),
|
||||
header.state_root().clone(),
|
||||
&transaction,
|
||||
self.engine.machine(),
|
||||
&env_info,
|
||||
self.factories.clone(),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
use verification::{VerifierType, QueueConfig};
|
||||
use journaldb;
|
||||
use snapshot::SnapshotConfiguration;
|
||||
|
||||
pub use std::time::Duration;
|
||||
pub use blockchain::Config as BlockChainConfig;
|
||||
@ -120,6 +121,8 @@ pub struct ClientConfig {
|
||||
pub check_seal: bool,
|
||||
/// Maximal number of transactions queued for verification in a separate thread.
|
||||
pub transaction_verification_queue_size: usize,
|
||||
/// Snapshot configuration
|
||||
pub snapshot: SnapshotConfiguration,
|
||||
}
|
||||
|
||||
impl Default for ClientConfig {
|
||||
@ -144,6 +147,7 @@ impl Default for ClientConfig {
|
||||
history_mem: 32 * mb,
|
||||
check_seal: true,
|
||||
transaction_verification_queue_size: 8192,
|
||||
snapshot: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ pub struct TestBlockChainClient {
|
||||
}
|
||||
|
||||
/// Used for generating test client blocks.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum EachBlockWith {
|
||||
/// Plain block.
|
||||
Nothing,
|
||||
@ -242,69 +242,68 @@ impl TestBlockChainClient {
|
||||
*self.error_on_logs.write() = val;
|
||||
}
|
||||
|
||||
/// Add blocks to test client.
|
||||
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||
let len = self.numbers.read().len();
|
||||
for n in len..(len + count) {
|
||||
let mut header = BlockHeader::new();
|
||||
header.set_difficulty(From::from(n));
|
||||
header.set_parent_hash(self.last_hash.read().clone());
|
||||
header.set_number(n as BlockNumber);
|
||||
header.set_gas_limit(U256::from(1_000_000));
|
||||
header.set_extra_data(self.extra_data.clone());
|
||||
let uncles = match with {
|
||||
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
|
||||
let mut uncles = RlpStream::new_list(1);
|
||||
let mut uncle_header = BlockHeader::new();
|
||||
uncle_header.set_difficulty(From::from(n));
|
||||
uncle_header.set_parent_hash(self.last_hash.read().clone());
|
||||
uncle_header.set_number(n as BlockNumber);
|
||||
uncles.append(&uncle_header);
|
||||
header.set_uncles_hash(keccak(uncles.as_raw()));
|
||||
uncles
|
||||
},
|
||||
_ => RlpStream::new_list(0)
|
||||
};
|
||||
let txs = match with {
|
||||
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
|
||||
let mut txs = RlpStream::new_list(1);
|
||||
let keypair = Random.generate().unwrap();
|
||||
// Update nonces value
|
||||
self.nonces.write().insert(keypair.address(), U256::one());
|
||||
let tx = Transaction {
|
||||
action: Action::Create,
|
||||
value: U256::from(100),
|
||||
data: "3331600055".from_hex().unwrap(),
|
||||
gas: U256::from(100_000),
|
||||
gas_price: U256::from(200_000_000_000u64),
|
||||
nonce: U256::zero()
|
||||
};
|
||||
let signed_tx = tx.sign(keypair.secret(), None);
|
||||
txs.append(&signed_tx);
|
||||
txs.out()
|
||||
},
|
||||
_ => ::rlp::EMPTY_LIST_RLP.to_vec()
|
||||
};
|
||||
/// Add a block to test client.
|
||||
pub fn add_block<F>(&self, with: EachBlockWith, hook: F)
|
||||
where F: Fn(BlockHeader) -> BlockHeader
|
||||
{
|
||||
let n = self.numbers.read().len();
|
||||
|
||||
let mut rlp = RlpStream::new_list(3);
|
||||
rlp.append(&header);
|
||||
rlp.append_raw(&txs, 1);
|
||||
rlp.append_raw(uncles.as_raw(), 1);
|
||||
let unverified = Unverified::from_rlp(rlp.out()).unwrap();
|
||||
self.import_block(unverified).unwrap();
|
||||
}
|
||||
}
|
||||
let mut header = BlockHeader::new();
|
||||
header.set_difficulty(From::from(n));
|
||||
header.set_parent_hash(self.last_hash.read().clone());
|
||||
header.set_number(n as BlockNumber);
|
||||
header.set_gas_limit(U256::from(1_000_000));
|
||||
header.set_extra_data(self.extra_data.clone());
|
||||
|
||||
header = hook(header);
|
||||
|
||||
let uncles = match with {
|
||||
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
|
||||
let mut uncles = RlpStream::new_list(1);
|
||||
let mut uncle_header = BlockHeader::new();
|
||||
uncle_header.set_difficulty(From::from(n));
|
||||
uncle_header.set_parent_hash(self.last_hash.read().clone());
|
||||
uncle_header.set_number(n as BlockNumber);
|
||||
uncles.append(&uncle_header);
|
||||
header.set_uncles_hash(keccak(uncles.as_raw()));
|
||||
uncles
|
||||
},
|
||||
_ => RlpStream::new_list(0)
|
||||
};
|
||||
let txs = match with {
|
||||
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
|
||||
let mut txs = RlpStream::new_list(1);
|
||||
let keypair = Random.generate().unwrap();
|
||||
// Update nonces value
|
||||
self.nonces.write().insert(keypair.address(), U256::one());
|
||||
let tx = Transaction {
|
||||
action: Action::Create,
|
||||
value: U256::from(100),
|
||||
data: "3331600055".from_hex().unwrap(),
|
||||
gas: U256::from(100_000),
|
||||
gas_price: U256::from(200_000_000_000u64),
|
||||
nonce: U256::zero()
|
||||
};
|
||||
let signed_tx = tx.sign(keypair.secret(), None);
|
||||
txs.append(&signed_tx);
|
||||
txs.out()
|
||||
},
|
||||
_ => ::rlp::EMPTY_LIST_RLP.to_vec()
|
||||
};
|
||||
|
||||
/// Make a bad block by setting invalid extra data.
|
||||
pub fn corrupt_block(&self, n: BlockNumber) {
|
||||
let hash = self.block_hash(BlockId::Number(n)).unwrap();
|
||||
let mut header: BlockHeader = self.block_header(BlockId::Number(n)).unwrap().decode().expect("decoding failed");
|
||||
header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec());
|
||||
let mut rlp = RlpStream::new_list(3);
|
||||
rlp.append(&header);
|
||||
rlp.append_raw(&::rlp::NULL_RLP, 1);
|
||||
rlp.append_raw(&::rlp::NULL_RLP, 1);
|
||||
self.blocks.write().insert(hash, rlp.out());
|
||||
rlp.append_raw(&txs, 1);
|
||||
rlp.append_raw(uncles.as_raw(), 1);
|
||||
let unverified = Unverified::from_rlp(rlp.out()).unwrap();
|
||||
self.import_block(unverified).unwrap();
|
||||
}
|
||||
|
||||
/// Add a sequence of blocks to test client.
|
||||
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||
for _ in 0..count {
|
||||
self.add_block(with, |header| header);
|
||||
}
|
||||
}
|
||||
|
||||
/// Make a bad block by setting invalid parent hash.
|
||||
|
@ -321,7 +321,7 @@ impl EmptyStep {
|
||||
|
||||
impl fmt::Display for EmptyStep {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "({}, {}, {})", self.signature, self.step, self.parent_hash)
|
||||
write!(f, "({:x}, {}, {:x})", self.signature, self.step, self.parent_hash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -829,6 +829,10 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
|
||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||
fn extra_info(&self, header: &Header) -> BTreeMap<String, String> {
|
||||
if header.seal().len() < header_expected_seal_fields(header, self.empty_steps_transition) {
|
||||
return BTreeMap::default();
|
||||
}
|
||||
|
||||
let step = header_step(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into());
|
||||
let signature = header_signature(header, self.empty_steps_transition).as_ref().map(ToString::to_string).unwrap_or("".into());
|
||||
|
||||
@ -1403,10 +1407,12 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
||||
use hash::keccak;
|
||||
use ethereum_types::{Address, H520, H256, U256};
|
||||
use ethkey::Signature;
|
||||
use header::Header;
|
||||
use rlp::encode;
|
||||
use block::*;
|
||||
@ -2072,4 +2078,40 @@ mod tests {
|
||||
addr1_balance + (1000 + 0) + (1000 + 2),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extra_info_from_seal() {
|
||||
let (spec, tap, accounts) = setup_empty_steps();
|
||||
let engine = &*spec.engine;
|
||||
|
||||
let addr1 = accounts[0];
|
||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||
|
||||
let mut header: Header = Header::default();
|
||||
let empty_step = empty_step(engine, 1, &header.parent_hash());
|
||||
let sealed_empty_step = empty_step.sealed();
|
||||
|
||||
header.set_number(2);
|
||||
header.set_seal(vec![
|
||||
encode(&2usize).to_vec(),
|
||||
encode(&H520::default()).to_vec(),
|
||||
::rlp::encode_list(&vec![sealed_empty_step]).to_vec(),
|
||||
]);
|
||||
|
||||
let info = engine.extra_info(&header);
|
||||
|
||||
let mut expected = BTreeMap::default();
|
||||
expected.insert("step".into(), "2".into());
|
||||
expected.insert("signature".into(), Signature::from(H520::default()).to_string());
|
||||
expected.insert("emptySteps".into(), format!("[{}]", empty_step));
|
||||
|
||||
assert_eq!(info, expected);
|
||||
|
||||
header.set_seal(vec![]);
|
||||
|
||||
assert_eq!(
|
||||
engine.extra_info(&header),
|
||||
BTreeMap::default(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use engines::{Engine, Seal};
|
||||
use parity_machine::{Machine, Transactions, TotalScoredHeader};
|
||||
|
||||
/// `InstantSeal` params.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
pub struct InstantSealParams {
|
||||
/// Whether to use millisecond timestamp
|
||||
pub millisecond_timestamp: bool,
|
||||
|
@ -32,7 +32,7 @@ pub mod epoch;
|
||||
pub use self::authority_round::AuthorityRound;
|
||||
pub use self::basic_authority::BasicAuthority;
|
||||
pub use self::epoch::{EpochVerifier, Transition as EpochTransition};
|
||||
pub use self::instant_seal::InstantSeal;
|
||||
pub use self::instant_seal::{InstantSeal, InstantSealParams};
|
||||
pub use self::null_engine::NullEngine;
|
||||
pub use self::tendermint::Tendermint;
|
||||
|
||||
@ -44,7 +44,7 @@ use self::epoch::PendingTransition;
|
||||
|
||||
use account_provider::AccountProvider;
|
||||
use builtin::Builtin;
|
||||
use vm::{EnvInfo, Schedule, CreateContractAddress};
|
||||
use vm::{EnvInfo, Schedule, CreateContractAddress, CallType, ActionValue};
|
||||
use error::Error;
|
||||
use header::{Header, BlockNumber};
|
||||
use snapshot::SnapshotComponents;
|
||||
@ -163,8 +163,10 @@ pub fn default_system_or_code_call<'a>(machine: &'a ::machine::EthereumMachine,
|
||||
None,
|
||||
Some(code),
|
||||
Some(code_hash),
|
||||
Some(ActionValue::Apparent(U256::zero())),
|
||||
U256::max_value(),
|
||||
Some(data),
|
||||
Some(CallType::StaticCall),
|
||||
)
|
||||
},
|
||||
};
|
||||
|
@ -693,7 +693,6 @@ impl Engine<EthereumMachine> for Tendermint {
|
||||
}
|
||||
|
||||
fn stop(&self) {
|
||||
self.step_service.stop()
|
||||
}
|
||||
|
||||
fn is_proposal(&self, header: &Header) -> bool {
|
||||
|
@ -152,6 +152,9 @@ pub fn new_frontier_test_machine() -> EthereumMachine { load_machine(include_byt
|
||||
/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier.
|
||||
pub fn new_homestead_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/homestead_test.json")) }
|
||||
|
||||
/// Create a new Foundation Homestead-EIP210-era chain spec as though it never changed from Homestead/Frontier.
|
||||
pub fn new_eip210_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/eip210_test.json")) }
|
||||
|
||||
/// Create a new Foundation Byzantium era spec.
|
||||
pub fn new_byzantium_test_machine() -> EthereumMachine { load_machine(include_bytes!("../../res/ethereum/byzantium_test.json")) }
|
||||
|
||||
|
@ -627,7 +627,8 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
let schedule = self.schedule;
|
||||
|
||||
// refunds from SSTORE nonzero -> zero
|
||||
let sstore_refunds = substate.sstore_clears_refund;
|
||||
assert!(substate.sstore_clears_refund >= 0, "On transaction level, sstore clears refund cannot go below zero.");
|
||||
let sstore_refunds = U256::from(substate.sstore_clears_refund as u64);
|
||||
// refunds from contract suicides
|
||||
let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len());
|
||||
let refunds_bound = sstore_refunds + suicide_refunds;
|
||||
@ -1653,7 +1654,7 @@ mod tests {
|
||||
let gas_used = gas - gas_left;
|
||||
// sstore: 0 -> (1) -> () -> (1 -> 0 -> 1)
|
||||
assert_eq!(gas_used, U256::from(41860));
|
||||
assert_eq!(refund, U256::from(19800));
|
||||
assert_eq!(refund, 19800);
|
||||
|
||||
assert_eq!(state.storage_at(&operating_address, &k).unwrap(), H256::from(U256::from(1)));
|
||||
// Test a call via top-level -> y2 -> x2
|
||||
@ -1671,7 +1672,7 @@ mod tests {
|
||||
let gas_used = gas - gas_left;
|
||||
// sstore: 1 -> (1) -> () -> (0 -> 1 -> 0)
|
||||
assert_eq!(gas_used, U256::from(11860));
|
||||
assert_eq!(refund, U256::from(19800));
|
||||
assert_eq!(refund, 19800);
|
||||
}
|
||||
|
||||
fn wasm_sample_code() -> Arc<Vec<u8>> {
|
||||
|
@ -394,12 +394,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
||||
self.depth
|
||||
}
|
||||
|
||||
fn add_sstore_refund(&mut self, value: U256) {
|
||||
self.substate.sstore_clears_refund = self.substate.sstore_clears_refund.saturating_add(value);
|
||||
fn add_sstore_refund(&mut self, value: usize) {
|
||||
self.substate.sstore_clears_refund += value as i128;
|
||||
}
|
||||
|
||||
fn sub_sstore_refund(&mut self, value: U256) {
|
||||
self.substate.sstore_clears_refund = self.substate.sstore_clears_refund.saturating_sub(value);
|
||||
fn sub_sstore_refund(&mut self, value: usize) {
|
||||
self.substate.sstore_clears_refund -= value as i128;
|
||||
}
|
||||
|
||||
fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool {
|
||||
|
@ -95,10 +95,11 @@ mod difficulty_test_foundation {
|
||||
declare_test!{DifficultyTests_difficultyMainNetwork, "BasicTests/difficultyMainNetwork.json"}
|
||||
}
|
||||
|
||||
mod difficulty_test_ropsten {
|
||||
difficulty_json_test_nopath!(new_ropsten_test);
|
||||
declare_test!{DifficultyTests_difficultyRopsten, "BasicTests/difficultyRopsten.json"}
|
||||
}
|
||||
// Disabling Ropsten diff tests; waiting for upstream ethereum/tests Constantinople update
|
||||
//mod difficulty_test_ropsten {
|
||||
// difficulty_json_test_nopath!(new_ropsten_test);
|
||||
// declare_test!{DifficultyTests_difficultyRopsten, "BasicTests/difficultyRopsten.json"}
|
||||
//}
|
||||
|
||||
mod difficulty_test_frontier {
|
||||
difficulty_json_test_nopath!(new_frontier_test);
|
||||
|
@ -209,11 +209,11 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
|
||||
false
|
||||
}
|
||||
|
||||
fn add_sstore_refund(&mut self, value: U256) {
|
||||
fn add_sstore_refund(&mut self, value: usize) {
|
||||
self.ext.add_sstore_refund(value)
|
||||
}
|
||||
|
||||
fn sub_sstore_refund(&mut self, value: U256) {
|
||||
fn sub_sstore_refund(&mut self, value: usize) {
|
||||
self.ext.sub_sstore_refund(value)
|
||||
}
|
||||
}
|
||||
|
@ -135,8 +135,10 @@ impl EthereumMachine {
|
||||
Some(contract_address),
|
||||
code,
|
||||
code_hash,
|
||||
None,
|
||||
gas,
|
||||
data
|
||||
data,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
@ -149,8 +151,10 @@ impl EthereumMachine {
|
||||
contract_address: Option<Address>,
|
||||
code: Option<Arc<Vec<u8>>>,
|
||||
code_hash: Option<H256>,
|
||||
value: Option<ActionValue>,
|
||||
gas: U256,
|
||||
data: Option<Vec<u8>>
|
||||
data: Option<Vec<u8>>,
|
||||
call_type: Option<CallType>,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let env_info = {
|
||||
let mut env_info = block.env_info();
|
||||
@ -167,11 +171,11 @@ impl EthereumMachine {
|
||||
origin: SYSTEM_ADDRESS,
|
||||
gas,
|
||||
gas_price: 0.into(),
|
||||
value: ActionValue::Transfer(0.into()),
|
||||
value: value.unwrap_or(ActionValue::Transfer(0.into())),
|
||||
code,
|
||||
code_hash,
|
||||
data,
|
||||
call_type: CallType::Call,
|
||||
call_type: call_type.unwrap_or(CallType::Call),
|
||||
params_type: ParamsType::Separate,
|
||||
};
|
||||
let schedule = self.schedule(env_info.number);
|
||||
@ -367,11 +371,11 @@ impl EthereumMachine {
|
||||
}
|
||||
|
||||
/// Does verification of the transaction against the parent state.
|
||||
pub fn verify_transaction<C: BlockInfo + CallContract>(&self, t: &SignedTransaction, header: &Header, client: &C)
|
||||
pub fn verify_transaction<C: BlockInfo + CallContract>(&self, t: &SignedTransaction, parent: &Header, client: &C)
|
||||
-> Result<(), transaction::Error>
|
||||
{
|
||||
if let Some(ref filter) = self.tx_filter.as_ref() {
|
||||
if !filter.transaction_allowed(header.parent_hash(), header.number(), t, client) {
|
||||
if !filter.transaction_allowed(&parent.hash(), parent.number() + 1, t, client) {
|
||||
return Err(transaction::Error::NotAllowed.into())
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use machine::EthereumMachine;
|
||||
use ids::BlockId;
|
||||
use header::Header;
|
||||
use receipt::Receipt;
|
||||
use snapshot::{Error, ManifestData};
|
||||
use snapshot::{Error, ManifestData, Progress};
|
||||
|
||||
use itertools::{Position, Itertools};
|
||||
use rlp::{RlpStream, Rlp};
|
||||
@ -59,6 +59,7 @@ impl SnapshotComponents for PoaSnapshot {
|
||||
chain: &BlockChain,
|
||||
block_at: H256,
|
||||
sink: &mut ChunkSink,
|
||||
_progress: &Progress,
|
||||
preferred_size: usize,
|
||||
) -> Result<(), Error> {
|
||||
let number = chain.block_number(&block_at)
|
||||
|
@ -22,7 +22,7 @@ use std::sync::Arc;
|
||||
|
||||
use blockchain::{BlockChain, BlockChainDB};
|
||||
use engines::EthEngine;
|
||||
use snapshot::{Error, ManifestData};
|
||||
use snapshot::{Error, ManifestData, Progress};
|
||||
|
||||
use ethereum_types::H256;
|
||||
|
||||
@ -49,6 +49,7 @@ pub trait SnapshotComponents: Send {
|
||||
chain: &BlockChain,
|
||||
block_at: H256,
|
||||
chunk_sink: &mut ChunkSink,
|
||||
progress: &Progress,
|
||||
preferred_size: usize,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
|
@ -28,7 +28,7 @@ use std::sync::Arc;
|
||||
|
||||
use blockchain::{BlockChain, BlockChainDB, BlockProvider};
|
||||
use engines::EthEngine;
|
||||
use snapshot::{Error, ManifestData};
|
||||
use snapshot::{Error, ManifestData, Progress};
|
||||
use snapshot::block::AbridgedBlock;
|
||||
use ethereum_types::H256;
|
||||
use kvdb::KeyValueDB;
|
||||
@ -65,6 +65,7 @@ impl SnapshotComponents for PowSnapshot {
|
||||
chain: &BlockChain,
|
||||
block_at: H256,
|
||||
chunk_sink: &mut ChunkSink,
|
||||
progress: &Progress,
|
||||
preferred_size: usize,
|
||||
) -> Result<(), Error> {
|
||||
PowWorker {
|
||||
@ -72,6 +73,7 @@ impl SnapshotComponents for PowSnapshot {
|
||||
rlps: VecDeque::new(),
|
||||
current_hash: block_at,
|
||||
writer: chunk_sink,
|
||||
progress: progress,
|
||||
preferred_size: preferred_size,
|
||||
}.chunk_all(self.blocks)
|
||||
}
|
||||
@ -96,6 +98,7 @@ struct PowWorker<'a> {
|
||||
rlps: VecDeque<Bytes>,
|
||||
current_hash: H256,
|
||||
writer: &'a mut ChunkSink<'a>,
|
||||
progress: &'a Progress,
|
||||
preferred_size: usize,
|
||||
}
|
||||
|
||||
@ -138,6 +141,7 @@ impl<'a> PowWorker<'a> {
|
||||
|
||||
last = self.current_hash;
|
||||
self.current_hash = block.header_view().parent_hash();
|
||||
self.progress.blocks.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
if loaded_size != 0 {
|
||||
|
@ -20,6 +20,7 @@
|
||||
//! https://wiki.parity.io/Warp-Sync-Snapshot-Format
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::cmp;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY};
|
||||
@ -43,6 +44,7 @@ use trie::{Trie, TrieMut};
|
||||
use ethtrie::{TrieDB, TrieDBMut};
|
||||
use rlp::{RlpStream, Rlp};
|
||||
use bloom_journal::Bloom;
|
||||
use num_cpus;
|
||||
|
||||
use self::io::SnapshotWriter;
|
||||
|
||||
@ -88,6 +90,28 @@ const MAX_CHUNK_SIZE: usize = PREFERRED_CHUNK_SIZE / 4 * 5;
|
||||
const MIN_SUPPORTED_STATE_CHUNK_VERSION: u64 = 1;
|
||||
// current state chunk version.
|
||||
const STATE_CHUNK_VERSION: u64 = 2;
|
||||
/// number of snapshot subparts, must be a power of 2 in [1; 256]
|
||||
const SNAPSHOT_SUBPARTS: usize = 16;
|
||||
/// Maximum number of snapshot subparts (must be a multiple of `SNAPSHOT_SUBPARTS`)
|
||||
const MAX_SNAPSHOT_SUBPARTS: usize = 256;
|
||||
|
||||
/// Configuration for the Snapshot service
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SnapshotConfiguration {
|
||||
/// If `true`, no periodic snapshots will be created
|
||||
pub no_periodic: bool,
|
||||
/// Number of threads for creating snapshots
|
||||
pub processing_threads: usize,
|
||||
}
|
||||
|
||||
impl Default for SnapshotConfiguration {
|
||||
fn default() -> Self {
|
||||
SnapshotConfiguration {
|
||||
no_periodic: false,
|
||||
processing_threads: ::std::cmp::max(1, num_cpus::get() / 2),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A progress indicator for snapshots.
|
||||
#[derive(Debug, Default)]
|
||||
@ -130,7 +154,8 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
|
||||
block_at: H256,
|
||||
state_db: &HashDB<KeccakHasher>,
|
||||
writer: W,
|
||||
p: &Progress
|
||||
p: &Progress,
|
||||
processing_threads: usize,
|
||||
) -> Result<(), Error> {
|
||||
let start_header = chain.block_header_data(&block_at)
|
||||
.ok_or(Error::InvalidStartingBlock(BlockId::Hash(block_at)))?;
|
||||
@ -142,17 +167,45 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
|
||||
let writer = Mutex::new(writer);
|
||||
let chunker = engine.snapshot_components().ok_or(Error::SnapshotsUnsupported)?;
|
||||
let snapshot_version = chunker.current_version();
|
||||
let (state_hashes, block_hashes) = scope(|scope| {
|
||||
let (state_hashes, block_hashes) = scope(|scope| -> Result<(Vec<H256>, Vec<H256>), Error> {
|
||||
let writer = &writer;
|
||||
let block_guard = scope.spawn(move || chunk_secondary(chunker, chain, block_at, writer, p));
|
||||
let state_res = chunk_state(state_db, &state_root, writer, p);
|
||||
|
||||
state_res.and_then(|state_hashes| {
|
||||
block_guard.join().map(|block_hashes| (state_hashes, block_hashes))
|
||||
})
|
||||
// The number of threads must be between 1 and SNAPSHOT_SUBPARTS
|
||||
assert!(processing_threads >= 1, "Cannot use less than 1 threads for creating snapshots");
|
||||
let num_threads: usize = cmp::min(processing_threads, SNAPSHOT_SUBPARTS);
|
||||
info!(target: "snapshot", "Using {} threads for Snapshot creation.", num_threads);
|
||||
|
||||
let mut state_guards = Vec::with_capacity(num_threads as usize);
|
||||
|
||||
for thread_idx in 0..num_threads {
|
||||
let state_guard = scope.spawn(move || -> Result<Vec<H256>, Error> {
|
||||
let mut chunk_hashes = Vec::new();
|
||||
|
||||
for part in (thread_idx..SNAPSHOT_SUBPARTS).step_by(num_threads) {
|
||||
debug!(target: "snapshot", "Chunking part {} in thread {}", part, thread_idx);
|
||||
let mut hashes = chunk_state(state_db, &state_root, writer, p, Some(part))?;
|
||||
chunk_hashes.append(&mut hashes);
|
||||
}
|
||||
|
||||
Ok(chunk_hashes)
|
||||
});
|
||||
state_guards.push(state_guard);
|
||||
}
|
||||
|
||||
let block_hashes = block_guard.join()?;
|
||||
let mut state_hashes = Vec::new();
|
||||
|
||||
for guard in state_guards {
|
||||
let part_state_hashes = guard.join()?;
|
||||
state_hashes.extend(part_state_hashes);
|
||||
}
|
||||
|
||||
debug!(target: "snapshot", "Took a snapshot of {} accounts", p.accounts.load(Ordering::SeqCst));
|
||||
Ok((state_hashes, block_hashes))
|
||||
})?;
|
||||
|
||||
info!("produced {} state chunks and {} block chunks.", state_hashes.len(), block_hashes.len());
|
||||
info!(target: "snapshot", "produced {} state chunks and {} block chunks.", state_hashes.len(), block_hashes.len());
|
||||
|
||||
let manifest_data = ManifestData {
|
||||
version: snapshot_version,
|
||||
@ -200,6 +253,7 @@ pub fn chunk_secondary<'a>(mut chunker: Box<SnapshotComponents>, chain: &'a Bloc
|
||||
chain,
|
||||
start_hash,
|
||||
&mut chunk_sink,
|
||||
progress,
|
||||
PREFERRED_CHUNK_SIZE,
|
||||
)?;
|
||||
}
|
||||
@ -263,10 +317,12 @@ impl<'a> StateChunker<'a> {
|
||||
|
||||
/// Walk the given state database starting from the given root,
|
||||
/// creating chunks and writing them out.
|
||||
/// `part` is a number between 0 and 15, which describe which part of
|
||||
/// the tree should be chunked.
|
||||
///
|
||||
/// Returns a list of hashes of chunks created, or any error it may
|
||||
/// have encountered.
|
||||
pub fn chunk_state<'a>(db: &HashDB<KeccakHasher>, root: &H256, writer: &Mutex<SnapshotWriter + 'a>, progress: &'a Progress) -> Result<Vec<H256>, Error> {
|
||||
pub fn chunk_state<'a>(db: &HashDB<KeccakHasher>, root: &H256, writer: &Mutex<SnapshotWriter + 'a>, progress: &'a Progress, part: Option<usize>) -> Result<Vec<H256>, Error> {
|
||||
let account_trie = TrieDB::new(db, &root)?;
|
||||
|
||||
let mut chunker = StateChunker {
|
||||
@ -281,11 +337,33 @@ pub fn chunk_state<'a>(db: &HashDB<KeccakHasher>, root: &H256, writer: &Mutex<Sn
|
||||
let mut used_code = HashSet::new();
|
||||
|
||||
// account_key here is the address' hash.
|
||||
for item in account_trie.iter()? {
|
||||
let mut account_iter = account_trie.iter()?;
|
||||
|
||||
let mut seek_to = None;
|
||||
|
||||
if let Some(part) = part {
|
||||
assert!(part < 16, "Wrong chunk state part number (must be <16) in snapshot creation.");
|
||||
|
||||
let part_offset = MAX_SNAPSHOT_SUBPARTS / SNAPSHOT_SUBPARTS;
|
||||
let mut seek_from = vec![0; 32];
|
||||
seek_from[0] = (part * part_offset) as u8;
|
||||
account_iter.seek(&seek_from)?;
|
||||
|
||||
// Set the upper-bound, except for the last part
|
||||
if part < SNAPSHOT_SUBPARTS - 1 {
|
||||
seek_to = Some(((part + 1) * part_offset) as u8)
|
||||
}
|
||||
}
|
||||
|
||||
for item in account_iter {
|
||||
let (account_key, account_data) = item?;
|
||||
let account = ::rlp::decode(&*account_data)?;
|
||||
let account_key_hash = H256::from_slice(&account_key);
|
||||
|
||||
if seek_to.map_or(false, |seek_to| account_key[0] >= seek_to) {
|
||||
break;
|
||||
}
|
||||
|
||||
let account = ::rlp::decode(&*account_data)?;
|
||||
let account_db = AccountDB::from_hash(db, account_key_hash);
|
||||
|
||||
let fat_rlps = account::to_fat_rlps(&account_key_hash, &account, &account_db, &mut used_code, PREFERRED_CHUNK_SIZE - chunker.chunk_size(), PREFERRED_CHUNK_SIZE)?;
|
||||
|
@ -22,7 +22,7 @@ use hash::{KECCAK_NULL_RLP, keccak};
|
||||
|
||||
use basic_account::BasicAccount;
|
||||
use snapshot::account;
|
||||
use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder};
|
||||
use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder, SNAPSHOT_SUBPARTS};
|
||||
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
|
||||
use super::helpers::{compare_dbs, StateProducer};
|
||||
|
||||
@ -53,7 +53,11 @@ fn snap_and_restore() {
|
||||
let state_root = producer.state_root();
|
||||
let writer = Mutex::new(PackedWriter::new(&snap_file).unwrap());
|
||||
|
||||
let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default()).unwrap();
|
||||
let mut state_hashes = Vec::new();
|
||||
for part in 0..SNAPSHOT_SUBPARTS {
|
||||
let mut hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), Some(part)).unwrap();
|
||||
state_hashes.append(&mut hashes);
|
||||
}
|
||||
|
||||
writer.into_inner().finish(::snapshot::ManifestData {
|
||||
version: 2,
|
||||
@ -164,7 +168,7 @@ fn checks_flag() {
|
||||
let state_root = producer.state_root();
|
||||
let writer = Mutex::new(PackedWriter::new(&snap_file).unwrap());
|
||||
|
||||
let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default()).unwrap();
|
||||
let state_hashes = chunk_state(&old_db, &state_root, &writer, &Progress::default(), None).unwrap();
|
||||
|
||||
writer.into_inner().finish(::snapshot::ManifestData {
|
||||
version: 2,
|
||||
|
@ -33,7 +33,10 @@ use vm::{EnvInfo, CallType, ActionValue, ActionParams, ParamsType};
|
||||
|
||||
use builtin::Builtin;
|
||||
use encoded;
|
||||
use engines::{EthEngine, NullEngine, InstantSeal, BasicAuthority, AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT};
|
||||
use engines::{
|
||||
EthEngine, NullEngine, InstantSeal, InstantSealParams, BasicAuthority,
|
||||
AuthorityRound, Tendermint, DEFAULT_BLOCKHASH_CONTRACT
|
||||
};
|
||||
use error::Error;
|
||||
use executive::Executive;
|
||||
use factory::Factories;
|
||||
@ -596,7 +599,8 @@ impl Spec {
|
||||
match engine_spec {
|
||||
ethjson::spec::Engine::Null(null) => Arc::new(NullEngine::new(null.params.into(), machine)),
|
||||
ethjson::spec::Engine::Ethash(ethash) => Arc::new(::ethereum::Ethash::new(spec_params.cache_dir, ethash.params.into(), machine, spec_params.optimization_setting)),
|
||||
ethjson::spec::Engine::InstantSeal(instant_seal) => Arc::new(InstantSeal::new(instant_seal.params.into(), machine)),
|
||||
ethjson::spec::Engine::InstantSeal(Some(instant_seal)) => Arc::new(InstantSeal::new(instant_seal.params.into(), machine)),
|
||||
ethjson::spec::Engine::InstantSeal(None) => Arc::new(InstantSeal::new(InstantSealParams::default(), machine)),
|
||||
ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(basic_authority.params.into(), machine)),
|
||||
ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(authority_round.params.into(), machine)
|
||||
.expect("Failed to start AuthorityRound consensus engine."),
|
||||
@ -873,14 +877,13 @@ impl Spec {
|
||||
data: d,
|
||||
}.fake_sign(from);
|
||||
|
||||
let res = ::state::prove_transaction(
|
||||
let res = ::state::prove_transaction_virtual(
|
||||
db.as_hashdb_mut(),
|
||||
*genesis.state_root(),
|
||||
&tx,
|
||||
self.engine.machine(),
|
||||
&env_info,
|
||||
factories.clone(),
|
||||
true,
|
||||
);
|
||||
|
||||
res.map(|(out, proof)| {
|
||||
|
@ -224,17 +224,16 @@ pub fn check_proof(
|
||||
}
|
||||
}
|
||||
|
||||
/// Prove a transaction on the given state.
|
||||
/// Prove a `virtual` transaction on the given state.
|
||||
/// Returns `None` when the transacion could not be proved,
|
||||
/// and a proof otherwise.
|
||||
pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>(
|
||||
pub fn prove_transaction_virtual<H: AsHashDB<KeccakHasher> + Send + Sync>(
|
||||
db: H,
|
||||
root: H256,
|
||||
transaction: &SignedTransaction,
|
||||
machine: &Machine,
|
||||
env_info: &EnvInfo,
|
||||
factories: Factories,
|
||||
virt: bool,
|
||||
) -> Option<(Bytes, Vec<DBValue>)> {
|
||||
use self::backend::Proving;
|
||||
|
||||
@ -252,7 +251,7 @@ pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>(
|
||||
};
|
||||
|
||||
let options = TransactOptions::with_no_tracing().dont_check_nonce().save_output_from_contract();
|
||||
match state.execute(env_info, machine, transaction, options, virt) {
|
||||
match state.execute(env_info, machine, transaction, options, true) {
|
||||
Err(ExecutionError::Internal(_)) => None,
|
||||
Err(e) => {
|
||||
trace!(target: "state", "Proved call failed: {}", e);
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Execution environment substate.
|
||||
use std::collections::HashSet;
|
||||
use ethereum_types::{U256, Address};
|
||||
use ethereum_types::Address;
|
||||
use log_entry::LogEntry;
|
||||
use evm::{Schedule, CleanDustMode};
|
||||
use super::CleanupMode;
|
||||
@ -35,7 +35,7 @@ pub struct Substate {
|
||||
pub logs: Vec<LogEntry>,
|
||||
|
||||
/// Refund counter of SSTORE.
|
||||
pub sstore_clears_refund: U256,
|
||||
pub sstore_clears_refund: i128,
|
||||
|
||||
/// Created contracts.
|
||||
pub contracts_created: Vec<Address>,
|
||||
@ -52,7 +52,7 @@ impl Substate {
|
||||
self.suicides.extend(s.suicides);
|
||||
self.touched.extend(s.touched);
|
||||
self.logs.extend(s.logs);
|
||||
self.sstore_clears_refund = self.sstore_clears_refund + s.sstore_clears_refund;
|
||||
self.sstore_clears_refund += s.sstore_clears_refund;
|
||||
self.contracts_created.extend(s.contracts_created);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ fn test_blockhash_eip210(factory: Factory) {
|
||||
let test_blockhash_contract = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b61014a565b4360003512151561009057600060405260206040f35b610100600035430312156100b357610100600035075460605260206060f3610149565b62010000600035430312156100d157600061010060003507146100d4565b60005b156100f6576101006101006000350507610100015460805260206080f3610148565b630100000060003543031215610116576000620100006000350714610119565b60005b1561013c57610100620100006000350507610200015460a052602060a0f3610147565b600060c052602060c0f35b5b5b5b5b";
|
||||
let blockhash_contract_code = Arc::new(test_blockhash_contract.from_hex().unwrap());
|
||||
let blockhash_contract_code_hash = keccak(blockhash_contract_code.as_ref());
|
||||
let machine = ::ethereum::new_constantinople_test_machine();
|
||||
let machine = ::ethereum::new_eip210_test_machine();
|
||||
let mut env_info = EnvInfo::default();
|
||||
|
||||
// populate state with 256 last hashes
|
||||
|
@ -465,19 +465,19 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
|
||||
/// Add a block to the queue.
|
||||
pub fn import(&self, input: K::Input) -> ImportResult {
|
||||
let h = input.hash();
|
||||
let hash = input.hash();
|
||||
{
|
||||
if self.processing.read().contains_key(&h) {
|
||||
if self.processing.read().contains_key(&hash) {
|
||||
bail!(ErrorKind::Import(ImportErrorKind::AlreadyQueued));
|
||||
}
|
||||
|
||||
let mut bad = self.verification.bad.lock();
|
||||
if bad.contains(&h) {
|
||||
if bad.contains(&hash) {
|
||||
bail!(ErrorKind::Import(ImportErrorKind::KnownBad));
|
||||
}
|
||||
|
||||
if bad.contains(&input.parent_hash()) {
|
||||
bad.insert(h.clone());
|
||||
bad.insert(hash);
|
||||
bail!(ErrorKind::Import(ImportErrorKind::KnownBad));
|
||||
}
|
||||
}
|
||||
@ -486,21 +486,21 @@ impl<K: Kind> VerificationQueue<K> {
|
||||
Ok(item) => {
|
||||
self.verification.sizes.unverified.fetch_add(item.heap_size_of_children(), AtomicOrdering::SeqCst);
|
||||
|
||||
self.processing.write().insert(h.clone(), item.difficulty());
|
||||
self.processing.write().insert(hash, item.difficulty());
|
||||
{
|
||||
let mut td = self.total_difficulty.write();
|
||||
*td = *td + item.difficulty();
|
||||
}
|
||||
self.verification.unverified.lock().push_back(item);
|
||||
self.more_to_verify.notify_all();
|
||||
Ok(h)
|
||||
Ok(hash)
|
||||
},
|
||||
Err(err) => {
|
||||
match err {
|
||||
// Don't mark future blocks as bad.
|
||||
Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _) => {},
|
||||
_ => {
|
||||
self.verification.bad.lock().insert(h.clone());
|
||||
self.verification.bad.lock().insert(hash);
|
||||
}
|
||||
}
|
||||
Err(err)
|
||||
|
@ -147,7 +147,9 @@ pub fn verify_block_family<C: BlockInfo + CallContract>(header: &Header, parent:
|
||||
verify_uncles(params.block, params.block_provider, engine)?;
|
||||
|
||||
for tx in ¶ms.block.transactions {
|
||||
engine.machine().verify_transaction(tx, header, params.client)?;
|
||||
// transactions are verified against the parent header since the current
|
||||
// state wasn't available when the tx was created
|
||||
engine.machine().verify_transaction(tx, parent, params.client)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -245,15 +247,15 @@ fn verify_uncles(block: &PreverifiedBlock, bc: &BlockProvider, engine: &EthEngin
|
||||
|
||||
/// Phase 4 verification. Check block information against transaction enactment results,
|
||||
pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> {
|
||||
if expected.state_root() != got.state_root() {
|
||||
return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() })))
|
||||
}
|
||||
if expected.gas_used() != got.gas_used() {
|
||||
return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used().clone(), found: got.gas_used().clone() })))
|
||||
}
|
||||
if expected.log_bloom() != got.log_bloom() {
|
||||
return Err(From::from(BlockError::InvalidLogBloom(Mismatch { expected: expected.log_bloom().clone(), found: got.log_bloom().clone() })))
|
||||
}
|
||||
if expected.state_root() != got.state_root() {
|
||||
return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root().clone(), found: got.state_root().clone() })))
|
||||
}
|
||||
if expected.receipts_root() != got.receipts_root() {
|
||||
return Err(From::from(BlockError::InvalidReceiptsRoot(Mismatch { expected: expected.receipts_root().clone(), found: got.receipts_root().clone() })))
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKi
|
||||
use ethcore::error::{ImportErrorKind, QueueErrorKind, BlockError};
|
||||
use sync_io::SyncIo;
|
||||
use blocks::{BlockCollection, SyncBody, SyncHeader};
|
||||
use chain::BlockSet;
|
||||
|
||||
const MAX_HEADERS_TO_REQUEST: usize = 128;
|
||||
const MAX_BODIES_TO_REQUEST: usize = 32;
|
||||
@ -35,6 +36,26 @@ const MAX_RECEPITS_TO_REQUEST: usize = 128;
|
||||
const SUBCHAIN_SIZE: u64 = 256;
|
||||
const MAX_ROUND_PARENTS: usize = 16;
|
||||
const MAX_PARALLEL_SUBCHAIN_DOWNLOAD: usize = 5;
|
||||
const MAX_USELESS_HEADERS_PER_ROUND: usize = 3;
|
||||
|
||||
// logging macros prepend BlockSet context for log filtering
|
||||
macro_rules! trace_sync {
|
||||
($self:ident, $fmt:expr, $($arg:tt)+) => {
|
||||
trace!(target: "sync", concat!("{:?}: ", $fmt), $self.block_set, $($arg)+);
|
||||
};
|
||||
($self:ident, $fmt:expr) => {
|
||||
trace!(target: "sync", concat!("{:?}: ", $fmt), $self.block_set);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_sync {
|
||||
($self:ident, $fmt:expr, $($arg:tt)+) => {
|
||||
debug!(target: "sync", concat!("{:?}: ", $fmt), $self.block_set, $($arg)+);
|
||||
};
|
||||
($self:ident, $fmt:expr) => {
|
||||
debug!(target: "sync", concat!("{:?}: ", $fmt), $self.block_set);
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
/// Downloader state
|
||||
@ -65,6 +86,7 @@ pub enum BlockRequest {
|
||||
}
|
||||
|
||||
/// Indicates sync action
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub enum DownloadAction {
|
||||
/// Do nothing
|
||||
None,
|
||||
@ -89,15 +111,17 @@ impl From<rlp::DecoderError> for BlockDownloaderImportError {
|
||||
/// Block downloader strategy.
|
||||
/// Manages state and block data for a block download process.
|
||||
pub struct BlockDownloader {
|
||||
/// Which set of blocks to download
|
||||
block_set: BlockSet,
|
||||
/// Downloader state
|
||||
state: State,
|
||||
/// Highest block number seen
|
||||
highest_block: Option<BlockNumber>,
|
||||
/// Downloaded blocks, holds `H`, `B` and `S`
|
||||
blocks: BlockCollection,
|
||||
/// Last impoted block number
|
||||
/// Last imported block number
|
||||
last_imported_block: BlockNumber,
|
||||
/// Last impoted block hash
|
||||
/// Last imported block hash
|
||||
last_imported_hash: H256,
|
||||
/// Number of blocks imported this round
|
||||
imported_this_round: Option<usize>,
|
||||
@ -112,15 +136,20 @@ pub struct BlockDownloader {
|
||||
target_hash: Option<H256>,
|
||||
/// Probing range for seeking common best block.
|
||||
retract_step: u64,
|
||||
/// Whether reorg should be limited.
|
||||
limit_reorg: bool,
|
||||
/// consecutive useless headers this round
|
||||
useless_headers_count: usize,
|
||||
}
|
||||
|
||||
impl BlockDownloader {
|
||||
/// Create a new instance of syncing strategy. This won't reorganize to before the
|
||||
/// last kept state.
|
||||
pub fn new(sync_receipts: bool, start_hash: &H256, start_number: BlockNumber) -> Self {
|
||||
/// Create a new instance of syncing strategy.
|
||||
/// For BlockSet::NewBlocks this won't reorganize to before the last kept state.
|
||||
pub fn new(block_set: BlockSet, start_hash: &H256, start_number: BlockNumber) -> Self {
|
||||
let sync_receipts = match block_set {
|
||||
BlockSet::NewBlocks => false,
|
||||
BlockSet::OldBlocks => true
|
||||
};
|
||||
BlockDownloader {
|
||||
block_set,
|
||||
state: State::Idle,
|
||||
highest_block: None,
|
||||
last_imported_block: start_number,
|
||||
@ -133,32 +162,14 @@ impl BlockDownloader {
|
||||
download_receipts: sync_receipts,
|
||||
target_hash: None,
|
||||
retract_step: 1,
|
||||
limit_reorg: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new instance of sync with unlimited reorg allowed.
|
||||
pub fn with_unlimited_reorg(sync_receipts: bool, start_hash: &H256, start_number: BlockNumber) -> Self {
|
||||
BlockDownloader {
|
||||
state: State::Idle,
|
||||
highest_block: None,
|
||||
last_imported_block: start_number,
|
||||
last_imported_hash: start_hash.clone(),
|
||||
last_round_start: start_number,
|
||||
last_round_start_hash: start_hash.clone(),
|
||||
blocks: BlockCollection::new(sync_receipts),
|
||||
imported_this_round: None,
|
||||
round_parents: VecDeque::new(),
|
||||
download_receipts: sync_receipts,
|
||||
target_hash: None,
|
||||
retract_step: 1,
|
||||
limit_reorg: false,
|
||||
useless_headers_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset sync. Clear all local downloaded data.
|
||||
pub fn reset(&mut self) {
|
||||
self.blocks.clear();
|
||||
self.useless_headers_count = 0;
|
||||
self.state = State::Idle;
|
||||
}
|
||||
|
||||
@ -220,45 +231,65 @@ impl BlockDownloader {
|
||||
}
|
||||
|
||||
/// Add new block headers.
|
||||
pub fn import_headers(&mut self, io: &mut SyncIo, r: &Rlp, expected_hash: Option<H256>) -> Result<DownloadAction, BlockDownloaderImportError> {
|
||||
pub fn import_headers(&mut self, io: &mut SyncIo, r: &Rlp, expected_hash: H256) -> Result<DownloadAction, BlockDownloaderImportError> {
|
||||
let item_count = r.item_count().unwrap_or(0);
|
||||
if self.state == State::Idle {
|
||||
trace!(target: "sync", "Ignored unexpected block headers");
|
||||
trace_sync!(self, "Ignored unexpected block headers");
|
||||
return Ok(DownloadAction::None)
|
||||
}
|
||||
if item_count == 0 && (self.state == State::Blocks) {
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
|
||||
// The request is generated in ::request_blocks.
|
||||
let (max_count, skip) = if self.state == State::ChainHead {
|
||||
(SUBCHAIN_SIZE as usize, (MAX_HEADERS_TO_REQUEST - 2) as u64)
|
||||
} else {
|
||||
(MAX_HEADERS_TO_REQUEST, 0)
|
||||
};
|
||||
|
||||
if item_count > max_count {
|
||||
debug!(target: "sync", "Headers response is larger than expected");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
|
||||
let mut headers = Vec::new();
|
||||
let mut hashes = Vec::new();
|
||||
let mut valid_response = item_count == 0; //empty response is valid
|
||||
let mut any_known = false;
|
||||
let mut last_header = None;
|
||||
for i in 0..item_count {
|
||||
let info = SyncHeader::from_rlp(r.at(i)?.as_raw().to_vec())?;
|
||||
let number = BlockNumber::from(info.header.number());
|
||||
let hash = info.header.hash();
|
||||
// Check if any of the headers matches the hash we requested
|
||||
if !valid_response {
|
||||
if let Some(expected) = expected_hash {
|
||||
valid_response = expected == hash;
|
||||
|
||||
let valid_response = match last_header {
|
||||
// First header must match expected hash.
|
||||
None => expected_hash == hash,
|
||||
Some((last_number, last_hash)) => {
|
||||
// Subsequent headers must be spaced by skip interval.
|
||||
let skip_valid = number == last_number + skip + 1;
|
||||
// Consecutive headers must be linked by parent hash.
|
||||
let parent_valid = (number != last_number + 1) || *info.header.parent_hash() == last_hash;
|
||||
skip_valid && parent_valid
|
||||
}
|
||||
}
|
||||
any_known = any_known || self.blocks.contains_head(&hash);
|
||||
if self.blocks.contains(&hash) {
|
||||
trace!(target: "sync", "Skipping existing block header {} ({:?})", number, hash);
|
||||
continue;
|
||||
};
|
||||
|
||||
// Disable the peer for this syncing round if it gives invalid chain
|
||||
if !valid_response {
|
||||
debug!(target: "sync", "Invalid headers response");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
|
||||
if self.highest_block.as_ref().map_or(true, |n| number > *n) {
|
||||
self.highest_block = Some(number);
|
||||
last_header = Some((number, hash));
|
||||
if self.blocks.contains(&hash) {
|
||||
trace_sync!(self, "Skipping existing block header {} ({:?})", number, hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
match io.chain().block_status(BlockId::Hash(hash.clone())) {
|
||||
BlockStatus::InChain | BlockStatus::Queued => {
|
||||
match self.state {
|
||||
State::Blocks => trace!(target: "sync", "Header already in chain {} ({})", number, hash),
|
||||
_ => trace!(target: "sync", "Header already in chain {} ({}), state = {:?}", number, hash, self.state),
|
||||
State::Blocks => trace_sync!(self, "Header already in chain {} ({})", number, hash),
|
||||
_ => trace_sync!(self, "Header already in chain {} ({}), state = {:?}", number, hash, self.state),
|
||||
}
|
||||
headers.push(info);
|
||||
hashes.push(hash);
|
||||
@ -273,53 +304,67 @@ impl BlockDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the peer for this syncing round if it gives invalid chain
|
||||
if !valid_response {
|
||||
trace!(target: "sync", "Invalid headers response");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
if let Some((number, _)) = last_header {
|
||||
if self.highest_block.as_ref().map_or(true, |n| number > *n) {
|
||||
self.highest_block = Some(number);
|
||||
}
|
||||
}
|
||||
|
||||
match self.state {
|
||||
State::ChainHead => {
|
||||
if !headers.is_empty() {
|
||||
// TODO: validate heads better. E.g. check that there is enough distance between blocks.
|
||||
trace!(target: "sync", "Received {} subchain heads, proceeding to download", headers.len());
|
||||
trace_sync!(self, "Received {} subchain heads, proceeding to download", headers.len());
|
||||
self.blocks.reset_to(hashes);
|
||||
self.state = State::Blocks;
|
||||
return Ok(DownloadAction::Reset);
|
||||
} else {
|
||||
trace_sync!(self, "No useful subchain heads received, expected hash {:?}", expected_hash);
|
||||
let best = io.chain().chain_info().best_block_number;
|
||||
let oldest_reorg = io.chain().pruning_info().earliest_state;
|
||||
let last = self.last_imported_block;
|
||||
if self.limit_reorg && best > last && (last == 0 || last < oldest_reorg) {
|
||||
trace!(target: "sync", "No common block, disabling peer");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
match self.block_set {
|
||||
BlockSet::NewBlocks if best > last && (last == 0 || last < oldest_reorg) => {
|
||||
trace_sync!(self, "No common block, disabling peer");
|
||||
return Err(BlockDownloaderImportError::Invalid)
|
||||
},
|
||||
BlockSet::OldBlocks => {
|
||||
trace_sync!(self, "Expected some useful headers for downloading OldBlocks. Try a different peer");
|
||||
return Err(BlockDownloaderImportError::Useless)
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
},
|
||||
State::Blocks => {
|
||||
let count = headers.len();
|
||||
// At least one of the heades must advance the subchain. Otherwise they are all useless.
|
||||
if count == 0 || !any_known {
|
||||
trace!(target: "sync", "No useful headers");
|
||||
// At least one of the headers must advance the subchain. Otherwise they are all useless.
|
||||
if count == 0 {
|
||||
self.useless_headers_count += 1;
|
||||
trace_sync!(self, "No useful headers ({:?} this round), expected hash {:?}", self.useless_headers_count, expected_hash);
|
||||
// only reset download if we have multiple subchain heads, to avoid unnecessary resets
|
||||
// when we are at the head of the chain when we may legitimately receive no useful headers
|
||||
if self.blocks.heads_len() > 1 && self.useless_headers_count >= MAX_USELESS_HEADERS_PER_ROUND {
|
||||
trace_sync!(self, "Received {:?} useless responses this round. Resetting sync", MAX_USELESS_HEADERS_PER_ROUND);
|
||||
self.reset();
|
||||
}
|
||||
return Err(BlockDownloaderImportError::Useless);
|
||||
}
|
||||
self.blocks.insert_headers(headers);
|
||||
trace!(target: "sync", "Inserted {} headers", count);
|
||||
trace_sync!(self, "Inserted {} headers", count);
|
||||
},
|
||||
_ => trace!(target: "sync", "Unexpected headers({})", headers.len()),
|
||||
_ => trace_sync!(self, "Unexpected headers({})", headers.len()),
|
||||
}
|
||||
|
||||
Ok(DownloadAction::None)
|
||||
}
|
||||
|
||||
/// Called by peer once it has new block bodies
|
||||
pub fn import_bodies(&mut self, r: &Rlp) -> Result<(), BlockDownloaderImportError> {
|
||||
pub fn import_bodies(&mut self, r: &Rlp, expected_hashes: &[H256]) -> Result<(), BlockDownloaderImportError> {
|
||||
let item_count = r.item_count().unwrap_or(0);
|
||||
if item_count == 0 {
|
||||
return Err(BlockDownloaderImportError::Useless);
|
||||
} else if self.state != State::Blocks {
|
||||
trace!(target: "sync", "Ignored unexpected block bodies");
|
||||
trace_sync!(self, "Ignored unexpected block bodies");
|
||||
} else {
|
||||
let mut bodies = Vec::with_capacity(item_count);
|
||||
for i in 0..item_count {
|
||||
@ -327,8 +372,13 @@ impl BlockDownloader {
|
||||
bodies.push(body);
|
||||
}
|
||||
|
||||
if self.blocks.insert_bodies(bodies) != item_count {
|
||||
trace!(target: "sync", "Deactivating peer for giving invalid block bodies");
|
||||
let hashes = self.blocks.insert_bodies(bodies);
|
||||
if hashes.len() != item_count {
|
||||
trace_sync!(self, "Deactivating peer for giving invalid block bodies");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
if !all_expected(hashes.as_slice(), expected_hashes, |&a, &b| a == b) {
|
||||
trace_sync!(self, "Deactivating peer for giving unexpected block bodies");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
}
|
||||
@ -336,25 +386,30 @@ impl BlockDownloader {
|
||||
}
|
||||
|
||||
/// Called by peer once it has new block bodies
|
||||
pub fn import_receipts(&mut self, _io: &mut SyncIo, r: &Rlp) -> Result<(), BlockDownloaderImportError> {
|
||||
pub fn import_receipts(&mut self, r: &Rlp, expected_hashes: &[H256]) -> Result<(), BlockDownloaderImportError> {
|
||||
let item_count = r.item_count().unwrap_or(0);
|
||||
if item_count == 0 {
|
||||
return Err(BlockDownloaderImportError::Useless);
|
||||
}
|
||||
else if self.state != State::Blocks {
|
||||
trace!(target: "sync", "Ignored unexpected block receipts");
|
||||
trace_sync!(self, "Ignored unexpected block receipts");
|
||||
}
|
||||
else {
|
||||
let mut receipts = Vec::with_capacity(item_count);
|
||||
for i in 0..item_count {
|
||||
let receipt = r.at(i).map_err(|e| {
|
||||
trace!(target: "sync", "Error decoding block receipts RLP: {:?}", e);
|
||||
trace_sync!(self, "Error decoding block receipts RLP: {:?}", e);
|
||||
BlockDownloaderImportError::Invalid
|
||||
})?;
|
||||
receipts.push(receipt.as_raw().to_vec());
|
||||
}
|
||||
if self.blocks.insert_receipts(receipts) != item_count {
|
||||
trace!(target: "sync", "Deactivating peer for giving invalid block receipts");
|
||||
let hashes = self.blocks.insert_receipts(receipts);
|
||||
if hashes.len() != item_count {
|
||||
trace_sync!(self, "Deactivating peer for giving invalid block receipts");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
if !all_expected(hashes.as_slice(), expected_hashes, |a, b| a.contains(b)) {
|
||||
trace_sync!(self, "Deactivating peer for giving unexpected block receipts");
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
}
|
||||
@ -363,7 +418,7 @@ impl BlockDownloader {
|
||||
|
||||
fn start_sync_round(&mut self, io: &mut SyncIo) {
|
||||
self.state = State::ChainHead;
|
||||
trace!(target: "sync", "Starting round (last imported count = {:?}, last started = {}, block = {:?}", self.imported_this_round, self.last_round_start, self.last_imported_block);
|
||||
trace_sync!(self, "Starting round (last imported count = {:?}, last started = {}, block = {:?}", self.imported_this_round, self.last_round_start, self.last_imported_block);
|
||||
// Check if need to retract to find the common block. The problem is that the peers still return headers by hash even
|
||||
// from the non-canonical part of the tree. So we also retract if nothing has been imported last round.
|
||||
let start = self.last_round_start;
|
||||
@ -375,12 +430,12 @@ impl BlockDownloader {
|
||||
if let Some(&(_, p)) = self.round_parents.iter().find(|&&(h, _)| h == start_hash) {
|
||||
self.last_imported_block = start - 1;
|
||||
self.last_imported_hash = p.clone();
|
||||
trace!(target: "sync", "Searching common header from the last round {} ({})", self.last_imported_block, self.last_imported_hash);
|
||||
trace_sync!(self, "Searching common header from the last round {} ({})", self.last_imported_block, self.last_imported_hash);
|
||||
} else {
|
||||
let best = io.chain().chain_info().best_block_number;
|
||||
let oldest_reorg = io.chain().pruning_info().earliest_state;
|
||||
if self.limit_reorg && best > start && start < oldest_reorg {
|
||||
debug!(target: "sync", "Could not revert to previous ancient block, last: {} ({})", start, start_hash);
|
||||
if self.block_set == BlockSet::NewBlocks && best > start && start < oldest_reorg {
|
||||
debug_sync!(self, "Could not revert to previous ancient block, last: {} ({})", start, start_hash);
|
||||
self.reset();
|
||||
} else {
|
||||
let n = start - cmp::min(self.retract_step, start);
|
||||
@ -389,10 +444,10 @@ impl BlockDownloader {
|
||||
Some(h) => {
|
||||
self.last_imported_block = n;
|
||||
self.last_imported_hash = h;
|
||||
trace!(target: "sync", "Searching common header in the blockchain {} ({})", start, self.last_imported_hash);
|
||||
trace_sync!(self, "Searching common header in the blockchain {} ({})", start, self.last_imported_hash);
|
||||
}
|
||||
None => {
|
||||
debug!(target: "sync", "Could not revert to previous block, last: {} ({})", start, self.last_imported_hash);
|
||||
debug_sync!(self, "Could not revert to previous block, last: {} ({})", start, self.last_imported_hash);
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
@ -420,7 +475,7 @@ impl BlockDownloader {
|
||||
State::ChainHead => {
|
||||
if num_active_peers < MAX_PARALLEL_SUBCHAIN_DOWNLOAD {
|
||||
// Request subchain headers
|
||||
trace!(target: "sync", "Starting sync with better chain");
|
||||
trace_sync!(self, "Starting sync with better chain");
|
||||
// Request MAX_HEADERS_TO_REQUEST - 2 headers apart so that
|
||||
// MAX_HEADERS_TO_REQUEST would include headers for neighbouring subchains
|
||||
return Some(BlockRequest::Headers {
|
||||
@ -463,8 +518,9 @@ impl BlockDownloader {
|
||||
}
|
||||
|
||||
/// Checks if there are blocks fully downloaded that can be imported into the blockchain and does the import.
|
||||
pub fn collect_blocks(&mut self, io: &mut SyncIo, allow_out_of_order: bool) -> Result<(), BlockDownloaderImportError> {
|
||||
let mut bad = false;
|
||||
/// Returns DownloadAction::Reset if it is imported all the the blocks it can and all downloading peers should be reset
|
||||
pub fn collect_blocks(&mut self, io: &mut SyncIo, allow_out_of_order: bool) -> DownloadAction {
|
||||
let mut download_action = DownloadAction::None;
|
||||
let mut imported = HashSet::new();
|
||||
let blocks = self.blocks.drain();
|
||||
let count = blocks.len();
|
||||
@ -478,8 +534,8 @@ impl BlockDownloader {
|
||||
|
||||
if self.target_hash.as_ref().map_or(false, |t| t == &h) {
|
||||
self.state = State::Complete;
|
||||
trace!(target: "sync", "Sync target reached");
|
||||
return Ok(());
|
||||
trace_sync!(self, "Sync target reached");
|
||||
return download_action;
|
||||
}
|
||||
|
||||
let result = if let Some(receipts) = receipts {
|
||||
@ -490,15 +546,15 @@ impl BlockDownloader {
|
||||
|
||||
match result {
|
||||
Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => {
|
||||
trace!(target: "sync", "Block already in chain {:?}", h);
|
||||
trace_sync!(self, "Block already in chain {:?}", h);
|
||||
self.block_imported(&h, number, &parent);
|
||||
},
|
||||
Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => {
|
||||
trace!(target: "sync", "Block already queued {:?}", h);
|
||||
trace_sync!(self, "Block already queued {:?}", h);
|
||||
self.block_imported(&h, number, &parent);
|
||||
},
|
||||
Ok(_) => {
|
||||
trace!(target: "sync", "Block queued {:?}", h);
|
||||
trace_sync!(self, "Block queued {:?}", h);
|
||||
imported.insert(h.clone());
|
||||
self.block_imported(&h, number, &parent);
|
||||
},
|
||||
@ -506,37 +562,34 @@ impl BlockDownloader {
|
||||
break;
|
||||
},
|
||||
Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(_)), _)) => {
|
||||
trace!(target: "sync", "Unknown new block parent, restarting sync");
|
||||
trace_sync!(self, "Unknown new block parent, restarting sync");
|
||||
break;
|
||||
},
|
||||
Err(BlockImportError(BlockImportErrorKind::Block(BlockError::TemporarilyInvalid(_)), _)) => {
|
||||
debug!(target: "sync", "Block temporarily invalid, restarting sync");
|
||||
debug_sync!(self, "Block temporarily invalid: {:?}, restarting sync", h);
|
||||
break;
|
||||
},
|
||||
Err(BlockImportError(BlockImportErrorKind::Queue(QueueErrorKind::Full(limit)), _)) => {
|
||||
debug!(target: "sync", "Block import queue full ({}), restarting sync", limit);
|
||||
debug_sync!(self, "Block import queue full ({}), restarting sync", limit);
|
||||
download_action = DownloadAction::Reset;
|
||||
break;
|
||||
},
|
||||
Err(e) => {
|
||||
debug!(target: "sync", "Bad block {:?} : {:?}", h, e);
|
||||
bad = true;
|
||||
debug_sync!(self, "Bad block {:?} : {:?}", h, e);
|
||||
download_action = DownloadAction::Reset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
trace!(target: "sync", "Imported {} of {}", imported.len(), count);
|
||||
trace_sync!(self, "Imported {} of {}", imported.len(), count);
|
||||
self.imported_this_round = Some(self.imported_this_round.unwrap_or(0) + imported.len());
|
||||
|
||||
if bad {
|
||||
return Err(BlockDownloaderImportError::Invalid);
|
||||
}
|
||||
|
||||
if self.blocks.is_empty() {
|
||||
// complete sync round
|
||||
trace!(target: "sync", "Sync round complete");
|
||||
self.reset();
|
||||
trace_sync!(self, "Sync round complete");
|
||||
download_action = DownloadAction::Reset;
|
||||
}
|
||||
Ok(())
|
||||
download_action
|
||||
}
|
||||
|
||||
fn block_imported(&mut self, hash: &H256, number: BlockNumber, parent: &H256) {
|
||||
@ -549,4 +602,392 @@ impl BlockDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: module tests
|
||||
// Determines if the first argument matches an ordered subset of the second, according to some predicate.
|
||||
fn all_expected<A, B, F>(values: &[A], expected_values: &[B], is_expected: F) -> bool
|
||||
where F: Fn(&A, &B) -> bool
|
||||
{
|
||||
let mut expected_iter = expected_values.iter();
|
||||
values.iter().all(|val1| {
|
||||
while let Some(val2) = expected_iter.next() {
|
||||
if is_expected(val1, val2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use ethcore::header::Header as BlockHeader;
|
||||
use ethcore::spec::Spec;
|
||||
use ethkey::{Generator,Random};
|
||||
use hash::keccak;
|
||||
use parking_lot::RwLock;
|
||||
use rlp::{encode_list,RlpStream};
|
||||
use tests::helpers::TestIo;
|
||||
use tests::snapshot::TestSnapshotService;
|
||||
use transaction::{Transaction,SignedTransaction};
|
||||
use triehash_ethereum::ordered_trie_root;
|
||||
|
||||
fn dummy_header(number: u64, parent_hash: H256) -> BlockHeader {
|
||||
let mut header = BlockHeader::new();
|
||||
header.set_gas_limit(0.into());
|
||||
header.set_difficulty((number * 100).into());
|
||||
header.set_timestamp(number * 10);
|
||||
header.set_number(number);
|
||||
header.set_parent_hash(parent_hash);
|
||||
header.set_state_root(H256::zero());
|
||||
header
|
||||
}
|
||||
|
||||
fn dummy_signed_tx() -> SignedTransaction {
|
||||
let keypair = Random.generate().unwrap();
|
||||
Transaction::default().sign(keypair.secret(), None)
|
||||
}
|
||||
|
||||
fn import_headers(headers: &[BlockHeader], downloader: &mut BlockDownloader, io: &mut SyncIo) -> Result<DownloadAction, BlockDownloaderImportError> {
|
||||
let mut stream = RlpStream::new();
|
||||
stream.append_list(headers);
|
||||
let bytes = stream.out();
|
||||
let rlp = Rlp::new(&bytes);
|
||||
let expected_hash = headers.first().unwrap().hash();
|
||||
downloader.import_headers(io, &rlp, expected_hash)
|
||||
}
|
||||
|
||||
fn import_headers_ok(headers: &[BlockHeader], downloader: &mut BlockDownloader, io: &mut SyncIo) {
|
||||
let res = import_headers(headers, downloader, io);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_headers_in_chain_head_state() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let spec = Spec::new_test();
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::NewBlocks, &genesis_hash, 0);
|
||||
downloader.state = State::ChainHead;
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
// Valid headers sequence.
|
||||
let valid_headers = [
|
||||
spec.genesis_header(),
|
||||
dummy_header(127, H256::random()),
|
||||
dummy_header(254, H256::random()),
|
||||
];
|
||||
let rlp_data = encode_list(&valid_headers);
|
||||
let valid_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &valid_rlp, genesis_hash) {
|
||||
Ok(DownloadAction::Reset) => assert_eq!(downloader.state, State::Blocks),
|
||||
_ => panic!("expected transition to Blocks state"),
|
||||
};
|
||||
|
||||
// Headers are rejected because the expected hash does not match.
|
||||
let invalid_start_block_headers = [
|
||||
dummy_header(0, H256::random()),
|
||||
dummy_header(127, H256::random()),
|
||||
dummy_header(254, H256::random()),
|
||||
];
|
||||
let rlp_data = encode_list(&invalid_start_block_headers);
|
||||
let invalid_start_block_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &invalid_start_block_rlp, genesis_hash) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
|
||||
// Headers are rejected because they are not spaced as expected.
|
||||
let invalid_skip_headers = [
|
||||
spec.genesis_header(),
|
||||
dummy_header(128, H256::random()),
|
||||
dummy_header(256, H256::random()),
|
||||
];
|
||||
let rlp_data = encode_list(&invalid_skip_headers);
|
||||
let invalid_skip_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &invalid_skip_rlp, genesis_hash) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
|
||||
// Invalid because the packet size is too large.
|
||||
let mut too_many_headers = Vec::with_capacity((SUBCHAIN_SIZE + 1) as usize);
|
||||
too_many_headers.push(spec.genesis_header());
|
||||
for i in 1..(SUBCHAIN_SIZE + 1) {
|
||||
too_many_headers.push(dummy_header((MAX_HEADERS_TO_REQUEST as u64 - 1) * i, H256::random()));
|
||||
}
|
||||
let rlp_data = encode_list(&too_many_headers);
|
||||
|
||||
let too_many_rlp = Rlp::new(&rlp_data);
|
||||
match downloader.import_headers(&mut io, &too_many_rlp, genesis_hash) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_headers_in_blocks_state() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
let mut headers = Vec::with_capacity(3);
|
||||
let parent_hash = H256::random();
|
||||
headers.push(dummy_header(127, parent_hash));
|
||||
let parent_hash = headers[0].hash();
|
||||
headers.push(dummy_header(128, parent_hash));
|
||||
let parent_hash = headers[1].hash();
|
||||
headers.push(dummy_header(129, parent_hash));
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::NewBlocks, &H256::random(), 0);
|
||||
downloader.state = State::Blocks;
|
||||
downloader.blocks.reset_to(vec![headers[0].hash()]);
|
||||
|
||||
let rlp_data = encode_list(&headers);
|
||||
let headers_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &headers_rlp, headers[0].hash()) {
|
||||
Ok(DownloadAction::None) => (),
|
||||
_ => panic!("expected successful import"),
|
||||
};
|
||||
|
||||
// Invalidate parent_hash link.
|
||||
headers[2] = dummy_header(129, H256::random());
|
||||
let rlp_data = encode_list(&headers);
|
||||
let headers_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &headers_rlp, headers[0].hash()) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
|
||||
// Invalidate header sequence by skipping a header.
|
||||
headers[2] = dummy_header(130, headers[1].hash());
|
||||
let rlp_data = encode_list(&headers);
|
||||
let headers_rlp = Rlp::new(&rlp_data);
|
||||
|
||||
match downloader.import_headers(&mut io, &headers_rlp, headers[0].hash()) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_bodies() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
// Import block headers.
|
||||
let mut headers = Vec::with_capacity(4);
|
||||
let mut bodies = Vec::with_capacity(4);
|
||||
let mut parent_hash = H256::zero();
|
||||
for i in 0..4 {
|
||||
// Construct the block body
|
||||
let mut uncles = if i > 0 {
|
||||
encode_list(&[dummy_header(i - 1, H256::random())]).into_vec()
|
||||
} else {
|
||||
::rlp::EMPTY_LIST_RLP.to_vec()
|
||||
};
|
||||
|
||||
let mut txs = encode_list(&[dummy_signed_tx()]);
|
||||
let tx_root = ordered_trie_root(Rlp::new(&txs).iter().map(|r| r.as_raw()));
|
||||
|
||||
let mut rlp = RlpStream::new_list(2);
|
||||
rlp.append_raw(&txs, 1);
|
||||
rlp.append_raw(&uncles, 1);
|
||||
bodies.push(rlp.out());
|
||||
|
||||
// Construct the block header
|
||||
let mut header = dummy_header(i, parent_hash);
|
||||
header.set_transactions_root(tx_root);
|
||||
header.set_uncles_hash(keccak(&uncles));
|
||||
parent_hash = header.hash();
|
||||
headers.push(header);
|
||||
}
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::NewBlocks, &headers[0].hash(), 0);
|
||||
downloader.state = State::Blocks;
|
||||
downloader.blocks.reset_to(vec![headers[0].hash()]);
|
||||
|
||||
// Only import the first three block headers.
|
||||
let rlp_data = encode_list(&headers[0..3]);
|
||||
let headers_rlp = Rlp::new(&rlp_data);
|
||||
assert!(downloader.import_headers(&mut io, &headers_rlp, headers[0].hash()).is_ok());
|
||||
|
||||
// Import first body successfully.
|
||||
let mut rlp_data = RlpStream::new_list(1);
|
||||
rlp_data.append_raw(&bodies[0], 1);
|
||||
let bodies_rlp = Rlp::new(rlp_data.as_raw());
|
||||
assert!(downloader.import_bodies(&bodies_rlp, &[headers[0].hash(), headers[1].hash()]).is_ok());
|
||||
|
||||
// Import second body successfully.
|
||||
let mut rlp_data = RlpStream::new_list(1);
|
||||
rlp_data.append_raw(&bodies[1], 1);
|
||||
let bodies_rlp = Rlp::new(rlp_data.as_raw());
|
||||
assert!(downloader.import_bodies(&bodies_rlp, &[headers[0].hash(), headers[1].hash()]).is_ok());
|
||||
|
||||
// Import unexpected third body.
|
||||
let mut rlp_data = RlpStream::new_list(1);
|
||||
rlp_data.append_raw(&bodies[2], 1);
|
||||
let bodies_rlp = Rlp::new(rlp_data.as_raw());
|
||||
match downloader.import_bodies(&bodies_rlp, &[headers[0].hash(), headers[1].hash()]) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_receipts() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
// Import block headers.
|
||||
let mut headers = Vec::with_capacity(4);
|
||||
let mut receipts = Vec::with_capacity(4);
|
||||
let mut parent_hash = H256::zero();
|
||||
for i in 0..4 {
|
||||
// Construct the receipts. Receipt root for the first two blocks is the same.
|
||||
//
|
||||
// The RLP-encoded integers are clearly not receipts, but the BlockDownloader treats
|
||||
// all receipts as byte blobs, so it does not matter.
|
||||
let mut receipts_rlp = if i < 2 {
|
||||
encode_list(&[0u32])
|
||||
} else {
|
||||
encode_list(&[i as u32])
|
||||
};
|
||||
let receipts_root = ordered_trie_root(Rlp::new(&receipts_rlp).iter().map(|r| r.as_raw()));
|
||||
receipts.push(receipts_rlp);
|
||||
|
||||
// Construct the block header.
|
||||
let mut header = dummy_header(i, parent_hash);
|
||||
header.set_receipts_root(receipts_root);
|
||||
parent_hash = header.hash();
|
||||
headers.push(header);
|
||||
}
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::OldBlocks, &headers[0].hash(), 0);
|
||||
downloader.state = State::Blocks;
|
||||
downloader.blocks.reset_to(vec![headers[0].hash()]);
|
||||
|
||||
// Only import the first three block headers.
|
||||
let rlp_data = encode_list(&headers[0..3]);
|
||||
let headers_rlp = Rlp::new(&rlp_data);
|
||||
assert!(downloader.import_headers(&mut io, &headers_rlp, headers[0].hash()).is_ok());
|
||||
|
||||
// Import second and third receipts successfully.
|
||||
let mut rlp_data = RlpStream::new_list(2);
|
||||
rlp_data.append_raw(&receipts[1], 1);
|
||||
rlp_data.append_raw(&receipts[2], 1);
|
||||
let receipts_rlp = Rlp::new(rlp_data.as_raw());
|
||||
assert!(downloader.import_receipts(&receipts_rlp, &[headers[1].hash(), headers[2].hash()]).is_ok());
|
||||
|
||||
// Import unexpected fourth receipt.
|
||||
let mut rlp_data = RlpStream::new_list(1);
|
||||
rlp_data.append_raw(&receipts[3], 1);
|
||||
let bodies_rlp = Rlp::new(rlp_data.as_raw());
|
||||
match downloader.import_bodies(&bodies_rlp, &[headers[1].hash(), headers[2].hash()]) {
|
||||
Err(BlockDownloaderImportError::Invalid) => (),
|
||||
_ => panic!("expected BlockDownloaderImportError"),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reset_after_multiple_sets_of_useless_headers() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let spec = Spec::new_test();
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::NewBlocks, &genesis_hash, 0);
|
||||
downloader.state = State::ChainHead;
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
let heads = [
|
||||
spec.genesis_header(),
|
||||
dummy_header(127, H256::random()),
|
||||
dummy_header(254, H256::random()),
|
||||
];
|
||||
|
||||
let short_subchain = [dummy_header(1, genesis_hash)];
|
||||
|
||||
import_headers_ok(&heads, &mut downloader, &mut io);
|
||||
import_headers_ok(&short_subchain, &mut downloader, &mut io);
|
||||
|
||||
assert_eq!(downloader.state, State::Blocks);
|
||||
assert!(!downloader.blocks.is_empty());
|
||||
|
||||
// simulate receiving useless headers
|
||||
let head = vec![short_subchain.last().unwrap().clone()];
|
||||
for _ in 0..MAX_USELESS_HEADERS_PER_ROUND {
|
||||
let res = import_headers(&head, &mut downloader, &mut io);
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
assert_eq!(downloader.state, State::Idle);
|
||||
assert!(downloader.blocks.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_reset_after_multiple_sets_of_useless_headers_for_chain_head() {
|
||||
::env_logger::try_init().ok();
|
||||
|
||||
let spec = Spec::new_test();
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
|
||||
let mut downloader = BlockDownloader::new(BlockSet::NewBlocks, &genesis_hash, 0);
|
||||
downloader.state = State::ChainHead;
|
||||
|
||||
let mut chain = TestBlockChainClient::new();
|
||||
let snapshot_service = TestSnapshotService::new();
|
||||
let queue = RwLock::new(VecDeque::new());
|
||||
let mut io = TestIo::new(&mut chain, &snapshot_service, &queue, None);
|
||||
|
||||
let heads = [
|
||||
spec.genesis_header()
|
||||
];
|
||||
|
||||
let short_subchain = [dummy_header(1, genesis_hash)];
|
||||
|
||||
import_headers_ok(&heads, &mut downloader, &mut io);
|
||||
import_headers_ok(&short_subchain, &mut downloader, &mut io);
|
||||
|
||||
assert_eq!(downloader.state, State::Blocks);
|
||||
assert!(!downloader.blocks.is_empty());
|
||||
|
||||
// simulate receiving useless headers
|
||||
let head = vec![short_subchain.last().unwrap().clone()];
|
||||
for _ in 0..MAX_USELESS_HEADERS_PER_ROUND {
|
||||
let res = import_headers(&head, &mut downloader, &mut io);
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
// download shouldn't be reset since this is the chain head for a single subchain.
|
||||
// this state usually occurs for NewBlocks when it has reached the chain head.
|
||||
assert_eq!(downloader.state, State::Blocks);
|
||||
assert!(!downloader.blocks.is_empty());
|
||||
}
|
||||
}
|
||||
|
@ -215,32 +215,28 @@ impl BlockCollection {
|
||||
}
|
||||
|
||||
/// Insert a collection of block bodies for previously downloaded headers.
|
||||
pub fn insert_bodies(&mut self, bodies: Vec<SyncBody>) -> usize {
|
||||
let mut inserted = 0;
|
||||
for b in bodies {
|
||||
if let Err(e) = self.insert_body(b) {
|
||||
trace!(target: "sync", "Ignored invalid body: {:?}", e);
|
||||
} else {
|
||||
inserted += 1;
|
||||
}
|
||||
}
|
||||
inserted
|
||||
pub fn insert_bodies(&mut self, bodies: Vec<SyncBody>) -> Vec<H256> {
|
||||
bodies.into_iter()
|
||||
.filter_map(|b| {
|
||||
self.insert_body(b)
|
||||
.map_err(|e| trace!(target: "sync", "Ignored invalid body: {:?}", e))
|
||||
.ok()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Insert a collection of block receipts for previously downloaded headers.
|
||||
pub fn insert_receipts(&mut self, receipts: Vec<Bytes>) -> usize {
|
||||
pub fn insert_receipts(&mut self, receipts: Vec<Bytes>) -> Vec<Vec<H256>> {
|
||||
if !self.need_receipts {
|
||||
return 0;
|
||||
return Vec::new();
|
||||
}
|
||||
let mut inserted = 0;
|
||||
for r in receipts {
|
||||
if let Err(e) = self.insert_receipt(r) {
|
||||
trace!(target: "sync", "Ignored invalid receipt: {:?}", e);
|
||||
} else {
|
||||
inserted += 1;
|
||||
}
|
||||
}
|
||||
inserted
|
||||
receipts.into_iter()
|
||||
.filter_map(|r| {
|
||||
self.insert_receipt(r)
|
||||
.map_err(|e| trace!(target: "sync", "Ignored invalid receipt: {:?}", e))
|
||||
.ok()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns a set of block hashes that require a body download. The returned set is marked as being downloaded.
|
||||
@ -401,9 +397,9 @@ impl BlockCollection {
|
||||
self.blocks.contains_key(hash)
|
||||
}
|
||||
|
||||
/// Check if collection contains a block header.
|
||||
pub fn contains_head(&self, hash: &H256) -> bool {
|
||||
self.heads.contains(hash)
|
||||
/// Check the number of heads
|
||||
pub fn heads_len(&self) -> usize {
|
||||
self.heads.len()
|
||||
}
|
||||
|
||||
/// Return used heap size.
|
||||
@ -421,7 +417,7 @@ impl BlockCollection {
|
||||
self.downloading_headers.contains(hash) || self.downloading_bodies.contains(hash)
|
||||
}
|
||||
|
||||
fn insert_body(&mut self, body: SyncBody) -> Result<(), network::Error> {
|
||||
fn insert_body(&mut self, body: SyncBody) -> Result<H256, network::Error> {
|
||||
let header_id = {
|
||||
let tx_root = ordered_trie_root(Rlp::new(&body.transactions_bytes).iter().map(|r| r.as_raw()));
|
||||
let uncles = keccak(&body.uncles_bytes);
|
||||
@ -438,7 +434,7 @@ impl BlockCollection {
|
||||
Some(ref mut block) => {
|
||||
trace!(target: "sync", "Got body {}", h);
|
||||
block.body = Some(body);
|
||||
Ok(())
|
||||
Ok(h)
|
||||
},
|
||||
None => {
|
||||
warn!("Got body with no header {}", h);
|
||||
@ -453,7 +449,7 @@ impl BlockCollection {
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_receipt(&mut self, r: Bytes) -> Result<(), network::Error> {
|
||||
fn insert_receipt(&mut self, r: Bytes) -> Result<Vec<H256>, network::Error> {
|
||||
let receipt_root = {
|
||||
let receipts = Rlp::new(&r);
|
||||
ordered_trie_root(receipts.iter().map(|r| r.as_raw()))
|
||||
@ -461,7 +457,8 @@ impl BlockCollection {
|
||||
self.downloading_receipts.remove(&receipt_root);
|
||||
match self.receipt_ids.entry(receipt_root) {
|
||||
hash_map::Entry::Occupied(entry) => {
|
||||
for h in entry.remove() {
|
||||
let block_hashes = entry.remove();
|
||||
for h in block_hashes.iter() {
|
||||
match self.blocks.get_mut(&h) {
|
||||
Some(ref mut block) => {
|
||||
trace!(target: "sync", "Got receipt {}", h);
|
||||
@ -473,7 +470,7 @@ impl BlockCollection {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(block_hashes.to_vec())
|
||||
},
|
||||
hash_map::Entry::Vacant(_) => {
|
||||
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
|
||||
|
@ -28,6 +28,7 @@ use network::PeerId;
|
||||
use rlp::Rlp;
|
||||
use snapshot::ChunkType;
|
||||
use std::cmp;
|
||||
use std::mem;
|
||||
use std::collections::HashSet;
|
||||
use std::time::Instant;
|
||||
use sync_io::SyncIo;
|
||||
@ -292,10 +293,19 @@ impl SyncHandler {
|
||||
let block_set = sync.peers.get(&peer_id)
|
||||
.and_then(|p| p.block_set)
|
||||
.unwrap_or(BlockSet::NewBlocks);
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockBodies) {
|
||||
let allowed = sync.peers.get(&peer_id).map(|p| p.is_allowed()).unwrap_or(false);
|
||||
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockBodies) || !allowed {
|
||||
trace!(target: "sync", "{}: Ignored unexpected bodies", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
let expected_blocks = match sync.peers.get_mut(&peer_id) {
|
||||
Some(peer) => mem::replace(&mut peer.asking_blocks, Vec::new()),
|
||||
None => {
|
||||
trace!(target: "sync", "{}: Ignored unexpected bodies (peer not found)", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let item_count = r.item_count()?;
|
||||
trace!(target: "sync", "{} -> BlockBodies ({} entries), set = {:?}", peer_id, item_count, block_set);
|
||||
if item_count == 0 {
|
||||
@ -315,7 +325,7 @@ impl SyncHandler {
|
||||
Some(ref mut blocks) => blocks,
|
||||
}
|
||||
};
|
||||
downloader.import_bodies(r)?;
|
||||
downloader.import_bodies(r, expected_blocks.as_slice())?;
|
||||
}
|
||||
sync.collect_blocks(io, block_set);
|
||||
Ok(())
|
||||
@ -368,10 +378,23 @@ impl SyncHandler {
|
||||
let expected_hash = sync.peers.get(&peer_id).and_then(|p| p.asking_hash);
|
||||
let allowed = sync.peers.get(&peer_id).map(|p| p.is_allowed()).unwrap_or(false);
|
||||
let block_set = sync.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks);
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockHeaders) || expected_hash.is_none() || !allowed {
|
||||
trace!(target: "sync", "{}: Ignored unexpected headers, expected_hash = {:?}", peer_id, expected_hash);
|
||||
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockHeaders) {
|
||||
debug!(target: "sync", "{}: Ignored unexpected headers", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
let expected_hash = match expected_hash {
|
||||
Some(hash) => hash,
|
||||
None => {
|
||||
debug!(target: "sync", "{}: Ignored unexpected headers (expected_hash is None)", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
if !allowed {
|
||||
debug!(target: "sync", "{}: Ignored unexpected headers (peer not allowed)", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let item_count = r.item_count()?;
|
||||
trace!(target: "sync", "{} -> BlockHeaders ({} entries), state = {:?}, set = {:?}", peer_id, item_count, sync.state, block_set);
|
||||
if (sync.state == SyncState::Idle || sync.state == SyncState::WaitingPeers) && sync.old_blocks.is_none() {
|
||||
@ -399,12 +422,8 @@ impl SyncHandler {
|
||||
downloader.import_headers(io, r, expected_hash)?
|
||||
};
|
||||
|
||||
if let DownloadAction::Reset = result {
|
||||
// mark all outstanding requests as expired
|
||||
trace!("Resetting downloads for {:?}", block_set);
|
||||
for (_, ref mut p) in sync.peers.iter_mut().filter(|&(_, ref p)| p.block_set == Some(block_set)) {
|
||||
p.reset_asking();
|
||||
}
|
||||
if result == DownloadAction::Reset {
|
||||
sync.reset_downloads(block_set);
|
||||
}
|
||||
|
||||
sync.collect_blocks(io, block_set);
|
||||
@ -415,10 +434,18 @@ impl SyncHandler {
|
||||
fn on_peer_block_receipts(sync: &mut ChainSync, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), DownloaderImportError> {
|
||||
sync.clear_peer_download(peer_id);
|
||||
let block_set = sync.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks);
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockReceipts) {
|
||||
let allowed = sync.peers.get(&peer_id).map(|p| p.is_allowed()).unwrap_or(false);
|
||||
if !sync.reset_peer_asking(peer_id, PeerAsking::BlockReceipts) || !allowed {
|
||||
trace!(target: "sync", "{}: Ignored unexpected receipts", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
let expected_blocks = match sync.peers.get_mut(&peer_id) {
|
||||
Some(peer) => mem::replace(&mut peer.asking_blocks, Vec::new()),
|
||||
None => {
|
||||
trace!(target: "sync", "{}: Ignored unexpected bodies (peer not found)", peer_id);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let item_count = r.item_count()?;
|
||||
trace!(target: "sync", "{} -> BlockReceipts ({} entries)", peer_id, item_count);
|
||||
if item_count == 0 {
|
||||
@ -438,7 +465,7 @@ impl SyncHandler {
|
||||
Some(ref mut blocks) => blocks,
|
||||
}
|
||||
};
|
||||
downloader.import_receipts(io, r)?;
|
||||
downloader.import_receipts(r, expected_blocks.as_slice())?;
|
||||
}
|
||||
sync.collect_blocks(io, block_set);
|
||||
Ok(())
|
||||
|
@ -109,7 +109,7 @@ use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, Bl
|
||||
use ethcore::snapshot::{RestorationStatus};
|
||||
use sync_io::SyncIo;
|
||||
use super::{WarpSync, SyncConfig};
|
||||
use block_sync::{BlockDownloader, BlockDownloaderImportError as DownloaderImportError};
|
||||
use block_sync::{BlockDownloader, DownloadAction};
|
||||
use rand::Rng;
|
||||
use snapshot::{Snapshot};
|
||||
use api::{EthProtocolInfo as PeerInfoDigest, WARP_SYNC_PROTOCOL_ID};
|
||||
@ -429,7 +429,7 @@ impl ChainSync {
|
||||
peers: HashMap::new(),
|
||||
handshaking_peers: HashMap::new(),
|
||||
active_peers: HashSet::new(),
|
||||
new_blocks: BlockDownloader::new(false, &chain_info.best_block_hash, chain_info.best_block_number),
|
||||
new_blocks: BlockDownloader::new(BlockSet::NewBlocks, &chain_info.best_block_hash, chain_info.best_block_number),
|
||||
old_blocks: None,
|
||||
last_sent_block_number: 0,
|
||||
network_id: config.network_id,
|
||||
@ -507,8 +507,9 @@ impl ChainSync {
|
||||
self.peers.clear();
|
||||
}
|
||||
|
||||
/// Reset sync. Clear all downloaded data but keep the queue
|
||||
fn reset(&mut self, io: &mut SyncIo) {
|
||||
/// Reset sync. Clear all downloaded data but keep the queue.
|
||||
/// Set sync state to the given state or to the initial state if `None` is provided.
|
||||
fn reset(&mut self, io: &mut SyncIo, state: Option<SyncState>) {
|
||||
self.new_blocks.reset();
|
||||
let chain_info = io.chain().chain_info();
|
||||
for (_, ref mut p) in &mut self.peers {
|
||||
@ -520,7 +521,7 @@ impl ChainSync {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.state = ChainSync::get_init_state(self.warp_sync, io.chain());
|
||||
self.state = state.unwrap_or_else(|| ChainSync::get_init_state(self.warp_sync, io.chain()));
|
||||
// Reactivate peers only if some progress has been made
|
||||
// since the last sync round of if starting fresh.
|
||||
self.active_peers = self.peers.keys().cloned().collect();
|
||||
@ -534,7 +535,7 @@ impl ChainSync {
|
||||
io.snapshot_service().abort_restore();
|
||||
}
|
||||
self.snapshot.clear();
|
||||
self.reset(io);
|
||||
self.reset(io, None);
|
||||
self.continue_sync(io);
|
||||
}
|
||||
|
||||
@ -637,13 +638,13 @@ impl ChainSync {
|
||||
pub fn update_targets(&mut self, chain: &BlockChainClient) {
|
||||
// Do not assume that the block queue/chain still has our last_imported_block
|
||||
let chain = chain.chain_info();
|
||||
self.new_blocks = BlockDownloader::new(false, &chain.best_block_hash, chain.best_block_number);
|
||||
self.new_blocks = BlockDownloader::new(BlockSet::NewBlocks, &chain.best_block_hash, chain.best_block_number);
|
||||
self.old_blocks = None;
|
||||
if self.download_old_blocks {
|
||||
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::with_unlimited_reorg(true, &ancient_block_hash, ancient_block_number);
|
||||
let mut downloader = BlockDownloader::new(BlockSet::OldBlocks, &ancient_block_hash, ancient_block_number);
|
||||
if let Some(hash) = chain.first_block_hash {
|
||||
trace!(target: "sync", "Downloader target set to {:?}", hash);
|
||||
downloader.set_target(&hash);
|
||||
@ -699,7 +700,7 @@ impl ChainSync {
|
||||
/// Called after all blocks have been downloaded
|
||||
fn complete_sync(&mut self, io: &mut SyncIo) {
|
||||
trace!(target: "sync", "Sync complete");
|
||||
self.reset(io);
|
||||
self.reset(io, Some(SyncState::Idle));
|
||||
}
|
||||
|
||||
/// Enter waiting state
|
||||
@ -762,12 +763,10 @@ impl ChainSync {
|
||||
}
|
||||
}
|
||||
|
||||
// Only ask for old blocks if the peer has a higher difficulty than the last imported old block
|
||||
let last_imported_old_block_difficulty = self.old_blocks.as_mut().and_then(|d| {
|
||||
io.chain().block_total_difficulty(BlockId::Number(d.last_imported_block_number()))
|
||||
});
|
||||
// Only ask for old blocks if the peer has an equal or higher difficulty
|
||||
let equal_or_higher_difficulty = peer_difficulty.map_or(false, |pd| pd >= syncing_difficulty);
|
||||
|
||||
if force || last_imported_old_block_difficulty.map_or(true, |ld| peer_difficulty.map_or(true, |pd| pd > ld)) {
|
||||
if force || equal_or_higher_difficulty {
|
||||
if let Some(request) = self.old_blocks.as_mut().and_then(|d| d.request_blocks(io, num_active_peers)) {
|
||||
SyncRequester::request_blocks(self, io, peer_id, request, BlockSet::OldBlocks);
|
||||
return;
|
||||
@ -775,9 +774,9 @@ impl ChainSync {
|
||||
} else {
|
||||
trace!(
|
||||
target: "sync",
|
||||
"peer {:?} is not suitable for requesting old blocks, last_imported_old_block_difficulty={:?}, peer_difficulty={:?}",
|
||||
"peer {:?} is not suitable for requesting old blocks, syncing_difficulty={:?}, peer_difficulty={:?}",
|
||||
peer_id,
|
||||
last_imported_old_block_difficulty,
|
||||
syncing_difficulty,
|
||||
peer_difficulty
|
||||
);
|
||||
self.deactivate_peer(io, peer_id);
|
||||
@ -855,18 +854,39 @@ impl ChainSync {
|
||||
fn collect_blocks(&mut self, io: &mut SyncIo, block_set: BlockSet) {
|
||||
match block_set {
|
||||
BlockSet::NewBlocks => {
|
||||
if self.new_blocks.collect_blocks(io, self.state == SyncState::NewBlocks) == Err(DownloaderImportError::Invalid) {
|
||||
self.restart(io);
|
||||
if self.new_blocks.collect_blocks(io, self.state == SyncState::NewBlocks) == DownloadAction::Reset {
|
||||
self.reset_downloads(block_set);
|
||||
self.new_blocks.reset();
|
||||
}
|
||||
},
|
||||
BlockSet::OldBlocks => {
|
||||
if self.old_blocks.as_mut().map_or(false, |downloader| { downloader.collect_blocks(io, false) == Err(DownloaderImportError::Invalid) }) {
|
||||
self.restart(io);
|
||||
} else if self.old_blocks.as_ref().map_or(false, |downloader| { downloader.is_complete() }) {
|
||||
let mut is_complete = false;
|
||||
let mut download_action = DownloadAction::None;
|
||||
if let Some(downloader) = self.old_blocks.as_mut() {
|
||||
download_action = downloader.collect_blocks(io, false);
|
||||
is_complete = downloader.is_complete();
|
||||
}
|
||||
|
||||
if download_action == DownloadAction::Reset {
|
||||
self.reset_downloads(block_set);
|
||||
if let Some(downloader) = self.old_blocks.as_mut() {
|
||||
downloader.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if is_complete {
|
||||
trace!(target: "sync", "Background block download is complete");
|
||||
self.old_blocks = None;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Mark all outstanding requests as expired
|
||||
fn reset_downloads(&mut self, block_set: BlockSet) {
|
||||
trace!(target: "sync", "Resetting downloads for {:?}", block_set);
|
||||
for (_, ref mut p) in self.peers.iter_mut().filter(|&(_, ref p)| p.block_set == Some(block_set)) {
|
||||
p.reset_asking();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ impl SyncPropagator {
|
||||
let appended = packet.append_raw_checked(&transaction.drain(), 1, MAX_TRANSACTION_PACKET_SIZE);
|
||||
if !appended {
|
||||
// Maximal packet size reached just proceed with sending
|
||||
debug!("Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
|
||||
debug!(target: "sync", "Transaction packet size limit reached. Sending incomplete set of {}/{} transactions.", pushed, to_send.len());
|
||||
to_send = to_send.into_iter().take(pushed).collect();
|
||||
break;
|
||||
}
|
||||
|
@ -225,32 +225,28 @@ fn propagate_blocks() {
|
||||
|
||||
#[test]
|
||||
fn restart_on_malformed_block() {
|
||||
::env_logger::try_init().ok();
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(1).chain.add_blocks(10, EachBlockWith::Uncle);
|
||||
net.peer(1).chain.corrupt_block(6);
|
||||
net.peer(1).chain.add_blocks(5, EachBlockWith::Nothing);
|
||||
net.peer(1).chain.add_block(EachBlockWith::Nothing, |mut header| {
|
||||
header.set_extra_data(b"This extra data is way too long to be considered valid".to_vec());
|
||||
header
|
||||
});
|
||||
net.sync_steps(20);
|
||||
|
||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5);
|
||||
// This gets accepted just fine since the TestBlockChainClient performs no validation.
|
||||
// Probably remove this test?
|
||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restart_on_broken_chain() {
|
||||
fn reject_on_broken_chain() {
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(1).chain.add_blocks(10, EachBlockWith::Uncle);
|
||||
net.peer(1).chain.add_blocks(10, EachBlockWith::Nothing);
|
||||
net.peer(1).chain.corrupt_block_parent(6);
|
||||
net.sync_steps(20);
|
||||
|
||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn high_td_attach() {
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(1).chain.add_blocks(10, EachBlockWith::Uncle);
|
||||
net.peer(1).chain.corrupt_block_parent(6);
|
||||
net.sync_steps(20);
|
||||
|
||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5);
|
||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -90,8 +90,8 @@ pub mod signature {
|
||||
match v {
|
||||
v if v == 27 => 0,
|
||||
v if v == 28 => 1,
|
||||
v if v > 36 => ((v - 1) % 2) as u8,
|
||||
_ => 4
|
||||
v if v >= 35 => ((v - 1) % 2) as u8,
|
||||
_ => 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -364,7 +364,7 @@ impl UnverifiedTransaction {
|
||||
pub fn chain_id(&self) -> Option<u64> {
|
||||
match self.v {
|
||||
v if self.is_unsigned() => Some(v),
|
||||
v if v > 36 => Some((v - 35) / 2),
|
||||
v if v >= 35 => Some((v - 35) / 2),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -583,6 +583,27 @@ mod tests {
|
||||
assert_eq!(t.chain_id(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signing_eip155_zero_chainid() {
|
||||
use ethkey::{Random, Generator};
|
||||
|
||||
let key = Random.generate().unwrap();
|
||||
let t = Transaction {
|
||||
action: Action::Create,
|
||||
nonce: U256::from(42),
|
||||
gas_price: U256::from(3000),
|
||||
gas: U256::from(50_000),
|
||||
value: U256::from(1),
|
||||
data: b"Hello!".to_vec()
|
||||
};
|
||||
|
||||
let hash = t.hash(Some(0));
|
||||
let sig = ::ethkey::sign(&key.secret(), &hash).unwrap();
|
||||
let u = t.with_signature(sig, Some(0));
|
||||
|
||||
assert!(SignedTransaction::new(u).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signing() {
|
||||
use ethkey::{Random, Generator};
|
||||
|
@ -7,7 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
byteorder = "1.0"
|
||||
parity-bytes = "0.1"
|
||||
ethereum-types = "0.4"
|
||||
patricia-trie = "0.2.1"
|
||||
patricia-trie = "0.2"
|
||||
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
|
||||
log = "0.4"
|
||||
common-types = { path = "../types" }
|
||||
|
@ -140,10 +140,10 @@ pub trait Ext {
|
||||
fn depth(&self) -> usize;
|
||||
|
||||
/// Increments sstore refunds counter.
|
||||
fn add_sstore_refund(&mut self, value: U256);
|
||||
fn add_sstore_refund(&mut self, value: usize);
|
||||
|
||||
/// Decrements sstore refunds counter.
|
||||
fn sub_sstore_refund(&mut self, value: U256);
|
||||
fn sub_sstore_refund(&mut self, value: usize);
|
||||
|
||||
/// Decide if any more operations should be traced. Passthrough for the VM trace.
|
||||
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }
|
||||
|
@ -56,7 +56,7 @@ pub struct FakeExt {
|
||||
pub store: HashMap<H256, H256>,
|
||||
pub suicides: HashSet<Address>,
|
||||
pub calls: HashSet<FakeCall>,
|
||||
pub sstore_clears: U256,
|
||||
pub sstore_clears: i128,
|
||||
pub depth: usize,
|
||||
pub blockhashes: HashMap<U256, H256>,
|
||||
pub codes: HashMap<Address, Arc<Bytes>>,
|
||||
@ -220,12 +220,12 @@ impl Ext for FakeExt {
|
||||
self.is_static
|
||||
}
|
||||
|
||||
fn add_sstore_refund(&mut self, value: U256) {
|
||||
self.sstore_clears = self.sstore_clears + value;
|
||||
fn add_sstore_refund(&mut self, value: usize) {
|
||||
self.sstore_clears += value as i128;
|
||||
}
|
||||
|
||||
fn sub_sstore_refund(&mut self, value: U256) {
|
||||
self.sstore_clears = self.sstore_clears - value;
|
||||
fn sub_sstore_refund(&mut self, value: usize) {
|
||||
self.sstore_clears -= value as i128;
|
||||
}
|
||||
|
||||
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _gas: U256) -> bool {
|
||||
|
@ -285,7 +285,7 @@ impl<'a> Runtime<'a> {
|
||||
self.ext.set_storage(key, val).map_err(|_| Error::StorageUpdateError)?;
|
||||
|
||||
if former_val != H256::zero() && val == H256::zero() {
|
||||
let sstore_clears_schedule = U256::from(self.schedule().sstore_refund_gas);
|
||||
let sstore_clears_schedule = self.schedule().sstore_refund_gas;
|
||||
self.ext.add_sstore_refund(sstore_clears_schedule);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub enum Engine {
|
||||
Null(NullEngine),
|
||||
/// Instantly sealing engine.
|
||||
#[serde(rename="instantSeal")]
|
||||
InstantSeal(InstantSeal),
|
||||
InstantSeal(Option<InstantSeal>),
|
||||
/// Ethash engine.
|
||||
Ethash(Ethash),
|
||||
/// BasicAuthority engine.
|
||||
@ -71,6 +71,17 @@ mod tests {
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
"instantSeal": null
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
|
||||
let s = r#"{
|
||||
"Ethash": {
|
||||
"params": {
|
||||
|
@ -704,11 +704,11 @@ usage! {
|
||||
"--price-update-period=[T]",
|
||||
"T will be allowed to pass between each gas price update. T may be daily, hourly, a number of seconds, or a time string of the form \"2 days\", \"30 minutes\" etc..",
|
||||
|
||||
ARG arg_gas_floor_target: (String) = "4700000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
|
||||
ARG arg_gas_floor_target: (String) = "8000000", or |c: &Config| c.mining.as_ref()?.gas_floor_target.clone(),
|
||||
"--gas-floor-target=[GAS]",
|
||||
"Amount of gas per block to target when sealing a new block.",
|
||||
|
||||
ARG arg_gas_cap: (String) = "6283184", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
|
||||
ARG arg_gas_cap: (String) = "10000000", or |c: &Config| c.mining.as_ref()?.gas_cap.clone(),
|
||||
"--gas-cap=[GAS]",
|
||||
"A cap on how large we will raise the gas limit per block due to transaction volume.",
|
||||
|
||||
@ -865,6 +865,10 @@ usage! {
|
||||
"--no-periodic-snapshot",
|
||||
"Disable automated snapshots which usually occur once every 10000 blocks.",
|
||||
|
||||
ARG arg_snapshot_threads: (Option<usize>) = None, or |c: &Config| c.snapshots.as_ref()?.processing_threads,
|
||||
"--snapshot-threads=[NUM]",
|
||||
"Enables multiple threads for snapshots creation.",
|
||||
|
||||
["Whisper Options"]
|
||||
FLAG flag_whisper: (bool) = false, or |c: &Config| c.whisper.as_ref()?.enabled,
|
||||
"--whisper",
|
||||
@ -1345,6 +1349,7 @@ struct Footprint {
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct Snapshots {
|
||||
disable_periodic: Option<bool>,
|
||||
processing_threads: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Deserialize)]
|
||||
@ -1712,7 +1717,7 @@ mod tests {
|
||||
arg_reseal_max_period: 60000u64,
|
||||
flag_reseal_on_uncle: false,
|
||||
arg_work_queue_size: 20usize,
|
||||
arg_tx_gas_limit: Some("6283184".into()),
|
||||
arg_tx_gas_limit: Some("10000000".into()),
|
||||
arg_tx_time_limit: Some(100u64),
|
||||
arg_relay_set: "cheap".into(),
|
||||
arg_min_gas_price: Some(0u64),
|
||||
@ -1721,8 +1726,8 @@ mod tests {
|
||||
arg_poll_lifetime: 60u32,
|
||||
arg_usd_per_eth: "auto".into(),
|
||||
arg_price_update_period: "hourly".into(),
|
||||
arg_gas_floor_target: "4700000".into(),
|
||||
arg_gas_cap: "6283184".into(),
|
||||
arg_gas_floor_target: "8000000".into(),
|
||||
arg_gas_cap: "10000000".into(),
|
||||
arg_extra_data: Some("Parity".into()),
|
||||
flag_tx_queue_no_unfamiliar_locals: false,
|
||||
flag_tx_queue_no_early_reject: false,
|
||||
@ -1771,6 +1776,7 @@ mod tests {
|
||||
arg_export_state_at: "latest".into(),
|
||||
arg_snapshot_at: "latest".into(),
|
||||
flag_no_periodic_snapshot: false,
|
||||
arg_snapshot_threads: None,
|
||||
|
||||
// -- Whisper options.
|
||||
flag_whisper: false,
|
||||
@ -2021,6 +2027,7 @@ mod tests {
|
||||
}),
|
||||
snapshots: Some(Snapshots {
|
||||
disable_periodic: Some(true),
|
||||
processing_threads: None,
|
||||
}),
|
||||
misc: Some(Misc {
|
||||
logging: Some("own_tx=trace".into()),
|
||||
|
@ -125,13 +125,13 @@ min_gas_price = 0
|
||||
usd_per_tx = "0.0001"
|
||||
usd_per_eth = "auto"
|
||||
price_update_period = "hourly"
|
||||
gas_floor_target = "4700000"
|
||||
gas_cap = "6283184"
|
||||
gas_floor_target = "8000000"
|
||||
gas_cap = "10000000"
|
||||
tx_queue_size = 8192
|
||||
tx_queue_strategy = "gas_factor"
|
||||
tx_queue_ban_count = 1
|
||||
tx_queue_ban_time = 180 #s
|
||||
tx_gas_limit = "6283184"
|
||||
tx_gas_limit = "10000000"
|
||||
tx_time_limit = 100 #ms
|
||||
tx_queue_no_unfamiliar_locals = false
|
||||
tx_queue_no_early_reject = false
|
||||
|
@ -30,8 +30,10 @@ use sync::{NetworkConfiguration, validate_node_url, self};
|
||||
use ethcore::ethstore::ethkey::{Secret, Public};
|
||||
use ethcore::client::{VMType};
|
||||
use ethcore::miner::{stratum, MinerOptions};
|
||||
use ethcore::snapshot::SnapshotConfiguration;
|
||||
use ethcore::verification::queue::VerifierSettings;
|
||||
use miner::pool;
|
||||
use num_cpus;
|
||||
|
||||
use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration};
|
||||
use parity_rpc::NetworkSettings;
|
||||
@ -125,6 +127,7 @@ impl Configuration {
|
||||
let update_policy = self.update_policy()?;
|
||||
let logger_config = self.logger_config();
|
||||
let ws_conf = self.ws_config()?;
|
||||
let snapshot_conf = self.snapshot_config()?;
|
||||
let http_conf = self.http_config()?;
|
||||
let ipc_conf = self.ipc_config()?;
|
||||
let net_conf = self.net_config()?;
|
||||
@ -298,6 +301,7 @@ impl Configuration {
|
||||
file_path: self.args.arg_snapshot_file.clone(),
|
||||
kind: snapshot::Kind::Take,
|
||||
block_at: to_block_id(&self.args.arg_snapshot_at)?,
|
||||
snapshot_conf: snapshot_conf,
|
||||
};
|
||||
Cmd::Snapshot(snapshot_cmd)
|
||||
} else if self.args.cmd_restore {
|
||||
@ -314,6 +318,7 @@ impl Configuration {
|
||||
file_path: self.args.arg_restore_file.clone(),
|
||||
kind: snapshot::Kind::Restore,
|
||||
block_at: to_block_id("latest")?, // unimportant.
|
||||
snapshot_conf: snapshot_conf,
|
||||
};
|
||||
Cmd::Snapshot(restore_cmd)
|
||||
} else if self.args.cmd_export_hardcoded_sync {
|
||||
@ -349,6 +354,7 @@ impl Configuration {
|
||||
gas_price_percentile: self.args.arg_gas_price_percentile,
|
||||
poll_lifetime: self.args.arg_poll_lifetime,
|
||||
ws_conf: ws_conf,
|
||||
snapshot_conf: snapshot_conf,
|
||||
http_conf: http_conf,
|
||||
ipc_conf: ipc_conf,
|
||||
net_conf: net_conf,
|
||||
@ -374,7 +380,6 @@ impl Configuration {
|
||||
private_tx_enabled,
|
||||
name: self.args.arg_identity,
|
||||
custom_bootnodes: self.args.arg_bootnodes.is_some(),
|
||||
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
||||
check_seal: !self.args.flag_no_seal_check,
|
||||
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
||||
verifier_settings: verifier_settings,
|
||||
@ -890,6 +895,18 @@ impl Configuration {
|
||||
Ok((provider_conf, encryptor_conf, self.args.flag_private_enabled))
|
||||
}
|
||||
|
||||
fn snapshot_config(&self) -> Result<SnapshotConfiguration, String> {
|
||||
let conf = SnapshotConfiguration {
|
||||
no_periodic: self.args.flag_no_periodic_snapshot,
|
||||
processing_threads: match self.args.arg_snapshot_threads {
|
||||
Some(threads) if threads > 0 => threads,
|
||||
_ => ::std::cmp::max(1, num_cpus::get() / 2),
|
||||
},
|
||||
};
|
||||
|
||||
Ok(conf)
|
||||
}
|
||||
|
||||
fn network_settings(&self) -> Result<NetworkSettings, String> {
|
||||
let http_conf = self.http_config()?;
|
||||
let net_addresses = self.net_addresses()?;
|
||||
@ -1398,7 +1415,7 @@ mod tests {
|
||||
name: "".into(),
|
||||
custom_bootnodes: false,
|
||||
fat_db: Default::default(),
|
||||
no_periodic_snapshot: false,
|
||||
snapshot_conf: Default::default(),
|
||||
stratum: None,
|
||||
check_seal: true,
|
||||
download_old_blocks: true,
|
||||
|
@ -286,7 +286,7 @@ impl Default for MinerExtras {
|
||||
author: Default::default(),
|
||||
engine_signer: Default::default(),
|
||||
extra_data: version_data(),
|
||||
gas_range_target: (4_700_000.into(), 6_283_184.into()),
|
||||
gas_range_target: (8_000_000.into(), 10_000_000.into()),
|
||||
work_notify: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
|
||||
use ethcore::client::{BlockId, CallContract, Client, Mode, DatabaseCompactionProfile, VMType, BlockChainClient, BlockInfo};
|
||||
use ethcore::ethstore::ethkey;
|
||||
use ethcore::miner::{stratum, Miner, MinerService, MinerOptions};
|
||||
use ethcore::snapshot;
|
||||
use ethcore::snapshot::{self, SnapshotConfiguration};
|
||||
use ethcore::spec::{SpecParams, OptimizeFor};
|
||||
use ethcore::verification::queue::VerifierSettings;
|
||||
use ethcore_logger::{Config as LogConfig, RotatingLogger};
|
||||
@ -119,7 +119,7 @@ pub struct RunCmd {
|
||||
pub name: String,
|
||||
pub custom_bootnodes: bool,
|
||||
pub stratum: Option<stratum::Options>,
|
||||
pub no_periodic_snapshot: bool,
|
||||
pub snapshot_conf: SnapshotConfiguration,
|
||||
pub check_seal: bool,
|
||||
pub download_old_blocks: bool,
|
||||
pub verifier_settings: VerifierSettings,
|
||||
@ -531,6 +531,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
|
||||
client_config.queue.verifier_settings = cmd.verifier_settings;
|
||||
client_config.transaction_verification_queue_size = ::std::cmp::max(2048, txpool_size / 4);
|
||||
client_config.snapshot = cmd.snapshot_conf.clone();
|
||||
|
||||
// set up bootnodes
|
||||
let mut net_conf = cmd.net_conf;
|
||||
@ -778,7 +779,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
|
||||
});
|
||||
|
||||
// the watcher must be kept alive.
|
||||
let watcher = match cmd.no_periodic_snapshot {
|
||||
let watcher = match cmd.snapshot_conf.no_periodic {
|
||||
true => None,
|
||||
false => {
|
||||
let sync = sync_provider.clone();
|
||||
@ -960,6 +961,11 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str,
|
||||
account_settings,
|
||||
);
|
||||
|
||||
// Add development account if running dev chain:
|
||||
if let SpecType::Dev = *spec {
|
||||
insert_dev_account(&account_provider);
|
||||
}
|
||||
|
||||
for a in cfg.unlocked_accounts {
|
||||
// Check if the account exists
|
||||
if !account_provider.has_account(a) {
|
||||
@ -976,11 +982,6 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str,
|
||||
}
|
||||
}
|
||||
|
||||
// Add development account if running dev chain:
|
||||
if let SpecType::Dev = *spec {
|
||||
insert_dev_account(&account_provider);
|
||||
}
|
||||
|
||||
Ok(account_provider)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ use std::sync::Arc;
|
||||
|
||||
use hash::keccak;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::snapshot::{Progress, RestorationStatus, SnapshotService as SS};
|
||||
use ethcore::snapshot::{Progress, RestorationStatus, SnapshotConfiguration, SnapshotService as SS};
|
||||
use ethcore::snapshot::io::{SnapshotReader, PackedReader, PackedWriter};
|
||||
use ethcore::snapshot::service::Service as SnapshotService;
|
||||
use ethcore::client::{Mode, DatabaseCompactionProfile, VMType};
|
||||
@ -62,6 +62,7 @@ pub struct SnapshotCommand {
|
||||
pub file_path: Option<String>,
|
||||
pub kind: Kind,
|
||||
pub block_at: BlockId,
|
||||
pub snapshot_conf: SnapshotConfiguration,
|
||||
}
|
||||
|
||||
// helper for reading chunks from arbitrary reader and feeding them into the
|
||||
@ -165,7 +166,7 @@ impl SnapshotCommand {
|
||||
execute_upgrades(&self.dirs.base, &db_dirs, algorithm, &self.compaction)?;
|
||||
|
||||
// prepare client config
|
||||
let client_config = to_client_config(
|
||||
let mut client_config = to_client_config(
|
||||
&self.cache_config,
|
||||
spec.name.to_lowercase(),
|
||||
Mode::Active,
|
||||
@ -180,6 +181,8 @@ impl SnapshotCommand {
|
||||
true,
|
||||
);
|
||||
|
||||
client_config.snapshot = self.snapshot_conf;
|
||||
|
||||
let restoration_db_handler = db::restoration_db_handler(&client_path, &client_config);
|
||||
let client_db = restoration_db_handler.open(&client_path)
|
||||
.map_err(|e| format!("Failed to open database {:?}", e))?;
|
||||
|
@ -58,7 +58,7 @@ keccak-hash = "0.1.2"
|
||||
parity-reactor = { path = "../util/reactor" }
|
||||
parity-updater = { path = "../updater" }
|
||||
parity-version = { path = "../util/version" }
|
||||
patricia-trie = "0.2.1"
|
||||
patricia-trie = "0.2"
|
||||
rlp = { version = "0.2.4", features = ["ethereum"] }
|
||||
stats = { path = "../util/stats" }
|
||||
vm = { path = "../ethcore/vm" }
|
||||
|
@ -50,8 +50,6 @@ impl TimeProvider for DefaultTimeProvider {
|
||||
const TIME_THRESHOLD: u64 = 7;
|
||||
/// minimal length of hash
|
||||
const TOKEN_LENGTH: usize = 16;
|
||||
/// special "initial" token used for authorization when there are no tokens yet.
|
||||
const INITIAL_TOKEN: &'static str = "initial";
|
||||
/// Separator between fields in serialized tokens file.
|
||||
const SEPARATOR: &'static str = ";";
|
||||
/// Number of seconds to keep unused tokens.
|
||||
@ -163,16 +161,6 @@ impl<T: TimeProvider> AuthCodes<T> {
|
||||
|
||||
let as_token = |code| keccak(format!("{}:{}", code, time));
|
||||
|
||||
// Check if it's the initial token.
|
||||
if self.is_empty() {
|
||||
let initial = &as_token(INITIAL_TOKEN) == hash;
|
||||
// Initial token can be used only once.
|
||||
if initial {
|
||||
let _ = self.generate_new();
|
||||
}
|
||||
return initial;
|
||||
}
|
||||
|
||||
// look for code
|
||||
for code in &mut self.codes {
|
||||
if &as_token(&code.code) == hash {
|
||||
@ -239,7 +227,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_true_if_code_is_initial_and_store_is_empty() {
|
||||
fn should_return_false_even_if_code_is_initial_and_store_is_empty() {
|
||||
// given
|
||||
let code = "initial";
|
||||
let time = 99;
|
||||
@ -250,7 +238,7 @@ mod tests {
|
||||
let res2 = codes.is_valid(&generate_hash(code, time), time);
|
||||
|
||||
// then
|
||||
assert_eq!(res1, true);
|
||||
assert_eq!(res1, false);
|
||||
assert_eq!(res2, false);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ use std::sync::Arc;
|
||||
|
||||
use devtools::http_client;
|
||||
use jsonrpc_core::MetaIoHandler;
|
||||
use rand;
|
||||
use ws;
|
||||
|
||||
use v1::{extractors, informant};
|
||||
@ -28,8 +27,7 @@ use tests::helpers::{GuardedAuthCodes, Server};
|
||||
|
||||
/// Setup a mock signer for tests
|
||||
pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) {
|
||||
let port = 35000 + rand::random::<usize>() % 10000;
|
||||
let address = format!("127.0.0.1:{}", port).parse().unwrap();
|
||||
let address = "127.0.0.1:0".parse().unwrap();
|
||||
let io = MetaIoHandler::default();
|
||||
let authcodes = GuardedAuthCodes::new();
|
||||
let stats = Arc::new(informant::RpcStats::default());
|
||||
@ -45,6 +43,7 @@ pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) {
|
||||
extractors::WsExtractor::new(Some(&authcodes.path)),
|
||||
extractors::WsStats::new(stats),
|
||||
).unwrap());
|
||||
let port = res.addr().port() as usize;
|
||||
|
||||
(res, port, authcodes)
|
||||
}
|
||||
@ -136,7 +135,7 @@ mod testing {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_allow_initial_connection_but_only_once() {
|
||||
fn should_not_allow_initial_connection_even_once() {
|
||||
// given
|
||||
let (server, port, authcodes) = serve();
|
||||
let code = "initial";
|
||||
@ -160,26 +159,9 @@ mod testing {
|
||||
timestamp,
|
||||
)
|
||||
);
|
||||
let response2 = http_client::request(server.addr(),
|
||||
&format!("\
|
||||
GET / HTTP/1.1\r\n\
|
||||
Host: 127.0.0.1:{}\r\n\
|
||||
Connection: Close\r\n\
|
||||
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\
|
||||
Sec-WebSocket-Protocol:{:?}_{}\r\n\
|
||||
Sec-WebSocket-Version: 13\r\n\
|
||||
\r\n\
|
||||
{{}}
|
||||
",
|
||||
port,
|
||||
keccak(format!("{}:{}", code, timestamp)),
|
||||
timestamp,
|
||||
)
|
||||
);
|
||||
|
||||
// then
|
||||
assert_eq!(response1.status, "HTTP/1.1 101 Switching Protocols".to_owned());
|
||||
assert_eq!(response2.status, "HTTP/1.1 403 Forbidden".to_owned());
|
||||
http_client::assert_security_headers_present(&response2.headers, None);
|
||||
assert_eq!(response1.status, "HTTP/1.1 403 Forbidden".to_owned());
|
||||
http_client::assert_security_headers_present(&response1.headers, None);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ use ethcore::encoded;
|
||||
use ethcore::filter::Filter as EthcoreFilter;
|
||||
use ethcore::ids::BlockId;
|
||||
use ethcore::receipt::Receipt;
|
||||
use ethcore::executed::ExecutionError;
|
||||
|
||||
use jsonrpc_core::{Result, Error};
|
||||
use jsonrpc_core::futures::{future, Future};
|
||||
@ -188,10 +189,10 @@ impl LightFetch {
|
||||
}
|
||||
|
||||
/// Helper for getting proved execution.
|
||||
pub fn proved_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
|
||||
pub fn proved_read_only_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
|
||||
const DEFAULT_GAS_PRICE: u64 = 21_000;
|
||||
// starting gas when gas not provided.
|
||||
const START_GAS: u64 = 50_000;
|
||||
// (21000 G_transaction + 32000 G_create + some marginal to allow a few operations)
|
||||
const START_GAS: u64 = 60_000;
|
||||
|
||||
let (sync, on_demand, client) = (self.sync.clone(), self.on_demand.clone(), self.client.clone());
|
||||
let req: CallRequestHelper = req.into();
|
||||
@ -247,19 +248,20 @@ impl LightFetch {
|
||||
}).join(header_fut).and_then(move |((gas_known, tx), hdr)| {
|
||||
// then request proved execution.
|
||||
// TODO: get last-hashes from network.
|
||||
let env_info = match client.env_info(id) {
|
||||
let hash = hdr.hash();
|
||||
let env_info = match client.env_info(BlockId::Hash(hash)) {
|
||||
Some(env_info) => env_info,
|
||||
_ => return Either::A(future::err(errors::unknown_block())),
|
||||
};
|
||||
|
||||
Either::B(execute_tx(gas_known, ExecuteParams {
|
||||
from: from,
|
||||
tx: tx,
|
||||
hdr: hdr,
|
||||
env_info: env_info,
|
||||
Either::B(execute_read_only_tx(gas_known, ExecuteParams {
|
||||
from,
|
||||
tx,
|
||||
hdr,
|
||||
env_info,
|
||||
engine: client.engine().clone(),
|
||||
on_demand: on_demand,
|
||||
sync: sync,
|
||||
on_demand,
|
||||
sync,
|
||||
}))
|
||||
}))
|
||||
}
|
||||
@ -596,28 +598,41 @@ struct ExecuteParams {
|
||||
sync: Arc<LightSync>,
|
||||
}
|
||||
|
||||
// has a peer execute the transaction with given params. If `gas_known` is false,
|
||||
// this will double the gas on each `OutOfGas` error.
|
||||
fn execute_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
|
||||
// Has a peer execute the transaction with given params. If `gas_known` is false, this will set the `gas value` to the
|
||||
// `required gas value` unless it exceeds the block gas limit
|
||||
fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
|
||||
if !gas_known {
|
||||
Box::new(future::loop_fn(params, |mut params| {
|
||||
execute_tx(true, params.clone()).and_then(move |res| {
|
||||
execute_read_only_tx(true, params.clone()).and_then(move |res| {
|
||||
match res {
|
||||
Ok(executed) => {
|
||||
// TODO: how to distinguish between actual OOG and
|
||||
// exception?
|
||||
if executed.exception.is_some() {
|
||||
let old_gas = params.tx.gas;
|
||||
params.tx.gas = params.tx.gas * 2u32;
|
||||
if params.tx.gas > params.hdr.gas_limit() {
|
||||
params.tx.gas = old_gas;
|
||||
// `OutOfGas` exception, try double the gas
|
||||
if let Some(vm::Error::OutOfGas) = executed.exception {
|
||||
// block gas limit already tried, regard as an error and don't retry
|
||||
if params.tx.gas >= params.hdr.gas_limit() {
|
||||
trace!(target: "light_fetch", "OutOutGas exception received, gas increase: failed");
|
||||
} else {
|
||||
params.tx.gas = cmp::min(params.tx.gas * 2_u32, params.hdr.gas_limit());
|
||||
trace!(target: "light_fetch", "OutOutGas exception received, gas increased to {}",
|
||||
params.tx.gas);
|
||||
return Ok(future::Loop::Continue(params))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(future::Loop::Break(Ok(executed)))
|
||||
}
|
||||
Err(ExecutionError::NotEnoughBaseGas { required, got }) => {
|
||||
trace!(target: "light_fetch", "Not enough start gas provided required: {}, got: {}",
|
||||
required, got);
|
||||
if required <= params.hdr.gas_limit() {
|
||||
params.tx.gas = required;
|
||||
return Ok(future::Loop::Continue(params))
|
||||
} else {
|
||||
warn!(target: "light_fetch",
|
||||
"Required gas is bigger than block header's gas dropping the request");
|
||||
Ok(future::Loop::Break(Err(ExecutionError::NotEnoughBaseGas { required, got })))
|
||||
}
|
||||
}
|
||||
// Non-recoverable execution error
|
||||
failed => Ok(future::Loop::Break(failed)),
|
||||
}
|
||||
})
|
||||
|
@ -398,7 +398,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
}
|
||||
|
||||
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
|
||||
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| {
|
||||
match res {
|
||||
Ok(exec) => Ok(exec.output.into()),
|
||||
Err(e) => Err(errors::execution(e)),
|
||||
@ -408,7 +408,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
|
||||
|
||||
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
|
||||
// TODO: binary chop for more accurate estimates.
|
||||
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| {
|
||||
match res {
|
||||
Ok(exec) => Ok((exec.refunded + exec.gas_used).into()),
|
||||
Err(e) => Err(errors::execution(e)),
|
||||
|
@ -22,7 +22,12 @@ use v1::traits::Net;
|
||||
|
||||
/// Net rpc implementation.
|
||||
pub struct NetClient<S: ?Sized> {
|
||||
sync: Arc<S>
|
||||
sync: Arc<S>,
|
||||
/// Cached `network_id`.
|
||||
///
|
||||
/// We cache it to avoid redundant aquire of sync read lock.
|
||||
/// https://github.com/paritytech/parity-ethereum/issues/8746
|
||||
network_id: u64,
|
||||
}
|
||||
|
||||
impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
||||
@ -30,17 +35,18 @@ impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
||||
pub fn new(sync: &Arc<S>) -> Self {
|
||||
NetClient {
|
||||
sync: sync.clone(),
|
||||
network_id: sync.status().network_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
|
||||
fn version(&self) -> Result<String> {
|
||||
Ok(format!("{}", self.sync.status().network_id).to_owned())
|
||||
Ok(format!("{}", self.network_id))
|
||||
}
|
||||
|
||||
fn peer_count(&self) -> Result<String> {
|
||||
Ok(format!("0x{:x}", self.sync.status().num_peers as u64).to_owned())
|
||||
Ok(format!("{:#x}", self.sync.status().num_peers as u64))
|
||||
}
|
||||
|
||||
fn is_listening(&self) -> Result<bool> {
|
||||
|
@ -1 +0,0 @@
|
||||
stable
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
cargo build -j $(nproc) --release --features final $CARGOFLAGS
|
||||
git clone https://github.com/paritytech/parity-import-tests
|
||||
cp target/release/parity parity-import-tests/aura/parity
|
||||
cd parity-import-tests/aura
|
||||
echo "Start Aura test"
|
||||
./parity import blocks.rlp --chain chain.json
|
||||
./parity restore snap --chain chain.json
|
||||
echo "Aura test complete"
|
@ -15,8 +15,17 @@ RUN apt autoremove -y
|
||||
RUN apt clean -y
|
||||
RUN rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
|
||||
|
||||
RUN groupadd -g 1000 parity \
|
||||
&& useradd -m -u 1000 -g parity -s /bin/sh parity
|
||||
|
||||
USER parity
|
||||
|
||||
WORKDIR /home/parity
|
||||
|
||||
ENV PATH "~/bin:${PATH}"
|
||||
|
||||
#add TARGET to docker image
|
||||
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET /usr/bin/$TARGET
|
||||
COPY artifacts/x86_64-unknown-linux-gnu/$TARGET ./bin/$TARGET
|
||||
|
||||
# Build a shell script because the ENTRYPOINT command doesn't like using ENV
|
||||
RUN echo "#!/bin/bash \n ${TARGET} \$@" > ./entrypoint.sh
|
@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
clone_repos() {
|
||||
git clone https://github.com/parity-js/jsonrpc.git jsonrpc
|
||||
git clone https://github.com/paritytech/wiki.git wiki
|
||||
}
|
||||
|
||||
build_docs() {
|
||||
npm install
|
||||
npm run build:markdown
|
||||
}
|
||||
|
||||
update_wiki_docs() {
|
||||
for file in $(ls jsonrpc/docs); do
|
||||
module_name=${file:0:-3}
|
||||
mv jsonrpc/docs/$file wiki/JSONRPC-$module_name-module.md
|
||||
done
|
||||
}
|
||||
|
||||
set_remote_wiki() {
|
||||
git config remote.origin.url "https://${GITHUB_TOKEN}@github.com/paritytech/wiki.git"
|
||||
}
|
||||
|
||||
setup_git() {
|
||||
git config --global user.email "devops@parity.com"
|
||||
git config --global user.name "Devops Parity"
|
||||
}
|
||||
|
||||
commit_files() {
|
||||
git checkout -b rpcdoc-update-${CI_COMMIT_REF_NAME}
|
||||
git add .
|
||||
git commit -m "Update docs to ${CI_COMMIT_REF_NAME}"
|
||||
git tag -a "${CI_COMMIT_REF_NAME}" -m "Updated to ${CI_COMMIT_REF_NAME}"
|
||||
}
|
||||
|
||||
upload_files() {
|
||||
git push --tags
|
||||
}
|
||||
|
||||
PROJECT_DIR=$(pwd)
|
||||
|
||||
setup_git
|
||||
cd ..
|
||||
clone_repos
|
||||
cp -r $PROJECT_DIR jsonrpc/.parity
|
||||
cd jsonrpc
|
||||
build_docs
|
||||
cd ..
|
||||
update_wiki_docs
|
||||
cd wiki
|
||||
set_remote_wiki
|
||||
commit_files
|
||||
upload_files
|
@ -2,16 +2,27 @@
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
echo "__________Show ENVIROMENT__________"
|
||||
echo "CC: " $CC
|
||||
echo "CXX: " $CXX
|
||||
echo "CI_SERVER_NAME: " $CI_SERVER_NAME
|
||||
echo "CARGO_HOME: " $CARGO_HOME
|
||||
echo "CARGO_TARGET: " $CARGO_TARGET
|
||||
echo "CC: " $CC
|
||||
echo "CXX: " $CXX
|
||||
|
||||
echo "__________CARGO CONFIG__________"
|
||||
rm -rf .cargo
|
||||
mkdir -p .cargo
|
||||
echo "[target.$CARGO_TARGET]" >> .cargo/config
|
||||
echo "linker= \"$CC\"" >> .cargo/config
|
||||
cat .cargo/config
|
||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||
then
|
||||
# use build container's cargo config
|
||||
cat /.cargo/config
|
||||
else
|
||||
mkdir -p .cargo
|
||||
rm -f .cargo/config
|
||||
echo "[target.$CARGO_TARGET]" >> .cargo/config
|
||||
echo "linker= \"$CC\"" >> .cargo/config
|
||||
cat .cargo/config
|
||||
fi
|
||||
|
||||
|
||||
echo "_____ Building target: "$CARGO_TARGET" _____"
|
||||
time cargo build --target $CARGO_TARGET --release --features final
|
||||
@ -26,10 +37,31 @@ mkdir -p artifacts
|
||||
cd artifacts
|
||||
mkdir -p $CARGO_TARGET
|
||||
cd $CARGO_TARGET
|
||||
cp ../../target/$CARGO_TARGET/release/{parity,parity-evm,ethstore,ethkey,whisper} .
|
||||
strip -v ./*
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity ./parity
|
||||
cp -v ../../target/$CARGO_TARGET/release/parity-evm ./parity-evm
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethstore ./ethstore
|
||||
cp -v ../../target/$CARGO_TARGET/release/ethkey ./ethkey
|
||||
cp -v ../../target/$CARGO_TARGET/release/whisper ./whisper
|
||||
|
||||
|
||||
# stripping can also be done on release build time
|
||||
# export RUSTFLAGS="${RUSTFLAGS} -C link-arg=-s"
|
||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||
then
|
||||
arm-linux-androideabi-strip -v ./*
|
||||
else
|
||||
strip -v ./*
|
||||
fi
|
||||
|
||||
echo "_____ Calculating checksums _____"
|
||||
for binary in $(ls)
|
||||
do
|
||||
rhash --sha256 $binary -o $binary.sha256
|
||||
if [ "${CARGO_TARGET}" = "armv7-linux-androideabi" ]
|
||||
then
|
||||
echo "> ${binary} cannot be hashed with cross-compiled binary"
|
||||
else
|
||||
./parity tools hash $binary > $binary.sha3
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -5,19 +5,24 @@ set -u # treat unset variables as error
|
||||
set INCLUDE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt"
|
||||
set LIB="C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64"
|
||||
|
||||
rustup default stable-x86_64-pc-windows-msvc
|
||||
echo "_____ Building _____"
|
||||
echo "__________Show ENVIROMENT__________"
|
||||
echo "CI_SERVER_NAME: " $CI_SERVER_NAME
|
||||
echo "CARGO_HOME: " $CARGO_HOME
|
||||
echo "CARGO_TARGET: " $CARGO_TARGET
|
||||
|
||||
echo "_____ Building target: "$CARGO_TARGET" _____"
|
||||
time cargo build --target $CARGO_TARGET --release --features final
|
||||
time cargo build --target $CARGO_TARGET --release -p evmbin
|
||||
time cargo build --target $CARGO_TARGET --release -p ethstore-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p ethkey-cli
|
||||
time cargo build --target $CARGO_TARGET --release -p whisper-cli
|
||||
|
||||
echo "__________Sign binaries__________"
|
||||
scripts/gitlab/sign.cmd $keyfile $certpass target/$CARGO_TARGET/release/parity.exe
|
||||
scripts/gitlab/sign.cmd $keyfile $certpass target/$CARGO_TARGET/release/parity-evm.exe
|
||||
scripts/gitlab/sign.cmd $keyfile $certpass target/$CARGO_TARGET/release/ethstore.exe
|
||||
scripts/gitlab/sign.cmd $keyfile $certpass target/$CARGO_TARGET/release/ethkey.exe
|
||||
scripts/gitlab/sign.cmd $keyfile $certpass target/$CARGO_TARGET/release/whisper.exe
|
||||
scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/parity.exe
|
||||
scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/parity-evm.exe
|
||||
scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/ethstore.exe
|
||||
scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/ethkey.exe
|
||||
scripts/gitlab/sign-win.cmd $keyfile $certpass target/$CARGO_TARGET/release/whisper.exe
|
||||
|
||||
echo "_____ Post-processing binaries _____"
|
||||
rm -rf artifacts
|
||||
@ -25,11 +30,17 @@ mkdir -p artifacts
|
||||
cd artifacts
|
||||
mkdir -p $CARGO_TARGET
|
||||
cd $CARGO_TARGET
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/{parity.exe,parity-evm.exe,ethstore.exe,ethkey.exe,whisper.exe} .
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/parity.exe ./parity.exe
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/parity-evm.exe ./parity-evm.exe
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/ethstore.exe ./ethstore.exe
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/ethkey.exe ./ethkey.exe
|
||||
cp --verbose ../../target/$CARGO_TARGET/release/whisper.exe ./whisper.exe
|
||||
|
||||
echo "_____ Calculating checksums _____"
|
||||
for binary in $(ls)
|
||||
do
|
||||
rhash --sha256 $binary -o $binary.sha256
|
||||
./parity.exe tools hash $binary > $binary.sha3
|
||||
done
|
||||
cp parity.exe.sha256 parity.sha256
|
||||
cp parity.exe.sha3 parity.sha3
|
||||
|
@ -3,5 +3,5 @@
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
cargo install clippy
|
||||
cargo clippy -- -D warnings
|
||||
cargo install cargo-audit
|
||||
cargo audit
|
@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
git submodule update --init --recursive
|
||||
rm -rf target/*
|
||||
cargo test --all --exclude evmjit --no-run -- --test-threads 8|| exit $?
|
||||
KCOV_TARGET="target/cov"
|
||||
KCOV_FLAGS="--verify"
|
||||
mkdir -p $KCOV_TARGET
|
||||
echo "__________Cover RUST___________"
|
||||
for FILE in `find target/debug/deps ! -name "*.*" -type f`
|
||||
do
|
||||
timeout --signal=SIGKILL 5m kcov --include-path=$(pwd) --exclude-path=$(pwd)/target $KCOV_FLAGS $KCOV_TARGET $FILE
|
||||
done
|
||||
timeout --signal=SIGKILL 5m kcov --include-path=$(pwd) --exclude-path=$(pwd)/target $KCOV_FLAGS $KCOV_TARGET target/debug/parity-*
|
||||
|
||||
bash <(curl -s https://codecov.io/bash) &&
|
||||
echo "Uploaded code coverage"
|
||||
|
||||
exit 0
|
@ -29,29 +29,35 @@ setup_git() {
|
||||
git config user.name "Devops Parity"
|
||||
}
|
||||
|
||||
set_remote_wiki() {
|
||||
git config remote.origin.url "https://${GITHUB_TOKEN}@github.com/paritytech/wiki.git"
|
||||
}
|
||||
|
||||
commit_files() {
|
||||
echo "__________Commit files__________"
|
||||
git checkout -b rpcdoc-update-${CI_COMMIT_REF_NAME}
|
||||
git add .
|
||||
git commit -m "Update docs to ${CI_COMMIT_REF_NAME}"
|
||||
git tag -a "${CI_COMMIT_REF_NAME}"
|
||||
git tag -a "${CI_COMMIT_REF_NAME}" -m "Update RPC docs to ${CI_COMMIT_REF_NAME}"
|
||||
}
|
||||
|
||||
upload_files() {
|
||||
echo "__________Upload files__________"
|
||||
git push origin HEAD
|
||||
git push --tags
|
||||
}
|
||||
|
||||
RPC_TRAITS_DIR="rpc/src/v1/traits/"
|
||||
RPC_TRAITS_DIR="rpc/src/v1/traits"
|
||||
|
||||
setup_git
|
||||
clone_repos
|
||||
mkdir -p "jsonrpc/.parity/$RPC_TRAITS_DIR"
|
||||
cp -r "$RPC_TRAITS_DIR" "jsonrpc/.parity/$RPC_TRAITS_DIR"
|
||||
cp $RPC_TRAITS_DIR/*.rs "jsonrpc/.parity/$RPC_TRAITS_DIR"
|
||||
cd jsonrpc
|
||||
build_docs
|
||||
cd ..
|
||||
update_wiki_docs
|
||||
cd wiki
|
||||
set_remote_wiki
|
||||
commit_files
|
||||
upload_files
|
@ -1,8 +0,0 @@
|
||||
echo "Parity Wallet
|
||||
=============
|
||||
|
||||
Welcome to Parity Wallet, your all-in-one Ethereum node and wallet.
|
||||
|
||||
If you continue, Parity will be installed as a user service. You will be able to use the Parity Wallet through your browser by using the menu bar icon, following the shortcut in the Launchpad or navigating to http://localhost:8180/ in your browser.
|
||||
|
||||
Parity is distributed under the terms of the GPL."
|
@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
case ${CI_COMMIT_REF_NAME} in
|
||||
nightly|*v2.1*) export GRADE="devel";;
|
||||
beta|*v2.0*) export GRADE="stable";;
|
||||
stable|*v1.11*) export GRADE="stable";;
|
||||
*) echo "No release" exit 0;;
|
||||
esac
|
||||
SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap"
|
||||
echo "__________Create snap package__________"
|
||||
echo "Release channel :" $GRADE " Branch/tag: " $CI_COMMIT_REF_NAME
|
||||
snapcraft clean
|
||||
echo $VERSION:$GRADE:$BUILD_ARCH
|
||||
cat scripts/gitlab/templates/snapcraft.template.yaml | envsubst '$VERSION:$GRADE:$BUILD_ARCH:$CARGO_TARGET' > snapcraft.yaml
|
||||
cat snapcraft.yaml
|
||||
snapcraft --target-arch=$BUILD_ARCH
|
||||
ls *.snap
|
||||
echo "__________Post-processing snap package__________"
|
||||
mkdir -p artifacts
|
||||
mv -v $SNAP_PACKAGE "artifacts/"$SNAP_PACKAGE
|
||||
echo "_____ Calculating checksums _____"
|
||||
cd artifacts
|
||||
rhash --sha256 $SNAP_PACKAGE -o $SNAP_PACKAGE".sha256"
|
49
scripts/gitlab/publish-awss3.sh
Executable file
49
scripts/gitlab/publish-awss3.sh
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
echo "__________Register Release__________"
|
||||
DATA="secret=$RELEASES_SECRET"
|
||||
|
||||
echo "Pushing release to Mainnet"
|
||||
./scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1337/push-release/$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA"
|
||||
|
||||
echo "Pushing release to Kovan"
|
||||
./scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1338/push-release/$CI_COMMIT_REF_NAME/$CI_COMMIT_SHA"
|
||||
|
||||
cd artifacts
|
||||
ls -l | sort -k9
|
||||
filetest=( * )
|
||||
echo ${filetest[*]}
|
||||
for DIR in "${filetest[@]}";
|
||||
do
|
||||
cd $DIR
|
||||
if [[ $DIR =~ "windows" ]];
|
||||
then
|
||||
WIN=".exe";
|
||||
else
|
||||
WIN="";
|
||||
fi
|
||||
sha3=$(cat parity.sha3 | awk '{print $1}')
|
||||
case $DIR in
|
||||
x86_64* )
|
||||
DATA="commit=$CI_COMMIT_SHA&sha3=$sha3&filename=parity$WIN&secret=$RELEASES_SECRET"
|
||||
../../scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1337/push-build/$CI_COMMIT_REF_NAME/$DIR"
|
||||
# Kovan
|
||||
../../scripts/gitlab/safe-curl.sh $DATA "http://update.parity.io:1338/push-build/$CI_COMMIT_REF_NAME/$DIR"
|
||||
;;
|
||||
esac
|
||||
cd ..
|
||||
done
|
||||
|
||||
echo "__________Push binaries to AWS S3____________"
|
||||
aws configure set aws_access_key_id $s3_key
|
||||
aws configure set aws_secret_access_key $s3_secret
|
||||
if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" || "$CI_COMMIT_REF_NAME" = "nightly" ]];
|
||||
then
|
||||
export S3_BUCKET=builds-parity-published;
|
||||
else
|
||||
export S3_BUCKET=builds-parity;
|
||||
fi
|
||||
aws s3 sync ./ s3://$S3_BUCKET/$CI_COMMIT_REF_NAME/
|
@ -3,9 +3,9 @@
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
if [ "$CI_COMMIT_REF_NAME" == "beta" ];
|
||||
then export DOCKER_BUILD_TAG="latest";
|
||||
else export DOCKER_BUILD_TAG=$CI_COMMIT_REF_NAME;
|
||||
if [ "$CI_COMMIT_REF_NAME" == "master" ];
|
||||
then export DOCKER_BUILD_TAG="latest";
|
||||
else export DOCKER_BUILD_TAG=$CI_COMMIT_REF_NAME;
|
||||
fi
|
||||
docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity
|
||||
|
||||
@ -17,6 +17,6 @@ export DOCKER_TARGET=$1
|
||||
echo $DOCKER_TARGET
|
||||
|
||||
echo "__________Docker build and push__________"
|
||||
docker build --build-arg TARGET=$DOCKER_TARGET --no-cache=true --tag parity/$DOCKER_TARGET:$DOCKER_BUILD_TAG -f docker/hub/Dockerfile .
|
||||
docker build --build-arg TARGET=$DOCKER_TARGET --no-cache=true --tag parity/$DOCKER_TARGET:$DOCKER_BUILD_TAG -f scripts/docker/hub/Dockerfile .
|
||||
docker push parity/$DOCKER_TARGET:$DOCKER_BUILD_TAG
|
||||
docker logout
|
||||
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
case ${CI_COMMIT_REF_NAME} in
|
||||
nightly|*v2.1*) export CHANNEL="edge";;
|
||||
beta|*v2.0*) export CHANNEL="beta";;
|
||||
stable|*v1.11*) export CHANNEL="stable";;
|
||||
*) echo "No release" exit 0;;
|
||||
esac
|
||||
echo "Release channel :" $CHANNEL " Branch/tag: " $CI_COMMIT_REF_NAME
|
||||
|
||||
echo $SNAPCRAFT_LOGIN_PARITY_BASE64 | base64 --decode > snapcraft.login
|
||||
snapcraft login --with snapcraft.login
|
||||
snapcraft push --release $CHANNEL "artifacts/parity_"$VERSION"_"$BUILD_ARCH".snap"
|
||||
snapcraft status parity
|
||||
snapcraft logout
|
@ -1,67 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
updater_push_release () {
|
||||
echo "push release"
|
||||
# Mainnet
|
||||
|
||||
}
|
||||
echo "__________Set ENVIROMENT__________"
|
||||
DESCRIPTION="$(cat CHANGELOG.md)"
|
||||
RELEASE_TABLE="$(cat scripts/gitlab/templates/release-table.md)"
|
||||
RELEASE_TABLE="$(echo "${RELEASE_TABLE//\$VERSION/${VERSION}}")"
|
||||
#The text in the file CANGELOG.md before which the table with links is inserted. Must be present in this file necessarily
|
||||
REPLACE_TEXT="The full list of included changes:"
|
||||
case ${CI_COMMIT_REF_NAME} in
|
||||
nightly|*v2.1*) NAME="Parity "$VERSION" nightly";;
|
||||
beta|*v2.0*) NAME="Parity "$VERSION" beta";;
|
||||
stable|*v1.11*) NAME="Parity "$VERSION" stable";;
|
||||
*) echo "No release" exit 0;;
|
||||
esac
|
||||
cd artifacts
|
||||
ls -l | sort -k9
|
||||
filetest=( * )
|
||||
echo ${filetest[*]}
|
||||
for DIR in "${filetest[@]}";
|
||||
do
|
||||
cd $DIR
|
||||
if [[ $DIR == "*windows*" ]];
|
||||
then
|
||||
WIN=".exe";
|
||||
else
|
||||
WIN="";
|
||||
fi
|
||||
for binary in $(ls parity.sha256)
|
||||
do
|
||||
sha256=$(cat $binary | awk '{ print $1}' )
|
||||
case $DIR in
|
||||
x86_64* )
|
||||
DATA="commit=$CI_BUILD_REF&sha3=$sha256&filename=parity$WIN&secret=$RELEASES_SECRET"
|
||||
../../scripts/gitlab/safe_curl.sh $DATA "http://update.parity.io:1337/push-build/$CI_BUILD_REF_NAME/$DIR"
|
||||
# Kovan
|
||||
../../scripts/gitlab/safe_curl.sh $DATA "http://update.parity.io:1338/push-build/$CI_BUILD_REF_NAME/$DIR"
|
||||
;;
|
||||
esac
|
||||
RELEASE_TABLE="$(echo "${RELEASE_TABLE/sha$DIR/${sha256}}")"
|
||||
done
|
||||
cd ..
|
||||
done
|
||||
#do not touch the following 3 lines. Features of output in Markdown
|
||||
DESCRIPTION="$(echo "${DESCRIPTION/${REPLACE_TEXT}/${RELEASE_TABLE}
|
||||
|
||||
${REPLACE_TEXT}}")"
|
||||
echo "$DESCRIPTION"
|
||||
if [[ "$CI_COMMIT_REF_NAME" == "nightly" ]]; then DESCRIPTION=""; fi #TODO in the future, we need to prepare a script that will do changelog
|
||||
echo "__________Create release to Github____________"
|
||||
github-release release --user devops-parity --repo parity-ethereum --tag "$CI_COMMIT_REF_NAME" --draft --name "$NAME" --description "$DESCRIPTION"
|
||||
echo "__________Push binaries to AWS S3____________"
|
||||
aws configure set aws_access_key_id $s3_key
|
||||
aws configure set aws_secret_access_key $s3_secret
|
||||
if [[ "$CI_BUILD_REF_NAME" = "beta" || "$CI_BUILD_REF_NAME" = "stable" || "$CI_BUILD_REF_NAME" = "nightly" ]];
|
||||
then
|
||||
export S3_BUCKET=builds-parity-published;
|
||||
else
|
||||
export S3_BUCKET=builds-parity;
|
||||
fi
|
||||
aws s3 sync ./ s3://$S3_BUCKET/$CI_BUILD_REF_NAME/
|
@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
cargo install rustfmt-nightly
|
||||
cargo fmt -- --write-mode=diff
|
@ -1,16 +0,0 @@
|
||||
| OS | Arch | Download | SHA256 Checksum |
|
||||
|:---:|:---:|:---|:---|
|
||||
| linux | arm64 | [parity](https://releases.parity.io/$VERSION/aarch64-unknown-linux-gnu/parity) | <sup>`shaaarch64-unknown-linux-gnu`</sup> |
|
||||
| android | armv7 | [parity](https://releases.parity.io/$VERSION/armv7-linux-androideabi/parity) | <sup>`shaarmv7-linux-androideabi`</sup> |
|
||||
| linux | armv7 | [parity](https://releases.parity.io/$VERSION/armv7-unknown-linux-gnueabihf/parity) | <sup>`shaarmv7-unknown-linux-gnueabihf`</sup> |
|
||||
| linux | i686 | [parity](https://releases.parity.io/$VERSION/i686-unknown-linux-gnu/parity) | <sup>`shai686-unknown-linux-gnu`</sup> |
|
||||
| osx | x64 | [parity](https://releases.parity.io/$VERSION/x86_64-apple-darwin/parity) | <sup>`shax86_64-apple-darwin`</sup> |
|
||||
| windows | x64 | [parity.exe](https://releases.parity.io/$VERSION/x86_64-pc-windows-msvc/parity.exe) | <sup>`shax86_64-pc-windows-msvc`</sup> |
|
||||
| linux | x64 | [parity](https://releases.parity.io/$VERSION/x86_64-unknown-linux-gnu/parity) | <sup>`shax86_64-unknown-linux-gnu`</sup> |
|
||||
|
||||
| OS | Alternative | Link |
|
||||
|:---:|:---:|:---|
|
||||
| <img src="https://gist.github.com/5chdn/1fce888fde1d773761f809b607757f76/raw/44c4f0fc63f1ea8e61a9513af5131ef65eaa6c75/apple.png" alt="Apple Icon by Pixel Perfect from https://www.flaticon.com/authors/pixel-perfect" style="width: 32px;"/> | Homebrew |[github.com/paritytech/homebrew-paritytech/blob/master/README.md](https://github.com/paritytech/homebrew-paritytech/blob/master/README.md) |
|
||||
| <img src="https://gist.github.com/5chdn/1fce888fde1d773761f809b607757f76/raw/44c4f0fc63f1ea8e61a9513af5131ef65eaa6c75/linux.png" alt="Linux Icon by Pixel Perfect from https://www.flaticon.com/authors/pixel-perfect" style="width: 32px;"/> | Snapcraft | [snapcraft.io/parity](https://snapcraft.io/parity/) |
|
||||
| <img src="https://gist.github.com/5chdn/1fce888fde1d773761f809b607757f76/raw/44c4f0fc63f1ea8e61a9513af5131ef65eaa6c75/settings.png" alt="Settings Icon by Pixel Perfect from https://www.flaticon.com/authors/pixel-perfect" style="width: 32px;"/> | Docker | [hub.docker.com/r/parity/parity](https://hub.docker.com/r/parity/parity) |
|
||||
| <img src="https://gist.github.com/5chdn/1fce888fde1d773761f809b607757f76/raw/44c4f0fc63f1ea8e61a9513af5131ef65eaa6c75/settings.png" alt="Settings Icon by Pixel Perfect from https://www.flaticon.com/authors/pixel-perfect" style="width: 32px;"/> | Other binaries | [vanity-service.parity.io/parity-binaries?format=markdown&version=$VERSION](https://vanity-service.parity.io/parity-binaries?format=markdown&version=$VERSION) |
|
@ -1,58 +0,0 @@
|
||||
name: parity
|
||||
version: $VERSION
|
||||
architectures: [$BUILD_ARCH]
|
||||
grade: $GRADE
|
||||
confinement: strict
|
||||
|
||||
summary: Fast, light, robust Ethereum implementation
|
||||
description: |
|
||||
Parity's goal is to be the fastest, lightest, and most secure Ethereum
|
||||
client. We are developing Parity using the sophisticated and cutting-edge
|
||||
Rust programming language. Parity is licensed under the GPLv3, and can be
|
||||
used for all your Ethereum needs.
|
||||
|
||||
|
||||
apps:
|
||||
parity:
|
||||
command: parity
|
||||
plugs: [home, network, network-bind, mount-observe, x11, unity7, desktop, desktop-legacy, wayland]
|
||||
desktop: usr/share/applications/parity.desktop
|
||||
parity-evm:
|
||||
command: parity-evm
|
||||
plugs: [home, network, network-bind]
|
||||
ethkey:
|
||||
command: ethkey
|
||||
plugs: [home]
|
||||
ethstore:
|
||||
command: ethstore
|
||||
plugs: [home]
|
||||
whisper:
|
||||
command: whisper
|
||||
plugs: [home]
|
||||
|
||||
icon: snap/gui/icon.png
|
||||
|
||||
parts:
|
||||
desktop-icon:
|
||||
source: ./snap
|
||||
plugin: nil
|
||||
override-build: |
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/applications
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps
|
||||
cp -v gui/parity.desktop $SNAPCRAFT_PART_INSTALL/usr/share/applications/
|
||||
cp -v gui/icon.png $SNAPCRAFT_PART_INSTALL/usr/share/pixmaps/
|
||||
parity:
|
||||
source: ./artifacts/$CARGO_TARGET
|
||||
plugin: nil
|
||||
override-build: |
|
||||
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/bin
|
||||
cp -v parity $SNAPCRAFT_PART_INSTALL/usr/bin/parity
|
||||
cp -v parity-evm $SNAPCRAFT_PART_INSTALL/usr/bin/parity-evm
|
||||
cp -v ethkey $SNAPCRAFT_PART_INSTALL/usr/bin/ethkey
|
||||
cp -v ethstore $SNAPCRAFT_PART_INSTALL/usr/bin/ethstore
|
||||
cp -v whisper $SNAPCRAFT_PART_INSTALL/usr/bin/whisper
|
||||
stage-packages: [libc6, libssl1.0.0, libudev1, libstdc++6, cmake]
|
||||
df:
|
||||
plugin: nil
|
||||
stage-packages: [coreutils]
|
||||
stage: [bin/df]
|
35
scripts/gitlab/test-all.sh
Executable file
35
scripts/gitlab/test-all.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# ARGUMENT $1 Rust flavor to test with (stable/beta/nightly)
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
git log --graph --oneline --decorate=short -n 10
|
||||
|
||||
case ${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}} in
|
||||
(beta|stable)
|
||||
export GIT_COMPARE=origin/${SCHEDULE_TAG:-${CI_COMMIT_REF_NAME}}~
|
||||
;;
|
||||
(master|nightly)
|
||||
export GIT_COMPARE=master~
|
||||
;;
|
||||
(*)
|
||||
export GIT_COMPARE=master
|
||||
;;
|
||||
esac
|
||||
|
||||
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^CHANGELOG.md -e ^test.sh -e ^scripts/ -e ^docs/ -e ^docker/ -e ^snap/ | wc -l | tr -d ' ')"
|
||||
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
|
||||
|
||||
if [ "${RUST_FILES_MODIFIED}" = "0" ]
|
||||
then
|
||||
echo "__________Skipping Rust tests since no Rust files modified__________";
|
||||
exit 0
|
||||
fi
|
||||
|
||||
rustup default $1
|
||||
|
||||
git submodule update --init --recursive
|
||||
rustup show
|
||||
|
||||
exec ./test.sh
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ARGUMENT $1 Rust flavor to test with (stable/beta/nightly)
|
||||
|
||||
set -e # fail on any error
|
||||
set -u # treat unset variables as error
|
||||
|
||||
rustup default $1
|
||||
|
||||
if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; then
|
||||
export GIT_COMPARE=$CI_COMMIT_REF_NAME~;
|
||||
else
|
||||
export GIT_COMPARE=master;
|
||||
fi
|
||||
|
||||
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)"
|
||||
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
|
||||
|
||||
git submodule update --init --recursive
|
||||
rustup show
|
||||
if [[ "${RUST_FILES_MODIFIED}" == "0" ]];
|
||||
then echo "__________Skipping Rust tests since no Rust files modified__________";
|
||||
else ./test.sh || exit $?;
|
||||
fi
|
||||
|
||||
# if [[ "$CI_COMMIT_REF_NAME" == "nightly" ]];
|
||||
# ### @TODO re-enable fail after https://github.com/paritytech/parity-import-tests/issues/3
|
||||
# then sh scripts/aura-test.sh; # || exit $?;
|
||||
# fi
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user