Rewrite load tester in C++ (#1989)
* Rewrite load tester from Rust to C++ * Boost 1.69/mac update * Rename results to primary_node_results to be more clear
This commit is contained in:
parent
092533d09d
commit
04e4eda0c3
16 changed files with 610 additions and 1745 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -18,9 +18,6 @@
|
|||
# Doxygen built HTML
|
||||
/doc-build
|
||||
|
||||
# Rust generated files
|
||||
/load-tester/target
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
|
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
os: osx
|
||||
compiler: clang
|
||||
before_install:
|
||||
- brew update && brew install qt5 && brew cask install xquartz && brew install rust && brew upgrade cmake;
|
||||
- brew update && brew install qt5 && brew cask install xquartz && brew upgrade cmake;
|
||||
install:
|
||||
- brew install ccache;
|
||||
- export PATH="/usr/local/opt/ccache/libexec:$PATH";
|
||||
|
@ -46,11 +46,10 @@ cache:
|
|||
- ccache: true
|
||||
- directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- $HOME/.cargo
|
||||
- $TRAVIS_BUILD_DIR/load-tester/target
|
||||
|
||||
script:
|
||||
- if [ -n "$ONE_TIME_TESTS" ]; then ci/check-commit-format.sh; fi
|
||||
- if [ -n "$ONE_TIME_TESTS" ]; then doxygen doxygen.config; fi # TODO also deploy the built HTML
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ci/build-travis.sh "/usr/local/opt/qt5/lib/cmake/Qt5"; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then docker run -v $TRAVIS_BUILD_DIR:/workspace -v $HOME/.ccache:/ccache -v $HOME/.cargo:/cargo nanocurrency/nano-ci-$TRAVIS_COMPILER /bin/bash -c "apt install ccache; cd /workspace && ASAN=${ASAN} TSAN=${TSAN} CCACHE_DIR=/ccache CARGO_HOME=/cargo ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}"; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then docker run -v $TRAVIS_BUILD_DIR:/workspace -v $HOME/.ccache:/ccache nanocurrency/nano-ci-$TRAVIS_COMPILER /bin/bash -c "apt install ccache; cd /workspace && ASAN=${ASAN} TSAN=${TSAN} CCACHE_DIR=/ccache ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}"; fi
|
||||
|
|
|
@ -312,6 +312,8 @@ if (NANO_TEST OR RAIBLOCKS_TEST)
|
|||
set (gtest_force_shared_crt OFF)
|
||||
endif()
|
||||
|
||||
add_subdirectory(nano/load_test)
|
||||
|
||||
add_subdirectory (gtest/googletest)
|
||||
# FIXME: This fixes gtest include directories without modifying gtest's
|
||||
# CMakeLists.txt. Ideally we should use GTest::GTest and GTest::Main as
|
||||
|
|
|
@ -43,9 +43,4 @@ fi
|
|||
|
||||
popd
|
||||
|
||||
pushd load-tester
|
||||
cargo build --release
|
||||
popd
|
||||
cp ./load-tester/target/release/nano-load-tester ./build/load_test
|
||||
|
||||
./ci/test.sh ./build
|
||||
|
|
|
@ -71,7 +71,7 @@ run_tests() {
|
|||
xvfb_run_ ./qt_test
|
||||
qt_test_res=${?}
|
||||
|
||||
${TIMEOUT_CMD} ${TIMEOUT_TIME_ARG} ${TIMEOUT_SEC-${TIMEOUT_DEFAULT}} ./load_test ./nano_node ./nano_rpc -s 150
|
||||
${TIMEOUT_CMD} ${TIMEOUT_TIME_ARG} ${TIMEOUT_SEC-${TIMEOUT_DEFAULT}} ./load_test -s 150
|
||||
load_test_res=${?}
|
||||
|
||||
echo "Core Test return code: ${core_test_res}"
|
||||
|
|
|
@ -8,8 +8,7 @@ RUN apt-get update -qq && apt-get install -yqq \
|
|||
RUN apt-get update -qq && apt-get install -yqq \
|
||||
qt5-default \
|
||||
valgrind \
|
||||
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic \
|
||||
cargo
|
||||
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
|
||||
|
||||
RUN apt-get update -qq && apt-get install -yqq \
|
||||
clang-3.9 lldb-3.9
|
||||
|
|
|
@ -17,6 +17,4 @@ RUN rm bootstrap_boost.sh
|
|||
RUN apt-get update -qq && apt-get install -yqq \
|
||||
qt5-default \
|
||||
valgrind \
|
||||
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic \
|
||||
cargo
|
||||
|
||||
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
|
||||
|
|
871
load-tester/Cargo.lock
generated
871
load-tester/Cargo.lock
generated
|
@ -1,871 +0,0 @@
|
|||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace-sys"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.29.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-cpupool"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.11.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "language-tags"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-named-pipes"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-uds"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "nano-load-tester"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-process 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "relay"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.11.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synom"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-core"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-process"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-signal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-proto"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-service"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-signal"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wincolor"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
|
||||
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
|
||||
"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9"
|
||||
"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
|
||||
"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum env_logger 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f15f0b172cb4f52ed5dbf47f774a387cd2315d1bf7894ab5af9b083ae27efa5a"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1"
|
||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
|
||||
"checksum hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6105c5eeb03068b10ff34475a0d166964f98e7b9777cc34b342a225af9b87c"
|
||||
"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7"
|
||||
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
|
||||
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd"
|
||||
"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0"
|
||||
"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
|
||||
"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
|
||||
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
||||
"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
|
||||
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
|
||||
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
|
||||
"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017"
|
||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa"
|
||||
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
|
||||
"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5"
|
||||
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
|
||||
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
||||
"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"
|
||||
"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0"
|
||||
"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5"
|
||||
"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb"
|
||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
|
||||
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||
"checksum socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a76b792959eba82f021c9028c8ecb6396f085268d6d46af2ed96a829cc758d7c"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
|
||||
"checksum termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9065bced9c3e43453aa3d56f1e98590b8455b341d2fa191a1090c0dd0b242c75"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
||||
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
|
||||
"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8"
|
||||
"checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743"
|
||||
"checksum tokio-process 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2e76e0cd21a4ae5362697e85f98aa5d26c88f09ce9fc367b57c0643ba0b022c2"
|
||||
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
|
||||
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
|
||||
"checksum tokio-signal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57c4031b97651d28c87a0a071e1c2809d70609d3120ce285b302eb7d52c96906"
|
||||
"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
||||
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
|
@ -1,17 +0,0 @@
|
|||
[package]
|
||||
name = "nano-load-tester"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
clap = "2.29.2"
|
||||
env_logger = "0.5.3"
|
||||
error-chain = "0.11.0"
|
||||
futures = "0.1.17"
|
||||
hyper = "0.11.15"
|
||||
rand = "0.4.2"
|
||||
serde = "1.0.27"
|
||||
serde_derive = "1.0.27"
|
||||
serde_json = "1.0.9"
|
||||
time = "0.1.39"
|
||||
tokio-core = "0.1.12"
|
||||
tokio-process = "0.1.5"
|
|
@ -1,185 +0,0 @@
|
|||
use std::io;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use serde_json;
|
||||
|
||||
use futures::Future;
|
||||
use hyper::client::Connect;
|
||||
|
||||
use tokio_core::reactor::Handle;
|
||||
use tokio_process::{Child, CommandExt};
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
use errors::*;
|
||||
|
||||
use rpc::RpcClient;
|
||||
|
||||
const RPC_PORT_START: u64 = 55000;
|
||||
const PEERING_PORT_START: u64 = 54000;
|
||||
const IPC_PORT_START: u64 = 56000;
|
||||
|
||||
pub fn launch_node_and_rpc(
|
||||
nano_node: &Path,
|
||||
nano_rpc: &Path,
|
||||
tmp_dir: &Path,
|
||||
handle: Handle,
|
||||
i: u64,
|
||||
) -> Result<(Child, Child, RpcClient)> {
|
||||
let data_dir = tmp_dir.join(format!("Nano_load_test_{}", i));
|
||||
match fs::create_dir(&data_dir) {
|
||||
Ok(_) => {}
|
||||
Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {
|
||||
let _ = fs::remove_file(data_dir.join("data.ldb"));
|
||||
let _ = fs::remove_file(data_dir.join("wallets.ldb"));
|
||||
}
|
||||
r => r.chain_err(|| "failed to create nano_node data directory")?,
|
||||
}
|
||||
let peering_port = PEERING_PORT_START + i;
|
||||
let ipc_port = IPC_PORT_START + i;
|
||||
|
||||
let config = json!({
|
||||
"version": "2",
|
||||
"rpc_enable": "false",
|
||||
"rpc": {
|
||||
"version": "1",
|
||||
"enable_sign_hash": "false",
|
||||
"max_work_generate_difficulty": "ffffffffc0000000",
|
||||
"child_process": {
|
||||
"enable": "false"
|
||||
}
|
||||
},
|
||||
"node": {
|
||||
"version": "17",
|
||||
"peering_port": peering_port.to_string(),
|
||||
"bootstrap_fraction_numerator": "1",
|
||||
"receive_minimum": "1000000000000000000000000",
|
||||
"logging": {
|
||||
"version": "7",
|
||||
"ledger": "false",
|
||||
"ledger_duplicate": "false",
|
||||
"vote": "false",
|
||||
"network": "true",
|
||||
"network_message": "false",
|
||||
"network_publish": "false",
|
||||
"network_packet": "false",
|
||||
"network_keepalive": "false",
|
||||
"network_node_id_handshake": "false",
|
||||
"node_lifetime_tracing": "false",
|
||||
"insufficient_work": "true",
|
||||
"log_ipc": "true",
|
||||
"bulk_pull": "false",
|
||||
"work_generation_time": "true",
|
||||
"upnp_details": "false",
|
||||
"timing": "false",
|
||||
"log_to_cerr": "false",
|
||||
"max_size": "134217728",
|
||||
"rotation_size": "4194304",
|
||||
"flush": "true",
|
||||
"min_time_between_output": "5"
|
||||
},
|
||||
"work_peers": "",
|
||||
"preconfigured_peers": "",
|
||||
"preconfigured_representatives": [
|
||||
"xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo"
|
||||
],
|
||||
"online_weight_minimum": "60000000000000000000000000000000000000",
|
||||
"online_weight_quorum": "50",
|
||||
"password_fanout": "1024",
|
||||
"io_threads": "8",
|
||||
"network_threads": "8",
|
||||
"work_threads": "8",
|
||||
"signature_checker_threads": "7",
|
||||
"enable_voting": "true",
|
||||
"bootstrap_connections": "4",
|
||||
"bootstrap_connections_max": "64",
|
||||
"callback_address": "",
|
||||
"callback_port": "0",
|
||||
"callback_target": "",
|
||||
"lmdb_max_dbs": "128",
|
||||
"block_processor_batch_max_time": "5000",
|
||||
"allow_local_peers": "true",
|
||||
"vote_minimum": "1000000000000000000000000000000000",
|
||||
"unchecked_cutoff_time": "14400",
|
||||
"ipc": {
|
||||
"tcp": {
|
||||
"enable": "true",
|
||||
"port": ipc_port.to_string (),
|
||||
"io_timeout": "15"
|
||||
},
|
||||
"local": {
|
||||
"enable": "false",
|
||||
"path": "/tmp/nano",
|
||||
"io_timeout": "15"
|
||||
},
|
||||
},
|
||||
"tcp_client_timeout": "5",
|
||||
"tcp_server_timeout": "30"
|
||||
},
|
||||
"opencl_enable": "false",
|
||||
"opencl": {
|
||||
"platform": "0",
|
||||
"device": "0",
|
||||
"threads": "1048576"
|
||||
}
|
||||
});
|
||||
|
||||
let rpc_port = RPC_PORT_START + i;
|
||||
let rpc_config = json!({
|
||||
"address": "::1",
|
||||
"port": rpc_port.to_string(),
|
||||
"enable_control": "true",
|
||||
"max_json_depth": "20",
|
||||
"version": "1",
|
||||
"process": {
|
||||
"ipc_port": ipc_port.to_string (),
|
||||
"io_threads": "8",
|
||||
"num_ipc_connections": "8"
|
||||
}
|
||||
});
|
||||
|
||||
let config_writer =
|
||||
File::create(data_dir.join("config.json")).chain_err(|| "failed to create config.json")?;
|
||||
serde_json::to_writer_pretty(config_writer, &config)
|
||||
.chain_err(|| "failed to write config.json")?;
|
||||
let child = Command::new(nano_node)
|
||||
.arg("--data_path")
|
||||
.arg(&data_dir)
|
||||
.arg("--daemon")
|
||||
.spawn_async(&handle)
|
||||
.chain_err(|| "failed to spawn nano_node")?;
|
||||
|
||||
let rpc_config_writer =
|
||||
File::create(data_dir.join("rpc_config.json")).chain_err(|| "failed to create rpc_config.json")?;
|
||||
serde_json::to_writer_pretty(rpc_config_writer, &rpc_config)
|
||||
.chain_err(|| "failed to write rpc_config.json")?;
|
||||
let rpc_child = Command::new(nano_rpc)
|
||||
.arg("--data_path")
|
||||
.arg(&data_dir)
|
||||
.arg("--daemon")
|
||||
.spawn_async(&handle)
|
||||
.chain_err(|| "failed to spawn nano_rpc")?;
|
||||
|
||||
let rpc_client = RpcClient::new(
|
||||
handle,
|
||||
format!("http://[::1]:{}/", rpc_port).parse().unwrap(),
|
||||
);
|
||||
Ok((child, rpc_child, rpc_client))
|
||||
}
|
||||
|
||||
pub fn connect_node<C: Connect>(
|
||||
node: &RpcClient<C>,
|
||||
i: u64,
|
||||
) -> Box<Future<Item = (), Error = Error>> {
|
||||
Box::new(
|
||||
node.call::<_, Value>(&json!({
|
||||
"action": "keepalive",
|
||||
"address": "::1",
|
||||
"port": PEERING_PORT_START + i,
|
||||
})).then(|x| x.chain_err(|| "failed to call nano_rpc"))
|
||||
.map(|_| ()),
|
||||
) as _
|
||||
}
|
|
@ -1,559 +0,0 @@
|
|||
#![recursion_limit = "128"]
|
||||
|
||||
use std::process;
|
||||
use std::path::PathBuf;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::collections::HashMap;
|
||||
use std::iter;
|
||||
use std::env;
|
||||
|
||||
extern crate clap;
|
||||
use clap::Arg;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
extern crate futures;
|
||||
use futures::{stream, Future, Stream};
|
||||
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
use serde_json::Value;
|
||||
|
||||
extern crate tokio_core;
|
||||
use tokio_core::reactor::Core;
|
||||
|
||||
extern crate tokio_process;
|
||||
|
||||
extern crate hyper;
|
||||
|
||||
extern crate rand;
|
||||
use rand::Rng;
|
||||
|
||||
extern crate time;
|
||||
|
||||
extern crate env_logger;
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
use errors::*;
|
||||
|
||||
mod rpc;
|
||||
use rpc::{RpcClient, RpcError};
|
||||
|
||||
mod launch_node_and_rpc;
|
||||
|
||||
struct Parameters {
|
||||
node_count: u16,
|
||||
node_path: PathBuf,
|
||||
rpc_path: PathBuf,
|
||||
tmp_dir: PathBuf,
|
||||
send_count: usize,
|
||||
dest_count: usize,
|
||||
simultaneous_process_calls: usize,
|
||||
catch_up_timeout: u64,
|
||||
generate_receives: bool,
|
||||
precompute_blocks: bool,
|
||||
output_stats: bool,
|
||||
}
|
||||
|
||||
// found in secure.cpp
|
||||
const GENESIS_ACCOUNT: &str = "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo";
|
||||
const GENESIS_PRIVKEY: &str = "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4";
|
||||
|
||||
fn run(params: Parameters) -> Result<()> {
|
||||
let output_stats = params.output_stats;
|
||||
macro_rules! tstat {
|
||||
($( $x:tt )*) => {
|
||||
if output_stats {
|
||||
let now = time::now().to_timespec();
|
||||
println!("{}.{:09},{}", now.sec, now.nsec, format_args!( $( $x )* ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if params.dest_count > params.send_count {
|
||||
bail!("send count should be greater than or equal to the destination count")
|
||||
}
|
||||
|
||||
let mut tokio_core = Core::new().chain_err(|| "failed to create tokio Core")?;
|
||||
let mut children = Vec::with_capacity(params.node_count as _);
|
||||
let mut rpc_children = Vec::with_capacity(params.node_count as _);
|
||||
let mut nodes: Vec<RpcClient<_>> = Vec::with_capacity(params.node_count as _);
|
||||
for i in 0..params.node_count {
|
||||
let (child, rpc_child, rpc_client) = launch_node_and_rpc::launch_node_and_rpc(
|
||||
¶ms.node_path,
|
||||
¶ms.rpc_path,
|
||||
¶ms.tmp_dir,
|
||||
tokio_core.handle(),
|
||||
i as _,
|
||||
)?;
|
||||
children.push(child);
|
||||
rpc_children.push(rpc_child);
|
||||
nodes.push(rpc_client);
|
||||
}
|
||||
if nodes.is_empty() {
|
||||
bail!("no nodes spun up");
|
||||
}
|
||||
eprintln!("Waiting for nodes to spin up...");
|
||||
thread::sleep(Duration::from_secs(7));
|
||||
eprintln!("Connecting nodes...");
|
||||
let primary_node = nodes.first().unwrap();
|
||||
for (a, node) in nodes.iter().enumerate() {
|
||||
for b in 0..nodes.len() {
|
||||
if a != b {
|
||||
tokio_core.run(launch_node_and_rpc::connect_node(node, b as _))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
eprintln!("Beginning tests");
|
||||
tstat!("start");
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct AccountInfo {
|
||||
frontier: String,
|
||||
balance: String,
|
||||
block_count: String,
|
||||
}
|
||||
tstat!("genesis_info,start");
|
||||
let genesis_initial = primary_node.call(&json!({
|
||||
"action": "account_info",
|
||||
"account": GENESIS_ACCOUNT,
|
||||
}));
|
||||
let genesis_initial: AccountInfo = tokio_core
|
||||
.run(genesis_initial)
|
||||
.chain_err(|| "failed to get genesis account info")?;
|
||||
tstat!("genesis_info,done");
|
||||
let genesis_initial_balance = genesis_initial.balance;
|
||||
#[derive(Deserialize)]
|
||||
#[allow(dead_code)]
|
||||
struct Account {
|
||||
account: String,
|
||||
private: String,
|
||||
public: String,
|
||||
}
|
||||
tstat!("key_create,start");
|
||||
let dest_accts = stream::iter_ok(0..params.dest_count)
|
||||
.map(|_| {
|
||||
primary_node.call(&json!({
|
||||
"action": "key_create",
|
||||
}))
|
||||
})
|
||||
.buffer_unordered(10) // execute 10 `key_create`s simultaneously
|
||||
.inspect(|_| {
|
||||
tstat!("key_create,progress");
|
||||
})
|
||||
.collect();
|
||||
tstat!("key_create,done");
|
||||
let dest_accts: Vec<Account> = tokio_core
|
||||
.run(dest_accts)
|
||||
.chain_err(|| "failed to generate destination accounts")?;
|
||||
if dest_accts.is_empty() {
|
||||
bail!("no destination accounts generated");
|
||||
}
|
||||
let mut frontiers = HashMap::new();
|
||||
#[derive(Deserialize)]
|
||||
struct BlockInfo {
|
||||
hash: String,
|
||||
block: String,
|
||||
}
|
||||
let mut rng: rand::XorShiftRng = rand::thread_rng().gen();
|
||||
if params.precompute_blocks {
|
||||
frontiers.insert(GENESIS_ACCOUNT, genesis_initial.frontier);
|
||||
let mut last_percent = 0;
|
||||
eprint!("Creating blocks: 00%");
|
||||
tstat!("block_create,start");
|
||||
let mut blocks: Vec<String> = Vec::new();
|
||||
for i in 0..params.send_count {
|
||||
let dest_acct = &rng.choose(&dest_accts).unwrap();
|
||||
// since only `balance - amount` matters, each block spends 1 raw
|
||||
let send_future = primary_node.call(&json!({
|
||||
"action": "block_create",
|
||||
"type": "send",
|
||||
"key": GENESIS_PRIVKEY,
|
||||
"balance": genesis_initial_balance,
|
||||
"amount": i + 1,
|
||||
"destination": dest_acct.account,
|
||||
"previous": frontiers[GENESIS_ACCOUNT],
|
||||
}));
|
||||
// needs to be synchronous because of frontier ordering
|
||||
let send: BlockInfo = tokio_core
|
||||
.run(send_future)
|
||||
.chain_err(|| "failed to create send block")?;
|
||||
tstat!("block_create,progress,send");
|
||||
blocks.push(send.block);
|
||||
frontiers.insert(GENESIS_ACCOUNT, send.hash.clone());
|
||||
if params.generate_receives {
|
||||
let recv_future = if let Some(frontier) = frontiers.get(dest_acct.account.as_str())
|
||||
{
|
||||
primary_node.call(&json!({
|
||||
"action": "block_create",
|
||||
"type": "receive",
|
||||
"key": dest_acct.private,
|
||||
"previous": frontier,
|
||||
"source": send.hash,
|
||||
}))
|
||||
} else {
|
||||
primary_node.call(&json!({
|
||||
"action": "block_create",
|
||||
"type": "open",
|
||||
"key": dest_acct.private,
|
||||
"source": send.hash,
|
||||
"representative": GENESIS_ACCOUNT,
|
||||
}))
|
||||
};
|
||||
let recv: BlockInfo = tokio_core
|
||||
.run(recv_future)
|
||||
.chain_err(|| "failed to create receive block")?;
|
||||
tstat!("block_create,progress,receive");
|
||||
frontiers.insert(&dest_acct.account, recv.hash);
|
||||
blocks.push(recv.block);
|
||||
}
|
||||
let new_percent = (100 * i) / params.send_count;
|
||||
if last_percent == new_percent {
|
||||
continue;
|
||||
}
|
||||
last_percent = new_percent;
|
||||
eprint!("\rCreating blocks: {:02}%", new_percent);
|
||||
}
|
||||
eprintln!("\rCreated blocks ");
|
||||
tstat!("block_create,done");
|
||||
let mut process_calls_completed = 0;
|
||||
last_percent = 0;
|
||||
let n_blocks = blocks.len();
|
||||
eprint!("Primary node processing blocks: 00%");
|
||||
tstat!("process,start");
|
||||
let process = stream::iter_ok(blocks.iter())
|
||||
.map(|block| {
|
||||
primary_node.call::<_, Value>(&json!({
|
||||
"action": "process",
|
||||
"block": block,
|
||||
}))
|
||||
})
|
||||
.buffer_unordered(params.simultaneous_process_calls)
|
||||
.then(|r| match r {
|
||||
Ok(_) => Ok(()),
|
||||
Err(RpcError::RpcError(Value::String(ref s)))
|
||||
if params.simultaneous_process_calls != 1 && s.starts_with("Gap") =>
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
})
|
||||
.inspect(|_| {
|
||||
process_calls_completed += 1;
|
||||
let new_percent = (100 * process_calls_completed) / n_blocks;
|
||||
if last_percent == new_percent {
|
||||
return;
|
||||
}
|
||||
last_percent = new_percent;
|
||||
eprint!("\rPrimary node processing blocks: {:02}%", new_percent);
|
||||
tstat!("process,progress");
|
||||
});
|
||||
tokio_core
|
||||
.run(process.fold((), |_, _| Ok(())))
|
||||
.chain_err(|| "failed to process blocks")?;
|
||||
tstat!("process,done");
|
||||
eprintln!("\rPrimary node processed blocks ");
|
||||
} else {
|
||||
#[derive(Deserialize)]
|
||||
struct WalletInfo {
|
||||
wallet: String,
|
||||
}
|
||||
let wallet = primary_node.call(&json!({
|
||||
"action": "wallet_create",
|
||||
}));
|
||||
let wallet: WalletInfo = tokio_core
|
||||
.run(wallet)
|
||||
.chain_err(|| "failed to create wallet")?;
|
||||
let wallet = wallet.wallet;
|
||||
tstat!("wallet_add_key,start");
|
||||
let add_genesis = primary_node.call::<_, Value>(&json!({
|
||||
"action": "wallet_add",
|
||||
"wallet": wallet,
|
||||
"key": GENESIS_PRIVKEY,
|
||||
}));
|
||||
tokio_core
|
||||
.run(add_genesis)
|
||||
.chain_err(|| "failed to add genesis key to wallet")?;
|
||||
tstat!("wallet_add_key,progress");
|
||||
let add_keys = stream::iter_ok(dest_accts.iter())
|
||||
.map(|acct| {
|
||||
primary_node.call::<_, Value>(&json!({
|
||||
"action": "wallet_add",
|
||||
"wallet": wallet,
|
||||
"key": acct.private,
|
||||
"work": false, // We always manually call `receive`
|
||||
}))
|
||||
})
|
||||
.buffer_unordered(10)
|
||||
.inspect(|_| tstat!("wallet_add_key,progress"));
|
||||
tokio_core
|
||||
.run(add_keys.fold((), |_, _| Ok(())))
|
||||
.chain_err(|| "failed to add keys to wallet")?;
|
||||
tstat!("wallet_add_key,done");
|
||||
let mut send_calls_completed = 0;
|
||||
let mut last_percent = 0;
|
||||
#[derive(Deserialize)]
|
||||
struct TransactionInfo {
|
||||
block: String,
|
||||
}
|
||||
eprint!("\rPrimary node processing transactions: 00%");
|
||||
tstat!("transaction,start");
|
||||
let wallet = wallet.as_str();
|
||||
let dest_accts = dest_accts.as_slice();
|
||||
let params = ¶ms;
|
||||
let stream = stream::iter_ok(0..params.send_count)
|
||||
.map(move |i| {
|
||||
// Make sure that every account is sent a block first, then pick randomly
|
||||
let mut dest_acct = rng.choose(dest_accts).unwrap();
|
||||
if i < params.dest_count {
|
||||
dest_acct = &dest_accts[i];
|
||||
}
|
||||
|
||||
let send_future = primary_node
|
||||
.call::<_, TransactionInfo>(&json!({
|
||||
"action": "send",
|
||||
"wallet": wallet,
|
||||
"source": GENESIS_ACCOUNT,
|
||||
"destination": dest_acct.account,
|
||||
"amount": "1",
|
||||
}))
|
||||
.inspect(move |_| {
|
||||
tstat!("transaction,progress,send");
|
||||
});
|
||||
if params.generate_receives {
|
||||
Box::new(send_future.and_then(move |send| {
|
||||
primary_node
|
||||
.call::<_, TransactionInfo>(&json!({
|
||||
"action": "receive",
|
||||
"wallet": wallet,
|
||||
"account": dest_acct.account,
|
||||
"block": send.block,
|
||||
}))
|
||||
.inspect(move |_| {
|
||||
tstat!("transaction,progress,receive");
|
||||
})
|
||||
})) as Box<Future<Item = TransactionInfo, Error = RpcError>>
|
||||
} else {
|
||||
Box::new(send_future) as Box<Future<Item = TransactionInfo, Error = RpcError>>
|
||||
}
|
||||
})
|
||||
.buffer_unordered(params.simultaneous_process_calls)
|
||||
.inspect(|_| {
|
||||
send_calls_completed += 1;
|
||||
let new_percent = (100 * send_calls_completed) / params.send_count;
|
||||
if last_percent == new_percent {
|
||||
return;
|
||||
}
|
||||
last_percent = new_percent;
|
||||
eprint!(
|
||||
"\rPrimary node processing transactions: {:02}%",
|
||||
new_percent
|
||||
);
|
||||
});
|
||||
tokio_core
|
||||
.run(stream.fold((), |_, _| Ok(())))
|
||||
.chain_err(|| "failed to process transactions")?;
|
||||
eprintln!("\rPrimary node processed transactions ");
|
||||
tstat!("transaction,progress,done");
|
||||
}
|
||||
let broadcasted_at = Instant::now();
|
||||
eprintln!("Waiting for nodes to catch up...");
|
||||
let timeout = Duration::from_secs(params.catch_up_timeout);
|
||||
let mut known_account_info = HashMap::new();
|
||||
tstat!("check,start");
|
||||
for node in &nodes {
|
||||
for (&acct, frontier) in frontiers.iter() {
|
||||
// We only know frontiers if `precompute_blocks` is enabled.
|
||||
loop {
|
||||
if Instant::now() - broadcasted_at > timeout {
|
||||
bail!("timed out while waiting for nodes to catch up");
|
||||
}
|
||||
let acct_info = node.call::<_, AccountInfo>(&json!({
|
||||
"action": "account_info",
|
||||
"account": acct,
|
||||
}));
|
||||
let acct_info = tokio_core
|
||||
.run(acct_info)
|
||||
.chain_err(|| "failed to check genesis account info")?;
|
||||
if &acct_info.frontier == frontier {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
if !frontiers.is_empty() {
|
||||
tstat!("check,progress");
|
||||
}
|
||||
if node as *const _ == primary_node as *const _ {
|
||||
for acct in dest_accts
|
||||
.iter()
|
||||
.map(|a| a.account.as_str())
|
||||
.chain(iter::once(GENESIS_ACCOUNT))
|
||||
{
|
||||
let acct_info = node.call(&json!({
|
||||
"action": "account_info",
|
||||
"account": acct,
|
||||
}));
|
||||
let acct_info: AccountInfo = tokio_core.run(acct_info).chain_err(|| {
|
||||
format!("failed to check account {} info on primary node", acct)
|
||||
})?;
|
||||
known_account_info.insert(acct, acct_info);
|
||||
}
|
||||
} else {
|
||||
for (&acct, acct_info) in known_account_info.iter() {
|
||||
loop {
|
||||
if Instant::now() - broadcasted_at > timeout {
|
||||
bail!("timed out while waiting for nodes to catch up");
|
||||
}
|
||||
let node_acct_info = node.call(&json!({
|
||||
"action": "account_info",
|
||||
"account": acct,
|
||||
}));
|
||||
let node_acct_info = tokio_core.run(node_acct_info);
|
||||
match node_acct_info {
|
||||
Err(RpcError::RpcError(ref s)) if s == "Account not found" => {}
|
||||
Ok(node_acct_info) => if acct_info == &node_acct_info {
|
||||
break;
|
||||
},
|
||||
r => {
|
||||
r.chain_err(|| {
|
||||
format!("failed to check account {} info on secondary node", acct)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
tstat!("check,progress");
|
||||
}
|
||||
tstat!("check,done");
|
||||
eprintln!("Done!");
|
||||
tstat!("done");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let matches = clap::App::new("nano-load-tester")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.arg(
|
||||
Arg::with_name("node_count")
|
||||
.short("n")
|
||||
.long("node-count")
|
||||
.value_name("N")
|
||||
.default_value("10")
|
||||
.help("The number of nodes to spin up"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("tmp_dir")
|
||||
.long("tmp-dir")
|
||||
.value_name("PATH")
|
||||
.help("The path to a temporary directory for nano_node data"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("node_path")
|
||||
.value_name("PATH")
|
||||
.required(true)
|
||||
.help("The path to the nano_node to test"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("rpc_path")
|
||||
.value_name("PATH")
|
||||
.required(true)
|
||||
.help("The path to the nano_rpc to test"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("send_count")
|
||||
.short("s")
|
||||
.long("send-count")
|
||||
.value_name("N")
|
||||
.default_value("2000")
|
||||
.help("How many send blocks to generate"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("destination_count")
|
||||
.short("d")
|
||||
.long("destination-count")
|
||||
.value_name("N")
|
||||
.default_value("2")
|
||||
.help("How many destination accounts to choose between"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("simultaneous_process_calls")
|
||||
.long("simultaneous-process-calls")
|
||||
.value_name("N")
|
||||
.default_value("20")
|
||||
.help("How many `process` or `send` calls to send at a given time"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("catch_up_timeout")
|
||||
.long("catch-up-timeout")
|
||||
.value_name("SECONDS")
|
||||
.default_value("120")
|
||||
.help("The maximum number of seconds to wait for nodes to catch up"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("no_receives")
|
||||
.long("no-receives")
|
||||
.help("Do not generate receives for the generated sends"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("precompute_blocks")
|
||||
.long("precompute-blocks")
|
||||
.help("Use the `block_create` and `process` endpoints to precompute blocks"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("stats")
|
||||
.long("stats")
|
||||
.help("Output stats on how long steps take in CSV format"),
|
||||
)
|
||||
.get_matches();
|
||||
macro_rules! num_arg {
|
||||
($arg:expr) => {
|
||||
match matches.value_of($arg).unwrap().parse() {
|
||||
Ok(n) => n,
|
||||
Err(err) => {
|
||||
eprintln!("Failed to parse {}: {}", $arg, err);
|
||||
process::exit(2);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
let params = Parameters {
|
||||
node_count: num_arg!("node_count"),
|
||||
node_path: matches.value_of("node_path").unwrap().into(),
|
||||
rpc_path: matches.value_of("rpc_path").unwrap().into(),
|
||||
tmp_dir: matches
|
||||
.value_of("tmp_dir")
|
||||
.or(env::var("TMPDIR").ok().as_ref().map(|x| x.as_str()))
|
||||
.unwrap_or("/tmp")
|
||||
.into(),
|
||||
send_count: num_arg!("send_count"),
|
||||
dest_count: num_arg!("destination_count"),
|
||||
simultaneous_process_calls: num_arg!("simultaneous_process_calls"),
|
||||
catch_up_timeout: num_arg!("catch_up_timeout"),
|
||||
generate_receives: !matches.is_present("no_receives"),
|
||||
precompute_blocks: matches.is_present("precompute_blocks"),
|
||||
output_stats: matches.is_present("stats"),
|
||||
};
|
||||
if let Err(ref e) = run(params) {
|
||||
eprintln!("Error: {}", e);
|
||||
for e in e.iter().skip(1) {
|
||||
eprintln!(" caused by: {}", e);
|
||||
}
|
||||
|
||||
if let Some(backtrace) = e.backtrace() {
|
||||
eprintln!("\nBacktrace:\n{:?}", backtrace);
|
||||
}
|
||||
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
use std::fmt;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use futures::future;
|
||||
|
||||
use tokio_core::reactor::Handle;
|
||||
|
||||
use hyper::{self, Request, Uri};
|
||||
use hyper::client::{Connect, HttpConnector};
|
||||
use hyper::header::{ContentLength, ContentType};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use serde_json::{self, Value};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RpcError {
|
||||
Http(hyper::Error),
|
||||
Json(serde_json::Error),
|
||||
/// An error returned from the RPC
|
||||
RpcError(Value),
|
||||
}
|
||||
|
||||
impl fmt::Display for RpcError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
RpcError::Http(ref err) => fmt::Display::fmt(err, f),
|
||||
RpcError::Json(ref err) => fmt::Display::fmt(err, f),
|
||||
RpcError::RpcError(ref val) => if let Some(s) = val.as_str() {
|
||||
fmt::Display::fmt(s, f)
|
||||
} else {
|
||||
fmt::Display::fmt(val, f)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::error::Error for RpcError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
RpcError::Http(_) => "HTTP error",
|
||||
RpcError::Json(_) => "JSON parsing error",
|
||||
RpcError::RpcError(_) => "RPC returned error",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RpcClient<C: Connect = HttpConnector> {
|
||||
http_client: hyper::Client<C>,
|
||||
uri: Uri,
|
||||
}
|
||||
|
||||
impl RpcClient<HttpConnector> {
|
||||
pub fn new(tokio_handle: Handle, rpc_uri: Uri) -> RpcClient<HttpConnector> {
|
||||
RpcClient::from_hyper_client(hyper::Client::new(&tokio_handle), rpc_uri)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Connect> RpcClient<C> {
|
||||
pub fn from_hyper_client(hyper_client: hyper::Client<C>, rpc_uri: Uri) -> RpcClient<C> {
|
||||
RpcClient {
|
||||
http_client: hyper_client,
|
||||
uri: rpc_uri,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call<'a, I: Serialize, O: Deserialize<'a> + 'static>(
|
||||
&self,
|
||||
request: &'a I,
|
||||
) -> Box<Future<Item = O, Error = RpcError>> {
|
||||
let json = match serde_json::to_vec(request).map_err(RpcError::Json) {
|
||||
Ok(json) => json,
|
||||
Err(err) => return Box::new(future::err(err)) as _,
|
||||
};
|
||||
let mut req = Request::new(hyper::Method::Post, self.uri.clone());
|
||||
req.headers_mut().set(ContentType::json());
|
||||
req.headers_mut().set(ContentLength(json.len() as u64));
|
||||
req.set_body(json);
|
||||
Box::new(
|
||||
self.http_client
|
||||
.request(req)
|
||||
.and_then(|res| res.body().concat2())
|
||||
.map_err(RpcError::Http)
|
||||
.and_then(|slice| serde_json::from_slice(&slice).map_err(RpcError::Json))
|
||||
.and_then(|mut json: Value| {
|
||||
if let Some(obj) = json.as_object_mut() {
|
||||
if let Some(err) = obj.remove("error") {
|
||||
return Err(RpcError::RpcError(err));
|
||||
}
|
||||
}
|
||||
O::deserialize(json).map_err(RpcError::Json)
|
||||
}),
|
||||
) as _
|
||||
}
|
||||
}
|
|
@ -31,5 +31,6 @@ target_compile_definitions(core_test
|
|||
PRIVATE
|
||||
-DNANO_VERSION_MAJOR=${CPACK_PACKAGE_VERSION_MAJOR}
|
||||
-DNANO_VERSION_MINOR=${CPACK_PACKAGE_VERSION_MINOR}
|
||||
-DNANO_VERSION_PATCH=${CPACK_PACKAGE_VERSION_PATCH})
|
||||
-DNANO_VERSION_PATCH=${CPACK_PACKAGE_VERSION_PATCH}
|
||||
-DBOOST_PROCESS_SUPPORTED=${BOOST_PROCESS_SUPPORTED})
|
||||
target_link_libraries (core_test node secure gtest libminiupnpc-static Boost::boost)
|
||||
|
|
8
nano/load_test/CMakeLists.txt
Normal file
8
nano/load_test/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
add_executable (load_test
|
||||
entry.cpp)
|
||||
|
||||
target_link_libraries (load_test node secure Boost::boost)
|
||||
|
||||
target_compile_definitions(load_test
|
||||
PRIVATE
|
||||
-DBOOST_PROCESS_SUPPORTED=${BOOST_PROCESS_SUPPORTED})
|
593
nano/load_test/entry.cpp
Normal file
593
nano/load_test/entry.cpp
Normal file
|
@ -0,0 +1,593 @@
|
|||
#include <boost/asio/connect.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/beast/version.hpp>
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <iomanip>
|
||||
#include <nano/core_test/testutil.hpp>
|
||||
#include <nano/node/daemonconfig.hpp>
|
||||
#include <nano/node/testing.hpp>
|
||||
#include <nano/secure/utility.hpp>
|
||||
#include <random>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
void force_nano_test_network ();
|
||||
}
|
||||
|
||||
namespace beast = boost::beast;
|
||||
namespace http = beast::http;
|
||||
namespace net = boost::asio;
|
||||
using tcp = net::ip::tcp;
|
||||
|
||||
#ifndef BOOST_PROCESS_SUPPORTED
|
||||
#error BOOST_PROCESS_SUPPORTED must be set, check configuration
|
||||
#endif
|
||||
|
||||
#if BOOST_PROCESS_SUPPORTED
|
||||
#include <boost/process.hpp>
|
||||
#endif
|
||||
|
||||
constexpr auto rpc_port_start = 60000;
|
||||
constexpr auto peering_port_start = 61000;
|
||||
constexpr auto ipc_port_start = 62000;
|
||||
|
||||
void write_config_files (boost::filesystem::path const & data_path, int index)
|
||||
{
|
||||
nano::daemon_config daemon_config (data_path);
|
||||
nano::jsonconfig json;
|
||||
json.read_and_update (daemon_config, data_path / "config.json");
|
||||
auto node_l = json.get_required_child ("node");
|
||||
node_l.put ("peering_port", peering_port_start + index);
|
||||
auto tcp = node_l.get_required_child ("ipc").get_required_child ("tcp");
|
||||
tcp.put ("enable", true);
|
||||
tcp.put ("port", ipc_port_start + index);
|
||||
json.write (data_path / "config.json");
|
||||
|
||||
nano::rpc_config rpc_config;
|
||||
nano::jsonconfig json1;
|
||||
json1.read_and_update (rpc_config, data_path / "rpc_config.json");
|
||||
json1.put ("port", rpc_port_start + index);
|
||||
json1.put ("enable_control", true);
|
||||
json1.get_required_child ("process").put ("ipc_port", ipc_port_start + index);
|
||||
json1.write (data_path / "rpc_config.json");
|
||||
}
|
||||
|
||||
// Report a failure
|
||||
void fail (boost::system::error_code ec, char const * what)
|
||||
{
|
||||
std::cerr << what << ": " << ec.message () << "\n";
|
||||
}
|
||||
|
||||
class account final
|
||||
{
|
||||
public:
|
||||
std::string private_key;
|
||||
std::string public_key;
|
||||
std::string as_string;
|
||||
};
|
||||
|
||||
class account_info final
|
||||
{
|
||||
public:
|
||||
bool operator== (account_info const & other)
|
||||
{
|
||||
return frontier == other.frontier && block_count == other.block_count && balance == other.balance && error == other.error;
|
||||
}
|
||||
|
||||
std::string frontier;
|
||||
std::string block_count;
|
||||
std::string balance;
|
||||
bool error{ false };
|
||||
};
|
||||
|
||||
class receive_session final : public std::enable_shared_from_this<receive_session>
|
||||
{
|
||||
public:
|
||||
receive_session (boost::asio::io_context & ioc, std::atomic<int> & send_calls_remaining, std::string const & wallet, std::string const & account, std::string const & block, tcp::resolver::results_type const & results) :
|
||||
socket (ioc),
|
||||
send_calls_remaining (send_calls_remaining),
|
||||
wallet (wallet),
|
||||
account (account),
|
||||
block (block),
|
||||
results (results),
|
||||
strand (socket.get_executor ())
|
||||
{
|
||||
}
|
||||
|
||||
void run ()
|
||||
{
|
||||
auto this_l (shared_from_this ());
|
||||
|
||||
boost::asio::async_connect (this_l->socket, this_l->results.cbegin (), this_l->results.cend (), boost::asio::bind_executor (strand, [this_l](boost::system::error_code const & ec, boost::asio::ip::tcp::resolver::iterator) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "connect");
|
||||
}
|
||||
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "receive");
|
||||
request.put ("wallet", this_l->wallet);
|
||||
request.put ("account", this_l->account);
|
||||
request.put ("block", this_l->block);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, request);
|
||||
|
||||
this_l->req.method (http::verb::post);
|
||||
this_l->req.version (11);
|
||||
this_l->req.target ("/");
|
||||
this_l->req.body () = ostream.str ();
|
||||
this_l->req.prepare_payload ();
|
||||
|
||||
http::async_write (this_l->socket, this_l->req, boost::asio::bind_executor (this_l->strand, [this_l](boost::system::error_code ec, std::size_t) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "write");
|
||||
}
|
||||
|
||||
http::async_read (this_l->socket, this_l->buffer, this_l->res, boost::asio::bind_executor (this_l->strand, [this_l](boost::system::error_code ec, std::size_t) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "read");
|
||||
}
|
||||
|
||||
--this_l->send_calls_remaining;
|
||||
|
||||
// Gracefully close the socket
|
||||
this_l->socket.shutdown (tcp::socket::shutdown_both, ec);
|
||||
if (ec && ec != boost::system::errc::not_connected)
|
||||
{
|
||||
return fail (ec, "shutdown");
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
private:
|
||||
tcp::socket socket;
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand;
|
||||
boost::beast::flat_buffer buffer;
|
||||
http::request<http::string_body> req;
|
||||
http::response<http::string_body> res;
|
||||
std::atomic<int> & send_calls_remaining;
|
||||
std::string wallet;
|
||||
std::string account;
|
||||
std::string block;
|
||||
tcp::resolver::results_type const & results;
|
||||
};
|
||||
|
||||
class send_session final : public std::enable_shared_from_this<send_session>
|
||||
{
|
||||
public:
|
||||
send_session (boost::asio::io_context & ioc, std::atomic<int> & send_calls_remaining, std::string const & wallet, std::string const & source, std::string const & destination, tcp::resolver::results_type const & results) :
|
||||
socket (ioc),
|
||||
send_calls_remaining (send_calls_remaining),
|
||||
wallet (wallet),
|
||||
source (source),
|
||||
destination (destination),
|
||||
results (results),
|
||||
strand (socket.get_executor ())
|
||||
{
|
||||
}
|
||||
|
||||
void run ()
|
||||
{
|
||||
auto this_l (shared_from_this ());
|
||||
|
||||
boost::asio::async_connect (this_l->socket, this_l->results.cbegin (), this_l->results.cend (), boost::asio::bind_executor (strand, [this_l](boost::system::error_code const & ec, boost::asio::ip::tcp::resolver::iterator) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "connect");
|
||||
}
|
||||
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "send");
|
||||
request.put ("wallet", this_l->wallet);
|
||||
request.put ("source", this_l->source);
|
||||
request.put ("destination", this_l->destination);
|
||||
request.put ("amount", "1");
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, request);
|
||||
|
||||
this_l->req.method (http::verb::post);
|
||||
this_l->req.version (11);
|
||||
this_l->req.target ("/");
|
||||
this_l->req.body () = ostream.str ();
|
||||
this_l->req.prepare_payload ();
|
||||
|
||||
http::async_write (this_l->socket, this_l->req, boost::asio::bind_executor (this_l->strand, [this_l](boost::system::error_code ec, std::size_t) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "write");
|
||||
}
|
||||
|
||||
http::async_read (this_l->socket, this_l->buffer, this_l->res, boost::asio::bind_executor (this_l->strand, [this_l](boost::system::error_code ec, std::size_t) {
|
||||
if (ec)
|
||||
{
|
||||
return fail (ec, "read");
|
||||
}
|
||||
|
||||
boost::property_tree::ptree json;
|
||||
std::stringstream body (this_l->res.body ());
|
||||
boost::property_tree::read_json (body, json);
|
||||
auto block = json.get<std::string> ("block");
|
||||
|
||||
std::make_shared<receive_session> (this_l->socket.get_io_context (), this_l->send_calls_remaining, this_l->wallet, this_l->destination, block, this_l->results)->run ();
|
||||
|
||||
this_l->socket.shutdown (tcp::socket::shutdown_both, ec);
|
||||
if (ec && ec != boost::system::errc::not_connected)
|
||||
{
|
||||
return fail (ec, "shutdown");
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
private:
|
||||
tcp::socket socket;
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand;
|
||||
boost::beast::flat_buffer buffer;
|
||||
http::request<http::string_body> req;
|
||||
http::response<http::string_body> res;
|
||||
std::atomic<int> & send_calls_remaining;
|
||||
std::string wallet;
|
||||
std::string source;
|
||||
std::string destination;
|
||||
tcp::resolver::results_type const & results;
|
||||
};
|
||||
|
||||
boost::property_tree::ptree rpc_request (boost::property_tree::ptree const & request, boost::asio::io_context & ioc, tcp::resolver::results_type const & results)
|
||||
{
|
||||
tcp::socket socket{ ioc };
|
||||
boost::asio::connect (socket, results.begin (), results.end ());
|
||||
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, request);
|
||||
auto request_string = ostream.str ();
|
||||
|
||||
http::request<http::string_body> req{ http::verb::post, "/", 11, request_string };
|
||||
req.prepare_payload ();
|
||||
|
||||
http::write (socket, req);
|
||||
boost::beast::flat_buffer buffer;
|
||||
|
||||
http::response<boost::beast::http::string_body> res;
|
||||
http::read (socket, buffer, res);
|
||||
|
||||
boost::property_tree::ptree json;
|
||||
std::stringstream body (res.body ());
|
||||
boost::property_tree::read_json (body, json);
|
||||
|
||||
// Gracefully close the socket
|
||||
boost::system::error_code ec;
|
||||
socket.shutdown (tcp::socket::shutdown_both, ec);
|
||||
|
||||
if (ec && ec != boost::system::errc::not_connected)
|
||||
{
|
||||
throw boost::system::system_error{ ec };
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
void keepalive_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results, uint16_t port)
|
||||
{
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "keepalive");
|
||||
request.put ("address", "::1");
|
||||
request.put ("port", port);
|
||||
|
||||
rpc_request (request, ioc, results);
|
||||
}
|
||||
|
||||
account key_create_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results)
|
||||
{
|
||||
std::string request_string;
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "key_create");
|
||||
|
||||
auto json = rpc_request (request, ioc, results);
|
||||
|
||||
account account_l;
|
||||
account_l.private_key = json.get<std::string> ("private");
|
||||
account_l.public_key = json.get<std::string> ("public");
|
||||
account_l.as_string = json.get<std::string> ("account");
|
||||
|
||||
return account_l;
|
||||
}
|
||||
|
||||
std::string wallet_create_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results)
|
||||
{
|
||||
std::string request_string;
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "wallet_create");
|
||||
|
||||
auto json = rpc_request (request, ioc, results);
|
||||
return json.get<std::string> ("wallet");
|
||||
}
|
||||
|
||||
void wallet_add_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results, std::string const & wallet, std::string const & prv_key)
|
||||
{
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "wallet_add");
|
||||
request.put ("wallet", wallet);
|
||||
request.put ("key", prv_key);
|
||||
rpc_request (request, ioc, results);
|
||||
}
|
||||
|
||||
void stop_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results)
|
||||
{
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "stop");
|
||||
rpc_request (request, ioc, results);
|
||||
}
|
||||
|
||||
account_info account_info_rpc (boost::asio::io_context & ioc, tcp::resolver::results_type const & results, std::string const & account)
|
||||
{
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "account_info");
|
||||
request.put ("account", account);
|
||||
|
||||
account_info account_info;
|
||||
auto json = rpc_request (request, ioc, results);
|
||||
|
||||
auto error = json.get_optional<std::string> ("error");
|
||||
if (error)
|
||||
{
|
||||
account_info.error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
account_info.balance = json.get<std::string> ("balance");
|
||||
account_info.block_count = json.get<std::string> ("block_count");
|
||||
account_info.frontier = json.get<std::string> ("frontier");
|
||||
}
|
||||
return account_info;
|
||||
}
|
||||
|
||||
/** This launches a node and fires a lot of send/recieve RPC requests at it (configurable), then other nodes are tested to make sure they observe these blocks as well. */
|
||||
int main (int argc, char * const * argv)
|
||||
{
|
||||
nano::force_nano_test_network ();
|
||||
|
||||
boost::program_options::options_description description ("Command line options");
|
||||
|
||||
// clang-format off
|
||||
description.add_options ()
|
||||
("help", "Print out options")
|
||||
("node_count,n", boost::program_options::value<int> ()->default_value (10), "The number of nodes to spin up")
|
||||
("send_count,s", boost::program_options::value<int> ()->default_value (2000), "How many send blocks to generate")
|
||||
("simultaneous_process_calls", boost::program_options::value<int> ()->default_value (20), "Number of simultaneous rpc sends to do")
|
||||
("destination_count", boost::program_options::value<int> ()->default_value (2), "How many destination accounts to choose between")
|
||||
("node_path", boost::program_options::value<std::string> (), "The path to the nano_node to test")
|
||||
("rpc_path", boost::program_options::value<std::string> (), "The path to do nano_rpc to test");
|
||||
// clang-format on
|
||||
|
||||
boost::program_options::variables_map vm;
|
||||
try
|
||||
{
|
||||
boost::program_options::store (boost::program_options::parse_command_line (argc, argv, description), vm);
|
||||
}
|
||||
catch (boost::program_options::error const & err)
|
||||
{
|
||||
std::cerr << err.what () << std::endl;
|
||||
return 1;
|
||||
}
|
||||
boost::program_options::notify (vm);
|
||||
int result (0);
|
||||
|
||||
auto node_count = vm.find ("node_count")->second.as<int> ();
|
||||
auto destination_count = vm.find ("destination_count")->second.as<int> ();
|
||||
auto send_count = vm.find ("send_count")->second.as<int> ();
|
||||
auto simultaneous_process_calls = vm.find ("simultaneous_process_calls")->second.as<int> ();
|
||||
|
||||
boost::system::error_code err;
|
||||
auto running_executable_filepath = boost::dll::program_location (err);
|
||||
|
||||
auto node_path_it (vm.find ("node_path"));
|
||||
std::string node_path;
|
||||
if (node_path_it != vm.end ())
|
||||
{
|
||||
node_path = node_path_it->second.as<std::string> ();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto node_filepath = running_executable_filepath.parent_path () / "nano_node";
|
||||
if (running_executable_filepath.has_extension ())
|
||||
{
|
||||
node_filepath.replace_extension (running_executable_filepath.extension ());
|
||||
}
|
||||
node_path = node_filepath.string ();
|
||||
}
|
||||
|
||||
auto rpc_path_it (vm.find ("rpc_path"));
|
||||
std::string rpc_path;
|
||||
if (rpc_path_it != vm.end ())
|
||||
{
|
||||
rpc_path = rpc_path_it->second.as<std::string> ();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rpc_filepath = running_executable_filepath.parent_path () / "nano_rpc";
|
||||
if (running_executable_filepath.has_extension ())
|
||||
{
|
||||
rpc_filepath.replace_extension (running_executable_filepath.extension ());
|
||||
}
|
||||
rpc_path = rpc_filepath.string ();
|
||||
}
|
||||
|
||||
nano::network_constants network_constants;
|
||||
|
||||
#if BOOST_PROCESS_SUPPORTED
|
||||
std::vector<std::unique_ptr<boost::process::child>> nodes;
|
||||
std::vector<std::unique_ptr<boost::process::child>> rpc_servers;
|
||||
#else
|
||||
std::vector<std::unique_ptr<std::thread>> nodes;
|
||||
std::vector<std::unique_ptr<std::thread>> rpc_servers;
|
||||
#endif
|
||||
for (auto i = 0; i < node_count; ++i)
|
||||
{
|
||||
auto data_path = nano::unique_path ();
|
||||
boost::filesystem::create_directory (data_path);
|
||||
write_config_files (data_path, i);
|
||||
|
||||
auto current_network = network_constants.get_current_network_as_string ();
|
||||
#if BOOST_PROCESS_SUPPORTED
|
||||
nodes.emplace_back (std::make_unique<boost::process::child> (node_path, "--daemon", "--data_path", data_path.string (), "--network", current_network));
|
||||
rpc_servers.emplace_back (std::make_unique<boost::process::child> (rpc_path, "--daemon", "--data_path", data_path.string (), "--network", current_network));
|
||||
#else
|
||||
auto node_exe_command = boost::str (boost::format ("%1% --daemon --data_path=%2% --network=%3%") % node_path % data_path.string () % current_network);
|
||||
nodes.emplace_back (std::make_unique<std::thread> ([node_exe_command]() {
|
||||
std::system (node_exe_command.c_str ());
|
||||
}));
|
||||
|
||||
auto rpc_exe_command = boost::str (boost::format ("%1% --daemon --data_path=%2% --network=%3%") % rpc_path % data_path.string () % current_network);
|
||||
rpc_servers.emplace_back (std::make_unique<std::thread> ([rpc_exe_command]() {
|
||||
std::system (rpc_exe_command.c_str ());
|
||||
}));
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cout << "Waiting for nodes to spin up..." << std::endl;
|
||||
std::this_thread::sleep_for (std::chrono::seconds (7));
|
||||
std::cout << "Connecting nodes..." << std::endl;
|
||||
|
||||
boost::asio::io_context ioc;
|
||||
tcp::resolver resolver{ ioc };
|
||||
auto const primary_node_results = resolver.resolve ("::1", std::to_string (rpc_port_start));
|
||||
|
||||
for (int i = 0; i < node_count; ++i)
|
||||
{
|
||||
keepalive_rpc (ioc, primary_node_results, peering_port_start + i);
|
||||
}
|
||||
|
||||
std::cout << "Beginning tests" << std::endl;
|
||||
|
||||
// Create keys
|
||||
std::vector<account> destination_accounts;
|
||||
for (int i = 0; i < destination_count; ++i)
|
||||
{
|
||||
destination_accounts.emplace_back (key_create_rpc (ioc, primary_node_results));
|
||||
}
|
||||
|
||||
// Create wallet
|
||||
std::string wallet = wallet_create_rpc (ioc, primary_node_results);
|
||||
|
||||
// Add genesis account to it
|
||||
wallet_add_rpc (ioc, primary_node_results, wallet, nano::test_genesis_key.prv.data.to_string ());
|
||||
|
||||
// Add destination accounts
|
||||
for (auto & account : destination_accounts)
|
||||
{
|
||||
wallet_add_rpc (ioc, primary_node_results, wallet, account.private_key);
|
||||
}
|
||||
|
||||
std::cout << "\rPrimary node processing transactions: 00%";
|
||||
|
||||
std::thread t ([send_count, &destination_accounts, &ioc, &primary_node_results, &wallet, &resolver, &node_count]() {
|
||||
std::random_device rd;
|
||||
std::mt19937 mt (rd ());
|
||||
std::uniform_int_distribution<size_t> dist (0, destination_accounts.size () - 1);
|
||||
|
||||
std::atomic<int> send_calls_remaining{ send_count };
|
||||
|
||||
for (auto i = 0; i < send_count; ++i)
|
||||
{
|
||||
account * destination_account;
|
||||
if (i < destination_accounts.size ())
|
||||
{
|
||||
destination_account = &destination_accounts[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
auto random_account_index = dist (mt);
|
||||
destination_account = &destination_accounts[random_account_index];
|
||||
}
|
||||
|
||||
std::make_shared<send_session> (ioc, send_calls_remaining, wallet, nano::genesis_account.to_account (), destination_account->as_string, primary_node_results)->run ();
|
||||
}
|
||||
|
||||
while (send_calls_remaining != 0)
|
||||
{
|
||||
static int last_percent = 0;
|
||||
auto percent = static_cast<int> (100 * ((send_count - send_calls_remaining) / static_cast<double> (send_count)));
|
||||
|
||||
if (last_percent != percent)
|
||||
{
|
||||
std::cout << "\rPrimary node processing transactions: " << std::setfill ('0') << std::setw (2) << percent << "%";
|
||||
last_percent = percent;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\rPrimary node processed transactions " << std::endl;
|
||||
|
||||
std::cout << "Waiting for nodes to catch up..." << std::endl;
|
||||
|
||||
std::map<std::string, account_info> known_account_info;
|
||||
for (int i = 0; i < destination_accounts.size (); ++i)
|
||||
{
|
||||
known_account_info.emplace (destination_accounts[i].as_string, account_info_rpc (ioc, primary_node_results, destination_accounts[i].as_string));
|
||||
}
|
||||
|
||||
nano::timer<std::chrono::milliseconds> timer;
|
||||
timer.start ();
|
||||
|
||||
for (int i = 1; i < node_count; ++i)
|
||||
{
|
||||
auto const results = resolver.resolve ("::1", std::to_string (rpc_port_start + i));
|
||||
for (auto & account_info : known_account_info)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
auto other_account_info = account_info_rpc (ioc, results, account_info.first);
|
||||
if (!other_account_info.error && account_info.second == other_account_info)
|
||||
{
|
||||
// Found the account in this node
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer.since_start () > std::chrono::seconds (120))
|
||||
{
|
||||
throw std::runtime_error ("Timed out");
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for (std::chrono::seconds (1));
|
||||
}
|
||||
}
|
||||
|
||||
stop_rpc (ioc, results);
|
||||
}
|
||||
|
||||
// Stop main node
|
||||
stop_rpc (ioc, primary_node_results);
|
||||
});
|
||||
nano::thread_runner runner (ioc, simultaneous_process_calls);
|
||||
t.join ();
|
||||
runner.join ();
|
||||
|
||||
#if BOOST_PROCESS_SUPPORTED
|
||||
for (auto & node : nodes)
|
||||
{
|
||||
node->wait ();
|
||||
}
|
||||
for (auto & rpc_server : rpc_servers)
|
||||
{
|
||||
rpc_server->wait ();
|
||||
}
|
||||
#else
|
||||
for (auto & node : nodes)
|
||||
{
|
||||
node->join ();
|
||||
}
|
||||
|
||||
for (auto & rpc_server : rpc_servers)
|
||||
{
|
||||
rpc_server->join ();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::cout << "Done!" << std::endl;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue