diff --git a/Makefile b/Makefile index e16f74598..3524a879f 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ nix-integration-test-upgrade: check-network nix run -f ./default.nix run-integration-tests -c run-integration-tests "pytest -v -m upgrade" nix-integration-test-ledger: check-network - nix run -f ./default.nix run-integration-tests -c run-integration-tests "pytest -v -m ledger" + nix run -f ./default.nix run-integration-tests-zemu -c run-integration-tests "pytest -v -m ledger" nix-integration-test-slow: check-network nix run -f ./default.nix run-integration-tests -c run-integration-tests "pytest -v -m slow" diff --git a/default.nix b/default.nix index e26dae11e..5b70e2866 100644 --- a/default.nix +++ b/default.nix @@ -68,6 +68,7 @@ rec { inherit (pkgs) hermes cosmovisor; chain-maind = build-chain-maind { }; + pystarport = import ./pystarport { inherit pkgs; chaind = "${chain-maind}/bin/chain-maind"; }; chain-maind-testnet = build-chain-maind { network = "testnet"; }; @@ -133,6 +134,8 @@ rec { set -e export PATH=${ci-env}/bin:$PATH export TESTS=${tests_src}/integration_tests + export PYTHONPATH=$PWD/pystarport/proto_python/:$PYTHONPATH + export CHAIN_MAIND="${chain-maind}/bin/chain-maind" # check argument exists, then use it, otherwise use default if [ -z $1 ] then @@ -142,6 +145,24 @@ rec { fi ''; + run-integration-tests-zemu = pkgs.writeShellScriptBin "run-integration-tests" '' + set -e + export PATH=${ci-env}/bin:$PATH + export TESTS=${tests_src}/integration_tests + export PYTHONPATH=$PWD/pystarport/proto_python/:$PYTHONPATH + export CHAIN_MAIND="${chain-maind-zemu}/bin/chain-maind" + echo "CHAIN_MAIND="$CHAIN_MAIND + # check argument exists, then use it, otherwise use default + if [ -z $1 ] + then + pytest -v -m 'not upgrade and not ledger and not slow and not ibc and not byzantine and not gov and not grpc' $TESTS + else + $1 $TESTS + fi + ''; + + + ci-shell = pkgs.mkShell { buildInputs = [ ci-env diff --git a/integration_tests/poetry.lock b/integration_tests/poetry.lock index 0bfd613ce..bb8b3948a 100644 --- a/integration_tests/poetry.lock +++ b/integration_tests/poetry.lock @@ -1,11 +1,3 @@ -[[package]] -name = "apipkg" -version = "1.5" -description = "apipkg: namespace control and lazy-import mechanism" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "appdirs" version = "1.4.4" @@ -24,17 +16,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "20.3.0" +version = "21.2.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] [[package]] name = "bech32" @@ -68,7 +60,7 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "certifi" -version = "2020.12.5" +version = "2021.5.30" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -101,11 +93,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "click" -version = "7.1.2" +version = "8.0.1" description = "Composable command line interface toolkit" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" @@ -158,40 +153,30 @@ gmpy2 = ["gmpy2"] [[package]] name = "execnet" -version = "1.8.0" +version = "1.9.0" description = "execnet: rapid multi-Python deployment" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.dependencies] -apipkg = ">=1.4" - [package.extras] testing = ["pre-commit"] [[package]] name = "fire" version = "0.4.0" -description = "" +description = "A library for automatically generating command line interfaces." category = "main" optional = false python-versions = "*" -develop = false [package.dependencies] six = "*" termcolor = "*" -[package.source] -type = "git" -url = "https://github.com/google/python-fire.git" -reference = "master" -resolved_reference = "c1266d0dbb2114514fcf8be62044344b5a51c733" - [[package]] name = "flake8" -version = "3.9.0" +version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" category = "main" optional = false @@ -243,7 +228,7 @@ flake8 = "*" [[package]] name = "grpcio" -version = "1.37.0" +version = "1.38.0" description = "HTTP/2-based RPC framework" category = "main" optional = false @@ -253,7 +238,7 @@ python-versions = "*" six = ">=1.5.2" [package.extras] -protobuf = ["grpcio-tools (>=1.37.0)"] +protobuf = ["grpcio-tools (>=1.38.0)"] [[package]] name = "hdwallets" @@ -333,7 +318,7 @@ python-versions = "*" [[package]] name = "more-itertools" -version = "8.7.0" +version = "8.8.0" description = "More routines for operating on iterables, beyond itertools" category = "main" optional = false @@ -401,7 +386,7 @@ dev = ["pre-commit", "tox"] [[package]] name = "protobuf" -version = "3.15.8" +version = "3.17.3" description = "Protocol Buffers" category = "main" optional = false @@ -452,18 +437,18 @@ python-versions = ">=3.5" [[package]] name = "pystarport" -version = "0.1.0" -description = "python version of cosmos starport" +version = "0.2.1" +description = "Spawn local devnets for cosmos-sdk chains" category = "main" optional = false -python-versions = "^3.7" +python-versions = "^3.8" develop = false [package.dependencies] bech32 = "^1.1.0" docker = "^4.3.1" durations = "^0.3.3" -fire = "branch master" +fire = "^0.4.0" jsonmerge = "^1.7.0" multitail2 = "^1.5.2" python-dateutil = "^2.8.1" @@ -472,8 +457,10 @@ supervisor = "^4.2.1" tomlkit = "^0.7.0" [package.source] -type = "directory" -url = "../pystarport" +type = "git" +url = "https://github.com/crypto-com/pystarport.git" +reference = "main" +resolved_reference = "0166c278ba6d73d86dbb47a32afb3f853f6be247" [[package]] name = "pytest" @@ -592,7 +579,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] [[package]] name = "six" -version = "1.15.0" +version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false @@ -640,7 +627,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomlkit" -version = "0.7.0" +version = "0.7.2" description = "Style preserving TOML library" category = "main" optional = false @@ -656,7 +643,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "3.7.4.3" +version = "3.10.0.0" description = "Backported and Experimental Type Hints for Python 3.5+" category = "main" optional = false @@ -664,16 +651,16 @@ python-versions = "*" [[package]] name = "urllib3" -version = "1.26.4" +version = "1.26.5" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] +brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "wcwidth" @@ -685,25 +672,18 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "0.58.0" +version = "1.1.0" description = "WebSocket client for Python with low level API options" category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -six = "*" +python-versions = ">=3.6" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "e2408d19e6f0efc91d6cca94b4c593a13c216138554b57d745a8d9358f51e1f0" +content-hash = "fd736ed50bcd1ee8052f47edcb712a7adcfe64b186d6d7bcdf4041ca9b56c257" [metadata.files] -apipkg = [ - {file = "apipkg-1.5-py2.py3-none-any.whl", hash = "sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c"}, - {file = "apipkg-1.5.tar.gz", hash = "sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6"}, -] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, @@ -713,8 +693,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, - {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, + {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, + {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] bech32 = [ {file = "bech32-1.1.0-py3-none-any.whl", hash = "sha256:5dde0114268ce7f12057dccd0bde51e44a50106231a8b127807d3aeca85f51e6"}, @@ -724,8 +704,8 @@ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] certifi = [ - {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, - {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, + {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, + {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, ] chainlibpy = [ {file = "chainlibpy-1.0.1.tar.gz", hash = "sha256:4e2602dbc62ebf7ed8d5410eb1ff0140478ef093456c4f4ce9894b4f190a90d4"}, @@ -735,11 +715,12 @@ chardet = [ {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] docker = [ {file = "docker-4.4.4-py2.py3-none-any.whl", hash = "sha256:f3607d5695be025fa405a12aca2e5df702a57db63790c73b927eb6a94aac60af"}, @@ -753,16 +734,19 @@ ecdsa = [ {file = "ecdsa-0.16.1.tar.gz", hash = "sha256:cfc046a2ddd425adbd1a78b3c46f0d1325c657811c0f45ecc3a0a6236c1e50ff"}, ] execnet = [ - {file = "execnet-1.8.0-py2.py3-none-any.whl", hash = "sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac"}, - {file = "execnet-1.8.0.tar.gz", hash = "sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4"}, + {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, + {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, +] +fire = [ + {file = "fire-0.4.0.tar.gz", hash = "sha256:c5e2b8763699d1142393a46d0e3e790c5eb2f0706082df8f647878842c216a62"}, ] -fire = [] flake8 = [ - {file = "flake8-3.9.0-py2.py3-none-any.whl", hash = "sha256:12d05ab02614b6aee8df7c36b97d1a3b2372761222b19b58621355e82acddcff"}, - {file = "flake8-3.9.0.tar.gz", hash = "sha256:78873e372b12b093da7b5e5ed302e8ad9e988b38b063b61ad937f26ca58fc5f0"}, + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] flake8-black = [ {file = "flake8-black-0.2.1.tar.gz", hash = "sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"}, + {file = "flake8_black-0.2.1-py3-none-any.whl", hash = "sha256:941514149cb8b489cb17a4bb1cf18d84375db3b34381bb018de83509437931a0"}, ] flake8-isort = [ {file = "flake8-isort-4.0.0.tar.gz", hash = "sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9"}, @@ -773,56 +757,57 @@ flake8-polyfill = [ {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, ] grpcio = [ - {file = "grpcio-1.37.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:8a0517e7a6784439a3730e50597bd64debf776692adea3c18f869a36454952e1"}, - {file = "grpcio-1.37.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96ca74522bcd979856d359fcca3128f760c69885d264dc22044fd1a468e0eb68"}, - {file = "grpcio-1.37.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3da2b0b8afe3ef34c9e2f90329b1f170fc50db5c4d0bbe986946caa659e5ed17"}, - {file = "grpcio-1.37.0-cp27-cp27m-win32.whl", hash = "sha256:0634cd805c6725ab71bebaf3370da0e5d32339c26eb1b6ad0f73d64224e19ddf"}, - {file = "grpcio-1.37.0-cp27-cp27m-win_amd64.whl", hash = "sha256:fe14c86c58190463f6e714637bba366874ca1e518ff1f82723d90765e6e39288"}, - {file = "grpcio-1.37.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:14d7a15030a3f72cfd16dde8018d9f0e29e3f52cb566506dc942220b69b65de8"}, - {file = "grpcio-1.37.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:9d389f4e008edbd91082baff37507bbf4b25afd6c239c8070071f8936466a374"}, - {file = "grpcio-1.37.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:a8b0914e6ac8987b8f59fcfb79519c5ce8df279b19d1c88bda2fc6e147821217"}, - {file = "grpcio-1.37.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:aaf44d496fe53ca1414677cab73b7935d01006f0b8ab4a32ab18704643a80ab5"}, - {file = "grpcio-1.37.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:fb6588a47d096cdaa0815d108b714d3e273361bfe03bc47725ddb1fdeaa56061"}, - {file = "grpcio-1.37.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:9b872b6c8ab618caa9bdee871c51021c7cc4890c141e7ee7bb6b923174bb299a"}, - {file = "grpcio-1.37.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:810d488804291f22cb696692cfddf75b12bbc9d34beca0159d99103286ac0091"}, - {file = "grpcio-1.37.0-cp35-cp35m-win32.whl", hash = "sha256:55fbdb9a2f81b28bd15af5c6e6669a2c8bb0bdb2add74c8818f9593a7428a164"}, - {file = "grpcio-1.37.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fa6cfecbafbab8c4a229c42787b02cf58d0f128ad43c27b89c4df603b66d7f3c"}, - {file = "grpcio-1.37.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:b36eeb8a29f214f876ddda563990267a8b35d0a6da587edfa97effa4cdf6e5bd"}, - {file = "grpcio-1.37.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:a89b5d2f64d588b46a8b77c04ada4c68ee1cfd0b7a148ff9108d72eefdc9b363"}, - {file = "grpcio-1.37.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:e0169f550dc9ba88da0bb60b8198437d9bd0e8600d600e3569cd3ba7d2ce0bc7"}, - {file = "grpcio-1.37.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:4408b2732fdf93f735ecb059193219528981d27483feaa822970226d5c66c143"}, - {file = "grpcio-1.37.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:5784d1e4877345efb6655f6851809441478769558565d8291a54e1bd3f19548b"}, - {file = "grpcio-1.37.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:96e3d85eb63d144656611eef4683f5b4003e1deec93bc2d6cbc5cf330f275a7e"}, - {file = "grpcio-1.37.0-cp36-cp36m-win32.whl", hash = "sha256:e1a5322d63346afdda8ad7ff8cf9933a0ab029546395eae31af7cd27ef75e47b"}, - {file = "grpcio-1.37.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5e11b7176e7c14675868b7c46b7aa2da0b184cf7c189348f3ad7c98829de07be"}, - {file = "grpcio-1.37.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:6c2798eaef4eebcf3f9d62b49652bc1110787c684861605d20fec842580f6cee"}, - {file = "grpcio-1.37.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:3e541240650f9173b4891f3e252234976199e487b9bd771e4f082403db50130d"}, - {file = "grpcio-1.37.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:b4f3ddfed733264c4f6431302e5fbafdd9c03f166b98b04d16a058fae3101a5d"}, - {file = "grpcio-1.37.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f16e40ea37600fe21b51651617867c46d26dcb3f25a5912b7e61c7199b3f5a9f"}, - {file = "grpcio-1.37.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b897b825fb464c940001a2cc1d631f418f5b071ccff64647148dbf99c775b98b"}, - {file = "grpcio-1.37.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:5e598af1d64ece6a91797b2dcacaf2d537ffb1c0075ecd184c62976068ce1f09"}, - {file = "grpcio-1.37.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:1a167d39b1db6e1b29653d69938ff79936602e95863db897ff9eeab81366b304"}, - {file = "grpcio-1.37.0-cp37-cp37m-win32.whl", hash = "sha256:c4f71341c20327bda9f8c28c35d1475af335bb27e591e7f6409d493b49e06223"}, - {file = "grpcio-1.37.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e86acc1462bc796df672568492d24c6b4e7692e3f58b873d56b215dc65553ae1"}, - {file = "grpcio-1.37.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:28f94700775ceca8820fa2c141501ec713e821de7362b966f8d7bf4d8e1eb93a"}, - {file = "grpcio-1.37.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ca5c96c61289c001b9bcd607dcc1df3060eb8cc13088baf8a6e13268e4879a1f"}, - {file = "grpcio-1.37.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:06cae65dc4557a445748092a61f2adb425ee472088a7e39826369f1f0ae9ffea"}, - {file = "grpcio-1.37.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6986d58240addd69e001e2e0e97c4b198370dd575162ab4bb1e3ea3816103e75"}, - {file = "grpcio-1.37.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:606f0bbfac3860cb6f23f8ebabb974c14db8797317a86d6df063b132f64318f9"}, - {file = "grpcio-1.37.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:1c611a4d137a40f8a6803933dd77ab43f04cc54c27fb0e07483fd37b70e7dae6"}, - {file = "grpcio-1.37.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:3acfb47d930daec7127a7bc27a7e9c1c276d5e4ae3d2b04a4c7a33432712c811"}, - {file = "grpcio-1.37.0-cp38-cp38-win32.whl", hash = "sha256:575b49cbdd7286df9f77451709060a4a311a9c8767e89cf4e28d3b3200893de4"}, - {file = "grpcio-1.37.0-cp38-cp38-win_amd64.whl", hash = "sha256:04582b260ff0c953011819b1964e875139a7a43adb84621d3ab57f66d0f3d04e"}, - {file = "grpcio-1.37.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:00f0acc463d9e6b1e74e71ce516c8cabd053619d08dd81765eb573492811de54"}, - {file = "grpcio-1.37.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:4eb3907fda03eda8bdb7d666f5371b6500a9054f355a547961da1ee231d2d6aa"}, - {file = "grpcio-1.37.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3eecf543aa66f7d8304f82854132df6116476279a8e3ba0665c5d93f1ef622de"}, - {file = "grpcio-1.37.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:91f91388e6f72a5d15161124458ad62387470f3a0a16b488db169232f79dd4d2"}, - {file = "grpcio-1.37.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:efb928f1a3fd5889b9045c323077d2696937cf9cdb7d2e60b90caa7da5bd1ce9"}, - {file = "grpcio-1.37.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:93d990885d392f564ef95a97e0d6936cb09ee404418e8c986835a4d1786b882d"}, - {file = "grpcio-1.37.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ebbb2796ec138cb56373f328f5046ccb9e591046cd8aaccbb8af5bfc397d8b53"}, - {file = "grpcio-1.37.0-cp39-cp39-win32.whl", hash = "sha256:adfef1a3994220bd39e5e2dd57714ca94c4c38c9015f2812a0b09b39f86ddbe0"}, - {file = "grpcio-1.37.0-cp39-cp39-win_amd64.whl", hash = "sha256:df142d51d7de3f8d13aaa78f7ddc7d74088226f92ec5aae8d98d8ae5d328f74b"}, - {file = "grpcio-1.37.0.tar.gz", hash = "sha256:b3ce16aa91569760fdabd77ca901b2288152eb16941d28edd9a3a75a0c4a8a85"}, + {file = "grpcio-1.38.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:db01eaea57e7a1898c69271e35a84341cf8150cfdec5f0411eddcfb65b5f590e"}, + {file = "grpcio-1.38.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:f6f6d51c9efbfe56af9eb9eeb4881cad1b869e4c0e2a32c1d345897fd0979ee3"}, + {file = "grpcio-1.38.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7466eef3b57b5ac8c7585251b26b917b093ab015750bf98aab4e0836c39e2a2b"}, + {file = "grpcio-1.38.0-cp27-cp27m-win32.whl", hash = "sha256:604da72df5bece8844a15990ce0b3f2f8c5243a1333d3dcc02371048bf6f9269"}, + {file = "grpcio-1.38.0-cp27-cp27m-win_amd64.whl", hash = "sha256:924552099365ea1dd32237dc161849452cd567d931efc57e8427260d8f0eacdb"}, + {file = "grpcio-1.38.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f19bd4b5bcf88ee059f478c4ab46a1607f09835587750294038fbd0120f1a9dc"}, + {file = "grpcio-1.38.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c47e85eae34af5d17d1c2007a1f0b13a0293d4b7a6d8c8ae23761d718293803e"}, + {file = "grpcio-1.38.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:d631304e66c908d5d2d1a3cc9c02d372d2f8bed8c3632902d6f3f77d7ca34ac2"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4a1dd16ccf76ddc18c1cde900049c04ed996e6c02e0588d88d06396c398e6023"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:32067791bd56a13614399f1994454afea9e2475019fcabc4abd3112f09892005"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:0247b045feb7b138754c91efcca9ea7f7d2cc9f0bd2cc73f6588c523f38873c3"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:07abf6b36c138bf247cef7ac0bad9f8ab1c8242f7c1302af23bb8e6877d08163"}, + {file = "grpcio-1.38.0-cp35-cp35m-win32.whl", hash = "sha256:2c26cb7566e8942542ff1aee71f10ed35e2f9ee95c2f27179b198af0727fbebb"}, + {file = "grpcio-1.38.0-cp35-cp35m-win_amd64.whl", hash = "sha256:e72dd202c982a5922c3b846976cae3b699e3fa8d2355d9d5bad119d066cf23ee"}, + {file = "grpcio-1.38.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:34fb08d46a70750bef6566c9556a16b98e08af6345a3bad6574477eb0b08c3dd"}, + {file = "grpcio-1.38.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:1d157a2ac6632d31a3ff21f56bbe73420e1d7a21e4fe89d8c7ac792b79c1a589"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3cacfee78310b5a89769b2fac20b8cd723470130f5b1ba0c960da8db39e74a97"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:e83ab148911e6c8ae4ec5e1334e6d800c6b84c432b92eb0ebf0808087117cb39"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:a836f21a1d08d28c8344e149b28729649ff4732c318a59a3628451bbd6c3c9ac"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b4cd8fb4e3725e8852b1da734904edb3579c76660ae26a72283ac580779e5bf0"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:d3566acd87a65a0bc93875125a7064293ab2b6ffb9327333030939681d269f4f"}, + {file = "grpcio-1.38.0-cp36-cp36m-win32.whl", hash = "sha256:f2c4ff0e8c98418c5d55c28ba4ff954e3a5d3c723af5008e8d3ddeae8f0ecb41"}, + {file = "grpcio-1.38.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9a2216df1be9fdbc3c1ebd3c5184d1ef4afb387c29224fce00346b9ddec7c7e3"}, + {file = "grpcio-1.38.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:9f1747b81d44daed0649ff10395b58c4f29b03139a628afeb058f3e942ba6893"}, + {file = "grpcio-1.38.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:ac05434a7a7f444b2ddd109d72f87f4704364be159aea42a04bd6ea2ba6e10e4"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:a4789014f9d9e9ff29551314a004266b1ac90225c8a009dc87947aaf823fd83c"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e3072b9ebb573fe1f6757a55b610e4975979d2d58247cbe18ff4385f5aaa81a5"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:7b74c48b2e41dd506f889a4a9974d40b3eead965b0fd2e0b1d55a9b3c0e3bc6e"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:291dcde4139bc25629de6a743cfcc0ca861e289e3547421ecd2273b51d95b8e1"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:0ab78d4c16d7f3924718711689f5e301aec52cfcf38eb4143bed0f74b7c4fd10"}, + {file = "grpcio-1.38.0-cp37-cp37m-win32.whl", hash = "sha256:10a6c62e0cddd456db91f9f04b53a8cccf67d86d7ca814d989423939099c2723"}, + {file = "grpcio-1.38.0-cp37-cp37m-win_amd64.whl", hash = "sha256:be83ca2d24321c8bf6516b9cd1064da15ac3ff3978c6c502643be114e2a54af2"}, + {file = "grpcio-1.38.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:897bcd54890e6ec6359063affb35e19a61a58ba37bc61c9e8ac6b464b854233e"}, + {file = "grpcio-1.38.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:f8dd51b05e7fde843d7a3140b058f02801fbec5784a036d5f6abb374450d4608"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:277faad1d8d462bd1b986f43a47a2c2fe795b2e0de72c9318e11826d921e665a"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a0d7c88b4cf9748147cd6c16e14569a124b683a3eb5d7787f43eb9d48cf86755"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2736b109ec5bd9fcf580bf871b5fd4f136c6ae9728407f344a3c64ad87bb6519"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:cbd2754da81bf5f18454c7808b4afe5b57c6736955a742fb599b32b6353fe99f"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a8f9fcf5623282e4804595166a4ee1401cf4ccfc16fe84bb69e1eb23ffd836ac"}, + {file = "grpcio-1.38.0-cp38-cp38-win32.whl", hash = "sha256:1c11041ecb69d962d49e8a38a35736cdc6fc74230867b5f0ac6138770387a950"}, + {file = "grpcio-1.38.0-cp38-cp38-win_amd64.whl", hash = "sha256:1d212af1008bdbfd4b8a287e17a8e63e14d72ac450475307452f20c1bbb6bae4"}, + {file = "grpcio-1.38.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:8c4f39ad529fb4a33cd6e58d1d860c3b583902208547614b4b5b75fc306f13f6"}, + {file = "grpcio-1.38.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:f9b3678920017842a1b576de3524ecf8f6a2bf4b39f86fb25b870693141e0584"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:1e88a8d5d961df958362f61b1b79ad3981a8b051f99224717b09308546298902"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6461d69a8ae20e7abce4c6d9cc2603e9f16f4d6b64865eddd0e664127349c04d"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:cd220606259f8aa2403bc0f4a4483bae5e36be879364ca3e256f0304ac44f575"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:25028420d004fe33d64015f5d4d97207c53530acdb493310e217fac76dcd2513"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:b86a1b0654804b5f2248d9262c77a9d5f19882481fc21df53eb2823d0875b86d"}, + {file = "grpcio-1.38.0-cp39-cp39-win32.whl", hash = "sha256:752593a275e26ef250dc4d93a6f7917dd9986396b41eabcc114b0e0315ec1bf6"}, + {file = "grpcio-1.38.0-cp39-cp39-win_amd64.whl", hash = "sha256:6824567e2372dde1bd70214427d23b709d09f1a02a552133d1e0f504b616c84e"}, + {file = "grpcio-1.38.0.tar.gz", hash = "sha256:abbf9c8c3df4d5233d5888c6cfa85c1bb68a6923749bd4dd1abc6e1e93986f17"}, ] hdwallets = [ {file = "hdwallets-0.1.2-py3-none-any.whl", hash = "sha256:455b55b061f2b356a93e305b0c2263a6007d2ed45e48749975f09308499a2fdb"}, @@ -852,8 +837,8 @@ mnemonic = [ {file = "mnemonic-0.19.tar.gz", hash = "sha256:4e37eb02b2cbd56a0079cabe58a6da93e60e3e4d6e757a586d9f23d96abea931"}, ] more-itertools = [ - {file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"}, - {file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"}, + {file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"}, + {file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"}, ] multitail2 = [ {file = "multitail2-1.5.2.tar.gz", hash = "sha256:7086598c1cd1901ec79ce3c1eda9420299e3778f6c18464958c1f74ffd1950c9"}, @@ -879,26 +864,29 @@ pluggy = [ {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] protobuf = [ - {file = "protobuf-3.15.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fad4f971ec38d8df7f4b632c819bf9bbf4f57cfd7312cf526c69ce17ef32436a"}, - {file = "protobuf-3.15.8-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f17b352d7ce33c81773cf81d536ca70849de6f73c96413f17309f4b43ae7040b"}, - {file = "protobuf-3.15.8-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:4a054b0b5900b7ea7014099e783fb8c4618e4209fffcd6050857517b3f156e18"}, - {file = "protobuf-3.15.8-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:efa4c4d4fc9ba734e5e85eaced70e1b63fb3c8d08482d839eb838566346f1737"}, - {file = "protobuf-3.15.8-cp35-cp35m-win32.whl", hash = "sha256:07eec4e2ccbc74e95bb9b3afe7da67957947ee95bdac2b2e91b038b832dd71f0"}, - {file = "protobuf-3.15.8-cp35-cp35m-win_amd64.whl", hash = "sha256:f9cadaaa4065d5dd4d15245c3b68b967b3652a3108e77f292b58b8c35114b56c"}, - {file = "protobuf-3.15.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2dc0e8a9e4962207bdc46a365b63a3f1aca6f9681a5082a326c5837ef8f4b745"}, - {file = "protobuf-3.15.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f80afc0a0ba13339bbab25ca0409e9e2836b12bb012364c06e97c2df250c3343"}, - {file = "protobuf-3.15.8-cp36-cp36m-win32.whl", hash = "sha256:c5566f956a26cda3abdfacc0ca2e21db6c9f3d18f47d8d4751f2209d6c1a5297"}, - {file = "protobuf-3.15.8-cp36-cp36m-win_amd64.whl", hash = "sha256:dab75b56a12b1ceb3e40808b5bd9dfdaef3a1330251956e6744e5b6ed8f8830b"}, - {file = "protobuf-3.15.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3053f13207e7f13dc7be5e9071b59b02020172f09f648e85dc77e3fcb50d1044"}, - {file = "protobuf-3.15.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1f0b5d156c3df08cc54bc2c8b8b875648ea4cd7ebb2a9a130669f7547ec3488c"}, - {file = "protobuf-3.15.8-cp37-cp37m-win32.whl", hash = "sha256:90270fe5732c1f1ff664a3bd7123a16456d69b4e66a09a139a00443a32f210b8"}, - {file = "protobuf-3.15.8-cp37-cp37m-win_amd64.whl", hash = "sha256:f42c2f5fb67da5905bfc03733a311f72fa309252bcd77c32d1462a1ad519521e"}, - {file = "protobuf-3.15.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6077db37bfa16494dca58a4a02bfdacd87662247ad6bc1f7f8d13ff3f0013e1"}, - {file = "protobuf-3.15.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:510e66491f1a5ac5953c908aa8300ec47f793130097e4557482803b187a8ee05"}, - {file = "protobuf-3.15.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5ff9fa0e67fcab442af9bc8d4ec3f82cb2ff3be0af62dba047ed4187f0088b7d"}, - {file = "protobuf-3.15.8-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1c0e9e56202b9dccbc094353285a252e2b7940b74fdf75f1b4e1b137833fabd7"}, - {file = "protobuf-3.15.8-py2.py3-none-any.whl", hash = "sha256:a0a08c6b2e6d6c74a6eb5bf6184968eefb1569279e78714e239d33126e753403"}, - {file = "protobuf-3.15.8.tar.gz", hash = "sha256:0277f62b1e42210cafe79a71628c1d553348da81cbd553402a7f7549c50b11d0"}, + {file = "protobuf-3.17.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ab6bb0e270c6c58e7ff4345b3a803cc59dbee19ddf77a4719c5b635f1d547aa8"}, + {file = "protobuf-3.17.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:13ee7be3c2d9a5d2b42a1030976f760f28755fcf5863c55b1460fd205e6cd637"}, + {file = "protobuf-3.17.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:1556a1049ccec58c7855a78d27e5c6e70e95103b32de9142bae0576e9200a1b0"}, + {file = "protobuf-3.17.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f0e59430ee953184a703a324b8ec52f571c6c4259d496a19d1cabcdc19dabc62"}, + {file = "protobuf-3.17.3-cp35-cp35m-win32.whl", hash = "sha256:a981222367fb4210a10a929ad5983ae93bd5a050a0824fc35d6371c07b78caf6"}, + {file = "protobuf-3.17.3-cp35-cp35m-win_amd64.whl", hash = "sha256:6d847c59963c03fd7a0cd7c488cadfa10cda4fff34d8bc8cba92935a91b7a037"}, + {file = "protobuf-3.17.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:145ce0af55c4259ca74993ddab3479c78af064002ec8227beb3d944405123c71"}, + {file = "protobuf-3.17.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ce4d8bf0321e7b2d4395e253f8002a1a5ffbcfd7bcc0a6ba46712c07d47d0b4"}, + {file = "protobuf-3.17.3-cp36-cp36m-win32.whl", hash = "sha256:7a4c97961e9e5b03a56f9a6c82742ed55375c4a25f2692b625d4087d02ed31b9"}, + {file = "protobuf-3.17.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a22b3a0dbac6544dacbafd4c5f6a29e389a50e3b193e2c70dae6bbf7930f651d"}, + {file = "protobuf-3.17.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ffea251f5cd3c0b9b43c7a7a912777e0bc86263436a87c2555242a348817221b"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9b7a5c1022e0fa0dbde7fd03682d07d14624ad870ae52054849d8960f04bc764"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8727ee027157516e2c311f218ebf2260a18088ffb2d29473e82add217d196b1c"}, + {file = "protobuf-3.17.3-cp37-cp37m-win32.whl", hash = "sha256:14c1c9377a7ffbeaccd4722ab0aa900091f52b516ad89c4b0c3bb0a4af903ba5"}, + {file = "protobuf-3.17.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c56c050a947186ba51de4f94ab441d7f04fcd44c56df6e922369cc2e1a92d683"}, + {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"}, + {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"}, + {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"}, + {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"}, ] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, @@ -1033,8 +1021,8 @@ requests = [ {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] supervisor = [ {file = "supervisor-4.2.2-py2.py3-none-any.whl", hash = "sha256:4adf63c8f18cf42313171ce06a73c9ae2c5e88ef27c2bb0de3b8405368595c04"}, @@ -1052,8 +1040,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomlkit = [ - {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"}, - {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"}, + {file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, + {file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, ] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, @@ -1088,19 +1076,19 @@ typed-ast = [ {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ - {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, - {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, - {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, + {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, + {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, + {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, ] urllib3 = [ - {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, - {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, + {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"}, + {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] websocket-client = [ - {file = "websocket_client-0.58.0-py2.py3-none-any.whl", hash = "sha256:44b5df8f08c74c3d82d28100fdc81f4536809ce98a17f0757557813275fbb663"}, - {file = "websocket_client-0.58.0.tar.gz", hash = "sha256:63509b41d158ae5b7f67eb4ad20fecbb4eee99434e73e140354dc3ff8e09716f"}, + {file = "websocket-client-1.1.0.tar.gz", hash = "sha256:b68e4959d704768fa20e35c9d508c8dc2bbc041fd8d267c0d7345cffe2824568"}, + {file = "websocket_client-1.1.0-py2.py3-none-any.whl", hash = "sha256:e5c333bfa9fa739538b652b6f8c8fc2559f1d364243c8a689d7c0e1d41c2e611"}, ] diff --git a/integration_tests/pyproject.toml b/integration_tests/pyproject.toml index 08d1487af..93a3af1ef 100644 --- a/integration_tests/pyproject.toml +++ b/integration_tests/pyproject.toml @@ -18,7 +18,7 @@ protobuf = "^3.13.0" grpcio = "^1.33.2" PyYAML = "^5.3.1" python-dateutil = "^2.8.1" -pystarport = {path = "../pystarport"} +pystarport = "^0.2.1" chainlibpy = "^1.0.0" [tool.poetry.dev-dependencies] diff --git a/integration_tests/test_basic.py b/integration_tests/test_basic.py index f3f605f19..e28af0e06 100644 --- a/integration_tests/test_basic.py +++ b/integration_tests/test_basic.py @@ -90,5 +90,5 @@ def test_statesync(cluster): cluster.supervisor.startProcess(f"{cluster.chain_id}-node{i}") # discovery_time is set to 5 seconds, add extra seconds for processing - wait_for_block(cluster.cosmos_cli(i), 5) + wait_for_block(cluster.cosmos_cli(i), 10) print("succesfully syncing") diff --git a/makeproto.sh b/makeproto.sh index 4d38d127a..c0dbfae24 100755 --- a/makeproto.sh +++ b/makeproto.sh @@ -1,3 +1,2 @@ #!/bin/bash -cd ./pystarport/pystarport -nix-shell . --run "" +nix-shell proto.nix --run "" diff --git a/pystarport/pystarport/default.nix b/proto.nix similarity index 85% rename from pystarport/pystarport/default.nix rename to proto.nix index 4477cb87d..121d803c9 100644 --- a/pystarport/pystarport/default.nix +++ b/proto.nix @@ -1,4 +1,4 @@ -{ pkgs ? import ../../nix { }, commit ? "" }: +{ pkgs ? import ./nix { }, commit ? "" }: with pkgs; pkgs.mkShell { buildInputs = [ @@ -8,5 +8,6 @@ pkgs.mkShell { git ]; shellHook = '' + cd ./pystarport ./convert.sh ''; } diff --git a/pystarport/.gitignore b/pystarport/.gitignore deleted file mode 100644 index 4d4c0d650..000000000 --- a/pystarport/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -__pycache__ -/dist -/*.egg-info -/data diff --git a/pystarport/LICENSE b/pystarport/LICENSE deleted file mode 100644 index 0cb27a607..000000000 --- a/pystarport/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ - Copyright 2021, CRO Protocol Labs ("Crypto.org"). - Copyright 2018 - 2020, Foris Limited ("Crypto.com"). - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/pystarport/README.md b/pystarport/README.md deleted file mode 100644 index f86d918c4..000000000 --- a/pystarport/README.md +++ /dev/null @@ -1,230 +0,0 @@ -pystarport is like a [cosmos starport](https://github.com/tendermint/starport) -without the scaffolding feature. it's mainly used for development and testing. It's developed for the Crypto.org Chain, but -it can also be used for any cosmos-sdk based projects. - -## Configuration - -a typical configuration for a devnet is like this: - -``` -chainmaind: - cmd: chain-maind # chain binary to use, optional - validators: # genesis validators - - coins: 10cro - staked: 10cro - - coins: 10cro - staked: 10cro - accounts: # genesis accounts - - name: community - coins: 100cro - - name: ecosystem - coins: 200cro - - name: reserve - coins: 200cro - vesting: "1d" - - name: launch - coins: 100cro - genesis: # patch genesis states - app_state: - staking: - params: - unbonding_time: "10s" -``` - -The `validators` section defines how many nodes to run, for each node, a home directory is initialized in -`data/node{i}`, and a validator account with specified coins is created. - -The `accounts` defines other non-validator accounts, they are created in `node0`'s keyring. - -In the `genesis` section you can override any genesis configuration with the same json path. - -## Usage - -``` -NAME - pystarport serve - prepare and start a devnet from scatch - -SYNOPSIS - pystarport serve - -DESCRIPTION - prepare and start a devnet from scatch - -FLAGS - --data=DATA - Type: str - Default: './data' - path to the root data directory - --config=CONFIG - Type: str - Default: './config.yaml' - path to the configuration file - --base_port=BASE_PORT - Type: int - Default: 26650 - the base port to use, the service ports of different nodes are calculated based on this - --cmd=CMD - Type: str - Default: 'chain-maind' - the chain binary to use -``` - -## Port rules - -The rules to calculate service ports based on base port is defined in the -[`ports.py`](https://github.com/crypto-org-chain/chain-main/blob/master/pystarport/pystarport/ports.py) module. - -For example, with default base port `26650`, the url of api servers of the nodes would be: - -- Node0: http://127.0.0.1:26654 -- Node1: http://127.0.0.1:26664 - -> The swagger doc of node0 is http://127.0.0.1:26654/swagger/ -> -> The default rpc port used by `chain-maind` is `26657`, that's the default node0's rpc port, so you can use -> `chain-maind` without change to access node0's rpc. - -## Supervisor - -`pystarport` embeded a [supervisor](http://supervisord.org/) to manage processes of multiple nodes, you can use -`pystarport supervisorctl` to manage the processes: - -``` -$ pystarport supervisorctl status -node0 RUNNING pid 35210, uptime 0:00:29 -node1 RUNNING pid 35211, uptime 0:00:29 -$ pystarport supervisorctl help - -default commands (type help ): -===================================== -add exit open reload restart start tail -avail fg pid remove shutdown status update -clear maintail quit reread signal stop version -``` - -Or enter an interactive shell: - -``` -$ pystarport supervisorctl -node0 RUNNING pid 35210, uptime 0:01:53 -node1 RUNNING pid 35211, uptime 0:01:53 -supervisor> -``` - -## Cli - -After started the chain, you can use `chain-maind` cli directly, there are also some wrapper commands provided by -`pystarport cli`. It understands the directory structure and port rules, also assuming `keyring-backend=test`, and there -are shortcuts for commonly used commands, so arguments are shorter. - -``` -$ pystarport cli - --help -... -``` - -## Transaction Bot - -A simple transaction bot that works for cluster created by pystarport as well as a local node - -Copy and modify `bot.yaml.sample` to `bot.yaml` with your desired bot configurations. - -### If you are running on a pystarport created cluster: -1. Make sure you have provide the `node` for each job in the `bot.yaml` -2. Run the command -``` -$ pystarport bot --chain-id=[cluster_chain_id] - start -``` - -### If you are running on a local node -``` -$ pstarport bot --node_rpc=tcp://127.0.0.1:26657 --data=/path/to/your/local/node/home/ - start -``` - -## docker-compose - -When used with `docker-compose` or multiple machines, you need to config hostnames, and you probabely want to use a same -`base_port` since you don't have port conflicts, you can config the `validators` like this: - -```yaml -validators: - - coins: 10cro - staked: 10cro - base_port: 26650 - hostname: node0 - - coins: 10cro - staked: 10cro - base_port: 26650 - hostname: node1 -``` - -`pystarport init --gen_compose_file` will also generate a `docker-compose.yml` file for you. - -## IBC - -It can setup multiple devnets at once, and connect them with ibc relayer. - -``` -ibc-0: - validators: - - coins: 10cro - staked: 10cro - base_port: 26650 - - coins: 10cro - staked: 10cro - accounts: - - name: relayer - coins: 100cro - genesis: - app_state: - transfer: - params: - receive_enabled: true - send_enabled: true -ibc-1: - validators: - - coins: 10cro - staked: 10cro - base_port: 26750 - - coins: 10cro - staked: 10cro - base_port: 26760 - accounts: - - name: relayer - coins: 100cro - genesis: - app_state: - transfer: - params: - receive_enabled: true - send_enabled: true -relayer: - global: - timeout: 10s - light-cache-size: 20 - paths: - demo: - src: - chain-id: ibc-0 - port-id: transfer - order: unordered - version: ics20-1 - dst: - chain-id: ibc-1 - port-id: transfer - order: unordered - version: ics20-1 - strategy: - type: naive -``` - -With following commands to setup ibc, you are ready to play with ibc functionalities: - -``` -# spawn the devnets -pystarport serve --config ibc.yaml -# setup ibc channel -hermes -c data/relayer.toml create channel ibc-0 ibc-1 --port-a transfer --port-b transfer -# start relayer process -supervisorctl -c data/tasks.ini relayer-demo -``` - diff --git a/pystarport/pystarport/convert.sh b/pystarport/convert.sh similarity index 96% rename from pystarport/pystarport/convert.sh rename to pystarport/convert.sh index 8fc531db3..e9a09096f 100755 --- a/pystarport/pystarport/convert.sh +++ b/pystarport/convert.sh @@ -1,6 +1,6 @@ #!/bin/bash OUTPUT=./proto_python -COSMOS=../../third_party/cosmos-sdk +COSMOS=../third_party/cosmos-sdk TENDERMINT=./tendermint TMP=$(whereis grpc_python_plugin) PLUGIN="$(cut -d' ' -f2 <<<"$TMP")" diff --git a/pystarport/default.nix b/pystarport/default.nix index 6698e898c..3fe538828 100644 --- a/pystarport/default.nix +++ b/pystarport/default.nix @@ -1,9 +1,3 @@ { pkgs ? import { } -, chaind ? "chain-maind" }: -pkgs.poetry2nix.mkPoetryApplication { - projectDir = ./.; - preBuild = '' - sed -i -e 's@CHAIN = "" # edit by nix-build@CHAIN = "${chaind}"@' pystarport/app.py - ''; -} +pkgs.poetry2nix.mkPoetryEnv { projectDir = ./.; } diff --git a/pystarport/poetry.lock b/pystarport/poetry.lock index 5a1ccc740..bb8b3948a 100644 --- a/pystarport/poetry.lock +++ b/pystarport/poetry.lock @@ -1,3 +1,19 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "attrs" version = "21.2.0" @@ -14,20 +30,59 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (> [[package]] name = "bech32" -version = "1.2.0" +version = "1.1.0" description = "Reference implementation for Bech32 and segwit addresses." category = "main" optional = false -python-versions = ">=3.5" +python-versions = "*" + +[[package]] +name = "black" +version = "20.8b1" +description = "The uncompromising code formatter." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.6,<1" +regex = ">=2020.1.8" +toml = ">=0.10.1" +typed-ast = ">=1.4.0" +typing-extensions = ">=3.7.4" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "certifi" -version = "2020.12.5" +version = "2021.5.30" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = "*" +[[package]] +name = "chainlibpy" +version = "1.0.1" +description = "Tools for Crypto.org Chain wallet management and offline transaction signing" +category = "main" +optional = false +python-versions = ">=3.6, <4" + +[package.dependencies] +bech32 = ">=1.1.0,<1.2.0" +ecdsa = ">=0.14.0,<0.17.0" +hdwallets = ">=0.1.0,<0.2.0" +mnemonic = ">=0.19,<0.20" + +[package.extras] +test = ["pytest", "pytest-cov", "pytest-randomly"] + [[package]] name = "chardet" version = "4.0.0" @@ -36,6 +91,25 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "click" +version = "8.0.1" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "docker" version = "4.4.4" @@ -62,6 +136,32 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "ecdsa" +version = "0.16.1" +description = "ECDSA cryptographic signature library (pure python)" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[package.dependencies] +six = ">=1.9.0" + +[package.extras] +gmpy = ["gmpy"] +gmpy2 = ["gmpy2"] + +[[package]] +name = "execnet" +version = "1.9.0" +description = "execnet: rapid multi-Python deployment" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +testing = ["pre-commit"] + [[package]] name = "fire" version = "0.4.0" @@ -74,6 +174,83 @@ python-versions = "*" six = "*" termcolor = "*" +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + +[[package]] +name = "flake8-black" +version = "0.2.1" +description = "flake8 plugin to call black as a code style validator" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +black = "*" +flake8 = ">=3.0.0" + +[[package]] +name = "flake8-isort" +version = "4.0.0" +description = "flake8 plugin that integrates isort ." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = ">=3.2.1,<4" +isort = ">=4.3.5,<6" +testfixtures = ">=6.8.0,<7" + +[package.extras] +test = ["pytest (>=4.0.2,<6)", "toml"] + +[[package]] +name = "flake8-polyfill" +version = "1.0.2" +description = "Polyfill package for Flake8 plugins" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "grpcio" +version = "1.38.0" +description = "HTTP/2-based RPC framework" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = ">=1.5.2" + +[package.extras] +protobuf = ["grpcio-tools (>=1.38.0)"] + +[[package]] +name = "hdwallets" +version = "0.1.2" +description = "Python implementation of the BIP32 key derivation scheme" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +ecdsa = ">=0.14.0" + [[package]] name = "idna" version = "2.10" @@ -83,20 +260,17 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] -name = "importlib-metadata" -version = "4.0.1" -description = "Read metadata from Python packages" +name = "isort" +version = "5.8.0" +description = "A Python utility / library to sort Python imports." category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" +python-versions = ">=3.6,<4.0" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] [[package]] name = "jsonmerge" @@ -119,7 +293,6 @@ python-versions = "*" [package.dependencies] attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} pyrsistent = ">=0.14.0" six = ">=1.11.0" @@ -127,6 +300,30 @@ six = ">=1.11.0" format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "mnemonic" +version = "0.19" +description = "Implementation of Bitcoin BIP-0039" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "more-itertools" +version = "8.8.0" +description = "More routines for operating on iterables, beyond itertools" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "multitail2" version = "1.5.2" @@ -138,6 +335,98 @@ python-versions = "*" [package.dependencies] six = "*" +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "packaging" +version = "20.9" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pathspec" +version = "0.8.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pep8-naming" +version = "0.11.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "protobuf" +version = "3.17.3" +description = "Protocol Buffers" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +six = ">=1.9" + +[[package]] +name = "py" +version = "1.10.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "pyrsistent" version = "0.17.3" @@ -146,6 +435,95 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "pystarport" +version = "0.2.1" +description = "Spawn local devnets for cosmos-sdk chains" +category = "main" +optional = false +python-versions = "^3.8" +develop = false + +[package.dependencies] +bech32 = "^1.1.0" +docker = "^4.3.1" +durations = "^0.3.3" +fire = "^0.4.0" +jsonmerge = "^1.7.0" +multitail2 = "^1.5.2" +python-dateutil = "^2.8.1" +PyYAML = "^5.3.1" +supervisor = "^4.2.1" +tomlkit = "^0.7.0" + +[package.source] +type = "git" +url = "https://github.com/crypto-com/pystarport.git" +reference = "main" +resolved_reference = "0166c278ba6d73d86dbb47a32afb3f853f6be247" + +[[package]] +name = "pytest" +version = "5.4.3" +description = "pytest: simple powerful testing with Python" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=17.4.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.extras] +checkqa-mypy = ["mypy (==v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-forked" +version = "1.3.0" +description = "run tests in isolated forked subprocesses" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +py = "*" +pytest = ">=3.10" + +[[package]] +name = "pytest-github-actions-annotate-failures" +version = "0.1.2" +description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pytest = ">=4.0.0" + +[[package]] +name = "pytest-xdist" +version = "1.34.0" +description = "pytest xdist plugin for distributed testing and loop-on-failing modes" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +execnet = ">=1.1" +pytest = ">=4.4.0" +pytest-forked = "*" +six = "*" + +[package.extras] +testing = ["filelock"] + [[package]] name = "python-dateutil" version = "2.8.1" @@ -173,6 +551,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +[[package]] +name = "regex" +version = "2021.4.4" +description = "Alternative regular expression module, to replace re." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "requests" version = "2.25.1" @@ -218,14 +604,43 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "testfixtures" +version = "6.17.1" +description = "A collection of helpers and mock objects for unit tests and doc tests." +category = "main" +optional = false +python-versions = "*" + +[package.extras] +build = ["setuptools-git", "wheel", "twine"] +docs = ["sphinx", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"] +test = ["pytest (>=3.6)", "pytest-cov", "pytest-django", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "tomlkit" -version = "0.7.0" +version = "0.7.2" description = "Style preserving TOML library" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "typed-ast" +version = "1.4.3" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" version = "3.10.0.0" @@ -236,62 +651,77 @@ python-versions = "*" [[package]] name = "urllib3" -version = "1.26.4" +version = "1.26.5" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] +brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -brotli = ["brotlipy (>=0.6.0)"] [[package]] -name = "websocket-client" -version = "0.59.0" -description = "WebSocket client for Python with low level API options" +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -six = "*" +python-versions = "*" [[package]] -name = "zipp" -version = "3.4.1" -description = "Backport of pathlib-compatible object wrapper for zip files" +name = "websocket-client" +version = "1.1.0" +description = "WebSocket client for Python with low level API options" category = "main" optional = false python-versions = ">=3.6" -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] - [metadata] lock-version = "1.1" -python-versions = "^3.7" -content-hash = "20557d9bb4f4f3c0b3220c3547c08acea16b202397fa33a15af52ee888fd7a19" +python-versions = "^3.8" +content-hash = "fd736ed50bcd1ee8052f47edcb712a7adcfe64b186d6d7bcdf4041ca9b56c257" [metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] bech32 = [ - {file = "bech32-1.2.0-py3-none-any.whl", hash = "sha256:990dc8e5a5e4feabbdf55207b5315fdd9b73db40be294a19b3752cde9e79d981"}, - {file = "bech32-1.2.0.tar.gz", hash = "sha256:7d6db8214603bd7871fcfa6c0826ef68b85b0abd90fa21c285a9c5e21d2bd899"}, + {file = "bech32-1.1.0-py3-none-any.whl", hash = "sha256:5dde0114268ce7f12057dccd0bde51e44a50106231a8b127807d3aeca85f51e6"}, + {file = "bech32-1.1.0.tar.gz", hash = "sha256:dbd24eae005c0c3458ec803ab51c0994f030366cb09a668d1949ab09f15cdd5e"}, +] +black = [ + {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] certifi = [ - {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, - {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, + {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, + {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, +] +chainlibpy = [ + {file = "chainlibpy-1.0.1.tar.gz", hash = "sha256:4e2602dbc62ebf7ed8d5410eb1ff0140478ef093456c4f4ce9894b4f190a90d4"}, ] chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] +click = [ + {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, + {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] docker = [ {file = "docker-4.4.4-py2.py3-none-any.whl", hash = "sha256:f3607d5695be025fa405a12aca2e5df702a57db63790c73b927eb6a94aac60af"}, {file = "docker-4.4.4.tar.gz", hash = "sha256:d3393c878f575d3a9ca3b94471a3c89a6d960b35feb92f033c0de36cc9d934db"}, @@ -299,16 +729,97 @@ docker = [ durations = [ {file = "durations-0.3.3.tar.gz", hash = "sha256:820ffe09c390469dc621b6a0aa46d3a624b6dadf09b439e175696b6f6b77ef2f"}, ] +ecdsa = [ + {file = "ecdsa-0.16.1-py2.py3-none-any.whl", hash = "sha256:881fa5e12bb992972d3d1b3d4dfbe149ab76a89f13da02daa5ea1ec7dea6e747"}, + {file = "ecdsa-0.16.1.tar.gz", hash = "sha256:cfc046a2ddd425adbd1a78b3c46f0d1325c657811c0f45ecc3a0a6236c1e50ff"}, +] +execnet = [ + {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, + {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, +] fire = [ {file = "fire-0.4.0.tar.gz", hash = "sha256:c5e2b8763699d1142393a46d0e3e790c5eb2f0706082df8f647878842c216a62"}, ] +flake8 = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] +flake8-black = [ + {file = "flake8-black-0.2.1.tar.gz", hash = "sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"}, + {file = "flake8_black-0.2.1-py3-none-any.whl", hash = "sha256:941514149cb8b489cb17a4bb1cf18d84375db3b34381bb018de83509437931a0"}, +] +flake8-isort = [ + {file = "flake8-isort-4.0.0.tar.gz", hash = "sha256:2b91300f4f1926b396c2c90185844eb1a3d5ec39ea6138832d119da0a208f4d9"}, + {file = "flake8_isort-4.0.0-py2.py3-none-any.whl", hash = "sha256:729cd6ef9ba3659512dee337687c05d79c78e1215fdf921ed67e5fe46cce2f3c"}, +] +flake8-polyfill = [ + {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, + {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] +grpcio = [ + {file = "grpcio-1.38.0-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:db01eaea57e7a1898c69271e35a84341cf8150cfdec5f0411eddcfb65b5f590e"}, + {file = "grpcio-1.38.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:f6f6d51c9efbfe56af9eb9eeb4881cad1b869e4c0e2a32c1d345897fd0979ee3"}, + {file = "grpcio-1.38.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7466eef3b57b5ac8c7585251b26b917b093ab015750bf98aab4e0836c39e2a2b"}, + {file = "grpcio-1.38.0-cp27-cp27m-win32.whl", hash = "sha256:604da72df5bece8844a15990ce0b3f2f8c5243a1333d3dcc02371048bf6f9269"}, + {file = "grpcio-1.38.0-cp27-cp27m-win_amd64.whl", hash = "sha256:924552099365ea1dd32237dc161849452cd567d931efc57e8427260d8f0eacdb"}, + {file = "grpcio-1.38.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f19bd4b5bcf88ee059f478c4ab46a1607f09835587750294038fbd0120f1a9dc"}, + {file = "grpcio-1.38.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c47e85eae34af5d17d1c2007a1f0b13a0293d4b7a6d8c8ae23761d718293803e"}, + {file = "grpcio-1.38.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:d631304e66c908d5d2d1a3cc9c02d372d2f8bed8c3632902d6f3f77d7ca34ac2"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4a1dd16ccf76ddc18c1cde900049c04ed996e6c02e0588d88d06396c398e6023"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:32067791bd56a13614399f1994454afea9e2475019fcabc4abd3112f09892005"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:0247b045feb7b138754c91efcca9ea7f7d2cc9f0bd2cc73f6588c523f38873c3"}, + {file = "grpcio-1.38.0-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:07abf6b36c138bf247cef7ac0bad9f8ab1c8242f7c1302af23bb8e6877d08163"}, + {file = "grpcio-1.38.0-cp35-cp35m-win32.whl", hash = "sha256:2c26cb7566e8942542ff1aee71f10ed35e2f9ee95c2f27179b198af0727fbebb"}, + {file = "grpcio-1.38.0-cp35-cp35m-win_amd64.whl", hash = "sha256:e72dd202c982a5922c3b846976cae3b699e3fa8d2355d9d5bad119d066cf23ee"}, + {file = "grpcio-1.38.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:34fb08d46a70750bef6566c9556a16b98e08af6345a3bad6574477eb0b08c3dd"}, + {file = "grpcio-1.38.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:1d157a2ac6632d31a3ff21f56bbe73420e1d7a21e4fe89d8c7ac792b79c1a589"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3cacfee78310b5a89769b2fac20b8cd723470130f5b1ba0c960da8db39e74a97"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:e83ab148911e6c8ae4ec5e1334e6d800c6b84c432b92eb0ebf0808087117cb39"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:a836f21a1d08d28c8344e149b28729649ff4732c318a59a3628451bbd6c3c9ac"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:b4cd8fb4e3725e8852b1da734904edb3579c76660ae26a72283ac580779e5bf0"}, + {file = "grpcio-1.38.0-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:d3566acd87a65a0bc93875125a7064293ab2b6ffb9327333030939681d269f4f"}, + {file = "grpcio-1.38.0-cp36-cp36m-win32.whl", hash = "sha256:f2c4ff0e8c98418c5d55c28ba4ff954e3a5d3c723af5008e8d3ddeae8f0ecb41"}, + {file = "grpcio-1.38.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9a2216df1be9fdbc3c1ebd3c5184d1ef4afb387c29224fce00346b9ddec7c7e3"}, + {file = "grpcio-1.38.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:9f1747b81d44daed0649ff10395b58c4f29b03139a628afeb058f3e942ba6893"}, + {file = "grpcio-1.38.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:ac05434a7a7f444b2ddd109d72f87f4704364be159aea42a04bd6ea2ba6e10e4"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:a4789014f9d9e9ff29551314a004266b1ac90225c8a009dc87947aaf823fd83c"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e3072b9ebb573fe1f6757a55b610e4975979d2d58247cbe18ff4385f5aaa81a5"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:7b74c48b2e41dd506f889a4a9974d40b3eead965b0fd2e0b1d55a9b3c0e3bc6e"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:291dcde4139bc25629de6a743cfcc0ca861e289e3547421ecd2273b51d95b8e1"}, + {file = "grpcio-1.38.0-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:0ab78d4c16d7f3924718711689f5e301aec52cfcf38eb4143bed0f74b7c4fd10"}, + {file = "grpcio-1.38.0-cp37-cp37m-win32.whl", hash = "sha256:10a6c62e0cddd456db91f9f04b53a8cccf67d86d7ca814d989423939099c2723"}, + {file = "grpcio-1.38.0-cp37-cp37m-win_amd64.whl", hash = "sha256:be83ca2d24321c8bf6516b9cd1064da15ac3ff3978c6c502643be114e2a54af2"}, + {file = "grpcio-1.38.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:897bcd54890e6ec6359063affb35e19a61a58ba37bc61c9e8ac6b464b854233e"}, + {file = "grpcio-1.38.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:f8dd51b05e7fde843d7a3140b058f02801fbec5784a036d5f6abb374450d4608"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:277faad1d8d462bd1b986f43a47a2c2fe795b2e0de72c9318e11826d921e665a"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a0d7c88b4cf9748147cd6c16e14569a124b683a3eb5d7787f43eb9d48cf86755"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2736b109ec5bd9fcf580bf871b5fd4f136c6ae9728407f344a3c64ad87bb6519"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:cbd2754da81bf5f18454c7808b4afe5b57c6736955a742fb599b32b6353fe99f"}, + {file = "grpcio-1.38.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a8f9fcf5623282e4804595166a4ee1401cf4ccfc16fe84bb69e1eb23ffd836ac"}, + {file = "grpcio-1.38.0-cp38-cp38-win32.whl", hash = "sha256:1c11041ecb69d962d49e8a38a35736cdc6fc74230867b5f0ac6138770387a950"}, + {file = "grpcio-1.38.0-cp38-cp38-win_amd64.whl", hash = "sha256:1d212af1008bdbfd4b8a287e17a8e63e14d72ac450475307452f20c1bbb6bae4"}, + {file = "grpcio-1.38.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:8c4f39ad529fb4a33cd6e58d1d860c3b583902208547614b4b5b75fc306f13f6"}, + {file = "grpcio-1.38.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:f9b3678920017842a1b576de3524ecf8f6a2bf4b39f86fb25b870693141e0584"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:1e88a8d5d961df958362f61b1b79ad3981a8b051f99224717b09308546298902"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6461d69a8ae20e7abce4c6d9cc2603e9f16f4d6b64865eddd0e664127349c04d"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:cd220606259f8aa2403bc0f4a4483bae5e36be879364ca3e256f0304ac44f575"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:25028420d004fe33d64015f5d4d97207c53530acdb493310e217fac76dcd2513"}, + {file = "grpcio-1.38.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:b86a1b0654804b5f2248d9262c77a9d5f19882481fc21df53eb2823d0875b86d"}, + {file = "grpcio-1.38.0-cp39-cp39-win32.whl", hash = "sha256:752593a275e26ef250dc4d93a6f7917dd9986396b41eabcc114b0e0315ec1bf6"}, + {file = "grpcio-1.38.0-cp39-cp39-win_amd64.whl", hash = "sha256:6824567e2372dde1bd70214427d23b709d09f1a02a552133d1e0f504b616c84e"}, + {file = "grpcio-1.38.0.tar.gz", hash = "sha256:abbf9c8c3df4d5233d5888c6cfa85c1bb68a6923749bd4dd1abc6e1e93986f17"}, +] +hdwallets = [ + {file = "hdwallets-0.1.2-py3-none-any.whl", hash = "sha256:455b55b061f2b356a93e305b0c2263a6007d2ed45e48749975f09308499a2fdb"}, + {file = "hdwallets-0.1.2.tar.gz", hash = "sha256:c85d08b59c3fd3bc5b29398583d7d7dc46f95456f69ff15a3ab0353084ee7529"}, +] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] -importlib-metadata = [ - {file = "importlib_metadata-4.0.1-py3-none-any.whl", hash = "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d"}, - {file = "importlib_metadata-4.0.1.tar.gz", hash = "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581"}, +isort = [ + {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, + {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, ] jsonmerge = [ {file = "jsonmerge-1.8.0.tar.gz", hash = "sha256:a86bfc44f32f6a28b749743df8960a4ce1930666b3b73882513825f845cb9558"}, @@ -317,12 +828,102 @@ jsonschema = [ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +mnemonic = [ + {file = "mnemonic-0.19-py2.py3-none-any.whl", hash = "sha256:a8d78c5100acfa7df9bab6b9db7390831b0e54490934b718ff9efd68f0d731a6"}, + {file = "mnemonic-0.19.tar.gz", hash = "sha256:4e37eb02b2cbd56a0079cabe58a6da93e60e3e4d6e757a586d9f23d96abea931"}, +] +more-itertools = [ + {file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"}, + {file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"}, +] multitail2 = [ {file = "multitail2-1.5.2.tar.gz", hash = "sha256:7086598c1cd1901ec79ce3c1eda9420299e3778f6c18464958c1f74ffd1950c9"}, ] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +packaging = [ + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, +] +pathspec = [ + {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, + {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, +] +pep8-naming = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +protobuf = [ + {file = "protobuf-3.17.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ab6bb0e270c6c58e7ff4345b3a803cc59dbee19ddf77a4719c5b635f1d547aa8"}, + {file = "protobuf-3.17.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:13ee7be3c2d9a5d2b42a1030976f760f28755fcf5863c55b1460fd205e6cd637"}, + {file = "protobuf-3.17.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:1556a1049ccec58c7855a78d27e5c6e70e95103b32de9142bae0576e9200a1b0"}, + {file = "protobuf-3.17.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f0e59430ee953184a703a324b8ec52f571c6c4259d496a19d1cabcdc19dabc62"}, + {file = "protobuf-3.17.3-cp35-cp35m-win32.whl", hash = "sha256:a981222367fb4210a10a929ad5983ae93bd5a050a0824fc35d6371c07b78caf6"}, + {file = "protobuf-3.17.3-cp35-cp35m-win_amd64.whl", hash = "sha256:6d847c59963c03fd7a0cd7c488cadfa10cda4fff34d8bc8cba92935a91b7a037"}, + {file = "protobuf-3.17.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:145ce0af55c4259ca74993ddab3479c78af064002ec8227beb3d944405123c71"}, + {file = "protobuf-3.17.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ce4d8bf0321e7b2d4395e253f8002a1a5ffbcfd7bcc0a6ba46712c07d47d0b4"}, + {file = "protobuf-3.17.3-cp36-cp36m-win32.whl", hash = "sha256:7a4c97961e9e5b03a56f9a6c82742ed55375c4a25f2692b625d4087d02ed31b9"}, + {file = "protobuf-3.17.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a22b3a0dbac6544dacbafd4c5f6a29e389a50e3b193e2c70dae6bbf7930f651d"}, + {file = "protobuf-3.17.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ffea251f5cd3c0b9b43c7a7a912777e0bc86263436a87c2555242a348817221b"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9b7a5c1022e0fa0dbde7fd03682d07d14624ad870ae52054849d8960f04bc764"}, + {file = "protobuf-3.17.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8727ee027157516e2c311f218ebf2260a18088ffb2d29473e82add217d196b1c"}, + {file = "protobuf-3.17.3-cp37-cp37m-win32.whl", hash = "sha256:14c1c9377a7ffbeaccd4722ab0aa900091f52b516ad89c4b0c3bb0a4af903ba5"}, + {file = "protobuf-3.17.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c56c050a947186ba51de4f94ab441d7f04fcd44c56df6e922369cc2e1a92d683"}, + {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"}, + {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"}, + {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"}, + {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"}, + {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"}, + {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"}, +] +py = [ + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, +] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] +pyflakes = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] pyrsistent = [ {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, ] +pystarport = [] +pytest = [ + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, +] +pytest-forked = [ + {file = "pytest-forked-1.3.0.tar.gz", hash = "sha256:6aa9ac7e00ad1a539c41bec6d21011332de671e938c7637378ec9710204e37ca"}, + {file = "pytest_forked-1.3.0-py2.py3-none-any.whl", hash = "sha256:dc4147784048e70ef5d437951728825a131b81714b398d5d52f17c7c144d8815"}, +] +pytest-github-actions-annotate-failures = [ + {file = "pytest-github-actions-annotate-failures-0.1.2.tar.gz", hash = "sha256:9eb6ee2943ecde2078fe620af7dbf32646c0267f538435cd805fe2e8d735ca3a"}, + {file = "pytest_github_actions_annotate_failures-0.1.2-py2.py3-none-any.whl", hash = "sha256:e0c4bd8720450fc37c4ee63465023101301980c2d24f14f8ab25358ba1fa68d4"}, +] +pytest-xdist = [ + {file = "pytest-xdist-1.34.0.tar.gz", hash = "sha256:340e8e83e2a4c0d861bdd8d05c5d7b7143f6eea0aba902997db15c2a86be04ee"}, + {file = "pytest_xdist-1.34.0-py2.py3-none-any.whl", hash = "sha256:ba5d10729372d65df3ac150872f9df5d2ed004a3b0d499cc0164aafedd8c7b66"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, @@ -372,6 +973,49 @@ pyyaml = [ {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] +regex = [ + {file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"}, + {file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"}, + {file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"}, + {file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"}, + {file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"}, + {file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"}, + {file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"}, + {file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"}, + {file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"}, + {file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"}, + {file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"}, + {file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"}, + {file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"}, + {file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"}, + {file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"}, + {file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"}, + {file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"}, +] requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, @@ -387,9 +1031,49 @@ supervisor = [ termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] +testfixtures = [ + {file = "testfixtures-6.17.1-py2.py3-none-any.whl", hash = "sha256:9ed31e83f59619e2fa17df053b241e16e0608f4580f7b5a9333a0c9bdcc99137"}, + {file = "testfixtures-6.17.1.tar.gz", hash = "sha256:5ec3a0dd6f71cc4c304fbc024a10cc293d3e0b852c868014b9f233203e149bda"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] tomlkit = [ - {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"}, - {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"}, + {file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, + {file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, +] +typed-ast = [ + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, + {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"}, + {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"}, + {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"}, + {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"}, + {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"}, + {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"}, + {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"}, + {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"}, + {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"}, + {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"}, + {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"}, + {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"}, + {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"}, + {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"}, + {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"}, + {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, + {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, @@ -397,14 +1081,14 @@ typing-extensions = [ {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, ] urllib3 = [ - {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, - {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, + {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"}, + {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"}, ] -websocket-client = [ - {file = "websocket-client-0.59.0.tar.gz", hash = "sha256:d376bd60eace9d437ab6d7ee16f4ab4e821c9dae591e1b783c58ebd8aaf80c5c"}, - {file = "websocket_client-0.59.0-py2.py3-none-any.whl", hash = "sha256:2e50d26ca593f70aba7b13a489435ef88b8fc3b5c5643c1ce8808ff9b40f0b32"}, +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] -zipp = [ - {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, - {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, +websocket-client = [ + {file = "websocket-client-1.1.0.tar.gz", hash = "sha256:b68e4959d704768fa20e35c9d508c8dc2bbc041fd8d267c0d7345cffe2824568"}, + {file = "websocket_client-1.1.0-py2.py3-none-any.whl", hash = "sha256:e5c333bfa9fa739538b652b6f8c8fc2559f1d364243c8a689d7c0e1d41c2e611"}, ] diff --git a/pystarport/proto_python/__init__.py b/pystarport/proto_python/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pystarport/pystarport/proto_python/api_util.py b/pystarport/proto_python/api_util.py similarity index 90% rename from pystarport/pystarport/proto_python/api_util.py rename to pystarport/proto_python/api_util.py index 4203ba6ee..0a132fadc 100644 --- a/pystarport/pystarport/proto_python/api_util.py +++ b/pystarport/proto_python/api_util.py @@ -27,7 +27,8 @@ def broadcast_tx(self, signed_tx: dict): response = requests.post(url, json=signed_tx) if not response.ok: raise Exception( - f"response code: {response.status_code}, {response.reason}, {response.json()}" + f"response code: {response.status_code}, " + + f"{response.reason}, {response.json()}" ) result = response.json() if result.get("code"): diff --git a/pystarport/pystarport/proto_python/grpc_util.py b/pystarport/proto_python/grpc_util.py similarity index 100% rename from pystarport/pystarport/proto_python/grpc_util.py rename to pystarport/proto_python/grpc_util.py diff --git a/pystarport/pyproject.toml b/pystarport/pyproject.toml index bea4a938d..4f7cbea9d 100644 --- a/pystarport/pyproject.toml +++ b/pystarport/pyproject.toml @@ -1,35 +1,28 @@ [tool.poetry] -name = "pystarport" -version = "0.1.1" -description = "Spawn local devnets for cosmos-sdk chains" -authors = ["huangyi "] -license = "Apache" -keywords = ["CRO", "blockchain", "crypto.com", "cosmos"] -readme = "README.md" -homepage = "https://github.com/crypto-org-chain/chain-main/tree/master/pystarport" -repository = "https://github.com/crypto-org-chain/chain-main" -include = [ - "LICENSE", -] +name = "pystarport_integration_tests" +version = "0.1.0" +description = "" +authors = ["Your Name "] [tool.poetry.dependencies] -python = "^3.7" -fire = "^0.4.0" -tomlkit = "^0.7.0" -jsonmerge = "^1.7.0" +python = "^3.8" +pytest = "^5.4.0" +pytest-xdist = "^1.34.0" +flake8 = "^3.8.4" +black = "^20.8b1" +flake8-black = "^0.2.1" +flake8-isort = "^4.0.0" +pep8-naming = "^0.11.1" +pytest-github-actions-annotate-failures = "^0.1.1" +protobuf = "^3.13.0" +grpcio = "^1.33.2" PyYAML = "^5.3.1" python-dateutil = "^2.8.1" -durations = "^0.3.3" -supervisor = "^4.2.1" -docker = "^4.3.1" -bech32 = "^1.1.0" -multitail2 = "^1.5.2" +pystarport = "^0.2.1" +chainlibpy = "^1.0.0" [tool.poetry.dev-dependencies] -[tool.poetry.scripts] -pystarport = "pystarport.cli:main" - [build-system] requires = ["poetry>=0.12"] build-backend = "poetry.masonry.api" diff --git a/pystarport/pystarport/__init__.py b/pystarport/pystarport/__init__.py deleted file mode 100644 index 780c8f2da..000000000 --- a/pystarport/pystarport/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -import os -import sys -from pathlib import Path - -proto_folder = Path(os.path.abspath(__file__)).parent.joinpath("proto_python") -sys.path.append(str(proto_folder)) diff --git a/pystarport/pystarport/app.py b/pystarport/pystarport/app.py deleted file mode 100644 index bf9937a90..000000000 --- a/pystarport/pystarport/app.py +++ /dev/null @@ -1,8 +0,0 @@ -import os - -CHAIN = "" # edit by nix-build -if not CHAIN: - CHAIN = os.environ.get("CHAIN_MAIND", "chain-maind") -IMAGE = "docker.pkg.github.com/crypto-org-chain/chain-main/chain-main-pystarport:latest" - -SUPERVISOR_CONFIG_FILE = "tasks.ini" diff --git a/pystarport/pystarport/bot.py b/pystarport/pystarport/bot.py deleted file mode 100644 index 23b08e656..000000000 --- a/pystarport/pystarport/bot.py +++ /dev/null @@ -1,152 +0,0 @@ -import random -import sys -import threading -import time - -import yaml - -from .cluster import ClusterCLI -from .cosmoscli import CosmosCLI - - -class TxJobThread(threading.Thread): - def __init__(self, label, job, cosmos_cli: CosmosCLI): - threading.Thread.__init__(self) - self.label = label - self.job = job - self.cosmos_cli = cosmos_cli - - def transfer_tx_job(self): - from_address = self.cosmos_cli.address( - self.job["from_account"], - ) - to_address = self.job["to_address"] - if "random_amount" in self.job: - amount = random_amount( - self.job["random_amount"][0], - self.job["random_amount"][1], - self.job["random_amount"][2], - ) - else: - amount = self.job["amount"] - - print( - "[%s] Transfer %s from %s to %s" - % (self.label, amount, from_address, to_address) - ) - result = self.cosmos_cli.transfer(from_address, to_address, amount) - print(result) - - def delegate_tx_job(self): - from_address = self.cosmos_cli.address(self.job["from_account"]) - to_address = self.job["to_validator_address"] - if "random_amount" in self.job: - amount = random_amount( - self.job["random_amount"][0], - self.job["random_amount"][1], - self.job["random_amount"][2], - ) - else: - amount = self.job["amount"] - - print( - "[%s] Delegate %s from %s to %s" - % (self.label, amount, from_address, to_address) - ) - result = self.cosmos_cli.delegate_amount(to_address, amount, from_address) - print(result) - - def withdraw_all_rewards_job(self): - from_address = self.cosmos_cli.address(self.job["from_account"]) - print("[%s] Withdraw all rewards from %s" % (self.label, from_address)) - result = self.cosmos_cli.withdraw_all_rewards(from_address) - print(result) - - def next_interval(self): - if "random_interval" in self.job: - return random.randint( - self.job["random_interval"][0], - self.job["random_interval"][1], - ) - return self.job["interval"] - - def run(self): - job_type = self.job["type"] - while 1: - begin = time.time() - - try: - if job_type == "transfer": - self.transfer_tx_job() - elif job_type == "delegate": - self.delegate_tx_job() - elif job_type == "withdraw_all_rewards": - self.withdraw_all_rewards_job() - else: - print("Unknown job type: %s", job_type) - sys.exit() - except Exception as e: - print("error executing job:", sys.exc_info(), str(e)) - - interval = self.next_interval() - - duration = time.time() - begin - if duration < interval: - sleep = interval - duration - print("Next %s in %ds ...\n" % (job_type, sleep)) - time.sleep(sleep) - - -def random_amount(min, max, denom): - return "%d%s" % (random.randint(min, max), denom) - - -class BotClusterCLI: - "transaction bot Cluster CLI" - - def __init__(self, config_path, cluster_cli: ClusterCLI): - self.config = yaml.safe_load(open(config_path)) - self.cluster_cli = cluster_cli - - def start(self): - """ - prepare and start a transaction bot from configuration - """ - threads = [] - for i, job in enumerate(self.config["jobs"], start=1): - node_i = job.get("node", 0) - cli = CosmosCLI( - self.cluster_cli.home(node_i), - self.cluster_cli.node_rpc(node_i), - chain_id=self.cluster_cli.chain_id, - cmd=self.cluster_cli.cmd, - ) - thread = TxJobThread(job.get("label", i), job, cli) - - threads.append(thread) - thread.start() - - for thread in threads: - thread.join() - - -class BotCLI: - "transaction bot CLI" - - def __init__(self, config_path, cosmos_cli=None): - self.config = yaml.safe_load(open(config_path)) - self.cosmos_cli = cosmos_cli - - def start(self): - """ - prepare and start a transaction bot from configuration - """ - threads = [] - for i, job in enumerate(self.config["jobs"], start=1): - thread = TxJobThread(job.get("label", i), job, self.cosmos_cli) - - threads.append(thread) - thread.start() - - for thread in threads: - thread.join() diff --git a/pystarport/pystarport/cli.py b/pystarport/pystarport/cli.py deleted file mode 100644 index adbf1c70f..000000000 --- a/pystarport/pystarport/cli.py +++ /dev/null @@ -1,163 +0,0 @@ -import os -import signal -from pathlib import Path - -import fire - -from .app import CHAIN, IMAGE, SUPERVISOR_CONFIG_FILE -from .bot import BotCLI, BotClusterCLI -from .cluster import ClusterCLI, init_cluster, start_cluster, start_tail_logs_thread -from .cosmoscli import CosmosCLI -from .utils import build_cli_args, interact - - -def init( - data, - config, - base_port, - *args, - **kwargs, -): - interact( - f"rm -r {data}; mkdir {data}", - ignore_error=True, - ) - return init_cluster(data, config, base_port, *args, **kwargs) - - -def start(data, quiet): - supervisord = start_cluster(data) - - # register signal to quit supervisord - for signame in ("SIGINT", "SIGTERM"): - signal.signal(getattr(signal, signame), lambda *args: supervisord.terminate()) - - if not quiet: - tailer = start_tail_logs_thread(data) - - supervisord.wait() - - if not quiet: - tailer.stop() - tailer.join() - - -def serve(data, config, base_port, cmd, quiet): - init(data, config, base_port, cmd=cmd) - start(data, quiet) - - -class CLI: - def __init__(self, /, cmd=CHAIN): - """ - :param cmd: path to the chain binary - """ - self.cmd = cmd - - def init( - self, - data: str = "./data", - config: str = "./config.yaml", - base_port: int = 26650, - image: str = IMAGE, - gen_compose_file: bool = False, - cmd: str = CHAIN, - ): - """ - prepare all the configurations of a devnet - - :param data: path to the root data directory - :param config: path to the configuration file - :param base_port: the base port to use, the service ports of different nodes - are calculated based on this - :param image: the image used in the generated docker-compose.yml - :param gen_compose_file: generate a docker-compose.yml - :param cmd: path to chain binary - """ - init(Path(data), config, base_port, image, self.cmd, gen_compose_file) - - def start(self, data: str = "./data", quiet: bool = False): - """ - start the prepared devnet - - :param data: path to the root data directory - :param quiet: don't print logs of subprocesses - """ - start(Path(data), quiet) - - def chaind(self, *args, **kwargs): - """ - start one node whose home directory is already initialized - can be used to launch chain-maind - - :param home: home directory - """ - os.execvp(self.cmd, [self.cmd] + build_cli_args(*args, **kwargs)) - - def serve( - self, - data: str = "./data", - config: str = "./config.yaml", - base_port: int = 26650, - quiet: bool = False, - ): - """ - prepare and start a devnet from scatch - - :param data: path to the root data directory - :param config: path to the configuration file - :param base_port: the base port to use, the service ports of different nodes - are calculated based on this - :param cmd: path to chain binary - :param quiet: don't print logs of subprocesses - """ - serve(Path(data), config, base_port, self.cmd, quiet) - - def supervisorctl(self, *args, data: str = "./data"): - from supervisor.supervisorctl import main - - main(("-c", Path(data) / SUPERVISOR_CONFIG_FILE, *args)) - - def cli(self, *args, data: str = "./data", chain_id: str = "chainmaind"): - """ - pystarport CLI - - :param data: path to the root data directory - :param chain_id: chain id of the cluster - """ - return ClusterCLI(Path(data), chain_id=chain_id, cmd=self.cmd) - - def bot( - self, - *args, - data: str = "./data", - config: str = "./bot.yaml", - chain_id: str = "chainmaind", - node_rpc: str = None, - ): - """ - transaction bot CLI - - :param data: path to the root data directory if connecting to pystarport - cluster. Path to the home directory if connecting to a node - :param config: path to the bot configuration file - (copy bot.yaml.example for reference) - :param chain_id: chain id of the cluster - :param node_rpc: custom Tendermint RPC endpoint to the node - """ - data_path = Path(data) - config_path = Path(config) - if node_rpc is None: - cluster_cli = ClusterCLI(data_path, chain_id=chain_id, cmd=self.cmd) - return BotClusterCLI(config_path, cluster_cli) - else: - cosmos_cli = CosmosCLI(data_path, node_rpc, cmd=self.cmd) - return BotCLI(config_path, cosmos_cli) - - -def main(): - fire.Fire(CLI) - - -if __name__ == "__main__": - main() diff --git a/pystarport/pystarport/cluster.py b/pystarport/pystarport/cluster.py deleted file mode 100644 index 377e97af0..000000000 --- a/pystarport/pystarport/cluster.py +++ /dev/null @@ -1,1071 +0,0 @@ -import base64 -import configparser -import datetime -import hashlib -import json -import os -import re -import subprocess -import sys -import threading -import time -from pathlib import Path -from typing import List - -import durations -import jsonmerge -import multitail2 -import tomlkit -import yaml -from dateutil.parser import isoparse -from supervisor import xmlrpc -from supervisor.compat import xmlrpclib - -from . import ports -from .app import CHAIN, IMAGE, SUPERVISOR_CONFIG_FILE -from .cosmoscli import ChainCommand, CosmosCLI, ModuleAccount, module_address -from .ledger import ZEMU_BUTTON_PORT, ZEMU_HOST -from .utils import format_doc_string, interact, write_ini - -COMMON_PROG_OPTIONS = { - # redirect to supervisord's stdout, easier to collect all logs - "autostart": "true", - "autorestart": "true", - "redirect_stderr": "true", - "startsecs": "3", -} - - -def home_dir(data_dir, i): - return data_dir / f"node{i}" - - -class ClusterCLI: - "the apis to interact with wallet and blockchain prepared with Cluster" - - def __init__( - self, - data, - chain_id="chainmaind", - cmd=CHAIN, - zemu_address=ZEMU_HOST, - zemu_button_port=ZEMU_BUTTON_PORT, - ): - self.data_root = data - self.cmd = cmd - self.zemu_address = zemu_address - self.zemu_button_port = zemu_button_port - self.chain_id = chain_id - self.data_dir = data / self.chain_id - self.config = json.load((self.data_dir / "config.json").open()) - - self._supervisorctl = None - self.output = None - self.error = None - - def cosmos_cli(self, i=0): - return CosmosCLI( - self.home(i), - self.node_rpc(i), - chain_id=self.chain_id, - cmd=self.cmd, - zemu_address=self.zemu_address, - zemu_button_port=self.zemu_button_port, - ) - - @property - def supervisor(self): - "http://supervisord.org/api.html" - # copy from: - # https://github.com/Supervisor/supervisor/blob/76df237032f7d9fbe80a0adce3829c8b916d5b58/supervisor/options.py#L1718 - if self._supervisorctl is None: - self._supervisorctl = xmlrpclib.ServerProxy( - # dumbass ServerProxy won't allow us to pass in a non-HTTP url, - # so we fake the url we pass into it and - # always use the transport's - # 'serverurl' to figure out what to attach to - "http://127.0.0.1", - transport=xmlrpc.SupervisorTransport( - serverurl=f"unix://{self.data_root}/supervisor.sock" - ), - ) - return self._supervisorctl.supervisor - - def reload_supervisor(self): - subprocess.run( - [ - sys.executable, - "-msupervisor.supervisorctl", - "-c", - self.data_root / SUPERVISOR_CONFIG_FILE, - "update", - ], - check=True, - ) - - def nodes_len(self): - "find how many 'node{i}' sub-directories" - return len( - [p for p in self.data_dir.iterdir() if re.match(r"^node\d+$", p.name)] - ) - - def copy_validator_key(self, from_node=1, to_node=2): - "Copy the validtor file in from_node to to_node" - from_key_file = "{}/node{}/config/priv_validator_key.json".format( - self.data_dir, from_node - ) - to_key_file = "{}/node{}/config/priv_validator_key.json".format( - self.data_dir, to_node - ) - with open(from_key_file, "r") as f: - key = f.read() - with open(to_key_file, "w") as f: - f.write(key) - - def update_genesis(self, i, genesis_data): - home = self.home(i) - genesis_file = home / "config/genesis.json" - with open(genesis_file, "w") as f: - f.write(json.dumps(genesis_data, indent=4)) - - def stop_node(self, i=0): - subprocess.run( - [ - sys.executable, - "-msupervisor.supervisorctl", - "-c", - self.data_root / SUPERVISOR_CONFIG_FILE, - "stop", - "{}-node{}".format(self.chain_id, i), - ] - ) - - def stop_relayer(self, path): - subprocess.run( - [ - sys.executable, - "-msupervisor.supervisorctl", - "-c", - self.data_root / SUPERVISOR_CONFIG_FILE, - "stop", - "program:relayer-{}".format(path), - ] - ) - - def restart_relayer(self, path): - subprocess.run( - [ - sys.executable, - "-msupervisor.supervisorctl", - "-c", - self.data_root / SUPERVISOR_CONFIG_FILE, - "restart", - "program:relayer-{}".format(path), - ] - ) - - def start_node(self, i): - subprocess.run( - [ - sys.executable, - "-msupervisor.supervisorctl", - "-c", - self.data_root / SUPERVISOR_CONFIG_FILE, - "start", - "{}-node{}".format(self.chain_id, i), - ] - ) - - def create_node( - self, - base_port=None, - moniker=None, - hostname="localhost", - statesync=False, - mnemonic=None, - ): - """create new node in the data directory, - process information is written into supervisor config - start it manually with supervisor commands - - :return: new node index and config - """ - i = self.nodes_len() - - # default configs - if base_port is None: - # use the node0's base_port + i * 10 as default base port for new ndoe - base_port = self.config["validators"][0]["base_port"] + i * 10 - if moniker is None: - moniker = f"node{i}" - - # add config - assert len(self.config["validators"]) == i - self.config["validators"].append( - { - "base_port": base_port, - "hostname": hostname, - "moniker": moniker, - } - ) - (self.data_dir / "config.json").write_text(json.dumps(self.config)) - - # init home directory - self.init(i) - home = self.home(i) - (home / "config/genesis.json").unlink() - (home / "config/genesis.json").symlink_to("../../genesis.json") - (home / "config/client.toml").write_text( - tomlkit.dumps( - { - "chain-id": self.chain_id, - "keyring-backend": "test", - "output": "json", - "node": self.node_rpc(i), - "broadcast-mode": "block", - } - ) - ) - # use p2p peers from node0's config - node0 = tomlkit.parse((self.data_dir / "node0/config/config.toml").read_text()) - - def custom_edit_tm(doc): - if statesync: - info = self.status()["SyncInfo"] - doc["statesync"].update( - { - "enable": True, - "rpc_servers": ",".join(self.node_rpc(i) for i in range(2)), - "trust_height": int(info["earliest_block_height"]), - "trust_hash": info["earliest_block_hash"], - "temp_dir": str(self.data_dir), - "discovery_time": "5s", - } - ) - - edit_tm_cfg( - home / "config/config.toml", - base_port, - node0["p2p"]["persistent_peers"], - custom_edit=custom_edit_tm, - ) - edit_app_cfg(home / "config/app.toml", base_port, {}) - - # create validator account - self.create_account("validator", i, mnemonic) - - # add process config into supervisor - path = self.data_dir / SUPERVISOR_CONFIG_FILE - ini = configparser.RawConfigParser() - ini.read_file(path.open()) - chain_id = self.chain_id - prgname = f"{chain_id}-node{i}" - section = f"program:{prgname}" - ini.add_section(section) - ini[section].update( - dict( - COMMON_PROG_OPTIONS, - command=f"{self.cmd} start --home %(here)s/node{i}", - autostart="false", - stdout_logfile=f"%(here)s/node{i}.log", - ) - ) - with path.open("w") as fp: - ini.write(fp) - self.reload_supervisor() - return i - - def home(self, i): - "home directory of i-th node" - return home_dir(self.data_dir, i) - - def base_port(self, i): - return self.config["validators"][i]["base_port"] - - def node_rpc(self, i): - "rpc url of i-th node" - return "tcp://127.0.0.1:%d" % ports.rpc_port(self.base_port(i)) - - # for query - def ipport_grpc(self, i): - "grpc url of i-th node" - return "127.0.0.1:%d" % ports.grpc_port(self.base_port(i)) - - # tx broadcast only - def ipport_grpc_tx(self, i): - "grpc url of i-th node" - return "127.0.0.1:%d" % ports.grpc_port_tx_only(self.base_port(i)) - - def node_id(self, i): - "get i-th node's tendermint node id" - return self.cosmos_cli(i).node_id() - - def delete_account(self, name, i=0): - "delete account in i-th node's keyring" - return self.cosmos_cli(i).delete_account(name) - - def create_account(self, name, i=0, mnemonic=None): - "create new keypair in i-th node's keyring" - return self.cosmos_cli(i).create_account(name, mnemonic) - - def create_account_ledger(self, name, i=0): - "create new ledger keypair" - return self.cosmos_cli(i).create_account_ledger(name) - - def init(self, i): - "the i-th node's config is already added" - return self.cosmos_cli(i).init(self.config["validators"][i]["moniker"]) - - def export(self, i=0): - return self.cosmos_cli(i).export() - - def validate_genesis(self, i=0): - return self.cosmos_cli(i).validate_genesis() - - def add_genesis_account(self, addr, coins, i=0, **kwargs): - return self.cosmos_cli(i).add_genesis_account(addr, coins, **kwargs) - - def gentx(self, name, coins, i=0, min_self_delegation=1, pubkey=None): - return self.cosmos_cli(i).gentx(name, coins, min_self_delegation, pubkey) - - def collect_gentxs(self, gentx_dir, i=0): - return self.cosmos_cli(i).collect_gentxs(gentx_dir) - - def status(self, i=0): - return self.cosmos_cli(i).status() - - def block_height(self, i=0): - return self.cosmos_cli(i).block_height() - - def block_time(self, i=0): - return self.cosmos_cli(i).block_time() - - def balance(self, addr, i=0): - return self.cosmos_cli(i).balance(addr) - - def query_all_txs(self, addr, i=0): - return self.cosmos_cli(i).query_all_txs(addr) - - def distribution_commission(self, addr, i=0): - return self.cosmos_cli(i).distribution_commission(addr) - - def distribution_community(self, i=0): - return self.cosmos_cli(i).distribution_community() - - def distribution_reward(self, delegator_addr, i=0): - return self.cosmos_cli(i).distribution_reward(delegator_addr) - - def address(self, name, i=0, bech="acc"): - return self.cosmos_cli(i).address(name, bech) - - @format_doc_string( - options=",".join(v.value for v in ModuleAccount.__members__.values()) - ) - def module_address(self, name): - """ - get address of module accounts - - :param name: name of module account, values: {options} - """ - return module_address(name) - - def account(self, addr, i=0): - return self.cosmos_cli(i).account(addr) - - def supply(self, supply_type, i=0): - return self.cosmos_cli(i).supply(supply_type) - - def validator(self, addr, i=0): - return self.cosmos_cli(i).validator(addr) - - def validators(self, i=0): - return self.cosmos_cli(i).validators() - - def staking_params(self, i=0): - return self.cosmos_cli(i).staking_params() - - def staking_pool(self, bonded=True, i=0): - return self.cosmos_cli(i).staking_pool(bonded) - - def transfer_offline(self, from_, to, coins, sequence, i=0, fees=None): - return self.cosmos_cli(i).transfer_offline(from_, to, coins, sequence, fees) - - def transfer(self, from_, to, coins, i=0, generate_only=False, fees=None): - return self.cosmos_cli(i).transfer(from_, to, coins, generate_only, fees) - - def transfer_from_ledger( - self, from_, to, coins, i=0, generate_only=False, fees=None - ): - return self.cosmos_cli(i).transfer_from_ledger( - from_, - to, - coins, - generate_only, - fees, - ) - - def get_delegated_amount(self, which_addr, i=0): - return self.cosmos_cli(i).get_delegated_amount(which_addr) - - def delegate_amount(self, to_addr, amount, from_addr, i=0): - return self.cosmos_cli(i).delegate_amount(to_addr, amount, from_addr) - - # to_addr: croclcl1... , from_addr: cro1... - def unbond_amount(self, to_addr, amount, from_addr, i=0): - return self.cosmos_cli(i).unbond_amount(to_addr, amount, from_addr) - - # to_validator_addr: crocncl1... , from_from_validator_addraddr: crocl1... - def redelegate_amount( - self, to_validator_addr, from_validator_addr, amount, from_addr, i=0 - ): - return self.cosmos_cli(i).redelegate_amount( - to_validator_addr, - from_validator_addr, - amount, - from_addr, - ) - - def withdraw_all_rewards(self, from_delegator, i=0): - return self.cosmos_cli(i).withdraw_all_rewards(from_delegator) - - def make_multisig(self, name, signer1, signer2, i=0): - return self.cosmos_cli(i).make_multisig(name, signer1, signer2) - - def sign_multisig_tx(self, tx_file, multi_addr, signer_name, i=0): - return self.cosmos_cli(i).sign_multisig_tx(tx_file, multi_addr, signer_name) - - def sign_batch_multisig_tx( - self, tx_file, multi_addr, signer_name, account_num, sequence, i=0 - ): - return self.cosmos_cli(i).sign_batch_multisig_tx( - tx_file, multi_addr, signer_name, account_num, sequence - ) - - def encode_signed_tx(self, signed_tx, i=0): - return self.cosmos_cli(i).encode_signed_tx(signed_tx) - - def sign_single_tx(self, tx_file, signer_name, i=0): - return self.cosmos_cli(i).sign_single_tx(tx_file, signer_name) - - def combine_multisig_tx(self, tx_file, multi_name, signer1_file, signer2_file, i=0): - return self.cosmos_cli(i).combine_multisig_tx( - tx_file, - multi_name, - signer1_file, - signer2_file, - ) - - def combine_batch_multisig_tx( - self, tx_file, multi_name, signer1_file, signer2_file, i=0 - ): - return self.cosmos_cli(i).combine_batch_multisig_tx( - tx_file, - multi_name, - signer1_file, - signer2_file, - ) - - def broadcast_tx(self, tx_file, i=0): - return self.cosmos_cli(i).broadcast_tx(tx_file) - - def unjail(self, addr, i=0): - return self.cosmos_cli(i).unjail(addr) - - def create_validator( - self, - amount, - i, - moniker=None, - commission_max_change_rate="0.01", - commission_rate="0.1", - commission_max_rate="0.2", - min_self_delegation="1", - identity="", - website="", - security_contact="", - details="", - ): - """MsgCreateValidator - create the node with create_node before call this""" - return self.cosmos_cli(i).create_validator( - amount, - moniker or self.config["validators"][i]["moniker"], - commission_max_change_rate, - commission_rate, - commission_max_rate, - min_self_delegation, - identity, - website, - security_contact, - details, - ) - - def edit_validator( - self, - i, - commission_rate=None, - moniker=None, - identity=None, - website=None, - security_contact=None, - details=None, - ): - """MsgEditValidator""" - return self.cosmos_cli(i).edit_validator( - commission_rate, - moniker, - identity, - website, - security_contact, - details, - ) - - def gov_propose(self, proposer, kind, proposal, i=0): - return self.cosmos_cli(i).gov_propose(proposer, kind, proposal) - - def gov_vote(self, voter, proposal_id, option, i=0): - return self.cosmos_cli(i).gov_vote(voter, proposal_id, option) - - def gov_deposit(self, depositor, proposal_id, amount, i=0): - return self.cosmos_cli(i).gov_deposit(depositor, proposal_id, amount) - - def query_proposals(self, depositor=None, limit=None, status=None, voter=None, i=0): - return self.cosmos_cli(i).query_proposals(depositor, limit, status, voter) - - def query_proposal(self, proposal_id, i=0): - return self.cosmos_cli(i).query_proposal(proposal_id) - - def query_tally(self, proposal_id, i=0): - return self.cosmos_cli(i).query_tally(proposal_id) - - def ibc_transfer( - self, - from_, - to, - amount, - channel, # src channel - target_version, # chain version number of target chain - i=0, - ): - return self.cosmos_cli(i).ibc_transfer( - from_, - to, - amount, - channel, - target_version, - ) - - def create_nft( - self, - from_addr, - denomid="mydenomid", - denomname="mydenomname", - schema='{"title":"Asset Metadata","type":"object",' - '"properties":{"name":{"type":"string",' - '"description":"testidentity"},"description":' - '{"type":"string","description":"testdescription"},' - '"image":{"type":"string","description":"testdescription"}}}', - fees=None, - i=0, - ): - return self.cosmos_cli(i).create_nft( - from_addr, denomid, denomname, schema, fees - ) - - def query_nft(self, denomid="mydenomid", i=0): - return self.cosmos_cli(i).query_nft(denomid) - - def query_denom_by_name(self, denomname="mydenomname", i=0): - return self.cosmos_cli(i).query_denom_by_name(denomname) - - def create_nft_token( - self, - from_addr, - to_addr, - denomid="mydenomid", - tokenid="mytokenid", - uri="myuri", - fees=None, - i=0, - ): - return self.cosmos_cli(i).create_nft_token( - from_addr, to_addr, denomid, tokenid, uri, fees - ) - - def query_nft_token(self, denomid="mydenomid", tokenid="mytokenid", i=0): - return self.cosmos_cli(i).query_nft_token(denomid, tokenid) - - def burn_nft_token(self, from_addr, denomid="mydenomid", tokenid="mytokenid", i=0): - return self.cosmos_cli(i).burn_nft_token(from_addr, denomid, tokenid) - - def edit_nft_token( - self, - from_addr, - denomid="mydenomid", - tokenid="mytokenid", - newuri="newuri", - newname="newname", - i=0, - ): - return self.cosmos_cli(i).edit_nft_token( - from_addr, denomid, tokenid, newuri, newname - ) - - def transfer_nft_token( - self, from_addr, to_addr, denomid="mydenomid", tokenid="mytokenid", i=0 - ): - return self.cosmos_cli(i).transfer_nft_token( - from_addr, to_addr, denomid, tokenid - ) - - -def start_cluster(data_dir): - cmd = [ - sys.executable, - "-msupervisor.supervisord", - "-c", - data_dir / SUPERVISOR_CONFIG_FILE, - ] - return subprocess.Popen(cmd, env=dict(os.environ, PYTHONPATH=":".join(sys.path))) - - -class TailLogsThread(threading.Thread): - def __init__(self, base_dir, pats: List[str]): - self.base_dir = base_dir - self.tailer = multitail2.MultiTail([str(base_dir / pat) for pat in pats]) - self._stop_event = threading.Event() - super().__init__() - - def run(self): - while not self.stopped: - for (path, _), s in self.tailer.poll(): - print(Path(path).relative_to(self.base_dir), s) - - # TODO Replace this with FAM/inotify for watching filesystem events. - time.sleep(0.5) - - def stop(self): - self._stop_event.set() - - @property - def stopped(self): - return self._stop_event.is_set() - - -def start_tail_logs_thread(data_dir): - t = TailLogsThread(data_dir, ["*/node*.log", "relayer-*.log"]) - t.start() - return t - - -def process_config(config, base_port): - """ - fill default values in config - """ - for i, val in enumerate(config["validators"]): - if "moniker" not in val: - val["moniker"] = f"node{i}" - if "base_port" not in val: - val["base_port"] = base_port + i * 10 - if "hostname" not in val: - val["hostname"] = "localhost" - - -def init_devnet( - data_dir, - config, - base_port, - image=IMAGE, - cmd=None, - gen_compose_file=False, -): - """ - init data directory - """ - - def create_account(cli, account, use_ledger=False): - if use_ledger: - acct = cli.create_account_ledger(account["name"]) - else: - acct = cli.create_account(account["name"]) - vesting = account.get("vesting") - if not vesting: - cli.add_genesis_account(acct["address"], account["coins"]) - else: - genesis_time = isoparse(genesis["genesis_time"]) - end_time = genesis_time + datetime.timedelta( - seconds=durations.Duration(vesting).to_seconds() - ) - vend = int(end_time.timestamp()) - cli.add_genesis_account( - acct["address"], - account["coins"], - vesting_amount=account["coins"], - vesting_end_time=vend, - ) - return acct - - process_config(config, base_port) - - (data_dir / "config.json").write_text(json.dumps(config)) - - cmd = config.get("cmd") or cmd or CHAIN - - # init home directories - for i, val in enumerate(config["validators"]): - ChainCommand(cmd)( - "init", - val["moniker"], - chain_id=config["chain_id"], - home=home_dir(data_dir, i), - ) - if "consensus_key" in val: - # restore consensus private key - with (home_dir(data_dir, i) / "config/priv_validator_key.json").open( - "w" - ) as fp: - json.dump( - { - "address": hashlib.sha256( - base64.b64decode(val["consensus_key"]["pub"]) - ) - .hexdigest()[:40] - .upper(), - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": val["consensus_key"]["pub"], - }, - "priv_key": { - "type": "tendermint/PrivKeyEd25519", - "value": val["consensus_key"]["priv"], - }, - }, - fp, - ) - if "genesis_file" in config: - genesis_bytes = open( - config["genesis_file"] % {"here": Path(config["path"]).parent}, "rb" - ).read() - else: - genesis_bytes = (data_dir / "node0/config/genesis.json").read_bytes() - (data_dir / "genesis.json").write_bytes(genesis_bytes) - (data_dir / "gentx").mkdir() - for i in range(len(config["validators"])): - try: - (data_dir / f"node{i}/config/genesis.json").unlink() - except OSError: - pass - (data_dir / f"node{i}/config/genesis.json").symlink_to("../../genesis.json") - (data_dir / f"node{i}/config/gentx").symlink_to("../../gentx") - - # write client config - rpc_port = ports.rpc_port(val["base_port"]) - (data_dir / f"node{i}/config/client.toml").write_text( - tomlkit.dumps( - { - "chain-id": config["chain_id"], - "keyring-backend": "test", - "output": "json", - "node": f"tcp://{val['hostname']}:{rpc_port}", - "broadcast-mode": "block", - } - ) - ) - - # now we can create ClusterCLI - cli = ClusterCLI(data_dir.parent, chain_id=config["chain_id"], cmd=cmd) - - # patch the genesis file - genesis = jsonmerge.merge( - json.load(open(data_dir / "genesis.json")), - config.get("genesis", {}), - ) - (data_dir / "genesis.json").write_text(json.dumps(genesis)) - cli.validate_genesis() - - # create accounts - accounts = [] - for i, node in enumerate(config["validators"]): - mnemonic = node.get("mnemonic") - account = cli.create_account("validator", i, mnemonic=mnemonic) - accounts.append(account) - if "coins" in node: - cli.add_genesis_account(account["address"], node["coins"], i) - if "staked" in node: - cli.gentx( - "validator", - node["staked"], - i=i, - min_self_delegation=node.get("min_self_delegation", 1), - pubkey=node.get("pubkey"), - ) - - # create accounts - for account in config.get("accounts", []): - account = create_account(cli, account) - accounts.append(account) - - account_hw = config.get("hw_account") - if account_hw: - account = create_account(cli, account_hw, True) - accounts.append(account) - - # output accounts - (data_dir / "accounts.json").write_text(json.dumps(accounts)) - - # collect-gentxs if directory not empty - if next((data_dir / "gentx").iterdir(), None) is not None: - cli.collect_gentxs(data_dir / "gentx", 0) - - # realise the symbolic links, so the node directories can be used independently - genesis_bytes = (data_dir / "genesis.json").read_bytes() - for i in range(len(config["validators"])): - (data_dir / f"node{i}/config/gentx").unlink() - tmp = data_dir / f"node{i}/config/genesis.json" - tmp.unlink() - tmp.write_bytes(genesis_bytes) - - # write tendermint config - peers = config.get("peers") or ",".join( - [ - "tcp://%s@%s:%d" - % (cli.node_id(i), val["hostname"], ports.p2p_port(val["base_port"])) - for i, val in enumerate(config["validators"]) - ] - ) - for i, val in enumerate(config["validators"]): - edit_tm_cfg(data_dir / f"node{i}/config/config.toml", val["base_port"], peers) - edit_app_cfg( - data_dir / f"node{i}/config/app.toml", - val["base_port"], - val.get("app-config", {}), - ) - - # write supervisord config file - with (data_dir / SUPERVISOR_CONFIG_FILE).open("w") as fp: - write_ini(fp, supervisord_ini(cmd, config["validators"], config["chain_id"])) - - if gen_compose_file: - yaml.dump( - docker_compose_yml(cmd, config["validators"], data_dir, image), - (data_dir / "docker-compose.yml").open("w"), - ) - - -def relayer_chain_config(data_dir, chain): - cfg = json.load((data_dir / chain["chain_id"] / "config.json").open()) - rpc_port = ports.rpc_port(cfg["validators"][0]["base_port"]) - grpc_port = ports.grpc_port(cfg["validators"][0]["base_port"]) - return { - "key_name": "relayer", - "id": chain["chain_id"], - "rpc_addr": f"http://localhost:{rpc_port}", - "grpc_addr": f"http://localhost:{grpc_port}", - "websocket_addr": f"ws://localhost:{rpc_port}/websocket", - "rpc_timeout": "10s", - "account_prefix": chain.get("account-prefix", "cro"), - "store_prefix": "ibc", - "gas": 300000, - "fee_denom": "basecro", - "fee_amount": 0, - "trusting_period": "336h", - } - - -def init_cluster( - data_dir, config_path, base_port, image=IMAGE, cmd=None, gen_compose_file=False -): - config = yaml.safe_load(open(config_path)) - - # override relayer config in config.yaml - rly_section = config.pop("relayer", {}) - for chain_id, cfg in config.items(): - cfg["path"] = str(config_path) - cfg["chain_id"] = chain_id - - chains = list(config.values()) - for chain in chains: - (data_dir / chain["chain_id"]).mkdir() - init_devnet( - data_dir / chain["chain_id"], chain, base_port, image, cmd, gen_compose_file - ) - paths = rly_section.get("paths", {}) - with (data_dir / SUPERVISOR_CONFIG_FILE).open("w") as fp: - write_ini( - fp, - supervisord_ini_group(config.keys(), paths), - ) - if len(chains) > 1: - relayer_config = data_dir / "relayer.toml" - # write relayer config - relayer_config.write_text( - tomlkit.dumps( - { - "global": { - "strategy": "naive", - "log_level": "info", - }, - "chains": [ - relayer_chain_config(data_dir, chain) for chain in chains - ], - "connections": [ - { - "a_chain": path["src"]["chain-id"], - "b_chain": path["dst"]["chain-id"], - "paths": [ - { - "a_port": path["src"]["port-id"], - "b_port": path["dst"]["port-id"], - } - ], - } - for path in paths.values() - ], - } - ) - ) - - # restore the relayer account in relayer - for chain in chains: - mnemonic = find_account(data_dir, chain["chain_id"], "relayer")["mnemonic"] - subprocess.run( - [ - "hermes", - "-c", - relayer_config, - "keys", - "restore", - chain["chain_id"], - "--mnemonic", - mnemonic, - "--coin-type", - str(chain.get("coin-type", 394)), - ], - check=True, - ) - - -def find_account(data_dir, chain_id, name): - accounts = json.load((data_dir / chain_id / "accounts.json").open()) - return next(acct for acct in accounts if acct["name"] == name) - - -def supervisord_ini(cmd, validators, chain_id): - ini = {} - for i, node in enumerate(validators): - ini[f"program:{chain_id}-node{i}"] = dict( - COMMON_PROG_OPTIONS, - command=f"{cmd} start --home %(here)s/node{i}", - stdout_logfile=f"%(here)s/node{i}.log", - ) - return ini - - -def supervisord_ini_group(chain_ids, paths): - cfg = { - "include": { - "files": " ".join( - f"%(here)s/{chain_id}/tasks.ini" for chain_id in chain_ids - ) - }, - "supervisord": { - "pidfile": "%(here)s/supervisord.pid", - "nodaemon": "true", - "logfile": "/dev/null", - "logfile_maxbytes": "0", - }, - "rpcinterface:supervisor": { - "supervisor.rpcinterface_factory": "supervisor.rpcinterface:" - "make_main_rpcinterface", - }, - "unix_http_server": {"file": "%(here)s/supervisor.sock"}, - "supervisorctl": {"serverurl": "unix://%(here)s/supervisor.sock"}, - } - for path, path_cfg in paths.items(): - src = path_cfg["src"]["chain-id"] - dst = path_cfg["dst"]["chain-id"] - cfg[f"program:relayer-{path}"] = dict( - COMMON_PROG_OPTIONS, - command=( - f"hermes -c %(here)s/relayer.toml start {src} {dst} " - "-p transfer -c channel-0" - ), - stdout_logfile=f"%(here)s/relayer-{path}.log", - autostart="false", - ) - return cfg - - -def docker_compose_yml(cmd, validators, data_dir, image): - return { - "version": "3", - "services": { - f"node{i}": { - "image": image, - "command": "chaind start", - "volumes": [f"{data_dir.absolute() / f'node{i}'}:/.chain-maind:Z"], - } - for i, val in enumerate(validators) - }, - } - - -def edit_tm_cfg(path, base_port, peers, *, custom_edit=None): - doc = tomlkit.parse(open(path).read()) - # tendermint is start in process, not needed - # doc['proxy_app'] = 'tcp://127.0.0.1:%d' % abci_port(base_port) - doc["rpc"]["laddr"] = "tcp://0.0.0.0:%d" % ports.rpc_port(base_port) - doc["rpc"]["pprof_laddr"] = "localhost:%d" % ports.pprof_port(base_port) - doc["rpc"]["grpc_laddr"] = "tcp://0.0.0.0:%d" % ports.grpc_port_tx_only(base_port) - doc["p2p"]["laddr"] = "tcp://0.0.0.0:%d" % ports.p2p_port(base_port) - doc["p2p"]["persistent_peers"] = peers - doc["p2p"]["addr_book_strict"] = False - doc["p2p"]["allow_duplicate_ip"] = True - doc["consensus"]["timeout_commit"] = "1s" - doc["rpc"]["timeout_broadcast_tx_commit"] = "30s" - if custom_edit is not None: - custom_edit(doc) - open(path, "w").write(tomlkit.dumps(doc)) - - -def patch_toml_doc(doc, patch): - for k, v in patch.items(): - if isinstance(v, dict): - patch_toml_doc(doc[k], v) - else: - doc[k] = v - - -def edit_app_cfg(path, base_port, app_config): - default_patch = { - "api": { - "enable": True, - "swagger": True, - "enable-unsafe-cors": True, - "address": "tcp://0.0.0.0:%d" % ports.api_port(base_port), - }, - "grpc": { - "address": "0.0.0.0:%d" % ports.grpc_port(base_port), - }, - "pruning": "nothing", - "state-sync": { - "snapshot-interval": 5, - "snapshot-keep-recent": 10, - }, - } - doc = tomlkit.parse(open(path).read()) - doc["grpc-web"] = {} - doc["grpc-web"]["address"] = "0.0.0.0:%d" % ports.grpc_web_port(base_port) - patch_toml_doc(doc, jsonmerge.merge(default_patch, app_config)) - open(path, "w").write(tomlkit.dumps(doc)) - - -if __name__ == "__main__": - interact("rm -r data; mkdir data", ignore_error=True) - data_dir = Path("data") - init_cluster(data_dir, "config.yaml", 26650) - supervisord = start_cluster(data_dir) - t = start_tail_logs_thread(data_dir) - supervisord.wait() - t.stop() - t.join() diff --git a/pystarport/pystarport/cosmoscli.py b/pystarport/pystarport/cosmoscli.py deleted file mode 100644 index 4708bac56..000000000 --- a/pystarport/pystarport/cosmoscli.py +++ /dev/null @@ -1,964 +0,0 @@ -import enum -import hashlib -import json -import tempfile -import threading -import time - -import bech32 -from dateutil.parser import isoparse - -from .app import CHAIN -from .ledger import ZEMU_BUTTON_PORT, ZEMU_HOST, LedgerButton -from .utils import build_cli_args_safe, format_doc_string, interact - - -class ModuleAccount(enum.Enum): - FeeCollector = "fee_collector" - Mint = "mint" - Gov = "gov" - Distribution = "distribution" - BondedPool = "bonded_tokens_pool" - NotBondedPool = "not_bonded_tokens_pool" - IBCTransfer = "transfer" - - -@format_doc_string( - options=",".join(v.value for v in ModuleAccount.__members__.values()) -) -def module_address(name): - """ - get address of module accounts - - :param name: name of module account, values: {options} - """ - data = hashlib.sha256(ModuleAccount(name).value.encode()).digest()[:20] - return bech32.bech32_encode("cro", bech32.convertbits(data, 8, 5)) - - -class ChainCommand: - def __init__(self, cmd=None): - self.cmd = cmd or CHAIN - - def __call__(self, cmd, *args, stdin=None, **kwargs): - "execute chain-maind" - args = " ".join(build_cli_args_safe(cmd, *args, **kwargs)) - return interact(f"{self.cmd} {args}", input=stdin) - - -class CosmosCLI: - "the apis to interact with wallet and blockchain" - - def __init__( - self, - data_dir, - node_rpc, - chain_id=None, - cmd=None, - zemu_address=ZEMU_HOST, - zemu_button_port=ZEMU_BUTTON_PORT, - ): - self.data_dir = data_dir - if chain_id is None: - self._genesis = json.load(open(self.data_dir / "config" / "genesis.json")) - self.chain_id = self._genesis["chain_id"] - else: - self.chain_id = chain_id - self.node_rpc = node_rpc - self.raw = ChainCommand(cmd) - self.leger_button = LedgerButton(zemu_address, zemu_button_port) - self.output = None - self.error = None - - def node_id(self): - "get tendermint node id" - output = self.raw("tendermint", "show-node-id", home=self.data_dir) - return output.decode().strip() - - def delete_account(self, name): - "delete wallet account in node's keyring" - return self.raw( - "keys", - "delete", - name, - "-y", - "--force", - home=self.data_dir, - output="json", - keyring_backend="test", - ) - - def create_account(self, name, mnemonic=None): - "create new keypair in node's keyring" - if mnemonic is None: - output = self.raw( - "keys", - "add", - name, - home=self.data_dir, - output="json", - keyring_backend="test", - ) - else: - output = self.raw( - "keys", - "add", - name, - "--recover", - home=self.data_dir, - output="json", - keyring_backend="test", - stdin=mnemonic.encode() + b"\n", - ) - return json.loads(output) - - def create_account_ledger(self, name): - "create new ledger keypair" - - def send_request(): - try: - self.output = self.raw( - "keys", - "add", - name, - "--ledger", - home=self.data_dir, - output="json", - keyring_backend="test", - ) - except Exception as e: - self.error = e - - t = threading.Thread(target=send_request) - t.start() - time.sleep(3) - for _ in range(0, 3): - self.leger_button.press_right() - time.sleep(0.2) - self.leger_button.press_both() - t.join() - if self.error: - raise self.error - return json.loads(self.output) - - def init(self, moniker): - "the node's config is already added" - return self.raw( - "init", - moniker, - chain_id=self.chain_id, - home=self.data_dir, - ) - - def validate_genesis(self): - return self.raw("validate-genesis", home=self.data_dir) - - def add_genesis_account(self, addr, coins, **kwargs): - return self.raw( - "add-genesis-account", - addr, - coins, - home=self.data_dir, - output="json", - **kwargs, - ) - - def gentx(self, name, coins, min_self_delegation=1, pubkey=None): - return self.raw( - "gentx", - name, - coins, - min_self_delegation=str(min_self_delegation), - home=self.data_dir, - chain_id=self.chain_id, - keyring_backend="test", - pubkey=pubkey, - ) - - def collect_gentxs(self, gentx_dir): - return self.raw("collect-gentxs", gentx_dir, home=self.data_dir) - - def status(self): - return json.loads(self.raw("status", node=self.node_rpc)) - - def block_height(self): - return int(self.status()["SyncInfo"]["latest_block_height"]) - - def block_time(self): - return isoparse(self.status()["SyncInfo"]["latest_block_time"]) - - def balance(self, addr): - coin = json.loads( - self.raw( - "query", "bank", "balances", addr, output="json", node=self.node_rpc - ) - )["balances"] - if len(coin) == 0: - return 0 - coin = coin[0] - return int(coin["amount"]) - - def query_all_txs(self, addr): - txs = self.raw( - "query", - "txs-all", - addr, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - return json.loads(txs) - - def distribution_commission(self, addr): - coin = json.loads( - self.raw( - "query", - "distribution", - "commission", - addr, - output="json", - node=self.node_rpc, - ) - )["commission"][0] - return float(coin["amount"]) - - def distribution_community(self): - coin = json.loads( - self.raw( - "query", - "distribution", - "community-pool", - output="json", - node=self.node_rpc, - ) - )["pool"][0] - return float(coin["amount"]) - - def distribution_reward(self, delegator_addr): - coin = json.loads( - self.raw( - "query", - "distribution", - "rewards", - delegator_addr, - output="json", - node=self.node_rpc, - ) - )["total"][0] - return float(coin["amount"]) - - def address(self, name, bech="acc"): - output = self.raw( - "keys", - "show", - name, - "-a", - home=self.data_dir, - keyring_backend="test", - bech=bech, - ) - return output.strip().decode() - - def account(self, addr): - return json.loads( - self.raw( - "query", "auth", "account", addr, output="json", node=self.node_rpc - ) - ) - - def supply(self, supply_type): - return json.loads( - self.raw("query", "supply", supply_type, output="json", node=self.node_rpc) - ) - - def validator(self, addr): - return json.loads( - self.raw( - "query", - "staking", - "validator", - addr, - output="json", - node=self.node_rpc, - ) - ) - - def validators(self): - return json.loads( - self.raw( - "query", "staking", "validators", output="json", node=self.node_rpc - ) - )["validators"] - - def staking_params(self): - return json.loads( - self.raw("query", "staking", "params", output="json", node=self.node_rpc) - ) - - def staking_pool(self, bonded=True): - return int( - json.loads( - self.raw("query", "staking", "pool", output="json", node=self.node_rpc) - )["bonded_tokens" if bonded else "not_bonded_tokens"] - ) - - def transfer(self, from_, to, coins, generate_only=False, fees=None): - return json.loads( - self.raw( - "tx", - "bank", - "send", - from_, - to, - coins, - "-y", - "--generate-only" if generate_only else None, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - fees=fees, - ) - ) - - def transfer_from_ledger(self, from_, to, coins, generate_only=False, fees=None): - def send_request(): - try: - self.output = self.raw( - "tx", - "bank", - "send", - from_, - to, - coins, - "-y", - "--generate-only" if generate_only else "", - "--ledger", - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - fees=fees, - sign_mode="amino-json", - ) - except Exception as e: - self.error = e - - t = threading.Thread(target=send_request) - t.start() - time.sleep(3) - for _ in range(0, 11): - self.leger_button.press_right() - time.sleep(0.4) - self.leger_button.press_both() - t.join() - if self.error: - raise self.error - return json.loads(self.output) - - def get_delegated_amount(self, which_addr): - return json.loads( - self.raw( - "query", - "staking", - "delegations", - which_addr, - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - output="json", - ) - ) - - def delegate_amount(self, to_addr, amount, from_addr): - return json.loads( - self.raw( - "tx", - "staking", - "delegate", - to_addr, - amount, - "-y", - home=self.data_dir, - from_=from_addr, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - # to_addr: croclcl1... , from_addr: cro1... - def unbond_amount(self, to_addr, amount, from_addr): - return json.loads( - self.raw( - "tx", - "staking", - "unbond", - to_addr, - amount, - "-y", - home=self.data_dir, - from_=from_addr, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - # to_validator_addr: crocncl1... , from_from_validator_addraddr: crocl1... - def redelegate_amount( - self, to_validator_addr, from_validator_addr, amount, from_addr - ): - return json.loads( - self.raw( - "tx", - "staking", - "redelegate", - from_validator_addr, - to_validator_addr, - amount, - "-y", - home=self.data_dir, - from_=from_addr, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - # from_delegator can be account name or address - def withdraw_all_rewards(self, from_delegator): - return json.loads( - self.raw( - "tx", - "distribution", - "withdraw-all-rewards", - "-y", - from_=from_delegator, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def make_multisig(self, name, signer1, signer2): - self.raw( - "keys", - "add", - name, - multisig=f"{signer1},{signer2}", - multisig_threshold="2", - home=self.data_dir, - keyring_backend="test", - ) - - def sign_multisig_tx(self, tx_file, multi_addr, signer_name): - return json.loads( - self.raw( - "tx", - "sign", - tx_file, - from_=signer_name, - multisig=multi_addr, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def sign_batch_multisig_tx( - self, tx_file, multi_addr, signer_name, account_number, sequence_number - ): - r = self.raw( - "tx", - "sign-batch", - "--offline", - tx_file, - account_number=account_number, - sequence=sequence_number, - from_=signer_name, - multisig=multi_addr, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - return r.decode("utf-8") - - def encode_signed_tx(self, signed_tx): - return self.raw( - "tx", - "encode", - signed_tx, - ) - - def sign_single_tx(self, tx_file, signer_name): - return json.loads( - self.raw( - "tx", - "sign", - tx_file, - from_=signer_name, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def combine_multisig_tx(self, tx_file, multi_name, signer1_file, signer2_file): - return json.loads( - self.raw( - "tx", - "multisign", - tx_file, - multi_name, - signer1_file, - signer2_file, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def combine_batch_multisig_tx( - self, tx_file, multi_name, signer1_file, signer2_file - ): - r = self.raw( - "tx", - "multisign-batch", - tx_file, - multi_name, - signer1_file, - signer2_file, - home=self.data_dir, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - return r.decode("utf-8") - - def broadcast_tx(self, tx_file): - r = self.raw( - "tx", "broadcast", tx_file, node=self.node_rpc, broadcast_mode="block" - ) - return r.decode("utf-8") - - def unjail(self, addr): - return json.loads( - self.raw( - "tx", - "slashing", - "unjail", - "-y", - from_=addr, - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - - def create_validator( - self, - amount, - moniker=None, - commission_max_change_rate="0.01", - commission_rate="0.1", - commission_max_rate="0.2", - min_self_delegation="1", - identity="", - website="", - security_contact="", - details="", - ): - """MsgCreateValidator - create the node with create_node before call this""" - pubkey = ( - self.raw( - "tendermint", - "show-validator", - home=self.data_dir, - ) - .strip() - .decode() - ) - return json.loads( - self.raw( - "tx", - "staking", - "create-validator", - "-y", - from_=self.address("validator"), - amount=amount, - pubkey=pubkey, - min_self_delegation=min_self_delegation, - # commision - commission_rate=commission_rate, - commission_max_rate=commission_max_rate, - commission_max_change_rate=commission_max_change_rate, - # description - moniker=moniker, - identity=identity, - website=website, - security_contact=security_contact, - details=details, - # basic - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - - def edit_validator( - self, - commission_rate=None, - moniker=None, - identity=None, - website=None, - security_contact=None, - details=None, - ): - """MsgEditValidator""" - options = dict( - commission_rate=commission_rate, - # description - moniker=moniker, - identity=identity, - website=website, - security_contact=security_contact, - details=details, - ) - return json.loads( - self.raw( - "tx", - "staking", - "edit-validator", - "-y", - from_=self.address("validator"), - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - **{k: v for k, v in options.items() if v is not None}, - ) - ) - - def gov_propose(self, proposer, kind, proposal): - if kind == "software-upgrade": - return json.loads( - self.raw( - "tx", - "gov", - "submit-proposal", - kind, - proposal["name"], - "-y", - from_=proposer, - # content - title=proposal.get("title"), - description=proposal.get("description"), - upgrade_height=proposal.get("upgrade-height"), - upgrade_time=proposal.get("upgrade-time"), - upgrade_info=proposal.get("upgrade-info"), - deposit=proposal.get("deposit"), - # basic - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - elif kind == "cancel-software-upgrade": - return json.loads( - self.raw( - "tx", - "gov", - "submit-proposal", - kind, - "-y", - from_=proposer, - # content - title=proposal.get("title"), - description=proposal.get("description"), - deposit=proposal.get("deposit"), - # basic - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - else: - with tempfile.NamedTemporaryFile("w") as fp: - json.dump(proposal, fp) - fp.flush() - return json.loads( - self.raw( - "tx", - "gov", - "submit-proposal", - kind, - fp.name, - "-y", - from_=proposer, - # basic - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - - def gov_vote(self, voter, proposal_id, option): - print(voter) - print(proposal_id) - print(option) - return json.loads( - self.raw( - "tx", - "gov", - "vote", - proposal_id, - option, - "-y", - from_=voter, - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - - def gov_deposit(self, depositor, proposal_id, amount): - return json.loads( - self.raw( - "tx", - "gov", - "deposit", - proposal_id, - amount, - "-y", - from_=depositor, - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - ) - ) - - def query_proposals(self, depositor=None, limit=None, status=None, voter=None): - return json.loads( - self.raw( - "query", - "gov", - "proposals", - depositor=depositor, - count_total=limit, - status=status, - voter=voter, - output="json", - node=self.node_rpc, - ) - ) - - def query_proposal(self, proposal_id): - return json.loads( - self.raw( - "query", - "gov", - "proposal", - proposal_id, - output="json", - node=self.node_rpc, - ) - ) - - def query_tally(self, proposal_id): - return json.loads( - self.raw( - "query", - "gov", - "tally", - proposal_id, - output="json", - node=self.node_rpc, - ) - ) - - def ibc_transfer( - self, - from_, - to, - amount, - channel, # src channel - target_version, # chain version number of target chain - i=0, - ): - return json.loads( - self.raw( - "tx", - "ibc-transfer", - "transfer", - "transfer", # src port - channel, - to, - amount, - "-y", - # FIXME https://github.com/cosmos/cosmos-sdk/issues/8059 - "--absolute-timeouts", - from_=from_, - home=self.data_dir, - node=self.node_rpc, - keyring_backend="test", - chain_id=self.chain_id, - packet_timeout_height=f"{target_version}-10000000000", - packet_timeout_timestamp=0, - ) - ) - - def export(self): - return self.raw("export", home=self.data_dir) - - def unsaferesetall(self): - return self.raw("unsafe-reset-all") - - def create_nft(self, from_addr, denomid, denomname, schema, fees): - return json.loads( - self.raw( - "tx", - "nft", - "issue", - denomid, - "-y", - fees=fees, - name=denomname, - schema=schema, - home=self.data_dir, - from_=from_addr, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def query_nft(self, denomid): - return json.loads( - self.raw( - "query", - "nft", - "denom", - denomid, - output="json", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def query_denom_by_name(self, denomname): - return json.loads( - self.raw( - "query", - "nft", - "denom-by-name", - denomname, - output="json", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def create_nft_token(self, from_addr, to_addr, denomid, tokenid, uri, fees): - return json.loads( - self.raw( - "tx", - "nft", - "mint", - denomid, - tokenid, - "-y", - uri=uri, - recipient=to_addr, - home=self.data_dir, - from_=from_addr, - keyring_backend="test", - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def query_nft_token(self, denomid, tokenid): - return json.loads( - self.raw( - "query", - "nft", - "token", - denomid, - tokenid, - output="json", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def burn_nft_token(self, from_addr, denomid, tokenid): - return json.loads( - self.raw( - "tx", - "nft", - "burn", - denomid, - tokenid, - "-y", - from_=from_addr, - keyring_backend="test", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def edit_nft_token(self, from_addr, denomid, tokenid, newuri, newname): - return json.loads( - self.raw( - "tx", - "nft", - "edit", - denomid, - tokenid, - "-y", - from_=from_addr, - uri=newuri, - name=newname, - keyring_backend="test", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) - - def transfer_nft_token(self, from_addr, to_addr, denomid, tokenid): - return json.loads( - self.raw( - "tx", - "nft", - "transfer", - to_addr, - denomid, - tokenid, - "-y", - from_=from_addr, - keyring_backend="test", - home=self.data_dir, - chain_id=self.chain_id, - node=self.node_rpc, - ) - ) diff --git a/pystarport/pystarport/ledger.py b/pystarport/pystarport/ledger.py deleted file mode 100644 index 6d38a3002..000000000 --- a/pystarport/pystarport/ledger.py +++ /dev/null @@ -1,102 +0,0 @@ -import socket -import time -import uuid - -import docker - -ZEMU_HOST = "127.0.0.1" -ZEMU_BUTTON_PORT = 9997 -ZEMU_GRPC_SERVER_PORT = 3002 -# dockerfile is integration_test/hardware_wallet/Dockerfile -ZEMU_IMAGE = "cryptocom/builder-zemu:latest" - - -class Ledger: - def __init__(self): - self.ledger_name = f"ledger_simulator_{uuid.uuid4().time_mid}" - self.proxy_name = f"ledger_proxy_{uuid.uuid4().time_mid}" - self.grpc_name = f"ledger_grpc_server_{uuid.uuid4().time_mid}" - self.cmds = { - self.ledger_name: [ - "./speculos/speculos.py", - "--display=headless", - f"--button-port={ZEMU_BUTTON_PORT}", - "./speculos/apps/crypto.elf", - ], - self.proxy_name: ["./speculos/tools/ledger-live-http-proxy.py", "-v"], - self.grpc_name: ["bash", "-c", "RUST_LOG=debug zemu-grpc-server"], - } - self.client = docker.from_env() - self.client.images.pull(ZEMU_IMAGE) - self.containers = [] - - def start(self): - host_config_ledger = self.client.api.create_host_config( - auto_remove=True, - port_bindings={ - ZEMU_BUTTON_PORT: ZEMU_BUTTON_PORT, - ZEMU_GRPC_SERVER_PORT: ZEMU_GRPC_SERVER_PORT, - }, - ) - container_ledger = self.client.api.create_container( - ZEMU_IMAGE, - self.cmds[self.ledger_name], - name=self.ledger_name, - ports=[ZEMU_BUTTON_PORT, ZEMU_GRPC_SERVER_PORT], - host_config=host_config_ledger, - ) - self.client.api.start(container_ledger["Id"]) - self.containers.append(container_ledger) - for name in [self.proxy_name, self.grpc_name]: - cmd = self.cmds[name] - try: - host_config = self.client.api.create_host_config( - auto_remove=True, network_mode=f"container:{self.ledger_name}" - ) - container = self.client.api.create_container( - ZEMU_IMAGE, - cmd, - name=name, - host_config=host_config, - ) - self.client.api.start(container["Id"]) - self.containers.append(container) - time.sleep(2) - except Exception as e: - print(e) - - def stop(self): - for container in self.containers: - try: - self.client.api.remove_container(container["Id"], force=True) - print("stop docker {}".format(container["Name"])) - except Exception as e: - print(e) - - -class LedgerButton: - def __init__(self, zemu_address, zemu_button_port): - self._client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.zemu_address = zemu_address - self.zemu_button_port = zemu_button_port - self.connected = False - - @property - def client(self): - if not self.connected: - time.sleep(5) - self._client.connect((self.zemu_address, self.zemu_button_port)) - self.connected = True - return self._client - - def press_left(self): - data = "Ll" - self.client.send(data.encode()) - - def press_right(self): - data = "Rr" - self.client.send(data.encode()) - - def press_both(self): - data = "LRlr" - self.client.send(data.encode()) diff --git a/pystarport/pystarport/ports.py b/pystarport/pystarport/ports.py deleted file mode 100644 index d19101325..000000000 --- a/pystarport/pystarport/ports.py +++ /dev/null @@ -1,26 +0,0 @@ -def p2p_port(base_port): - return base_port - - -def rpc_port(base_port): - return base_port + 7 - - -def grpc_port(base_port): - return base_port + 3 - - -def api_port(base_port): - return base_port + 4 - - -def pprof_port(base_port): - return base_port + 5 - - -def grpc_port_tx_only(base_port): - return base_port + 6 - - -def grpc_web_port(base_port): - return base_port + 8 diff --git a/pystarport/pystarport/utils.py b/pystarport/pystarport/utils.py deleted file mode 100644 index 33bb77453..000000000 --- a/pystarport/pystarport/utils.py +++ /dev/null @@ -1,63 +0,0 @@ -import configparser -import subprocess - - -def interact(cmd, ignore_error=False, input=None, **kwargs): - proc = subprocess.Popen( - cmd, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - shell=True, - **kwargs, - ) - # begin = time.perf_counter() - (stdout, _) = proc.communicate(input=input) - # print('[%.02f] %s' % (time.perf_counter() - begin, cmd)) - if not ignore_error: - assert proc.returncode == 0, f'{stdout.decode("utf-8")} ({cmd})' - return stdout - - -def write_ini(fp, cfg): - ini = configparser.RawConfigParser() - for section, items in cfg.items(): - ini.add_section(section) - sec = ini[section] - sec.update(items) - ini.write(fp) - - -def safe_cli_string(s): - 'wrap string in "", used for cli argument when contains spaces' - if len(f"{s}".split()) > 1: - return f"'{s}'" - return f"{s}" - - -def build_cli_args_safe(*args, **kwargs): - args = [safe_cli_string(arg) for arg in args if arg] - for k, v in kwargs.items(): - if v is None: - continue - args.append("--" + k.strip("_").replace("_", "-")) - args.append(safe_cli_string(v)) - return list(map(str, args)) - - -def build_cli_args(*args, **kwargs): - args = [arg for arg in args if arg is not None] - for k, v in kwargs.items(): - if v is None: - continue - args.append("--" + k.strip("_").replace("_", "-")) - args.append(v) - return list(map(str, args)) - - -def format_doc_string(**kwargs): - def decorator(target): - target.__doc__ = target.__doc__.format(**kwargs) - return target - - return decorator