Compare commits

..

108 Commits

Author SHA1 Message Date
Clayton Calabrese 4ccaca399f Merge branch 'fix_missing_node_py_changes' of https://github.com/AntelopeIO/leap into fix_missing_node_py_changes 2023-03-22 18:14:16 -05:00
Clayton Calabrese 09390a4725 return lost changes to Node.py functions 2023-03-22 18:13:24 -05:00
Matt Witherspoon 7c94e3a102 add PACKED_STRUCT on ControlStructureImm to silence warning 2023-03-22 18:12:54 -05:00
Matt Witherspoon f469d2b78a add static_assert()s on required size of IR::OpcodeAndImm<>s 2023-03-22 18:12:54 -05:00
Matt Witherspoon a9c5cd9f95 fix comparison of different signedness warning in log_index 2023-03-22 18:12:54 -05:00
Lin Huang 41f5a148bb correct version after merging from 4.0.0-rc1 2023-03-22 18:12:54 -05:00
Zach Butler 1f0f5280d5 Restore markdown formatting erroneously deleted in commit 06c9e25327 2023-03-22 18:12:54 -05:00
Zach Butler 6b54dac75f Cardinal objects should be in a numbered list 2023-03-22 18:12:54 -05:00
Zach Butler df4a974b8a Pull note about sudo into its own quote block 2023-03-22 18:12:54 -05:00
Zach Butler c9596cd699 Minor pinned build script README changes 2023-03-22 18:12:54 -05:00
Clayton Calabrese 6c8441bc6c return lost changes to Node.py functions 2023-03-22 17:15:59 -05:00
Matt Witherspoon 1985e28a63 Merge pull request #866 from AntelopeIO/ignored_pack_warn_fix
fix noisy `ignoring packed attribute` warning on `IR::ControlStructureImm`
2023-03-22 11:06:46 -07:00
Vlad 2829420ecb Merge pull request #856 from AntelopeIO/increase-snapshot-test-robustness
[4.0] Increase robustness of snapshot diff python test
2023-03-22 11:51:46 -04:00
Matt Witherspoon 95c22b6e70 add PACKED_STRUCT on ControlStructureImm to silence warning 2023-03-22 10:57:40 -04:00
Matt Witherspoon f8ca18d5f5 add static_assert()s on required size of IR::OpcodeAndImm<>s 2023-03-22 10:55:29 -04:00
Matt Witherspoon bef672aae2 Merge pull request #860 from AntelopeIO/log_index_un_signed_warn
fix comparison of different signedness warning in log_index
2023-03-22 07:30:28 -07:00
Kevin Heifner 87c7480656 Merge pull request #852 from AntelopeIO/GH-850-test-fix
[4.0] Test Fix: Pass a large time limit to get table call
2023-03-22 09:25:02 -05:00
Matt Witherspoon c2366d392b fix comparison of different signedness warning in log_index 2023-03-21 20:17:49 -04:00
766C6164 cb64c3fb38 schedule snapshot at exact block num of another one 2023-03-21 15:43:31 -04:00
Lin Huang c7d0f6c1c2 Merge pull request #855 from AntelopeIO/merge_4_0_0_rc_1
[4.0 -> main] Merge 4.0.0-rc1 version bump to main
2023-03-21 15:31:31 -04:00
Lin Huang 3beffd5765 correct version after merging from 4.0.0-rc1 2023-03-21 14:46:34 -04:00
Lin Huang 1e3f12dc60 Merge remote-tracking branch 'origin/release/4.0' into merge_4_0_0_rc_1 2023-03-21 14:43:12 -04:00
Lin Huang 61cb264885 Merge pull request #851 from AntelopeIO/create_release_4_0_rc_1
Create v4.0.0-rc1 on release/4.0 branch
2023-03-21 14:34:46 -04:00
Kevin Heifner 446a04a607 GH-850 Pass a large time limit so python does not have to handle more=true case. 2023-03-21 13:09:26 -05:00
Zach f3aab2cfa5 Merge pull request #849 from AntelopeIO/zach-readme
Fix README.md Formatting
2023-03-21 14:08:04 -04:00
Lin Huang 28ac7906dc Create v4.0.0-rc1 on release/4.0 branch 2023-03-21 14:03:42 -04:00
Lin Huang 5d4a7ee60e Merge pull request #848 from AntelopeIO/bump_to_4_1
Bump Leap Main branch version to 4.1.0-dev
2023-03-21 13:35:49 -04:00
Zach Butler 8fc769efd1 Restore markdown formatting erroneously deleted in commit 06c9e25327 2023-03-21 13:19:33 -04:00
Zach Butler 7f27916d3d Cardinal objects should be in a numbered list 2023-03-21 13:19:19 -04:00
Zach Butler df3685516e Pull note about sudo into its own quote block 2023-03-21 13:17:58 -04:00
Zach Butler 866dfae99c Minor pinned build script README changes 2023-03-21 13:12:34 -04:00
Lin Huang 4ef610fa33 Bump Leap Main branch version to 4.1.0-dev 2023-03-21 13:00:08 -04:00
Zach 17ca88c8ad Merge pull request #847 from AntelopeIO/zach-libcurl4-openssl-dev
Restore libcurl4-openssl-dev
2023-03-20 22:26:45 -04:00
Zach Butler 60e757d677 export TZ 2023-03-20 18:36:55 -04:00
Zach Butler cc6c3255a7 SC2034 - warning: DEBIAN_FRONTEND appears unused. Verify use (or export if used externally). 2023-03-20 18:01:01 -04:00
Zach Butler 958f6d53b6 tzdata does not need to be separate 2023-03-20 18:00:26 -04:00
Zach Butler e0dac2c6ed Restore libcurl4-openssl-dev 2023-03-20 17:51:58 -04:00
Zach Butler 5027a17a3b Sort packages, each one on its own line 2023-03-20 17:48:57 -04:00
Zach Butler 9398564118 Quote strings 2023-03-20 17:48:49 -04:00
Zach Butler d42262bfeb "apt-get install -y" 2023-03-20 17:48:31 -04:00
Zach Butler 3ba58b20b7 Whitespace 2023-03-20 17:48:23 -04:00
Zach 35b56406cc Merge pull request #835 from AntelopeIO/zach-ascii-art
Change ASCII Art Banner in Build Script
2023-03-20 13:41:26 -04:00
Zach 069245d4f3 Merge pull request #812 from AntelopeIO/zach-lint
Pinned Build Script Linter Changes
2023-03-20 13:39:33 -04:00
Zach 0f84d4e534 Merge pull request #833 from AntelopeIO/zach-revert-799
Fix Pinned Build on Ubuntu 22.04
2023-03-20 10:01:05 -04:00
Lin Huang ace9c40d56 Merge pull request #845 from AntelopeIO/fix_pr_192_bad_merge
Fix test coverage regression by a bad merge conflict in PR #192
2023-03-17 19:31:54 -04:00
Lin Huang 3c53734d2f add missing 2023-03-17 18:59:30 -04:00
Lin Huang 255617660d Fix test coverage regression by a bad merge conflict in PR #192 2023-03-17 18:29:20 -04:00
Vlad e3807c2b5f Merge pull request #842 from AntelopeIO/snapshot-diff-test-fix
snapshot-diff-test fix
2023-03-17 14:35:44 -04:00
766C6164 5324a5da79 sync scheduled snapshot with 2 others 2023-03-17 13:56:06 -04:00
ClaytonCalabrese 264737b4ef Merge pull request #791 from AntelopeIO/performance_harness_distributed_producer_ports
[PH] Distribute Transaction Generators Across Producer Nodes.
2023-03-17 12:28:19 -05:00
766C6164 b4fe3c654f test fix 2023-03-17 12:49:47 -04:00
Clayton Calabrese be75e8aa3a merge from main 2023-03-17 11:26:55 -05:00
Peter Oschwald 77dfd0c2bf Merge pull request #818 from AntelopeIO/dev-install-add-testharness
Add TestHarness python integration scripts to dev package
2023-03-17 11:07:03 -05:00
Peter Oschwald b1225959e4 Merge pull request #798 from AntelopeIO/GH-789-remove-private-key
Remove deprecated `--private-key` option from nodeos
2023-03-17 11:06:04 -05:00
jgiszczak 0c6892fe65 Merge pull request #192 from AntelopeIO/eosio-launcher-python-port
Port eosio-launcher to Python
2023-03-17 11:04:16 -05:00
Kevin Heifner 6491c667a3 Merge pull request #836 from AntelopeIO/fix-snapshot-schedule
Snapshot: fix issue with erasing element while iterating
2023-03-17 10:36:31 -05:00
Peter Oschwald d6e6a93150 Fix CORE_SYMBOL import and cleanup other imports. 2023-03-17 10:17:40 -05:00
Peter Oschwald 3e9d098e4b Merge branch 'eosio-launcher-python-port' into dev-install-add-testharness 2023-03-17 10:00:04 -05:00
Kevin Heifner 48f2396904 Fix issue with erasing element while iterating 2023-03-17 09:03:30 -05:00
Zach Butler 383fb714d4 Appreciate our users and make them feel like they are part of a community 2023-03-17 02:09:45 -04:00
Zach Butler 01b4454090 Cooler Leap ASCII art banner at end of pinned build script 2023-03-17 02:09:38 -04:00
Zach Butler 08aca00905 Revert "Merge pull request #799 from AntelopeIO/sbailey/autofind_llvm_7-11"
Co-authored-by: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com>
2023-03-17 00:53:32 -04:00
Zach Butler 03b1ebd46f Fix shebang in bash build scripts
Looking for BASH in the environment instead of invoking it directly
enables attacks where malware could escalate privileges by pointing BASH
to itself and tricking the user into entering a superuser password when
a user invokes our script, a familiar request the user may be expecting.
2023-03-16 21:03:43 -04:00
Zach Butler 0697aa31f3 SC2016 - note: Expressions don't expand in single quotes, use double quotes for that 2023-03-16 21:03:43 -04:00
Zach Butler 07208ec800 SC2006 - note: Use $(...) notation instead of legacy backticks ... 2023-03-16 21:03:42 -04:00
Zach Butler eee850dc38 SC2086 - note: Double quote to prevent globbing and word splitting. 2023-03-16 21:03:42 -04:00
Zach Butler 1038a94e66 SC2294 - warning: eval negates the benefit of arrays. Drop eval to preserve whitespace/symbols (or eval as string). 2023-03-16 21:03:42 -04:00
Zach Butler 633a8d37b3 SC2164 - Use "pushd ... || exit" or "pushd ... || return" in case pushd fails. 2023-03-16 21:03:42 -04:00
Zach Butler 83e6c6c6eb SC2034 - warning: "output" appears unused. Verify use (or export if used externally). 2023-03-16 21:03:41 -04:00
Zach Butler 46e50a4ee5 SC2034 - warning: ARCH appears unused. Verify use (or export if used externally). 2023-03-16 21:03:41 -04:00
Zach Butler 28c790be89 SC2034 - warning: CORE_SYM appears unused. Verify use (or export if used externally). 2023-03-16 21:03:41 -04:00
Zach Butler 25a7550166 SC2068 - error: Double quote array expansions to avoid re-splitting elements 2023-03-16 21:03:41 -04:00
Zach Butler 2e831bf906 SC2242 - error: Can only exit with status 0-255. Other data should be written to stdout/stderr. 2023-03-16 21:03:40 -04:00
Zach Butler 108a902a83 E011 - then keyword is not on same line as if or elif keyword 2023-03-16 21:03:40 -04:00
Zach Butler 2c92ef7ef2 E001 - Trailing Whitespace 2023-03-16 21:03:40 -04:00
Zach Butler a3284f4d5d E003 - Inconsistent indentation 2023-03-16 21:03:40 -04:00
Peter Oschwald e7e66a5d19 Simplify postinst and prerm scripts
leap_testing dir is already part of package so don't need to mkdir or rmdir as it will be cleaned up appropriately.

However, continue to clean up dir potentially created directly by postinst
2023-03-16 19:39:52 -05:00
Peter Oschwald 7d78b885d6 Merge branch 'dev-install-add-testharness' of ssh://github.com/AntelopeIO/leap into dev-install-add-testharness 2023-03-16 19:08:51 -05:00
Peter Oschwald c46400c527 Best effort attempt to remove the directorys we may have created during the install.
Can ignore failed directory deletion as they may be installing to location that has more than leap in it, for instance the ~/lib/python3/dist-packages, however if it is empty it is a safe assumption that it is in the location the install created it and can be removed as the inverse uninstall operation.
2023-03-16 19:07:10 -05:00
Peter Oschwald 9c066a76af Update package.cmake
Co-authored-by: Scott B <Scott@TheBaileyFamily.org>
2023-03-16 18:11:15 -05:00
Clayton Calabrese 39bdbfe675 use lambda for transaction generator calculations 2023-03-16 17:52:37 -05:00
Peter Oschwald 8c8ad50862 Don't overwrite the env variable so you get both postinst and prerm 2023-03-16 15:50:00 -05:00
Peter Oschwald 08b1eb5252 Addressing peer review comment.
Simplify prerm script.
2023-03-16 14:34:29 -05:00
Peter Oschwald 61b0efe536 Address a couple more review comments. 2023-03-16 14:24:15 -05:00
Peter Oschwald b6007e022d Peer review recommended using sh instead of bash as more likely to exist. 2023-03-16 13:56:16 -05:00
Peter Oschwald be154da603 Address peer review comments.
Adding additional commentary on cmake version based processing paths.

Added prerm script to cleanup symbolic links

Added EXCLUDE_FROM_ALL where necessary.

Move setting scripts to the package.cmake location suggested.
2023-03-16 13:54:19 -05:00
Clayton Calabrese 15d92a1797 use proper arg instead of empty string in launch transaction generators 2023-03-16 12:34:45 -05:00
Clayton Calabrese 5e21ecfea4 handle whitespace stripping in launch transaction generators 2023-03-16 12:31:37 -05:00
Clayton Calabrese 07ec10dd46 update readme to reflect port endpoint changes in performance harness 2023-03-16 11:03:47 -05:00
Peter Oschwald 38f8c59642 Address peer review comment. 2023-03-16 10:54:07 -05:00
Clayton Calabrese e3915ba846 merge from main 2023-03-16 10:53:05 -05:00
Peter Oschwald c8d36c2ff7 Merge branch 'eosio-launcher-python-port' into dev-install-add-testharness 2023-03-16 08:30:41 -05:00
Peter Oschwald 315874ae2f DataDir now returns absolute path instead of relative.
Don't add cwd to the front of the already absolute path. Fixes error where unix socket path  was too long.
2023-03-15 23:59:57 -05:00
Peter Oschwald d55b043b8d Merge branch 'eosio-launcher-python-port' into dev-install-add-testharness 2023-03-15 22:02:10 -05:00
Peter Oschwald b2db52d14b Update install mkdir and symbolic linking steps.
Existing steps were failing to work with package and old versions of cmake.
2023-03-15 21:24:28 -05:00
Peter Oschwald d56b97e527 Update core_symbol imports to reflect it being part of TestHarness module. 2023-03-14 19:16:01 -05:00
Peter Oschwald 6f16347f6e Fix install steps to only apply to COMPONENT dev 2023-03-14 18:46:21 -05:00
Peter Oschwald 0a1ec82bcd Add TestHarness python integration scripts to dev-install package. 2023-03-14 18:11:08 -05:00
Peter Oschwald f81921ad3b Fix lost force option. 2023-03-14 18:01:08 -05:00
Clayton Calabrese 26da362b5d Convert Cluster's connectionPairList to match proper format 2023-03-14 16:04:17 -05:00
Clayton Calabrese 3e19ad1fb0 rework when splitting of connectionpairList happens to simplify use 2023-03-14 13:27:25 -05:00
Clayton Calabrese 9a2eb7b85b allow passing of endpoints in addition to ports. Create even distribution of generators accross ports based on number of ports passed to the transaction generator launcher 2023-03-14 10:25:56 -05:00
Kevin Heifner c2c784fb25 GH-789 Fix regex 2023-03-09 14:09:28 -06:00
Kevin Heifner 2099dc1d36 GH-789 Remove --private-key option from nodeos 2023-03-09 14:05:47 -06:00
Clayton Calabrese 29564f6a6f Remove hardcoded number of ports in transaction generator 2023-03-08 09:45:20 -06:00
Clayton Calabrese 5747877d1c update readmes for trxgen and perf test to fit new port system 2023-03-07 17:45:19 -06:00
Clayton Calabrese 1c2f0567ce account for other routes into transactiongeneratorlauncher when dealing with ports 2023-03-07 16:55:33 -06:00
Clayton Calabrese 5baeede259 evenly distribute created transaction generators across multiple producer's ports 2023-03-07 16:17:29 -06:00
54 changed files with 585 additions and 350 deletions
+50 -23
View File
@@ -14,7 +14,7 @@ set( CMAKE_CXX_EXTENSIONS ON )
set( CXX_STANDARD_REQUIRED ON)
set(VERSION_MAJOR 4)
set(VERSION_MINOR 0)
set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
set(VERSION_SUFFIX dev)
@@ -77,29 +77,9 @@ if(ENABLE_OC AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
list(APPEND EOSIO_WASM_RUNTIMES eos-vm-oc)
# EOS VM OC requires LLVM, but move the check up here to a central location so that the EosioTester.cmakes
# can be created with the exact version found
# find_package VERSION range is only available in 3.19 and newer.
if(${CMAKE_VERSION} VERSION_LESS "3.19")
find_package(LLVM REQUIRED CONFIG)
else()
# Preferring the latest LLVM version, search through major 11..7 and minor 9..0 in reverse order.
# Minor versions may break API. This manifests in the LLVM config files such that a range of `11...<12`
# will NOT find LLVM `11.1`. We loop over minor as well as major to resolve this.
set(max_minor 9)
set(major 11)
set(minor ${max_minor})
while(NOT LLVM_FOUND AND major GREATER_EQUAL 7)
math(EXPR end "${major} + 1")
find_package(LLVM ${major}.${minor}...<${end} CONFIG QUIET)
if(minor GREATER 0)
math(EXPR minor "${minor} - 1")
else()
math(EXPR major "${major} - 1")
set(minor ${max_minor})
endif()
endwhile()
endif()
find_package(LLVM REQUIRED CONFIG)
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER_EQUAL 12)
message(FATAL_ERROR "Leap requires an LLVM version 7 through 11")
message(FATAL_ERROR "Leap requires an LLVM version 7 through 11")
endif()
endif()
endif()
@@ -257,6 +237,53 @@ configure_file(programs/cleos/LICENSE.CLI11 licen
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libraries/testing/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/libraries/testing COMPONENT dev EXCLUDE_FROM_ALL
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "Makefile" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/unittests/contracts DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/unittests COMPONENT dev EXCLUDE_FROM_ALL
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.cmake" EXCLUDE
PATTERN "Makefile" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/tests COMPONENT dev EXCLUDE_FROM_ALL
FILES_MATCHING
PATTERN "*.py"
PATTERN "*.json"
PATTERN "__pycache__" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tests/launcher.py DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/tests COMPONENT dev EXCLUDE_FROM_ALL)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
# Cmake versions < 3.21 did not support installing symbolic links to a directory via install(FILES ...)
# Cmake 3.21 fixed this (https://gitlab.kitware.com/cmake/cmake/-/commit/d71a7cc19d6e03f89581efdaa8d63db216184d40)
# If/when the lowest cmake version supported becomes >= 3.21, the else block as well as the postinit and prerm scripts
# would be a good option to remove in favor of using the facilities in cmake / cpack directly.
add_custom_target(link_target ALL
COMMAND ${CMAKE_COMMAND} -E make_directory lib/python3/dist-packages
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../share/leap_testing/tests/TestHarness lib/python3/dist-packages/TestHarness
COMMAND ${CMAKE_COMMAND} -E make_directory share/leap_testing
COMMAND ${CMAKE_COMMAND} -E create_symlink ../../bin share/leap_testing/bin)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/python3/dist-packages/TestHarness DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages COMPONENT dev EXCLUDE_FROM_ALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/leap_testing/bin DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing COMPONENT dev EXCLUDE_FROM_ALL)
else()
# The following install(CODE ...) steps are necessary for `make dev-install` to work on cmake versions < 3.21.
# However, it can flag as an error if using `make package` instead of `make dev-install` for installation.
# This is due to those directories and symbolic links being created in the postinit script during the package install instead.
# Note If/when doing `make package`, it is not a true error if you see:
# Error creating directory "/<leap_install_dir>/lib/python3/dist-packages".
# CMake Error: failed to create symbolic link '/<leap_install_dir>/lib/python3/dist-packages/TestHarness': no such file or directory
# CMake Error: failed to create symbolic link '/<leap_install_dir>/share/leap_testing/bin': no such file or directory
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages)" COMPONENT dev EXCLUDE_FROM_ALL)
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../share/leap_testing/tests/TestHarness ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages/TestHarness)" COMPONENT dev EXCLUDE_FROM_ALL)
install(CODE "execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ../../bin ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/bin)" COMPONENT dev EXCLUDE_FROM_ALL)
# The `make package` installation of symlinks happens via the `postinst` script installed in cmake.package via the line below
endif()
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/leap-util
${CMAKE_BINARY_DIR}/programs/leap-util/bash-completion/completions/leap-util COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/libraries/cli11/bash-completion/completions/cleos
+12 -12
View File
@@ -72,7 +72,7 @@ git clone --recursive https://github.com/AntelopeIO/leap.git
git clone --recursive git@github.com:AntelopeIO/leap.git
```
> ️ **HTTPS vs. SSH Clone**
> ️ **HTTPS vs. SSH Clone**
Both an HTTPS or SSH git clone will yield the same result - a folder named `leap` containing our source code. It doesn't matter which type you use.
Navigate into that folder:
@@ -96,13 +96,13 @@ git submodule update --init --recursive
### Step 3 - Build
Select build instructions below for a [pinned build](#pinned-build) (preferred) or an [unpinned build](#unpinned-build).
> ️ **Pinned vs. Unpinned Build**
> ️ **Pinned vs. Unpinned Build**
We have two types of builds for Leap: "pinned" and "unpinned." The only difference is that pinned builds use specific versions for some dependencies hand-picked by the Leap engineers - they are "pinned" to those versions. In contrast, unpinned builds use the default dependency versions available on the build system at the time. We recommend performing a "pinned" build to ensure the compiler and boost versions remain the same between builds of different Leap versions. Leap requires these versions to remain the same, otherwise its state might need to be recovered from a portable snapshot or the chain needs to be replayed.
> ⚠️ **A Warning On Parallel Compilation Jobs (`-j` flag)** ⚠️
> ⚠️ **A Warning On Parallel Compilation Jobs (`-j` flag)** ⚠️
When building C/C++ software, often the build is performed in parallel via a command such as `make -j "$(nproc)"` which uses all available CPU threads. However, be aware that some compilation units (`*.cpp` files) in Leap will consume nearly 4GB of memory. Failures due to memory exhaustion will typically, but not always, manifest as compiler crashes. Using all available CPU threads may also prevent you from doing other things on your computer during compilation. For these reasons, consider reducing this value.
> 🐋 **Docker and `sudo`** 🐋
> 🐋 **Docker and `sudo`** 🐋
If you are in an Ubuntu docker container, omit `sudo` from all commands because you run as `root` by default. Most other docker containers also exclude `sudo`, especially Debian-family containers. If your shell prompt is a hash tag (`#`), omit `sudo`.
#### Pinned Build
@@ -111,12 +111,14 @@ Make sure you are in the root of the `leap` repo, then run the `install_depts.sh
sudo scripts/install_deps.sh
```
Next, run the pinned build script. You have to give it three arguments, in the following order:
- A temporary folder, for all dependencies that need to be built from source.
- A build folder, where the binaries you need to install will be built to.
- The number of jobs or CPU cores/threads to use (note the [jobs flag](#step-3---build) warning above).
Next, run the pinned build script. You have to give it three arguments in the following order:
1. A temporary folder, for all dependencies that need to be built from source.
1. A build folder, where the binaries you need to install will be built to.
1. The number of jobs or CPU cores/threads to use (note the [jobs flag](#step-3---build) warning above).
The following command runs the `pinned_build.sh` script, specifies a `deps` and `build` folder in the root of the Leap repo for the first two arguments, then builds the packages using all of your computer's CPU threads (Note: you don't need `sudo` for this command):
> 🔒 You do not need to run this script with `sudo` or as root.
For example, the following command runs the `pinned_build.sh` script, specifies a `deps` and `build` folder in the root of the Leap repo for the first two arguments, then builds the packages using all of your computer's CPU threads:
```bash
scripts/pinned_build.sh deps build "$(nproc)"
```
@@ -146,11 +148,9 @@ To build, make sure you are in the root of the `leap` repo, then run the followi
```bash
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-11 ..
make -j "$(nproc)" package
```
If CMake fails to find a valid llvm configure file, it may be necessary to add `-DCMAKE_PREFIX_PATH=/usr/lib/llvm-11` to the cmake command.
</details>
<details> <summary>Ubuntu 18.04 Bionic</summary>
@@ -143,7 +143,7 @@ We now have an account that is available to have a contract assigned to it, enab
In the fourth terminal window, start a second `nodeos` instance. Notice that this command line is substantially longer than the one we used above to create the first producer. This is necessary to avoid collisions with the first `nodeos` instance. Fortunately, you can just cut and paste this command line and adjust the keys:
```sh
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --private-key [\"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\",\"5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr\"]
nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --signature-provider EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg=KEY:5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr
```
The output from this new node will show a little activity but will stop reporting until the last step in this tutorial, when the `inita` account is registered as a producer account and activated. Here is some example output from a newly started node. Your output might look a little different, depending on how much time you took entering each of these commands. Furthermore, this example is only the last few lines of output:
@@ -39,10 +39,6 @@ Config Options for eosio::producer_plugin:
-p [ --producer-name ] arg ID of producer controlled by this node
(e.g. inita; may specify multiple
times)
--private-key arg (DEPRECATED - Use signature-provider
instead) Tuple of [public key, WIF
private key] (may specify multiple
times)
--signature-provider arg (=EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3)
Key=Value pairs in the form
<public-key>=<provider-spec>
+1 -1
View File
@@ -1533,7 +1533,7 @@ namespace eosio { namespace chain {
ilog("blocks.log and blocks.index agree on number of blocks");
if (interval == 0) {
interval = std::max((log_bundle.log_index.num_blocks() + 7) >> 3, 1);
interval = std::max((log_bundle.log_index.num_blocks() + 7u) >> 3, 1u);
}
uint32_t expected_block_num = log_bundle.log_data.first_block_num();
@@ -32,7 +32,7 @@ class log_index {
bool is_open() const { return file_.is_open(); }
uint64_t back() { return nth_block_position(num_blocks()-1); }
int num_blocks() const { return num_blocks_; }
unsigned num_blocks() const { return num_blocks_; }
uint64_t nth_block_position(uint32_t n) {
file_.seek(n*sizeof(uint64_t));
uint64_t r;
+18 -2
View File
@@ -12,10 +12,11 @@ namespace IR
struct NoImm {};
struct MemoryImm {};
PACKED_STRUCT(
struct ControlStructureImm
{
ResultType resultType{};
};
});
struct BranchImm
{
@@ -675,4 +676,19 @@ namespace IR
};
IR_API const char* getOpcodeName(Opcode opcode);
}
}
//paranoia for future platforms
static_assert(sizeof(IR::OpcodeAndImm<IR::NoImm>) == 2);
static_assert(sizeof(IR::OpcodeAndImm<IR::MemoryImm>) == 2);
static_assert(sizeof(IR::OpcodeAndImm<IR::ControlStructureImm>) == 3);
static_assert(sizeof(IR::OpcodeAndImm<IR::BranchImm>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::BranchTableImm>) == 18);
static_assert(sizeof(IR::OpcodeAndImm<IR::LiteralImm<I32>>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::LiteralImm<I64>>) == 10);
static_assert(sizeof(IR::OpcodeAndImm<IR::LiteralImm<F32>>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::LiteralImm<F64>>) == 10);
static_assert(sizeof(IR::OpcodeAndImm<IR::GetOrSetVariableImm<false>>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::CallImm>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::CallIndirectImm>) == 6);
static_assert(sizeof(IR::OpcodeAndImm<IR::LoadOrStoreImm<0>>) == 10);
+2 -1
View File
@@ -61,7 +61,7 @@ set(CPACK_DEBIAN_BASE_FILE_NAME "${CPACK_DEBIAN_FILE_NAME}.deb")
string(REGEX REPLACE "^(${CMAKE_PROJECT_NAME})" "\\1-dev" CPACK_DEBIAN_DEV_FILE_NAME "${CPACK_DEBIAN_BASE_FILE_NAME}")
#deb package tooling will be unable to detect deps for the dev package. llvm is tricky since we don't know what package could have been used; try to figure it out
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libboost-all-dev, libssl-dev, libgmp-dev")
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "libboost-all-dev, libssl-dev, libgmp-dev, python3-numpy")
find_program(DPKG_QUERY "dpkg-query")
if(DPKG_QUERY AND OS_RELEASE MATCHES "\n?ID=\"?ubuntu" AND LLVM_CMAKE_DIR)
execute_process(COMMAND "${DPKG_QUERY}" -S "${LLVM_CMAKE_DIR}" COMMAND cut -d: -f1 RESULT_VARIABLE LLVM_PKG_FIND_RESULT OUTPUT_VARIABLE LLVM_PKG_FIND_OUTPUT)
@@ -70,6 +70,7 @@ if(DPKG_QUERY AND OS_RELEASE MATCHES "\n?ID=\"?ubuntu" AND LLVM_CMAKE_DIR)
string(APPEND CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ", ${LLVM_PKG_FIND_OUTPUT}")
endif()
endif()
set(CPACK_DEBIAN_DEV_PACKAGE_CONTROL_EXTRA "${CMAKE_BINARY_DIR}/scripts/postinst;${CMAKE_BINARY_DIR}/scripts/prerm")
#since rpm packages aren't component based, make sure description picks up more detailed description instead of just summary
set(CPACK_RPM_PACKAGE_DESCRIPTION "${CPACK_COMPONENT_BASE_DESCRIPTION}")
@@ -846,8 +846,6 @@ void producer_plugin::set_program_options(
"Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited)")
("producer-name,p", boost::program_options::value<vector<string>>()->composing()->multitoken(),
"ID of producer controlled by this node (e.g. inita; may specify multiple times)")
("private-key", boost::program_options::value<vector<string>>()->composing()->multitoken(),
"(DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times)")
("signature-provider", boost::program_options::value<vector<string>>()->composing()->multitoken()->default_value(
{default_priv_key.get_public_key().to_string() + "=KEY:" + default_priv_key.to_string()},
default_priv_key.get_public_key().to_string() + "=KEY:" + default_priv_key.to_string()),
@@ -954,22 +952,6 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_
chain::controller& chain = my->chain_plug->chain();
if( options.count("private-key") )
{
const std::vector<std::string> key_id_to_wif_pair_strings = options["private-key"].as<std::vector<std::string>>();
for (const std::string& key_id_to_wif_pair_string : key_id_to_wif_pair_strings)
{
try {
auto key_id_to_wif_pair = dejsonify<std::pair<public_key_type, private_key_type>>(key_id_to_wif_pair_string);
my->_signature_providers[key_id_to_wif_pair.first] = app().get_plugin<signature_provider_plugin>().signature_provider_for_private_key(key_id_to_wif_pair.second);
auto blanked_privkey = std::string(key_id_to_wif_pair.second.to_string().size(), '*' );
wlog("\"private-key\" is DEPRECATED, use \"signature-provider=${pub}=KEY:${priv}\"", ("pub",key_id_to_wif_pair.first)("priv", blanked_privkey));
} catch ( const std::exception& e ) {
elog("Malformed private key pair");
}
}
}
if( options.count("signature-provider") ) {
const std::vector<std::string> key_spec_pairs = options["signature-provider"].as<std::vector<std::string>>();
for (const auto& key_spec_pair : key_spec_pairs) {
+1 -1
View File
@@ -5,7 +5,7 @@ if( UNIX AND NOT APPLE )
endif()
configure_file(config.hpp.in config.hpp ESCAPE_QUOTES)
configure_file(logging.json ${CMAKE_BINARY_DIR}/logging.json COPYONLY)
configure_file(logging.json ${CMAKE_BINARY_DIR}/tests/TestHarness/logging-template.json)
target_include_directories(${NODE_EXECUTABLE_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+2
View File
@@ -4,3 +4,5 @@ configure_file(eosio-tn_down.sh eosio-tn_down.sh COPYONLY)
configure_file(eosio-tn_roll.sh eosio-tn_roll.sh COPYONLY)
configure_file(eosio-tn_up.sh eosio-tn_up.sh COPYONLY)
configure_file(abi_is_json.py abi_is_json.py COPYONLY)
configure_file(postinst .)
configure_file(prerm .)
+25 -4
View File
@@ -1,6 +1,27 @@
#!/usr/bin/env bash
#!/bin/bash
apt-get update
apt-get update --fix-missing
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata
apt-get -y install zip unzip libncurses5 wget git build-essential cmake curl libgmp-dev libssl-dev libzstd-dev time zlib1g-dev libtinfo-dev bzip2 libbz2-dev python3 python3-numpy file
export DEBIAN_FRONTEND='noninteractive'
export TZ='Etc/UTC'
apt-get install -y \
build-essential \
bzip2 \
cmake \
curl \
file \
git \
libbz2-dev \
libcurl4-openssl-dev \
libgmp-dev \
libncurses5 \
libssl-dev \
libtinfo-dev \
libzstd-dev \
python3 \
python3-numpy \
time \
tzdata \
unzip \
wget \
zip \
zlib1g-dev
+137 -103
View File
@@ -1,151 +1,185 @@
#!/usr/bin/env bash
#!/bin/bash
set -eo pipefail
echo "Leap Pinned Build"
if [[ "$(uname)" == "Linux" ]]; then
if [[ -e /etc/os-release ]]; then
# obtain NAME and other information
. /etc/os-release
if [[ ${NAME} != "Ubuntu" ]]; then
echo "Currently only supporting Ubuntu based builds. Proceed at your own risk."
fi
else
echo "Currently only supporting Ubuntu based builds. /etc/os-release not found. Your Linux distribution is not supported. Proceed at your own risk."
fi
if [[ -e /etc/os-release ]]; then
# obtain NAME and other information
. /etc/os-release
if [[ "${NAME}" != "Ubuntu" ]]; then
echo "Currently only supporting Ubuntu based builds. Proceed at your own risk."
fi
else
echo "Currently only supporting Ubuntu based builds. /etc/os-release not found. Your Linux distribution is not supported. Proceed at your own risk."
fi
else
echo "Currently only supporting Ubuntu based builds. Your architecture is not supported. Proceed at your own risk."
fi
if [ $# -eq 0 ] || [ -z "$1" ]
then
echo "Please supply a directory for the build dependencies to be placed and a directory for leap build and a value for the number of jobs to use for building."
echo "The binary packages will be created and placed into the leap build directory."
echo "./pinned_build.sh <dependencies directory> <leap build directory> <1-100>"
exit -1
if [ $# -eq 0 ] || [ -z "$1" ]; then
echo "Please supply a directory for the build dependencies to be placed and a directory for leap build and a value for the number of jobs to use for building."
echo "The binary packages will be created and placed into the leap build directory."
echo "./pinned_build.sh <dependencies directory> <leap build directory> <1-100>"
exit 255
fi
CORE_SYM=EOS
export CORE_SYM='EOS'
# CMAKE_C_COMPILER requires absolute path
DEP_DIR=`realpath $1`
LEAP_DIR=$2
JOBS=$3
DEP_DIR="$(realpath "$1")"
LEAP_DIR="$2"
JOBS="$3"
CLANG_VER=11.0.1
BOOST_VER=1.70.0
LLVM_VER=7.1.0
ARCH=`uname -m`
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )";
START_DIR="$(pwd)"
pushdir() {
DIR=$1
mkdir -p ${DIR}
pushd ${DIR} &> /dev/null
DIR="$1"
mkdir -p "${DIR}"
pushd "${DIR}" &> /dev/null
}
popdir() {
EXPECTED=$1
D=`popd`
popd &> /dev/null
echo ${D}
D=`eval echo $D | head -n1 | cut -d " " -f1`
EXPECTED="$1"
D="$(popd)"
popd &> /dev/null
echo "${D}"
D="$(eval echo "$D" | head -n1 | cut -d " " -f1)"
# -ef compares absolute paths
if ! [[ ${D} -ef ${EXPECTED} ]]; then
echo "Directory is not where expected EXPECTED=${EXPECTED} at ${D}"
exit 1
fi
# -ef compares absolute paths
if ! [[ "${D}" -ef "${EXPECTED}" ]]; then
echo "Directory is not where expected EXPECTED=${EXPECTED} at ${D}"
exit 1
fi
}
try(){
output=$($@)
res=$?
if [[ ${res} -ne 0 ]]; then
exit -1
fi
"$@"
res=$?
if [[ ${res} -ne 0 ]]; then
exit 255
fi
}
install_clang() {
CLANG_DIR=$1
if [ ! -d "${CLANG_DIR}" ]; then
echo "Installing Clang ${CLANG_VER} @ ${CLANG_DIR}"
mkdir -p ${CLANG_DIR}
CLANG_FN=clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-16.04.tar.xz
try wget -O ${CLANG_FN} https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VER}/${CLANG_FN}
try tar -xvf ${CLANG_FN} -C ${CLANG_DIR}
pushdir ${CLANG_DIR}
mv clang+*/* .
popdir ${DEP_DIR}
rm ${CLANG_FN}
fi
export PATH=${CLANG_DIR}/bin:$PATH
export CLANG_DIR=${CLANG_DIR}
CLANG_DIR="$1"
if [ ! -d "${CLANG_DIR}" ]; then
echo "Installing Clang ${CLANG_VER} @ ${CLANG_DIR}"
mkdir -p "${CLANG_DIR}"
CLANG_FN="clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-16.04.tar.xz"
try wget -O "${CLANG_FN}" "https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VER}/${CLANG_FN}"
try tar -xvf "${CLANG_FN}" -C "${CLANG_DIR}"
pushdir "${CLANG_DIR}"
mv clang+*/* .
popdir "${DEP_DIR}"
rm "${CLANG_FN}"
fi
export PATH="${CLANG_DIR}/bin:$PATH"
export CLANG_DIR="${CLANG_DIR}"
}
install_llvm() {
LLVM_DIR=$1
if [ ! -d "${LLVM_DIR}" ]; then
echo "Installing LLVM ${LLVM_VER} @ ${LLVM_DIR}"
mkdir -p ${LLVM_DIR}
try wget -O llvm-${LLVM_VER}.src.tar.xz https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VER}/llvm-${LLVM_VER}.src.tar.xz
try tar -xvf llvm-${LLVM_VER}.src.tar.xz
pushdir "${LLVM_DIR}.src"
pushdir build
try cmake -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_DIR}/pinned_toolchain.cmake -DCMAKE_INSTALL_PREFIX=${LLVM_DIR} -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_BUILD_TOOLS=Off -DLLVM_ENABLE_RTTI=On -DLLVM_ENABLE_TERMINFO=Off -DCMAKE_EXE_LINKER_FLAGS=-pthread -DCMAKE_SHARED_LINKER_FLAGS=-pthread -DLLVM_ENABLE_PIC=NO ..
try make -j${JOBS}
try make -j${JOBS} install
popdir "${LLVM_DIR}.src"
popdir ${DEP_DIR}
rm -rf ${LLVM_DIR}.src
rm llvm-${LLVM_VER}.src.tar.xz
fi
export LLVM_DIR=${LLVM_DIR}
LLVM_DIR="$1"
if [ ! -d "${LLVM_DIR}" ]; then
echo "Installing LLVM ${LLVM_VER} @ ${LLVM_DIR}"
mkdir -p "${LLVM_DIR}"
try wget -O "llvm-${LLVM_VER}.src.tar.xz" "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VER}/llvm-${LLVM_VER}.src.tar.xz"
try tar -xvf "llvm-${LLVM_VER}.src.tar.xz"
pushdir "${LLVM_DIR}.src"
pushdir build
try cmake -DCMAKE_TOOLCHAIN_FILE="${SCRIPT_DIR}/pinned_toolchain.cmake" -DCMAKE_INSTALL_PREFIX="${LLVM_DIR}" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_BUILD_TOOLS=Off -DLLVM_ENABLE_RTTI=On -DLLVM_ENABLE_TERMINFO=Off -DCMAKE_EXE_LINKER_FLAGS=-pthread -DCMAKE_SHARED_LINKER_FLAGS=-pthread -DLLVM_ENABLE_PIC=NO ..
try make -j "${JOBS}"
try make -j "${JOBS}" install
popdir "${LLVM_DIR}.src"
popdir "${DEP_DIR}"
rm -rf "${LLVM_DIR}.src"
rm "llvm-${LLVM_VER}.src.tar.xz"
fi
export LLVM_DIR="${LLVM_DIR}"
}
install_boost() {
BOOST_DIR=$1
BOOST_DIR="$1"
if [ ! -d "${BOOST_DIR}" ]; then
echo "Installing Boost ${BOOST_VER} @ ${BOOST_DIR}"
try wget -O boost_${BOOST_VER//\./_}.tar.gz https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VER}/source/boost_${BOOST_VER//\./_}.tar.gz
try tar --transform="s:^boost_${BOOST_VER//\./_}:boost_${BOOST_VER//\./_}patched:" -xvzf boost_${BOOST_VER//\./_}.tar.gz -C ${DEP_DIR}
pushdir ${BOOST_DIR}
patch -p1 < "${SCRIPT_DIR}/0001-beast-fix-moved-from-executor.patch"
try ./bootstrap.sh -with-toolset=clang --prefix=${BOOST_DIR}/bin
./b2 toolset=clang cxxflags='-stdlib=libc++ -D__STRICT_ANSI__ -nostdinc++ -I${CLANG_DIR}/include/c++/v1 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE' linkflags='-stdlib=libc++ -pie' link=static threading=multi --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -q -j${JOBS} install
popdir ${DEP_DIR}
rm boost_${BOOST_VER//\./_}.tar.gz
fi
export BOOST_DIR=${BOOST_DIR}
if [ ! -d "${BOOST_DIR}" ]; then
echo "Installing Boost ${BOOST_VER} @ ${BOOST_DIR}"
try wget -O "boost_${BOOST_VER//\./_}.tar.gz" "https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VER}/source/boost_${BOOST_VER//\./_}.tar.gz"
try tar --transform="s:^boost_${BOOST_VER//\./_}:boost_${BOOST_VER//\./_}patched:" -xvzf "boost_${BOOST_VER//\./_}.tar.gz" -C "${DEP_DIR}"
pushdir "${BOOST_DIR}"
patch -p1 < "${SCRIPT_DIR}/0001-beast-fix-moved-from-executor.patch"
try ./bootstrap.sh -with-toolset=clang --prefix="${BOOST_DIR}/bin"
./b2 toolset=clang cxxflags="-stdlib=libc++ -D__STRICT_ANSI__ -nostdinc++ -I\${CLANG_DIR}/include/c++/v1 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE" linkflags='-stdlib=libc++ -pie' link=static threading=multi --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -q -j "${JOBS}" install
popdir "${DEP_DIR}"
rm "boost_${BOOST_VER//\./_}.tar.gz"
fi
export BOOST_DIR="${BOOST_DIR}"
}
pushdir ${DEP_DIR}
pushdir "${DEP_DIR}"
install_clang ${DEP_DIR}/clang-${CLANG_VER}
install_llvm ${DEP_DIR}/llvm-${LLVM_VER}
install_boost ${DEP_DIR}/boost_${BOOST_VER//\./_}patched
install_clang "${DEP_DIR}/clang-${CLANG_VER}"
install_llvm "${DEP_DIR}/llvm-${LLVM_VER}"
install_boost "${DEP_DIR}/boost_${BOOST_VER//\./_}patched"
# go back to the directory where the script starts
popdir ${START_DIR}
popdir "${START_DIR}"
pushdir ${LEAP_DIR}
pushdir "${LEAP_DIR}"
# build Leap
echo "Building Leap ${SCRIPT_DIR}"
try cmake -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_DIR}/pinned_toolchain.cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${LLVM_DIR}/lib/cmake -DCMAKE_PREFIX_PATH=${BOOST_DIR}/bin ${SCRIPT_DIR}/..
try cmake -DCMAKE_TOOLCHAIN_FILE="${SCRIPT_DIR}/pinned_toolchain.cmake" -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="${LLVM_DIR}/lib/cmake" -DCMAKE_PREFIX_PATH="${BOOST_DIR}/bin" "${SCRIPT_DIR}/.."
try make -j${JOBS}
try make -j "${JOBS}"
try cpack
echo " .----------------. .----------------. .----------------. .----------------. ";
echo "| .--------------. || .--------------. || .--------------. || .--------------. |";
echo "| | _____ | || | _________ | || | __ | || | ______ | |";
echo "| | |_ _| | || | |_ ___ | | || | / \ | || | |_ __ \ | |";
echo "| | | | | || | | |_ \_| | || | / /\ \ | || | | |__) | | |";
echo "| | | | _ | || | | _| _ | || | / ____ \ | || | | ___/ | |";
echo "| | _| |__/ | | || | _| |___/ | | || | _/ / \ \_ | || | _| |_ | |";
echo "| | |________| | || | |_________| | || ||____| |____|| || | |_____| | |";
echo "| | | || | | || | | || | | |";
echo "| '--------------' || '--------------' || '--------------' || '--------------' |";
echo " '----------------' '----------------' '----------------' '----------------' ";
echo "Leap has successfully built and constructed its packages. You should be able to find the packages at ${LEAP_DIR}. Enjoy!!!"
# art generated with DALL-E (https://openai.com/blog/dall-e), then fed through ASCIIart.club (https://asciiart.club) with permission
cat <<'TXT' # BASH interpolation must remain disabled for the ASCII art to print correctly
,▄▄A`
_╓▄██`
╓▄▓▓▀▀`
╓▓█▀╓▄▓
▓▌▓▓▓▀
,▄▓███▓H
_╨╫▀╚▀╠▌`╙¥,
╓« _╟▄▄ `½, ╓▄▄╦▄≥_
╙▓╫╬▒R▀▀╙▀▀▓φ_ «_╙Y╥▄mmMM#╦▄,_ ,╓╦mM╩╨╙╙╙\`║═
`` `▀▄__╫▓▓╨` _```"""*ⁿⁿ^`````Ω, `╟∩
╙▌▓▓"` ,«ñ` ╔╬▓▌⌂ ╔▌
╙█▌,,╔╗M╨,░ ` "╫▓m_ ╟H _
_,,,,__,╠█▓▒` .╣▌µ _ _.╓╔▄▄▓█▓▓N_ ╙▀╩KKM╙╟▓N
,▄▓█▓████▀▀▀╙▀╓╔φ»█▓▓Ñ╦«, :»»µ╦▓▓█▀└╙▀███▓╥__ _,╓▄▓▓▓M▓`,
__╓Φ▓█╫▓▓▓▓▓▓▓▓▓▓▓▓▓▀K▀▀███▓▓▓▓▓▓▀▀╙ `▀▀▀▓▄▄K╨╙└ `▀▌╙█▄*.
,╓Φ▓▓▀▄▓▀` ╙▀╙ ╙▓╙╙▓▄*
.▄▓╫▀╦▄▀` ╙▓╙µ╙▀
▄▓▀╨▓▓╨_ `▀▄▄M
_█▌▄▌╙` `╙
╙└`
Ñ▓▓▓▓ ¢▄▄▄▄▄▄▄▄▄▄ , ,,,,,,,,,,,_
_╫▓▓█▌ ╟▓████████▀ ╓╣▓▌_ ╠╫▓█▓▓▓▓█▓▓▓▓▄
_▓▓▓█▌ ╟╫██▄,,,,_ æ▄███▓▄ ▐║████▀╨╨▀▓███▌
:╫▓▓█▌ ╟╢████████▓ ,╬███████▓, ▐║████▓▄▄▓▓███▀
:╫▓▓█▌_ _╟║███▀▀▀▀▀▀ ╓╫███╣╫╬███▓N_ j▐██▀▀▀▀▀▀▀▀▀`
___________]╫▓▓█▓φ╓╓╓╓╓╓,__╟╣█▌▌,,,,,_ _╬▓████████████▓▄_ ▐M█▌
_ _________]╫▌▓█████████▓▓▄╟╣████████▓▄╣██▓▀^ _ ╙▓██▓▓╗__M█▓
___ _ _ ▀╣▀╣╩╩╩╩╩╩╩▀▀▀▀╙▀▀▀▀▀▀▀▀▀▀▀▀▀▀` ╙▀▀▀▀╩═╩▀▀
_ __ __ _____ ___ ____ _ __ _ ____ ___
____ ____ __ _ _ _ _ _ _ __ _ __ __
__ _ ________ ___ ________ ___ _ _ _ _
_ __ __ _ __ ____ _ _ ____ _ _ _ _
_ _ _ ____ ____ _ _ _ __ _ _ _ __
---
Leap has successfully built and constructed its packages. You should be able to
find the packages at:
TXT
echo "${LEAP_DIR}"
echo
echo 'Thank you, fam!!'
echo
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
set -e
if [ ! -L ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages/TestHarness ]; then
mkdir -p ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages
ln -s ../../../share/leap_testing/tests/TestHarness ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages/TestHarness
fi
# leap_testing is part of the package so should already exist by the time postinst runs
if [ ! -L ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/bin ]; then
ln -s ../../bin ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/bin
fi
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
# Cleanup symbolic links created during postinst
rm -f ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages/TestHarness
rm -f ${CMAKE_INSTALL_FULL_DATAROOTDIR}/leap_testing/bin
# Attempt to clean up directories that may have been created during postinst
# Also may have already existed, so it is acceptable to leave them in place if the rmdir fails
rmdir --ignore-fail-on-non-empty ${CMAKE_INSTALL_FULL_LIBDIR}/python3/dist-packages
rmdir --ignore-fail-on-non-empty ${CMAKE_INSTALL_FULL_LIBDIR}/python3
+6 -4
View File
@@ -13,8 +13,6 @@ target_include_directories( plugin_test PUBLIC
${CMAKE_SOURCE_DIR}/unittests
${CMAKE_BINARY_DIR}/unittests/include/ )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/core_symbol.py.in ${CMAKE_CURRENT_BINARY_DIR}/core_symbol.py)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/p2p_tests/dawn_515/test.sh ${CMAKE_CURRENT_BINARY_DIR}/p2p_tests/dawn_515/test.sh COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/block_log_util_test.py ${CMAKE_CURRENT_BINARY_DIR}/block_log_util_test.py COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/block_log_retain_blocks_test.py ${CMAKE_CURRENT_BINARY_DIR}/block_log_retain_blocks_test.py COPYONLY)
@@ -127,8 +125,12 @@ add_test(NAME nodeos_protocol_feature_test COMMAND tests/nodeos_protocol_feature
set_property(TEST nodeos_protocol_feature_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME compute_transaction_test COMMAND tests/compute_transaction_test.py -v -p 2 -n 3 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST compute_transaction_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME read_only_trx_test COMMAND tests/read_only_trx_test.py -v -p 2 -n 3 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST read_only_trx_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME read-only-trx-basic-test COMMAND tests/read_only_trx_test.py -v -p 2 -n 3 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST read-only-trx-basic-test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME read-only-trx-parallel-test COMMAND tests/read_only_trx_test.py -v -p 2 -n 3 --read-only-threads 3 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST read-only-trx-parallel-test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME read-only-trx-parallel-eos-vm-oc-test COMMAND tests/read_only_trx_test.py -v -p 2 -n 3 --eos-vm-oc-enable --read-only-threads 3 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST read-only-trx-parallel-eos-vm-oc-test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME subjective_billing_test COMMAND tests/subjective_billing_test.py -v -p 2 -n 4 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST subjective_billing_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME get_account_test COMMAND tests/get_account_test.py -v -p 2 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+1
View File
@@ -1,4 +1,5 @@
configure_file(__init__.py . COPYONLY)
configure_file(core_symbol.py.in core_symbol.py)
configure_file(testUtils.py . COPYONLY)
configure_file(WalletMgr.py . COPYONLY)
configure_file(Node.py . COPYONLY)
+20 -15
View File
@@ -14,7 +14,7 @@ import json
import socket
from pathlib import Path
from core_symbol import CORE_SYMBOL
from .core_symbol import CORE_SYMBOL
from .testUtils import Account
from .testUtils import BlockLogAction
from .testUtils import Utils
@@ -133,6 +133,10 @@ class Cluster(object):
self.nodeosVers=nodeosVers
self.nodeosLogPath=Path(Utils.TestLogRoot) / Path(f'{Path(sys.argv[0]).stem}{os.getpid()}')
self.launcherPath = Path(__file__).resolve().parents[1] / "launcher.py"
self.libTestingContractsPath = Path(__file__).resolve().parents[2] / "libraries" / "testing" / "contracts"
self.unittestsContractsPath = Path(__file__).resolve().parents[2] / "unittests" / "contracts"
if unshared:
unshare(CLONE_NEWNET)
for index, name in socket.if_nameindex():
@@ -259,7 +263,7 @@ class Cluster(object):
time.sleep(2)
loggingLevelDictString = json.dumps(self.loggingLevelDict, separators=(',', ':'))
cmd="%s %s -p %s -n %s -d %s -i %s -f %s --unstarted-nodes %s --logging-level %s --logging-level-map %s" % (
sys.executable, "tests/launcher.py", pnodes, totalNodes, delay, datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3],
sys.executable, str(self.launcherPath), pnodes, totalNodes, delay, datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3],
producerFlag, unstartedNodes, self.loggingLevel, loggingLevelDictString)
cmdArr=cmd.split()
if self.staging:
@@ -976,7 +980,7 @@ class Cluster(object):
with open(configFile, 'r') as f:
configStr=f.read()
pattern=r"^\s*private-key\s*=\W+(\w+)\W+(\w+)\W+$"
pattern=r"^\s*signature-provider\s*=\s*(\w+)=KEY:(\w+)$"
m=re.search(pattern, configStr, re.MULTILINE)
regMsg="None" if m is None else "NOT None"
if m is None:
@@ -1083,11 +1087,11 @@ class Cluster(object):
return None
contract="eosio.bios"
contractDir="libraries/testing/contracts/%s" % (contract)
contractDir= str(self.libTestingContractsPath / contract)
if PFSetupPolicy.hasPreactivateFeature(pfSetupPolicy):
contractDir="libraries/testing/contracts/old_versions/v1.7.0-develop-preactivate_feature/%s" % (contract)
contractDir=str(self.libTestingContractsPath / "old_versions" / "v1.7.0-develop-preactivate_feature" / contract)
else:
contractDir="libraries/testing/contracts/old_versions/v1.6.0-rc3/%s" % (contract)
contractDir=str(self.libTestingContractsPath / "old_versions" / "v1.6.0-rc3" / contract)
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
@@ -1203,7 +1207,7 @@ class Cluster(object):
eosioTokenAccount = copy.deepcopy(eosioAccount)
eosioTokenAccount.name = 'eosio.token'
contract="eosio.token"
contractDir="unittests/contracts/%s" % (contract)
contractDir=str(self.unittestsContractsPath / contract)
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
@@ -1259,7 +1263,7 @@ class Cluster(object):
if loadSystemContract:
contract="eosio.system"
contractDir="unittests/contracts/%s" % (contract)
contractDir=str(self.unittestsContractsPath / contract)
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
@@ -1443,7 +1447,7 @@ class Cluster(object):
def killall(self, kill=True, silent=True, allInstances=False):
"""Kill cluster nodeos instances. allInstances will kill all nodeos instances running on the system."""
signalNum=9 if kill else 15
cmd="%s -k %d --nogen -p 1 -n 1 --nodeos-log-path %s" % ("python3 tests/launcher.py", signalNum, self.nodeosLogPath)
cmd="%s -k %d --nogen -p 1 -n 1 --nodeos-log-path %s" % (f"python3 {str(self.launcherPath)}", signalNum, self.nodeosLogPath)
if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
if 0 != subprocess.call(cmd.split(), stdout=Utils.FNull):
if not silent: Utils.Print("Launcher failed to shut down eos cluster.")
@@ -1689,7 +1693,6 @@ class Cluster(object):
waitToComplete:bool=False, abiFile=None, actionsData=None, actionsAuths=None):
Utils.Print("Configure txn generators")
node=self.getNode(nodeId)
p2pListenPort = self.getNodeP2pPort(nodeId)
info = node.getInfo()
chainId = info['chain_id']
lib_id = info['last_irreversible_block_id']
@@ -1698,13 +1701,12 @@ class Cluster(object):
tpsLimitPerGenerator=tpsPerGenerator
self.preExistingFirstTrxFiles = glob.glob(f"{Utils.DataDir}/first_trx_*.txt")
tpsTrxGensConfig = TpsTrxGensConfig(targetTps=targetTps, tpsLimitPerGenerator=tpsLimitPerGenerator)
connectionPairList = [f"{self.host}:{self.getNodeP2pPort(nodeId)}"]
tpsTrxGensConfig = TpsTrxGensConfig(targetTps=targetTps, tpsLimitPerGenerator=tpsLimitPerGenerator, connectionPairList=connectionPairList)
self.trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id,
contractOwnerAccount=contractOwnerAcctName, accts=','.join(map(str, acctNamesList)),
privateKeys=','.join(map(str, acctPrivKeysList)), trxGenDurationSec=durationSec, logDir=Utils.DataDir,
abiFile=abiFile, actionsData=actionsData, actionsAuths=actionsAuths,
peerEndpoint=self.host, port=p2pListenPort, tpsTrxGensConfig=tpsTrxGensConfig)
abiFile=abiFile, actionsData=actionsData, actionsAuths=actionsAuths, tpsTrxGensConfig=tpsTrxGensConfig)
Utils.Print("Launch txn generators and start generating/sending transactions")
self.trxGenLauncher.launch(waitToComplete=waitToComplete)
@@ -1725,4 +1727,7 @@ class Cluster(object):
for line in f:
firstTrxs.append(line.rstrip('\n'))
Utils.Print(f"first transactions: {firstTrxs}")
node.waitForTransactionsInBlock(firstTrxs)
status = node.waitForTransactionsInBlock(firstTrxs)
if status is None:
Utils.Print('ERROR: Failed to spin up transaction generators: never received first transactions')
return status
+5 -1
View File
@@ -10,7 +10,7 @@ import sys
from datetime import datetime
from datetime import timedelta
from core_symbol import CORE_SYMBOL
from .core_symbol import CORE_SYMBOL
from .queries import NodeosQueries, BlockType
from .transactions import Transactions
from .testUtils import Utils
@@ -484,6 +484,10 @@ class Node(Transactions):
def scheduleSnapshot(self):
return self.processUrllibRequest("producer", "schedule_snapshot")
def scheduleSnapshotAt(self, sbn):
param = { "start_block_num": sbn, "end_block_num": sbn }
return self.processUrllibRequest("producer", "schedule_snapshot", param)
# kill all existing nodeos in case lingering from previous test
@staticmethod
+2 -1
View File
@@ -1,4 +1,4 @@
__all__ = ['Node', 'Cluster', 'WalletMgr', 'logging', 'depresolver', 'testUtils', 'TestHelper', 'queries', 'transactions', 'launch_transaction_generators', 'TransactionGeneratorsLauncher', 'TpsTrxGensConfig']
__all__ = ['Node', 'Cluster', 'WalletMgr', 'logging', 'depresolver', 'testUtils', 'TestHelper', 'queries', 'transactions', 'launch_transaction_generators', 'TransactionGeneratorsLauncher', 'TpsTrxGensConfig', 'core_symbol']
from .Cluster import Cluster
from .Node import Node
@@ -9,3 +9,4 @@ from .testUtils import Utils
from .Node import ReturnType
from .TestHelper import TestHelper
from .launch_transaction_generators import TransactionGeneratorsLauncher, TpsTrxGensConfig
from .core_symbol import CORE_SYMBOL
+5
View File
@@ -0,0 +1,5 @@
import os
sys_core_symbol = os.environ.get('CORE_SYMBOL_NAME')
CORE_SYMBOL=sys_core_symbol if sys_core_symbol else '${CORE_SYMBOL_NAME}'
@@ -10,16 +10,19 @@ sys.path.append(harnessPath)
from .testUtils import Utils
from pathlib import Path
from re import sub
Print = Utils.Print
class TpsTrxGensConfig:
def __init__(self, targetTps: int, tpsLimitPerGenerator: int):
def __init__(self, targetTps: int, tpsLimitPerGenerator: int, connectionPairList: list):
self.targetTps: int = targetTps
self.tpsLimitPerGenerator: int = tpsLimitPerGenerator
self.numGenerators = math.ceil(self.targetTps / self.tpsLimitPerGenerator)
self.connectionPairList = connectionPairList
self.numConnectionPairs = len(self.connectionPairList)
round_to_multiple = lambda num, multiple: math.ceil(num/multiple) * multiple
self.numGenerators = round_to_multiple(math.ceil(self.targetTps / self.tpsLimitPerGenerator), self.numConnectionPairs)
self.initialTpsPerGenerator = math.floor(self.targetTps / self.numGenerators)
self.modTps = self.targetTps % self.numGenerators
self.cleanlyDivisible = self.modTps == 0
@@ -35,8 +38,7 @@ class TpsTrxGensConfig:
class TransactionGeneratorsLauncher:
def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAccount: str, accts: str, privateKeys: str, trxGenDurationSec: int, logDir: str,
abiFile: Path, actionsData, actionsAuths,
peerEndpoint: str, port: int, tpsTrxGensConfig: TpsTrxGensConfig):
abiFile: Path, actionsData, actionsAuths, tpsTrxGensConfig: TpsTrxGensConfig):
self.chainId = chainId
self.lastIrreversibleBlockId = lastIrreversibleBlockId
self.contractOwnerAccount = contractOwnerAccount
@@ -46,14 +48,14 @@ class TransactionGeneratorsLauncher:
self.tpsTrxGensConfig = tpsTrxGensConfig
self.logDir = logDir
self.abiFile = abiFile
self.actionsData=actionsData
self.actionsAuths=actionsAuths
self.peerEndpoint = peerEndpoint
self.port = port
self.actionsData = actionsData
self.actionsAuths = actionsAuths
def launch(self, waitToComplete=True):
self.subprocess_ret_codes = []
connectionPairIter = 0
for id, targetTps in enumerate(self.tpsTrxGensConfig.targetTpsPerGenList):
connectionPair = self.tpsTrxGensConfig.connectionPairList[connectionPairIter].rsplit(":")
popenStringList = [
'./tests/trx_generator/trx_generator',
'--generator-id', f'{id}',
@@ -65,8 +67,8 @@ class TransactionGeneratorsLauncher:
'--trx-gen-duration', f'{self.trxGenDurationSec}',
'--target-tps', f'{targetTps}',
'--log-dir', f'{self.logDir}',
'--peer-endpoint', f'{self.peerEndpoint}',
'--port', f'{self.port}']
'--peer-endpoint', f'{connectionPair[0]}',
'--port', f'{connectionPair[1]}']
if self.abiFile is not None and self.actionsData is not None and self.actionsAuths is not None:
popenStringList.extend(['--abi-file', f'{self.abiFile}',
'--actions-data', f'{self.actionsData}',
@@ -74,6 +76,7 @@ class TransactionGeneratorsLauncher:
if Utils.Debug:
Print(f"Running trx_generator: {' '.join(popenStringList)}")
self.subprocess_ret_codes.append(subprocess.Popen(popenStringList))
connectionPairIter = (connectionPairIter + 1) % len(self.tpsTrxGensConfig.connectionPairList)
exitCodes=None
if waitToComplete:
exitCodes = [ret_code.wait() for ret_code in self.subprocess_ret_codes]
@@ -100,20 +103,20 @@ def parseArgs():
parser.add_argument("abi_file", type=str, help="The path to the contract abi file to use for the supplied transaction action data")
parser.add_argument("actions_data", type=str, help="The json actions data file or json actions data description string to use")
parser.add_argument("actions_auths", type=str, help="The json actions auth file or json actions auths description string to use, containting authAcctName to activePrivateKey pairs.")
parser.add_argument("peer_endpoint", type=str, help="set the peer endpoint to send transactions to", default="127.0.0.1")
parser.add_argument("port", type=int, help="set the peer endpoint port to send transactions to", default=9876)
parser.add_argument("connection_pair_list", type=str, help="Comma separated list of endpoint:port combinations to send transactions to", default="localhost:9876")
args = parser.parse_args()
return args
def main():
args = parseArgs()
connectionPairList = sub('[\s+]', '', args.connection_pair_list)
connectionPairList = connectionPairList.rsplit(',')
trxGenLauncher = TransactionGeneratorsLauncher(chainId=args.chain_id, lastIrreversibleBlockId=args.last_irreversible_block_id,
contractOwnerAccount=args.contract_owner_account, accts=args.accounts,
privateKeys=args.priv_keys, trxGenDurationSec=args.trx_gen_duration, logDir=args.log_dir,
abiFile=args.abi_file, actionsData=args.actions_data, actionsAuths=args.actions_auths,
peerEndpoint=args.peer_endpoint, port=args.port,
tpsTrxGensConfig=TpsTrxGensConfig(targetTps=args.target_tps, tpsLimitPerGenerator=args.tps_limit_per_generator))
tpsTrxGensConfig=TpsTrxGensConfig(targetTps=args.target_tps, tpsLimitPerGenerator=args.tps_limit_per_generator, connectionPairList=connectionPairList))
exit_codes = trxGenLauncher.launch()
+12 -11
View File
@@ -10,7 +10,7 @@ import urllib.request
import urllib.parse
import urllib.error
from core_symbol import CORE_SYMBOL
from .core_symbol import CORE_SYMBOL
from .testUtils import Account
from .testUtils import EnumType
from .testUtils import addEnum
@@ -118,10 +118,10 @@ class NodeosQueries:
# could be a transaction response
if cntxt.hasKey("processed"):
cntxt.add("processed")
cntxt.add("action_traces")
cntxt.index(0)
if not cntxt.isSectionNull("except"):
return "no_block"
cntxt.add("action_traces")
cntxt.index(0)
return cntxt.add("block_num")
# or what the trace api plugin returns
@@ -242,7 +242,7 @@ class NodeosQueries:
assert(isinstance(transId, str))
exitOnErrorForDelayed=not delayedRetry and exitOnError
timeout=3
cmdDesc="get transaction_trace"
cmdDesc=self.fetchTransactionCommand()
cmd="%s %s" % (cmdDesc, transId)
msg="(transaction id=%s)" % (transId);
for i in range(0,(int(60/timeout) - 1)):
@@ -295,8 +295,8 @@ class NodeosQueries:
refBlockNum=None
key=""
try:
key="[transaction][transaction_header][ref_block_num]"
refBlockNum=trans["transaction_header"]["ref_block_num"]
key = self.fetchKeyCommand()
refBlockNum = self.fetchRefBlock(trans)
refBlockNum=int(refBlockNum)+1
except (TypeError, ValueError, KeyError) as _:
Utils.Print("transaction%s not found. Transaction: %s" % (key, trans))
@@ -347,8 +347,8 @@ class NodeosQueries:
def getTable(self, contract, scope, table, exitOnError=False):
cmdDesc = "get table"
cmd="%s %s %s %s" % (cmdDesc, contract, scope, table)
msg="contract=%s, scope=%s, table=%s" % (contract, scope, table);
cmd=f"{cmdDesc} {self.cleosLimit} {contract} {scope} {table}"
msg=f"contract={contract}, scope={scope}, table={table}"
return self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
def getTableAccountBalance(self, contract, scope):
@@ -529,7 +529,7 @@ class NodeosQueries:
return m.group(1)
except subprocess.CalledProcessError as ex:
end=time.perf_counter()
msg=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
Utils.Print("ERROR: Exception during code hash retrieval. cmd Duration: %.3f sec. %s" % (end-start, msg))
return None
@@ -580,8 +580,9 @@ class NodeosQueries:
except subprocess.CalledProcessError as ex:
if not silentErrors:
end=time.perf_counter()
msg=ex.output.decode("utf-8")
errorMsg="Exception during \"%s\". Exception message: %s. cmd Duration=%.3f sec. %s" % (cmdDesc, msg, end-start, exitMsg)
out=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
errorMsg="Exception during \"%s\". Exception message: %s. stdout: %s. cmd Duration=%.3f sec. %s" % (cmdDesc, msg, out, end-start, exitMsg)
if exitOnError:
Utils.cmdError(errorMsg)
Utils.errorExit(errorMsg)
+11 -9
View File
@@ -16,6 +16,7 @@ from sys import exit
import traceback
import shutil
import sys
from pathlib import Path
###########################################################################################
@@ -55,27 +56,28 @@ class Utils:
Debug=False
FNull = open(os.devnull, 'w')
EosClientPath="programs/cleos/cleos"
testBinPath = Path(__file__).resolve().parents[2] / 'bin'
EosClientPath=str(testBinPath / "cleos")
MiscEosClientArgs="--no-auto-keosd"
LeapClientPath="programs/leap-util/leap-util"
LeapClientPath=str(testBinPath / "leap-util")
EosWalletName="keosd"
EosWalletPath="programs/keosd/"+ EosWalletName
EosWalletPath=str(testBinPath / EosWalletName)
EosServerName="nodeos"
EosServerPath="programs/nodeos/"+ EosServerName
EosServerPath=str(testBinPath / EosServerName)
EosLauncherPath="programs/eosio-launcher/eosio-launcher"
ShuttingDown=False
FileDivider="================================================================="
TestLogRoot="TestLogs"
TestLogRoot=f"{str(Path.cwd().resolve())}/TestLogs"
DataRoot=os.path.basename(sys.argv[0]).rsplit('.',maxsplit=1)[0]
PID = os.getpid()
DataPath= f"{TestLogRoot}/{DataRoot}{PID}"
DataDir= f"{DataPath}/"
ConfigDir="etc/eosio/"
ConfigDir=f"{str(Path.cwd().resolve())}/etc/eosio/"
TimeFmt='%Y-%m-%dT%H:%M:%S.%f'
@@ -88,10 +90,10 @@ class Utils:
stop=Utils.timestamp()
if not hasattr(Utils, "checkOutputFile"):
if not os.path.isdir(Utils.TestLogRoot):
if Utils.Debug: Utils.Print("creating dir %s in dir: %s" % (Utils.TestLogRoot, os.getcwd()))
if Utils.Debug: Utils.Print("TestLogRoot creating dir %s in dir: %s" % (Utils.TestLogRoot, os.getcwd()))
os.mkdir(Utils.TestLogRoot)
if not os.path.isdir(Utils.DataPath):
if Utils.Debug: Utils.Print("creating dir %s in dir: %s" % (Utils.DataPath, os.getcwd()))
if Utils.Debug: Utils.Print("DataPath creating dir %s in dir: %s" % (Utils.DataPath, os.getcwd()))
os.mkdir(Utils.DataPath)
filename=f"{Utils.DataPath}/subprocess_results.log"
if Utils.Debug: Utils.Print("opening %s in dir: %s" % (filename, os.getcwd()))
+10 -9
View File
@@ -4,7 +4,7 @@ import json
import subprocess
import time
from core_symbol import CORE_SYMBOL
from .core_symbol import CORE_SYMBOL
from .depresolver import dep
from .queries import NodeosQueries
from .testUtils import Account
@@ -107,7 +107,7 @@ class Transactions(NodeosQueries):
self.trackCmdTransaction(trans, reportStatus=reportStatus)
except subprocess.CalledProcessError as ex:
end=time.perf_counter()
msg=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
Utils.Print("ERROR: Exception during funds transfer. cmd Duration: %.3f sec. %s" % (end-start, msg))
if exitOnError:
Utils.cmdError("could not transfer \"%s\" from %s to %s" % (amountStr, source, destination))
@@ -131,7 +131,7 @@ class Transactions(NodeosQueries):
Utils.Print("cmd Duration: %.3f sec" % (end-start))
except subprocess.CalledProcessError as ex:
end=time.perf_counter()
msg=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
Utils.Print("ERROR: Exception during spawn of funds transfer. cmd Duration: %.3f sec. %s" % (end-start, msg))
if exitOnError:
Utils.cmdError("could not transfer \"%s\" from %s to %s" % (amountStr, source, destination))
@@ -158,15 +158,15 @@ class Transactions(NodeosQueries):
except subprocess.CalledProcessError as ex:
if not shouldFail:
end=time.perf_counter()
msg=ex.output.decode("utf-8")
Utils.Print("ERROR: Exception during set contract. cmd Duration: %.3f sec. %s" % (end-start, msg))
out=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
Utils.Print("ERROR: Exception during set contract. stderr: %s. stdout: %s. cmd Duration: %.3f sec." % (msg, out, end-start))
return None
else:
retMap={}
retMap["returncode"]=ex.returncode
retMap["cmd"]=ex.cmd
retMap["output"]=ex.output
retMap["stdout"]=ex.stdout
retMap["stderr"]=ex.stderr
return retMap
@@ -213,20 +213,22 @@ class Transactions(NodeosQueries):
Utils.Print("cmd Duration: %.3f sec" % (end-start))
return (NodeosQueries.getTransStatus(retTrans) == 'executed', retTrans)
except subprocess.CalledProcessError as ex:
msg=ex.output.decode("utf-8")
msg=ex.stderr.decode("utf-8")
if not silentErrors:
end=time.perf_counter()
Utils.Print("ERROR: Exception during push transaction. cmd Duration=%.3f sec. %s" % (end - start, msg))
return (False, msg)
# returns tuple with transaction execution status and transaction
def pushMessage(self, account, action, data, opts, silentErrors=False, signatures=None, expectTrxTrace=True):
def pushMessage(self, account, action, data, opts, silentErrors=False, signatures=None, expectTrxTrace=True, force=False):
cmd="%s %s push action -j %s %s" % (Utils.EosClientPath, self.eosClientArgs(), account, action)
cmdArr=cmd.split()
# not using sign_str, since cmdArr messes up the string
if signatures is not None:
cmdArr.append("--sign-with")
cmdArr.append("[ \"%s\" ]" % ("\", \"".join(signatures)))
if force:
cmdArr.append("-f")
if data is not None:
cmdArr.append(data)
if opts is not None:
@@ -243,7 +245,6 @@ class Transactions(NodeosQueries):
except subprocess.CalledProcessError as ex:
msg=ex.stderr.decode("utf-8")
output=ex.output.decode("utf-8")
msg=ex.output.decode("utf-8")
if not silentErrors:
end=time.perf_counter()
Utils.Print("ERROR: Exception during push message. stderr: %s. stdout: %s. cmd Duration=%.3f sec." % (msg, output, end - start))
-2
View File
@@ -18,8 +18,6 @@ from TestHarness.Node import BlockType
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
def verifyBlockLog(expected_block_num, trimmedBlockLog):
firstBlockNum = expected_block_num
for block in trimmedBlockLog:
+1 -2
View File
@@ -2,8 +2,7 @@
import random
from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr
from core_symbol import CORE_SYMBOL
from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr, CORE_SYMBOL
###############################################################
# compute_transaction_tests
-1
View File
@@ -1 +0,0 @@
CORE_SYMBOL='${CORE_SYMBOL_NAME}'
-1
View File
@@ -3,7 +3,6 @@
import random
from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr
from core_symbol import CORE_SYMBOL
###############################################################
# get_account_test
+2 -2
View File
@@ -349,7 +349,7 @@ class launcher(object):
is_bios = node.name == 'bios'
peers = '\n'.join([f'p2p-peer-address = {self.network.nodes[p].p2p_endpoint}' for p in node.peers])
if len(node.producers) > 0:
producer_keys = f'private-key = ["{node.keys[0].pubkey}","{node.keys[0].privkey}"]\n'
producer_keys = f'signature-provider = {node.keys[0].pubkey}=KEY:{node.keys[0].privkey}\n'
producer_names = '\n'.join([f'producer-name = {p}' for p in node.producers])
producer_plugin = 'plugin = eosio::producer_plugin\n'
else:
@@ -380,7 +380,7 @@ plugin = eosio::chain_api_plugin
dex = str(node.index).zfill(2)
if dex in self.args.logging_level_map:
ll = self.args.logging_level_map[dex]
with open(Path(os.getcwd()) / 'logging.json', 'r') as default:
with open(Path(__file__).resolve().parents[0] / 'TestHarness' / 'logging-template.json', 'r') as default:
cfg = json.load(default)
for logger in cfg['loggers']:
logger['level'] = ll
+1 -2
View File
@@ -4,7 +4,7 @@ import decimal
import re
import os
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from pathlib import Path
###############################################################
@@ -17,7 +17,6 @@ from pathlib import Path
Print=Utils.Print
errorExit=Utils.errorExit
cmdError=Utils.cmdError
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--defproducera_prvt_key","--dump-error-details","--dont-launch","--keep-logs",
"-v","--leave-running","--clean-run","--unshared"})
+1 -2
View File
@@ -3,8 +3,7 @@
import signal
import time
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from core_symbol import CORE_SYMBOL
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
###############################################################
# nodeos_contrl_c_lr_test
+1 -7
View File
@@ -1,14 +1,9 @@
#!/usr/bin/env python3
import decimal
import re
import json
import os
import copy
import math
import time
from TestHarness import Account, Cluster, Node, ReturnType, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Cluster import PFSetupPolicy
from TestHarness.TestHelper import AppArgs
@@ -22,7 +17,6 @@ from TestHarness.TestHelper import AppArgs
Print=Utils.Print
errorExit=Utils.errorExit
cmdError=Utils.cmdError
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--host","--port","-p","--defproducera_prvt_key","--defproducerb_prvt_key"
,"--dump-error-details","--dont-launch","--keep-logs","-v","--leave-running","--clean-run"
+1 -3
View File
@@ -6,7 +6,7 @@ import time
import json
import signal
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
###############################################################
# nodeos_forked_chain_test
@@ -32,8 +32,6 @@ from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
Print=Utils.Print
from core_symbol import CORE_SYMBOL
def analyzeBPs(bps0, bps1, expectDivergence):
start=0
index=None
+1 -2
View File
@@ -4,10 +4,9 @@ import signal
import time
import json
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Cluster import NamedAccounts
from TestHarness.TestHelper import AppArgs
from core_symbol import CORE_SYMBOL
###############################################################
# nodeos_high_transaction_test
+1 -2
View File
@@ -4,10 +4,9 @@ import signal
import time
import json
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Cluster import NamedAccounts
from TestHarness.TestHelper import AppArgs
from core_symbol import CORE_SYMBOL
###############################################################
# nodeos_retry_transaction_test
+1 -2
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from TestHarness import Account, Cluster, Node, ReturnType, TestHelper, Utils, WalletMgr
from TestHarness import Account, Cluster, Node, ReturnType, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from pathlib import Path
import decimal
@@ -19,7 +19,6 @@ import sys
Print=Utils.Print
errorExit=Utils.errorExit
cmdError=Utils.cmdError
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--host","--port","--prod-count","--defproducera_prvt_key","--defproducerb_prvt_key"
,"--dump-error-details","--dont-launch","--keep-logs","-v","--leave-running","--only-bios","--clean-run"
+1 -7
View File
@@ -1,13 +1,9 @@
#!/usr/bin/env python3
import time
import decimal
import math
import re
import signal
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness.Node import BlockType
from TestHarness import Cluster, TestHelper, Utils, WalletMgr
###############################################################
# nodeos_short_fork_take_over_test
@@ -19,8 +15,6 @@ from TestHarness.Node import BlockType
###############################################################
Print=Utils.Print
from core_symbol import CORE_SYMBOL
def analyzeBPs(bps0, bps1, expectDivergence):
start=0
index=None
+27 -14
View File
@@ -126,13 +126,15 @@ try:
waitForBlock(node0, blockNum, blockType=BlockType.lib)
Print("Configure and launch txn generators")
targetTpsPerGenerator = 10
testTrxGenDurationSec=60*30
cluster.launchTrxGenerators(contractOwnerAcctName=cluster.eosioAccount.name, acctNamesList=[account1Name, account2Name],
acctPrivKeysList=[account1PrivKey,account2PrivKey], nodeId=snapshotNodeId, tpsPerGenerator=targetTpsPerGenerator,
numGenerators=trxGeneratorCnt, durationSec=testTrxGenDurationSec, waitToComplete=False)
cluster.waitForTrxGeneratorsSpinup(nodeId=snapshotNodeId, numGenerators=trxGeneratorCnt)
status = cluster.waitForTrxGeneratorsSpinup(nodeId=snapshotNodeId, numGenerators=trxGeneratorCnt)
assert status is not None, "ERROR: Failed to spinup Transaction Generators"
blockNum=node0.getBlockNum(BlockType.head)
timePerBlock=500
@@ -156,11 +158,8 @@ try:
minReqPctLeeway=0.60
minRequiredTransactions=minReqPctLeeway*transactionsPerBlock
assert steadyStateAvg>=minRequiredTransactions, "Expected to at least receive %s transactions per block, but only getting %s" % (minRequiredTransactions, steadyStateAvg)
Print("Create snapshot")
ret = nodeProg.scheduleSnapshot()
assert ret is not None, "Snapshot creation failed"
Print("Create snapshot (node 0)")
ret = nodeSnap.createSnapshot()
assert ret is not None, "Snapshot creation failed"
ret_head_block_num = ret["payload"]["head_block_num"]
@@ -177,6 +176,29 @@ try:
Utils.processLeapUtilCmd("snapshot to-json --input-file {}".format(snapshotFile), "snapshot to-json", silentErrors=False)
snapshotFile = snapshotFile + ".json"
Print("Trim programmable blocklog to snapshot head block num and relaunch programmable node")
nodeProg.kill(signal.SIGTERM)
output=cluster.getBlockLog(progNodeId, blockLogAction=BlockLogAction.trim, first=0, last=ret_head_block_num, throwException=True)
removeState(progNodeId)
Utils.rmFromFile(Utils.getNodeConfigDir(progNodeId, "config.ini"), "p2p-peer-address")
isRelaunchSuccess = nodeProg.relaunch(chainArg="--replay", addSwapFlags={}, timeout=relaunchTimeout, cachePopen=True)
assert isRelaunchSuccess, "Failed to relaunch programmable node"
Print("Schedule snapshot (node 2)")
ret = nodeProg.scheduleSnapshotAt(ret_head_block_num)
assert ret is not None, "Snapshot scheduling failed"
Print("Wait for programmable node lib to advance")
waitForBlock(nodeProg, ret_head_block_num+1, blockType=BlockType.lib)
Print("Kill programmable node")
nodeProg.kill(signal.SIGTERM)
Print("Convert snapshot to JSON")
progSnapshotFile = getLatestSnapshot(progNodeId)
Utils.processLeapUtilCmd("snapshot to-json --input-file {}".format(progSnapshotFile), "snapshot to-json", silentErrors=False)
progSnapshotFile = progSnapshotFile + ".json"
Print("Trim irreversible blocklog to snapshot head block num")
nodeIrr.kill(signal.SIGTERM)
output=cluster.getBlockLog(irrNodeId, blockLogAction=BlockLogAction.trim, first=0, last=ret_head_block_num, throwException=True)
@@ -204,15 +226,6 @@ try:
irrSnapshotFile = irrSnapshotFile + ".json"
assert Utils.compareFiles(snapshotFile, irrSnapshotFile), f"Snapshot files differ {snapshotFile} != {irrSnapshotFile}"
Print("Kill programmable node")
nodeProg.kill(signal.SIGTERM)
Print("Convert snapshot to JSON")
progSnapshotFile = getLatestSnapshot(progNodeId)
Utils.processLeapUtilCmd("snapshot to-json --input-file {}".format(progSnapshotFile), "snapshot to-json", silentErrors=False)
progSnapshotFile = progSnapshotFile + ".json"
assert Utils.compareFiles(progSnapshotFile, irrSnapshotFile), f"Snapshot files differ {progSnapshotFile} != {irrSnapshotFile}"
testSuccessful=True
+1 -8
View File
@@ -1,14 +1,10 @@
#!/usr/bin/env python3
import os
import time
import decimal
import json
import math
import re
import signal
from TestHarness import Account, Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Account, Cluster, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Node import BlockType
###############################################################
@@ -24,9 +20,6 @@ from TestHarness.Node import BlockType
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--prod-count","--dump-error-details","--keep-logs","-v","--leave-running","--clean-run",
"--wallet-port","--unshared"})
Utils.Debug=args.v
+2 -3
View File
@@ -28,8 +28,6 @@ from TestHarness.TestHelper import AppArgs
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
appArgs=AppArgs()
extraArgs = appArgs.add(flag="--catchup-count", type=int, help="How many catchup-nodes to launch", default=10)
extraArgs = appArgs.add(flag="--txn-gen-nodes", type=int, help="How many transaction generator nodes", default=2)
@@ -120,7 +118,8 @@ try:
tpsPerGenerator=targetTpsPerGenerator, numGenerators=trxGeneratorCnt, durationSec=testTrxGenDurationSec,
waitToComplete=False)
cluster.waitForTrxGeneratorsSpinup(nodeId=node0.nodeId, numGenerators=trxGeneratorCnt)
status = cluster.waitForTrxGeneratorsSpinup(nodeId=node0.nodeId, numGenerators=trxGeneratorCnt)
assert status is not None, "ERROR: Failed to spinup Transaction Generators"
blockNum=head(node0)
timePerBlock=500
+1 -5
View File
@@ -1,13 +1,9 @@
#!/usr/bin/env python3
import time
import decimal
import math
import re
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Cluster import NamedAccounts
from core_symbol import CORE_SYMBOL
###############################################################
# nodeos_under_min_avail_ram
+1 -7
View File
@@ -1,10 +1,6 @@
#!/usr/bin/env python3
import decimal
import math
import re
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Cluster, TestHelper, Utils, WalletMgr, CORE_SYMBOL
###############################################################
# nodeos_voting_test
@@ -140,8 +136,6 @@ def verifyProductionRounds(trans, node, prodsActive, rounds):
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--prod-count","--dump-error-details","--keep-logs","-v","--leave-running","--clean-run",
"--wallet-port","--unshared"})
Utils.Debug=args.v
+1 -1
View File
@@ -50,7 +50,7 @@ http-server-address = 127.0.0.1:8888
blocks-dir = blocks
p2p-listen-endpoint = 0.0.0.0:9876
allowed-connection = any
private-key = ['EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV','5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3']
signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
send-whole-blocks = true
readonly = 0
p2p-max-nodes-per-host = 10
+1 -2
View File
@@ -488,8 +488,7 @@ Performance Test Basic Single Test:
* `abi_file` The path to the contract abi file to use for the supplied transaction action data
* `actions_data` The json actions data file or json actions data description string to use
* `actions_auths` The json actions auth file or json actions auths description string to use, containting authAcctName to activePrivateKey pairs.
* `peer_endpoint` set the peer endpoint to send transactions to, default="127.0.0.1"
* `port` set the peer endpoint port to send transactions to, default=9876
* `connection_pair_list` Comma separated list of endpoint:port combinations to send transactions to
</details>
#### Transaction Generator
@@ -327,7 +327,9 @@ class PerformanceTestBasic:
def runTpsTest(self) -> PtbTpsTestResult:
completedRun = False
self.producerNode = self.cluster.getNode(self.producerNodeId)
self.producerP2pPort = self.cluster.getNodeP2pPort(self.producerNodeId)
self.connectionPairList = []
for producer in range(0, self.clusterConfig.pnodes):
self.connectionPairList.append(f"{self.cluster.getNode(producer).host}:{self.cluster.getNodeP2pPort(producer)}")
self.validationNode = self.cluster.getNode(self.validationNodeId)
self.wallet = self.walletMgr.create('default')
self.setupContract()
@@ -371,13 +373,13 @@ class PerformanceTestBasic:
self.cluster.biosNode.kill(signal.SIGTERM)
self.data.startBlock = self.waitForEmptyBlocks(self.validationNode, self.emptyBlockGoal)
tpsTrxGensConfig = TpsTrxGensConfig(targetTps=self.ptbConfig.targetTps, tpsLimitPerGenerator=self.ptbConfig.tpsLimitPerGenerator)
tpsTrxGensConfig = TpsTrxGensConfig(targetTps=self.ptbConfig.targetTps, tpsLimitPerGenerator=self.ptbConfig.tpsLimitPerGenerator, connectionPairList=self.connectionPairList)
self.cluster.trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, contractOwnerAccount=self.clusterConfig.specifiedContract.account.name,
accts=','.join(map(str, self.accountNames)), privateKeys=','.join(map(str, self.accountPrivKeys)),
trxGenDurationSec=self.ptbConfig.testTrxGenDurationSec, logDir=self.trxGenLogDirPath,
abiFile=abiFile, actionsData=actionsDataJson, actionsAuths=actionsAuthsJson,
peerEndpoint=self.producerNode.host, port=self.producerP2pPort, tpsTrxGensConfig=tpsTrxGensConfig)
tpsTrxGensConfig=tpsTrxGensConfig)
trxGenExitCodes = self.cluster.trxGenLauncher.launch()
print(f"Transaction Generator exit codes: {trxGenExitCodes}")
-1
View File
@@ -16,7 +16,6 @@ from TestHarness.Cluster import PFSetupPolicy
Print=Utils.Print
errorExit=Utils.errorExit
cmdError=Utils.cmdError
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--host","--port","--defproducera_prvt_key","--defproducerb_prvt_key"
,"--dump-error-details","--dont-launch","--keep-logs","-v","--leave-running","--only-bios","--clean-run"
+167 -23
View File
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
import random
import time
import signal
import threading
from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr
from TestHarness.TestHelper import AppArgs
from core_symbol import CORE_SYMBOL
###############################################################
# send_read_only_transaction_tests
@@ -30,6 +32,10 @@ pnodes=args.p
topo=args.s
delay=args.d
total_nodes = pnodes if args.n < pnodes else args.n
# For this test, we need at least 1 non-producer
if total_nodes <= pnodes:
Print ("non-producing nodes %d must be greater than 0. Force it to %d. producing nodes: %d," % (total_nodes - pnodes, pnodes + 1, pnodes))
total_nodes = pnodes + 1
debug=args.v
nodesFile=args.nodes_file
dontLaunch=nodesFile is not None
@@ -46,6 +52,7 @@ if nodesFile is not None:
Utils.Debug=debug
testSuccessful=False
errorInThread=False
random.seed(seed) # Use a fixed seed for repeatability.
cluster=Cluster(walletd=True,unshared=args.unshared)
@@ -55,6 +62,9 @@ EOSIO_ACCT_PRIVATE_DEFAULT_KEY = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79z
EOSIO_ACCT_PUBLIC_DEFAULT_KEY = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
try:
TestHelper.printSystemInfo("BEGIN")
cluster.setWalletMgr(walletMgr)
if dontLaunch: # run test against remote cluster
jsonStr=None
with open(nodesFile, "r") as f:
@@ -72,11 +82,25 @@ try:
cluster.killall(allInstances=killAll)
cluster.cleanup()
Print ("producing nodes: %s, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % (pnodes, total_nodes-pnodes, topo, delay))
Print ("producing nodes: %d, non-producing nodes: %d, topology: %s, delay between nodes launch(seconds): %d" % (pnodes, total_nodes-pnodes, topo, delay))
cluster.killall(allInstances=killAll)
cluster.cleanup()
Print("Stand up cluster")
# set up read-only options for API node
specificExtraNodeosArgs={}
# producer nodes will be mapped to 0 through pnodes-1, so the number pnodes is the no-producing API node
specificExtraNodeosArgs[pnodes]=" --plugin eosio::net_api_plugin"
if args.read_only_threads > 0:
specificExtraNodeosArgs[pnodes]+=" --read-only-threads "
specificExtraNodeosArgs[pnodes]+=str(args.read_only_threads)
if args.eos_vm_oc_enable:
specificExtraNodeosArgs[pnodes]+=" --eos-vm-oc-enable"
if args.wasm_runtime:
specificExtraNodeosArgs[pnodes]+=" --wasm-runtime "
specificExtraNodeosArgs[pnodes]+=args.wasm_runtime
extraNodeosArgs=" --http-max-response-time-ms 990000 --disable-subjective-api-billing false "
if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, topo=topo, delay=delay,extraNodeosArgs=extraNodeosArgs ) is False:
if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, topo=topo, delay=delay, specificExtraNodeosArgs=specificExtraNodeosArgs, extraNodeosArgs=extraNodeosArgs ) is False:
errorExit("Failed to stand up eos cluster.")
Print ("Wait for Cluster stabilization")
@@ -98,7 +122,7 @@ try:
userAccount = Account(userAccountName)
userAccount.ownerPublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY
userAccount.activePublicKey = EOSIO_ACCT_PUBLIC_DEFAULT_KEY
cluster.createAccountAndVerify(userAccount, cluster.eosioAccount)
cluster.createAccountAndVerify(userAccount, cluster.eosioAccount, stakeCPU=2000)
noAuthTableContractDir="unittests/test-contracts/no_auth_table"
noAuthTableWasmFile="no_auth_table.wasm"
@@ -117,28 +141,148 @@ try:
}
return apiNode.pushTransaction(trx, opts)
Print("Insert a user")
results = sendTransaction('insert', {"user": userAccountName, "id": 1, "age": 10}, auth=[{"actor": userAccountName, "permission":"active"}])
assert(results[0])
apiNode.waitForTransactionInBlock(results[1]['transaction_id'])
def sendReadOnlyTrxOnThread(startId, numTrxs):
Print("start sendReadOnlyTrxOnThread")
# verify the return value (age) from read-only is the same as created.
Print("Send a read-only Get transaction to verify previous Insert")
results = sendTransaction('getage', {"user": userAccountName}, opts='--read')
assert(results[0])
assert(results[1]['processed']['action_traces'][0]['return_value_data'] == 10)
global errorInThread
errorInThread = False
try:
for i in range(numTrxs):
results = sendTransaction('age', {"user": userAccountName, "id": startId + i}, opts='--read')
assert(results[0])
assert(results[1]['processed']['action_traces'][0]['return_value_data'] == 25)
except Exception as e:
Print("Exception in sendReadOnlyTrxOnThread: ", e)
errorInThread = True
# verify non-read-only modification works
Print("Send a non-read-only Modify transaction")
results = sendTransaction('modify', {"user": userAccountName, "age": 25}, auth=[{"actor": userAccountName, "permission": "active"}])
assert(results[0])
apiNode.waitForTransactionInBlock(results[1]['transaction_id'])
def sendTrxsOnThread(startId, numTrxs, opts=None):
Print("sendTrxsOnThread: ", startId, numTrxs, opts)
# verify 'cleos push action getage "user": "user" --read' works
Print("Send a read-only Get action")
results = apiNode.pushMessage(testAccountName, 'getage', "{{\"user\": \"{}\"}}".format(userAccountName), opts='--read');
assert(results[0])
assert(results[1]['processed']['action_traces'][0]['return_value_data'] == 25)
global errorInThread
errorInThread = False
try:
for i in range(numTrxs):
results = sendTransaction('age', {"user": userAccountName, "id": startId + i}, auth=[{"actor": userAccountName, "permission":"active"}], opts=opts)
assert(results[0])
except Exception as e:
Print("Exception in sendTrxsOnThread: ", e)
errorInThread = True
def doRpc(resource, command, numRuns, fieldIn, expectedValue, code, payload={}):
global errorInThread
errorInThread = False
try:
for i in range(numRuns):
ret_json = apiNode.processUrllibRequest(resource, command, payload)
if code is None:
assert(ret_json["payload"][fieldIn] is not None)
if expectedValue is not None:
assert(ret_json["payload"][fieldIn] == expectedValue)
else:
assert(ret_json["code"] == code)
except Exception as e:
Print("Exception in doRpc: ", e)
errorInThread = True
def runReadOnlyTrxAndRpcInParallel(resource, command, fieldIn=None, expectedValue=None, code=None, payload={}):
Print("runReadOnlyTrxAndRpcInParallel: ", command)
numRuns = 10
trxThread = threading.Thread(target = sendReadOnlyTrxOnThread, args = (0, numRuns ))
rpcThread = threading.Thread(target = doRpc, args = (resource, command, numRuns, fieldIn, expectedValue, code, payload))
trxThread.start()
rpcThread.start()
trxThread.join()
rpcThread.join()
assert(not errorInThread)
def mixedOpsTest(opt=None):
Print("mixedOpsTest -- opt = ", opt)
numRuns = 300
readOnlyThread = threading.Thread(target = sendReadOnlyTrxOnThread, args = (0, numRuns ))
readOnlyThread.start()
sendTrxThread = threading.Thread(target = sendTrxsOnThread, args = (numRuns, numRuns, opt))
sendTrxThread.start()
pushBlockThread = threading.Thread(target = doRpc, args = ("chain", "push_block", numRuns, None, None, 202, {"block":"signed_block"}))
pushBlockThread.start()
readOnlyThread.join()
sendTrxThread.join()
pushBlockThread.join()
assert(not errorInThread)
def sendMulReadOnlyTrx(numThreads):
threadList = []
num_trxs_per_thread = 500
for i in range(numThreads):
thr = threading.Thread(target = sendReadOnlyTrxOnThread, args = (i * num_trxs_per_thread, num_trxs_per_thread ))
thr.start()
threadList.append(thr)
for thr in threadList:
thr.join()
def basicTests():
Print("Insert a user")
results = sendTransaction('insert', {"user": userAccountName, "id": 1, "age": 10}, auth=[{"actor": userAccountName, "permission":"active"}])
assert(results[0])
apiNode.waitForTransactionInBlock(results[1]['transaction_id'])
# verify the return value (age) from read-only is the same as created.
Print("Send a read-only Get transaction to verify previous Insert")
results = sendTransaction('getage', {"user": userAccountName}, opts='--read')
assert(results[0])
assert(results[1]['processed']['action_traces'][0]['return_value_data'] == 10)
# verify non-read-only modification works
Print("Send a non-read-only Modify transaction")
results = sendTransaction('modify', {"user": userAccountName, "age": 25}, auth=[{"actor": userAccountName, "permission": "active"}])
assert(results[0])
apiNode.waitForTransactionInBlock(results[1]['transaction_id'])
def multiReadOnlyTests():
Print("Verify multiple read-only Get actions work after Modify")
sendMulReadOnlyTrx(numThreads=5)
def chainApiTests():
# verify chain APIs can run in parallel with read-ony transactions
runReadOnlyTrxAndRpcInParallel("chain", "get_info", "server_version")
runReadOnlyTrxAndRpcInParallel("chain", "get_consensus_parameters", "chain_config")
runReadOnlyTrxAndRpcInParallel("chain", "get_activated_protocol_features", "activated_protocol_features")
runReadOnlyTrxAndRpcInParallel("chain", "get_block", "block_num", expectedValue=1, payload={"block_num_or_id":1})
runReadOnlyTrxAndRpcInParallel("chain", "get_block_info", "block_num", expectedValue=1, payload={"block_num":1})
runReadOnlyTrxAndRpcInParallel("chain", "get_account", "account_name", expectedValue=userAccountName, payload = {"account_name":userAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_code", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_code_hash", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_abi", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_raw_code_and_abi", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_raw_abi", "account_name", expectedValue=testAccountName, payload = {"account_name":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_producers", "rows", payload = {"json":"true","lower_bound":""})
runReadOnlyTrxAndRpcInParallel("chain", "get_table_rows", code=500, payload = {"json":"true","table":"noauth"})
runReadOnlyTrxAndRpcInParallel("chain", "get_table_by_scope", fieldIn="rows", payload = {"json":"true","table":"noauth"})
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_balance", code=200, payload = {"code":"eosio.token", "account":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_stats", fieldIn="SYS", payload = {"code":"eosio.token", "symbol":"SYS"})
runReadOnlyTrxAndRpcInParallel("chain", "get_required_keys", code=400)
runReadOnlyTrxAndRpcInParallel("chain", "get_transaction_id", code=200, payload = {"ref_block_num":"1"})
runReadOnlyTrxAndRpcInParallel("chain", "push_block", code=202, payload = {"block":"signed_block"})
runReadOnlyTrxAndRpcInParallel("chain", "get_producer_schedule", "active")
runReadOnlyTrxAndRpcInParallel("chain", "get_scheduled_transactions", "transactions", payload = {"json":"true","lower_bound":""})
def netApiTests():
# NET APIs
runReadOnlyTrxAndRpcInParallel("net", "status", code=201, payload = "localhost")
runReadOnlyTrxAndRpcInParallel("net", "connections", code=201)
runReadOnlyTrxAndRpcInParallel("net", "connect", code=201, payload = "localhost")
runReadOnlyTrxAndRpcInParallel("net", "disconnect", code=201, payload = "localhost")
basicTests()
if args.read_only_threads > 0: # Save test time. No need to run other tests if multi-threaded is not enabled
multiReadOnlyTests()
chainApiTests()
netApiTests()
mixedOpsTest()
testSuccessful = True
finally:
+1 -1
View File
@@ -87,7 +87,7 @@ try:
shipClient = "tests/ship_client"
cmd = "%s --num-requests %d" % (shipClient, args.num_requests)
if args.unix_socket:
cmd += " -a ws+unix:///%s/%s" % (os.getcwd(), Utils.getNodeDataDir(shipNodeNum, "ship.sock"))
cmd += " -a ws+unix:///%s" % (Utils.getNodeDataDir(shipNodeNum, "ship.sock"))
if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
clients = []
files = []
-1
View File
@@ -4,7 +4,6 @@ import time
import random
from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr
from core_symbol import CORE_SYMBOL
###############################################################
# subjective-billing-test
+1 -2
View File
@@ -6,8 +6,7 @@ import time
import unittest
import os
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr
from core_symbol import CORE_SYMBOL
from TestHarness import Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
class TraceApiPluginTest(unittest.TestCase):
sleep_s = 1
+1 -3
View File
@@ -7,7 +7,7 @@ import math
import re
import signal
from TestHarness import Account, Cluster, Node, TestHelper, Utils, WalletMgr
from TestHarness import Account, Cluster, Node, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Node import BlockType
###############################################################
@@ -20,8 +20,6 @@ from TestHarness.Node import BlockType
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
args = TestHelper.parse_args({"--prod-count","--dump-error-details","--keep-logs","-v","--leave-running","--clean-run",
"--wallet-port","--unshared"})
+1 -4
View File
@@ -7,7 +7,7 @@ import os
import signal
import subprocess
from TestHarness import Account, Cluster, TestHelper, Utils, WalletMgr
from TestHarness import Account, Cluster, TestHelper, Utils, WalletMgr, CORE_SYMBOL
from TestHarness.Node import BlockType
from TestHarness.TestHelper import AppArgs
@@ -27,9 +27,6 @@ from TestHarness.TestHelper import AppArgs
Print=Utils.Print
errorExit=Utils.errorExit
from core_symbol import CORE_SYMBOL
appArgs=AppArgs()
args = TestHelper.parse_args({"-n", "--dump-error-details","--keep-logs","-v","--leave-running","--clean-run","--unshared"})
Utils.Debug=args.v
@@ -118,7 +118,7 @@ def startNode(nodeIndex, account):
' --p2p-max-nodes-per-host ' + str(maxClients) +
' --enable-stale-production'
' --producer-name ' + account['name'] +
' --private-key \'["' + account['pub'] + '","' + account['pvt'] + '"]\''
' --signature-provider ' + account['pub'] + '=KEY:' + account['pvt'] +
' --plugin eosio::http_plugin'
' --plugin eosio::chain_api_plugin'
' --plugin eosio::chain_plugin'