diff --git a/CMakeLists.txt b/CMakeLists.txt index 59c72fb4d55..45275a7de8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,14 +14,8 @@ endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libraries/fc/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") -if (UNIX) - if (APPLE) - execute_process(COMMAND xcrun --show-sdk-path - OUTPUT_VARIABLE CMAKE_OSX_SYSROOT - OUTPUT_STRIP_TRAILING_WHITESPACE) - list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/llvm@4") - list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/gettext") - endif() +if (UNIX AND APPLE) + list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/llvm@4" "/usr/local/opt/gettext") endif() include( GNUInstallDirs ) @@ -37,7 +31,7 @@ set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 1) set(VERSION_MINOR 7) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) if(VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") @@ -109,18 +103,23 @@ IF( WIN32 ) set(BOOST_ALL_DYN_LINK OFF) # force dynamic linking for all libraries ENDIF(WIN32) FIND_PACKAGE(Boost 1.67 REQUIRED COMPONENTS - thread date_time filesystem system program_options - serialization chrono unit_test_framework - context - locale iostreams) +# Some new stdlibc++s will #error on ; a problem for boost pre-1.69 +if( APPLE AND UNIX ) + add_definitions(-DBOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) +endif() + +set(THREADS_PREFER_PTHREAD_FLAG 1) +find_package(Threads) +link_libraries(Threads::Threads) + if( WIN32 ) message( STATUS "Configuring EOSIO on WIN32") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..40ecbf9cea8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,148 @@ +# Contributing to eos + +Interested in contributing? That's awesome! Here are some guidelines to get started quickly and easily: + +- [Reporting An Issue](#reporting-an-issue) + - [Bug Reports](#bug-reports) + - [Feature Requests](#feature-requests) + - [Change Requests](#change-requests) +- [Working on eos](#working-on-eos) + - [Feature Branches](#feature-branches) + - [Submitting Pull Requests](#submitting-pull-requests) + - [Testing and Quality Assurance](#testing-and-quality-assurance) +- [Conduct](#conduct) +- [Contributor License & Acknowledgments](#contributor-license--acknowledgments) +- [References](#references) + +## Reporting An Issue + +If you're about to raise an issue because you think you've found a problem with eos, or you'd like to make a request for a new feature in the codebase, or any other reason… please read this first. + +The GitHub issue tracker is the preferred channel for [bug reports](#bug-reports), [feature requests](#feature-requests), and [submitting pull requests](#submitting-pull-requests), but please respect the following restrictions: + +* Please **search for existing issues**. Help us keep duplicate issues to a minimum by checking to see if someone has already reported your problem or requested your idea. + +* Please **be civil**. Keep the discussion on topic and respect the opinions of others. See also our [Contributor Code of Conduct](#conduct). + +### Bug Reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +1. **Check if the issue has been fixed** — look for [closed issues in the + current milestone](https://github.com/EOSIO/eos/issues?q=is%3Aissue+is%3Aclosed) or try to reproduce it + using the latest `develop` branch. + +A good bug report shouldn't leave others needing to chase you up for more information. Be sure to include the details of your environment and relevant tests that demonstrate the failure. + +[Report a bug](https://github.com/EOSIO/eos/issues/new?title=Bug%3A) + +### Feature Requests + +Feature requests are welcome. Before you submit one be sure to have: + +1. **Use the GitHub search** and check the feature hasn't already been requested. +1. Take a moment to think about whether your idea fits with the scope and aims of the project. +1. Remember, it's up to *you* to make a strong case to convince the project's leaders of the merits of this feature. Please provide as much detail and context as possible, this means explaining the use case and why it is likely to be common. + +### Change Requests + +Change requests cover both architectural and functional changes to how eos works. If you have an idea for a new or different dependency, a refactor, or an improvement to a feature, etc - please be sure to: + +1. **Use the GitHub search** and check someone else didn't get there first +1. Take a moment to think about the best way to make a case for, and explain what you're thinking. Are you sure this shouldn't really be + a [bug report](#bug-reports) or a [feature request](#feature-requests)? Is it really one idea or is it many? What's the context? What problem are you solving? Why is what you are suggesting better than what's already there? + +## Working on eos + +Code contributions are welcome and encouraged! If you are looking for a good place to start, check out the [good first issue](https://github.com/EOSIO/eos/labels/good%20first%20issue) label in GitHub issues. + +Also, please follow these guidelines when submitting code: + +### Feature Branches + +To get it out of the way: + +- **[develop](https://github.com/EOSIO/eos/tree/develop)** is the development branch. All work on the next release happens here so you should generally branch off `develop`. Do **NOT** use this branch for a production site. +- **[master](https://github.com/EOSIO/eos/tree/master)** contains the latest release of eos. This branch may be used in production. Do **NOT** use this branch to work on eos's source. + +### Submitting Pull Requests + +Pull requests are awesome. If you're looking to raise a PR for something which doesn't have an open issue, please think carefully about [raising an issue](#reporting-an-issue) which your PR can close, especially if you're fixing a bug. This makes it more likely that there will be enough information available for your PR to be properly tested and merged. + +### Testing and Quality Assurance + +Never underestimate just how useful quality assurance is. If you're looking to get involved with the code base and don't know where to start, checking out and testing a pull request is one of the most useful things you could do. + +Essentially, [check out the latest develop branch](#working-on-eos), take it for a spin, and if you find anything odd, please follow the [bug report guidelines](#bug-reports) and let us know! + +## Conduct + +While contributing, please be respectful and constructive, so that participation in our project is a positive experience for everyone. + +Examples of behavior that contributes to creating a positive environment include: +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior include: +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Contributor License & Acknowledgments + +Whenever you make a contribution to this project, you license your contribution under the same terms as set out in LICENSE, and you represent and warrant that you have the right to license your contribution under those terms. Whenever you make a contribution to this project, you also certify in the terms of the Developer’s Certificate of Origin set out below: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## References + +* Overall CONTRIB adapted from https://github.com/mathjax/MathJax/blob/master/CONTRIBUTING.md +* Conduct section adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/Docker/README.md b/Docker/README.md index a9154a86817..a15e72c91e3 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -20,10 +20,10 @@ cd eos/Docker docker build . -t eosio/eos ``` -The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.7.0 tag, you could do the following: +The above will build off the most recent commit to the master branch by default. If you would like to target a specific branch/tag, you may use a build argument. For example, if you wished to generate a docker image based off of the v1.7.1 tag, you could do the following: ```bash -docker build -t eosio/eos:v1.7.0 --build-arg branch=v1.7.0 . +docker build -t eosio/eos:v1.7.1 --build-arg branch=v1.7.1 . ``` By default, the symbol in eosio.system is set to SYS. You can override this using the symbol argument while building the docker image. @@ -133,7 +133,45 @@ docker volume rm keosd-data-volume ### Docker Hub -Docker Hub images are now deprecated. New build images were discontinued on January 1st, 2019. The existing old images will be removed on June 1st, 2019. +Docker Hub image available from [docker hub](https://hub.docker.com/r/eosio/eos/). +Create a new `docker-compose.yaml` file with the content below + +```bash +version: "3" + +services: + nodeosd: + image: eosio/eos:latest + command: /opt/eosio/bin/nodeosd.sh --data-dir /opt/eosio/bin/data-dir -e --http-alias=nodeosd:8888 --http-alias=127.0.0.1:8888 --http-alias=localhost:8888 + hostname: nodeosd + ports: + - 8888:8888 + - 9876:9876 + expose: + - "8888" + volumes: + - nodeos-data-volume:/opt/eosio/bin/data-dir + + keosd: + image: eosio/eos:latest + command: /opt/eosio/bin/keosd --wallet-dir /opt/eosio/bin/data-dir --http-server-address=127.0.0.1:8900 --http-alias=localhost:8900 --http-alias=keosd:8900 + hostname: keosd + links: + - nodeosd + volumes: + - keosd-data-volume:/opt/eosio/bin/data-dir + +volumes: + nodeos-data-volume: + keosd-data-volume: + +``` + +*NOTE:* the default version is the latest, you can change it to what you want + +run `docker pull eosio/eos:latest` + +run `docker-compose up` ### EOSIO Testnet diff --git a/LICENSE b/LICENSE index 1516b96cbdf..22d36d65db1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019 Respective Authors all rights reserved. +Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. The MIT License diff --git a/README.md b/README.md index ca5f9fbfe62..e55c45a7026 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ $ brew remove eosio ``` #### Ubuntu 18.04 Debian Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.7.0/eosio_1.7.0-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio_1.7.0-1-ubuntu-18.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v1.7.1/eosio_1.7.1-1-ubuntu-18.04_amd64.deb +$ sudo apt install ./eosio_1.7.1-1-ubuntu-18.04_amd64.deb ``` #### Ubuntu 16.04 Debian Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.7.0/eosio_1.7.0-1-ubuntu-16.04_amd64.deb -$ sudo apt install ./eosio_1.7.0-1-ubuntu-16.04_amd64.deb +$ wget https://github.com/eosio/eos/releases/download/v1.7.1/eosio_1.7.1-1-ubuntu-16.04_amd64.deb +$ sudo apt install ./eosio_1.7.1-1-ubuntu-16.04_amd64.deb ``` #### Debian Package Uninstall ```sh @@ -53,8 +53,8 @@ $ sudo apt remove eosio ``` #### Centos RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.7.0/eosio-1.7.0-1.el7.x86_64.rpm -$ sudo yum install ./eosio-1.7.0-1.el7.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v1.7.1/eosio-1.7.1-1.el7.x86_64.rpm +$ sudo yum install ./eosio-1.7.1-1.el7.x86_64.rpm ``` #### Centos RPM Package Uninstall ```sh @@ -62,8 +62,8 @@ $ sudo yum remove eosio.cdt ``` #### Fedora RPM Package Install ```sh -$ wget https://github.com/eosio/eos/releases/download/v1.7.0/eosio-1.7.0-1.fc27.x86_64.rpm -$ sudo yum install ./eosio-1.7.0-1.fc27.x86_64.rpm +$ wget https://github.com/eosio/eos/releases/download/v1.7.1/eosio-1.7.1-1.fc27.x86_64.rpm +$ sudo yum install ./eosio-1.7.1-1.fc27.x86_64.rpm ``` #### Fedora RPM Package Uninstall ```sh @@ -76,9 +76,9 @@ EOSIO currently supports the following operating systems: 2. Centos 7 3. Fedora 25 and higher (Fedora 27 recommended) 4. Mint 18 -5. Ubuntu 16.04 (Ubuntu 16.10 recommended) +5. Ubuntu 16.04 6. Ubuntu 18.04 -7. MacOS Darwin 10.12 and higher (MacOS 10.13.x recommended) +7. MacOS Darwin 10.12 and higher (MacOS 10.14.x recommended) ## Resources 1. [Website](https://eos.io) @@ -93,3 +93,17 @@ EOSIO currently supports the following operating systems: ## Getting Started Instructions detailing the process of getting the software, building it, running a simple test network that produces blocks, account creation and uploading a sample contract to the blockchain can be found in [Getting Started](https://developers.eos.io/eosio-home/docs) on the [EOSIO Developer Portal](https://developers.eos.io). + +## Contributing + +[Contributing Guide](./CONTRIBUTING.md) + +[Code of Conduct](./CONTRIBUTING.md#conduct) + +## License + +[MIT](./LICENSE) + +## Important + +See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index a40355971a9..39d0398305d 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory( fc ) add_subdirectory( builtins ) add_subdirectory( softfloat ) add_subdirectory( chainbase ) -add_subdirectory( wasm-jit ) +add_subdirectory( wasm-jit EXCLUDE_FROM_ALL ) add_subdirectory( appbase ) add_subdirectory( chain ) add_subdirectory( testing ) diff --git a/libraries/appbase b/libraries/appbase index 9da0818154c..737df2c70b0 160000 --- a/libraries/appbase +++ b/libraries/appbase @@ -1 +1 @@ -Subproject commit 9da0818154c3ebade946f29f5f0328117578058c +Subproject commit 737df2c70b0b5467ce928d97457985c852f7850e diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 09a3f7ecb32..a8f714bb1e5 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -421,14 +421,7 @@ struct controller_impl { void clear_all_undo() { // Rewind the database to the last irreversible block - db.with_write_lock([&] { - db.undo_all(); - /* - FC_ASSERT(db.revision() == self.head_block_num(), - "Chainbase revision does not match head block num", - ("rev", db.revision())("head_block", self.head_block_num())); - */ - }); + db.undo_all(); } void add_contract_tables_to_snapshot( const snapshot_writer_ptr& snapshot ) const { @@ -999,9 +992,10 @@ struct controller_impl { auto start = fc::time_point::now(); const bool check_auth = !self.skip_auth_check() && !trx->implicit; // call recover keys so that trx->sig_cpu_usage is set correctly - const flat_set& recovered_keys = check_auth ? trx->recover_keys( chain_id ) : flat_set(); + const fc::microseconds sig_cpu_usage = check_auth ? std::get<0>( trx->recover_keys( chain_id ) ) : fc::microseconds(); + const flat_set& recovered_keys = check_auth ? std::get<1>( trx->recover_keys( chain_id ) ) : flat_set(); if( !explicit_billed_cpu_time ) { - fc::microseconds already_consumed_time( EOS_PERCENT(trx->sig_cpu_usage.count(), conf.sig_cpu_bill_pct) ); + fc::microseconds already_consumed_time( EOS_PERCENT(sig_cpu_usage.count(), conf.sig_cpu_bill_pct) ); if( start.time_since_epoch() < already_consumed_time ) { start = fc::time_point(); @@ -1199,7 +1193,7 @@ struct controller_impl { auto& pt = receipt.trx.get(); auto mtrx = std::make_shared( std::make_shared( pt ) ); if( !self.skip_auth_check() ) { - transaction_metadata::create_signing_keys_future( mtrx, thread_pool, chain_id, microseconds::maximum() ); + transaction_metadata::start_recover_keys( mtrx, thread_pool, chain_id, microseconds::maximum() ); } packed_transactions.emplace_back( std::move( mtrx ) ); } diff --git a/libraries/chain/include/eosio/chain/transaction_metadata.hpp b/libraries/chain/include/eosio/chain/transaction_metadata.hpp index 6136580fa44..0847159e6de 100644 --- a/libraries/chain/include/eosio/chain/transaction_metadata.hpp +++ b/libraries/chain/include/eosio/chain/transaction_metadata.hpp @@ -15,6 +15,10 @@ namespace eosio { namespace chain { class transaction_metadata; using transaction_metadata_ptr = std::shared_ptr; +using signing_keys_future_value_type = std::tuple>; +using signing_keys_future_type = std::shared_future; +using recovery_keys_type = std::pair&>; + /** * This data structure should store context-free cached data about a transaction such as * packed/unpacked/compressed and recovered keys @@ -24,10 +28,7 @@ class transaction_metadata { transaction_id_type id; transaction_id_type signed_id; packed_transaction_ptr packed_trx; - fc::microseconds sig_cpu_usage; - optional>> signing_keys; - std::future>> - signing_keys_future; + signing_keys_future_type signing_keys_future; bool accepted = false; bool implicit = false; bool scheduled = false; @@ -50,10 +51,14 @@ class transaction_metadata { signed_id = digest_type::hash(*packed_trx); } - const flat_set& recover_keys( const chain_id_type& chain_id ); + // must be called from main application thread + static signing_keys_future_type + start_recover_keys( const transaction_metadata_ptr& mtrx, boost::asio::thread_pool& thread_pool, + const chain_id_type& chain_id, fc::microseconds time_limit ); + + // start_recover_keys must be called first + recovery_keys_type recover_keys( const chain_id_type& chain_id ); - static void create_signing_keys_future( const transaction_metadata_ptr& mtrx, boost::asio::thread_pool& thread_pool, - const chain_id_type& chain_id, fc::microseconds time_limit ); }; diff --git a/libraries/chain/transaction_metadata.cpp b/libraries/chain/transaction_metadata.cpp index 482b3c488f7..9c33121a5a6 100644 --- a/libraries/chain/transaction_metadata.cpp +++ b/libraries/chain/transaction_metadata.cpp @@ -4,34 +4,39 @@ namespace eosio { namespace chain { - -const flat_set& transaction_metadata::recover_keys( const chain_id_type& chain_id ) { +recovery_keys_type transaction_metadata::recover_keys( const chain_id_type& chain_id ) { // Unlikely for more than one chain_id to be used in one nodeos instance - if( !signing_keys || signing_keys->first != chain_id ) { - if( signing_keys_future.valid() ) { - std::tuple> sig_keys = signing_keys_future.get(); - if( std::get<0>( sig_keys ) == chain_id ) { - sig_cpu_usage = std::get<1>( sig_keys ); - signing_keys.emplace( std::get<0>( sig_keys ), std::move( std::get<2>( sig_keys ))); - return signing_keys->second; - } + if( signing_keys_future.valid() ) { + const std::tuple>& sig_keys = signing_keys_future.get(); + if( std::get<0>( sig_keys ) == chain_id ) { + return std::make_pair( std::get<1>( sig_keys ), std::cref( std::get<2>( sig_keys ) ) ); } - flat_set recovered_pub_keys; - sig_cpu_usage = packed_trx->get_signed_transaction().get_signature_keys( chain_id, fc::time_point::maximum(), recovered_pub_keys ); - signing_keys.emplace( chain_id, std::move( recovered_pub_keys )); } - return signing_keys->second; + + // shared_keys_future not created or different chain_id + std::promise p; + flat_set recovered_pub_keys; + const signed_transaction& trn = packed_trx->get_signed_transaction(); + fc::microseconds cpu_usage = trn.get_signature_keys( chain_id, fc::time_point::maximum(), recovered_pub_keys ); + p.set_value( std::make_tuple( chain_id, cpu_usage, std::move( recovered_pub_keys ) ) ); + signing_keys_future = p.get_future().share(); + + const std::tuple>& sig_keys = signing_keys_future.get(); + return std::make_pair( std::get<1>( sig_keys ), std::cref( std::get<2>( sig_keys ) ) ); } -void transaction_metadata::create_signing_keys_future( const transaction_metadata_ptr& mtrx, - boost::asio::thread_pool& thread_pool, const chain_id_type& chain_id, fc::microseconds time_limit ) { - if( mtrx->signing_keys_future.valid() || mtrx->signing_keys.valid() ) // already created - return; +signing_keys_future_type transaction_metadata::start_recover_keys( const transaction_metadata_ptr& mtrx, + boost::asio::thread_pool& thread_pool, + const chain_id_type& chain_id, + fc::microseconds time_limit ) +{ + if( mtrx->signing_keys_future.valid() && std::get<0>( mtrx->signing_keys_future.get() ) == chain_id ) // already created + return mtrx->signing_keys_future; std::weak_ptr mtrx_wp = mtrx; mtrx->signing_keys_future = async_thread_pool( thread_pool, [time_limit, chain_id, mtrx_wp]() { fc::time_point deadline = time_limit == fc::microseconds::maximum() ? - fc::time_point::maximum() : fc::time_point::now() + time_limit; + fc::time_point::maximum() : fc::time_point::now() + time_limit; auto mtrx = mtrx_wp.lock(); fc::microseconds cpu_usage; flat_set recovered_pub_keys; @@ -41,6 +46,8 @@ void transaction_metadata::create_signing_keys_future( const transaction_metadat } return std::make_tuple( chain_id, cpu_usage, std::move( recovered_pub_keys )); } ); + + return mtrx->signing_keys_future; } diff --git a/libraries/chainbase b/libraries/chainbase index 8ca96ad6b18..02c1ea29133 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 8ca96ad6b18709d65a7d1f67f8893978f25babcf +Subproject commit 02c1ea2913358959a26036779b512432f036946e diff --git a/libraries/fc b/libraries/fc index 12956c33041..063353354d0 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 12956c330413e69bd998cd0657c8a82ef3e8a106 +Subproject commit 063353354d04b631541083ba65fbe2667ef4f097 diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index a6a77ff2998..63a0788931f 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -346,7 +346,13 @@ namespace eosio { namespace testing { { try { if( !control->pending_block_state() ) _start_block(control->head_block_time() + fc::microseconds(config::block_interval_us)); - auto r = control->push_transaction( std::make_shared(std::make_shared(trx)), deadline, billed_cpu_time_us ); + + auto mtrx = std::make_shared( std::make_shared(trx) ); + auto time_limit = deadline == fc::time_point::maximum() ? + fc::microseconds::maximum() : + fc::microseconds( deadline - fc::time_point::now() ); + transaction_metadata::start_recover_keys( mtrx, control->get_thread_pool(), control->get_chain_id(), time_limit ); + auto r = control->push_transaction( mtrx, deadline, billed_cpu_time_us ); if( r->except_ptr ) std::rethrow_exception( r->except_ptr ); if( r->except ) throw *r->except; return r; @@ -365,7 +371,12 @@ namespace eosio { namespace testing { c = packed_transaction::zlib; } - auto r = control->push_transaction( std::make_shared(trx,c), deadline, billed_cpu_time_us ); + auto time_limit = deadline == fc::time_point::maximum() ? + fc::microseconds::maximum() : + fc::microseconds( deadline - fc::time_point::now() ); + auto mtrx = std::make_shared(trx, c); + transaction_metadata::start_recover_keys( mtrx, control->get_thread_pool(), control->get_chain_id(), time_limit ); + auto r = control->push_transaction( mtrx, deadline, billed_cpu_time_us ); if( r->except_ptr ) std::rethrow_exception( r->except_ptr ); if( r->except) throw *r->except; return r; diff --git a/libraries/wasm-jit/Source/Programs/Assemble.cpp b/libraries/wasm-jit/Source/Programs/Assemble.cpp index a3328794ddd..60ca42cf0f9 100644 --- a/libraries/wasm-jit/Source/Programs/Assemble.cpp +++ b/libraries/wasm-jit/Source/Programs/Assemble.cpp @@ -7,7 +7,7 @@ int commandMain(int argc,char** argv) { if(argc < 3) { - std::cerr << "Usage: eosio-wast2wasm in.wast out.wasm [switches]" << std::endl; + std::cerr << "Usage: Assemble in.wast out.wasm [switches]" << std::endl; std::cerr << " -n|--omit-names\t\tOmits WAST function and local names from the output" << std::endl; return EXIT_FAILURE; } diff --git a/libraries/wasm-jit/Source/Programs/CMakeLists.txt b/libraries/wasm-jit/Source/Programs/CMakeLists.txt index 27a3aa427b4..260f4c1092c 100644 --- a/libraries/wasm-jit/Source/Programs/CMakeLists.txt +++ b/libraries/wasm-jit/Source/Programs/CMakeLists.txt @@ -1,7 +1,6 @@ -add_executable(eosio-wast2wasm Assemble.cpp CLI.h) -target_link_libraries(eosio-wast2wasm Logging IR WAST WASM) -set_target_properties(eosio-wast2wasm PROPERTIES FOLDER Programs) -INSTALL(TARGETS eosio-wast2wasm DESTINATION ${CMAKE_INSTALL_BINDIR}) +add_executable(Assemble Assemble.cpp CLI.h) +target_link_libraries(Assemble Logging IR WAST WASM) +set_target_properties(Assemble PROPERTIES FOLDER Programs) add_executable(Disassemble Disassemble.cpp CLI.h) target_link_libraries(Disassemble Logging IR WAST WASM) diff --git a/plugins/mongo_db_plugin/mongo_db_plugin.cpp b/plugins/mongo_db_plugin/mongo_db_plugin.cpp index ee22c65c7cc..e4feea00187 100644 --- a/plugins/mongo_db_plugin/mongo_db_plugin.cpp +++ b/plugins/mongo_db_plugin/mongo_db_plugin.cpp @@ -16,11 +16,10 @@ #include #include #include -#include -#include -#include #include +#include +#include #include #include @@ -162,9 +161,9 @@ class mongo_db_plugin_impl { std::deque block_state_process_queue; std::deque irreversible_block_state_queue; std::deque irreversible_block_state_process_queue; - boost::mutex mtx; - boost::condition_variable condition; - boost::thread consume_thread; + std::mutex mtx; + std::condition_variable condition; + std::thread consume_thread; std::atomic_bool done{false}; std::atomic_bool startup{true}; fc::optional chain_id; @@ -290,7 +289,7 @@ bool mongo_db_plugin_impl::filter_include( const transaction& trx ) const template void mongo_db_plugin_impl::queue( Queue& queue, const Entry& e ) { - boost::mutex::scoped_lock lock( mtx ); + std::unique_lock lock( mtx ); auto queue_size = queue.size(); if( queue_size > max_queue_size ) { lock.unlock(); @@ -298,7 +297,7 @@ void mongo_db_plugin_impl::queue( Queue& queue, const Entry& e ) { queue_sleep_time += 10; if( queue_sleep_time > 1000 ) wlog("queue size: ${q}", ("q", queue_size)); - boost::this_thread::sleep_for( boost::chrono::milliseconds( queue_sleep_time )); + std::this_thread::sleep_for( std::chrono::milliseconds( queue_sleep_time )); lock.lock(); } else { queue_sleep_time -= 10; @@ -406,7 +405,7 @@ void mongo_db_plugin_impl::consume_blocks() { _account_controls = mongo_conn[db_name][account_controls_col]; while (true) { - boost::mutex::scoped_lock lock(mtx); + std::unique_lock lock(mtx); while ( transaction_metadata_queue.empty() && transaction_trace_queue.empty() && block_state_queue.empty() && @@ -779,8 +778,8 @@ void mongo_db_plugin_impl::_process_accepted_transaction( const chain::transacti } string signing_keys_json; - if( t->signing_keys.valid() ) { - signing_keys_json = fc::json::to_string( t->signing_keys->second ); + if( t->signing_keys_future.valid() ) { + signing_keys_json = fc::json::to_string( std::get<2>( t->signing_keys_future.get() ) ); } else { flat_set keys; trx.get_signature_keys( *chain_id, fc::time_point::maximum(), keys, false ); @@ -1471,7 +1470,7 @@ void mongo_db_plugin_impl::init() { ilog("starting db plugin thread"); - consume_thread = boost::thread([this] { consume_blocks(); }); + consume_thread = std::thread([this] { consume_blocks(); }); startup = false; } diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 91ff34f00d5..d2f9fcabfb6 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -497,7 +497,8 @@ namespace eosio { transaction_state_index trx_state; optional peer_requested; // this peer is requesting info from us std::shared_ptr server_ioc; // keep ioc alive - socket_ptr socket; + boost::asio::io_context::strand strand; + socket_ptr socket; fc::message_buffer<1024*1024> pending_message_buffer; fc::optional outstanding_read_bytes; @@ -578,9 +579,6 @@ namespace eosio { const string peer_name(); - void txn_send_pending(const vector& ids); - void txn_send(const vector& txn_lis); - void blk_send_branch(); void blk_send(const block_id_type& blkid); void stop_send(); @@ -730,6 +728,7 @@ namespace eosio { trx_state(), peer_requested(), server_ioc( my_impl->server_ioc ), + strand( app().get_io_service() ), socket( std::make_shared( std::ref( *my_impl->server_ioc ))), node_id(), last_handshake_recv(), @@ -755,6 +754,7 @@ namespace eosio { trx_state(), peer_requested(), server_ioc( my_impl->server_ioc ), + strand( app().get_io_service() ), socket( s ), node_id(), last_handshake_recv(), @@ -823,27 +823,6 @@ namespace eosio { fc_dlog(logger, "canceling wait on ${p}", ("p",peer_name())); cancel_wait(); if( read_delay_timer ) read_delay_timer->cancel(); - pending_message_buffer.reset(); - } - - void connection::txn_send_pending(const vector& ids) { - const std::set known_ids(ids.cbegin(), ids.cend()); - my_impl->expire_local_txns(); - for(auto tx = my_impl->local_txns.begin(); tx != my_impl->local_txns.end(); ++tx ){ - const bool found = known_ids.find( tx->id ) != known_ids.cend(); - if( !found ) { - queue_write( tx->serialized_txn, true, priority::low, []( boost::system::error_code ec, std::size_t ) {} ); - } - } - } - - void connection::txn_send(const vector& ids) { - for(const auto& t : ids) { - auto tx = my_impl->local_txns.get().find(t); - if( tx != my_impl->local_txns.end() ) { - queue_write( tx->serialized_txn, true, priority::low, []( boost::system::error_code ec, std::size_t ) {} ); - } - } } void connection::blk_send_branch() { @@ -976,7 +955,8 @@ namespace eosio { std::vector bufs; buffer_queue.fill_out_buffer( bufs ); - boost::asio::async_write(*socket, bufs, [c, priority]( boost::system::error_code ec, std::size_t w ) { + boost::asio::async_write(*socket, bufs, + boost::asio::bind_executor(strand, [c, priority]( boost::system::error_code ec, std::size_t w ) { app().post(priority, [c, priority, ec, w]() { try { auto conn = c.lock(); @@ -1016,7 +996,7 @@ namespace eosio { fc_elog( logger,"Exception in do_queue_write to ${p}", ("p",pname) ); } }); - }); + })); } void connection::cancel_sync(go_away_reason reason) { @@ -1849,7 +1829,7 @@ namespace eosio { connection_wptr weak_conn = c; // Note: need to add support for IPv6 too - resolver->async_resolve( query, + resolver->async_resolve( query, boost::asio::bind_executor( c->strand, [weak_conn, this]( const boost::system::error_code& err, tcp::resolver::iterator endpoint_itr ) { app().post( priority::low, [err, endpoint_itr, weak_conn, this]() { auto c = weak_conn.lock(); @@ -1861,7 +1841,7 @@ namespace eosio { ("peer_addr", c->peer_name())( "error", err.message()) ); } } ); - } ); + } ) ); } void net_plugin_impl::connect(const connection_ptr& c, tcp::resolver::iterator endpoint_itr) { @@ -1872,8 +1852,10 @@ namespace eosio { auto current_endpoint = *endpoint_itr; ++endpoint_itr; c->connecting = true; + c->pending_message_buffer.reset(); connection_wptr weak_conn = c; - c->socket->async_connect( current_endpoint, [weak_conn, endpoint_itr, this]( const boost::system::error_code& err ) { + c->socket->async_connect( current_endpoint, boost::asio::bind_executor( c->strand, + [weak_conn, endpoint_itr, this]( const boost::system::error_code& err ) { app().post( priority::low, [weak_conn, endpoint_itr, this, err]() { auto c = weak_conn.lock(); if( !c ) return; @@ -1892,7 +1874,7 @@ namespace eosio { } } } ); - } ); + } ) ); } bool net_plugin_impl::start_session(const connection_ptr& con) { @@ -2042,10 +2024,11 @@ namespace eosio { ++conn->reads_in_flight; boost::asio::async_read(*conn->socket, conn->pending_message_buffer.get_buffer_sequence_for_boost_async_read(), completion_handler, + boost::asio::bind_executor( conn->strand, [this,weak_conn]( boost::system::error_code ec, std::size_t bytes_transferred ) { app().post( priority::medium, [this,weak_conn, ec, bytes_transferred]() { auto conn = weak_conn.lock(); - if (!conn) { + if (!conn || !conn->socket || !conn->socket->is_open()) { return; } @@ -2124,7 +2107,7 @@ namespace eosio { close( conn ); } }); - }); + })); } catch (...) { string pname = conn ? conn->peer_name() : "no connection name"; fc_elog( logger, "Undefined exception handling reading ${p}",("p",pname) ); @@ -2393,17 +2376,6 @@ namespace eosio { break; } case catch_up : { - if( msg.known_trx.pending > 0) { - // plan to get all except what we already know about. - req.req_trx.mode = catch_up; - send_req = true; - size_t known_sum = local_txns.size(); - if( known_sum ) { - for( const auto& t : local_txns.get() ) { - req.req_trx.ids.push_back( t.id ); - } - } - } break; } case normal: { @@ -2461,14 +2433,17 @@ namespace eosio { switch (msg.req_trx.mode) { case catch_up : - c->txn_send_pending(msg.req_trx.ids); - break; - case normal : - c->txn_send(msg.req_trx.ids); break; case none : if(msg.req_blocks.mode == none) c->stop_send(); + // no break + case normal : + if( !msg.req_trx.ids.empty() ) { + elog( "Invalid request_message, req_trx.ids.size ${s}", ("s", msg.req_trx.ids.size()) ); + close(c); + return; + } break; default:; } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index f3eb2164cea..8f188f7ae39 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -351,10 +351,11 @@ class producer_plugin_impl : public std::enable_shared_from_this next) { chain::controller& chain = chain_plug->chain(); const auto& cfg = chain.get_global_properties().configuration; - transaction_metadata::create_signing_keys_future( trx, *_thread_pool, chain.get_chain_id(), fc::microseconds( cfg.max_transaction_cpu_usage ) ); - boost::asio::post( *_thread_pool, [self = this, trx, persist_until_expired, next]() { - if( trx->signing_keys_future.valid() ) - trx->signing_keys_future.wait(); + signing_keys_future_type future = transaction_metadata::start_recover_keys( trx, *_thread_pool, + chain.get_chain_id(), fc::microseconds( cfg.max_transaction_cpu_usage ) ); + boost::asio::post( *_thread_pool, [self = this, future, trx, persist_until_expired, next]() { + if( future.valid() ) + future.wait(); app().post(priority::low, [self, trx, persist_until_expired, next]() { self->process_incoming_transaction_async( trx, persist_until_expired, next ); }); diff --git a/plugins/state_history_plugin/state_history_plugin.cpp b/plugins/state_history_plugin/state_history_plugin.cpp index 49c47041e3d..7aead3d1052 100644 --- a/plugins/state_history_plugin/state_history_plugin.cpp +++ b/plugins/state_history_plugin/state_history_plugin.cpp @@ -345,7 +345,7 @@ struct state_history_plugin_impl : std::enable_shared_from_thisreceipt) { + if (p->receipt && trace_log) { if (is_onblock(p)) onblock_trace = p; else if (p->failed_dtrx_trace) diff --git a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp index d4f197df468..f86253fbfac 100755 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -69,7 +69,10 @@ using io_work_t = boost::asio::executor_work_guard>(0);\ + auto result_handler = [times_called{std::move(times_called)}, cb, body](const fc::exception_ptr& e) mutable {\ + if( ++(*times_called) > 1 ) return;\ if (e) {\ try {\ e->dynamic_rethrow_exception();\ diff --git a/programs/cleos/main.cpp b/programs/cleos/main.cpp index feef29cbfd9..b2cd9aa6988 100644 --- a/programs/cleos/main.cpp +++ b/programs/cleos/main.cpp @@ -443,9 +443,11 @@ bytes json_or_file_to_bin( const account_name& account, const action_name& actio void print_action_tree( const fc::variant& action ) { print_action( action ); - const auto& inline_traces = action["inline_traces"].get_array(); - for( const auto& t : inline_traces ) { - print_action_tree( t ); + if( action.get_object().contains( "inline_traces" ) ) { + const auto& inline_traces = action["inline_traces"].get_array(); + for( const auto& t : inline_traces ) { + print_action_tree( t ); + } } } @@ -453,12 +455,13 @@ void print_result( const fc::variant& result ) { try { if (result.is_object() && result.get_object().contains("processed")) { const auto& processed = result["processed"]; const auto& transaction_id = processed["id"].as_string(); - string status = processed["receipt"].is_object() ? processed["receipt"]["status"].as_string() : "failed"; + string status = "failed"; int64_t net = -1; int64_t cpu = -1; if( processed.get_object().contains( "receipt" )) { const auto& receipt = processed["receipt"]; if( receipt.is_object()) { + status = receipt["status"].as_string(); net = receipt["net_usage_words"].as_int64() * 8; cpu = receipt["cpu_usage_us"].as_int64(); } diff --git a/scripts/boost.rb b/scripts/boost.rb deleted file mode 100644 index a322acbdd11..00000000000 --- a/scripts/boost.rb +++ /dev/null @@ -1,131 +0,0 @@ -class Boost < Formula - desc "Collection of portable C++ source libraries" - homepage "https://www.boost.org/" - revision 1 - head "https://github.com/boostorg/boost.git" - - stable do - url "https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2" - sha256 "2684c972994ee57fc5632e03bf044746f6eb45d4920c343937a465fd67a5adba" - - # Remove for > 1.67.0 - # Fix "error: no member named 'next' in namespace 'boost'" - # Upstream commit from 1 Dec 2017 "Add #include ; no - # longer in utility.hpp" - patch :p2 do - url "https://github.com/boostorg/lockfree/commit/12726cd.patch?full_index=1" - sha256 "f165823d961a588b622b20520668b08819eb5fdc08be7894c06edce78026ce0a" - end - end - - bottle do - cellar :any - sha256 "265ab8beaa6fa26a7c305ef2e6aec8bd26ca1db105aca0aaca028f32c5245a90" => :high_sierra - sha256 "567f3e9a294413c1701b698d666a521cfdeec846e256c6e66576d5b70eb26f08" => :sierra - sha256 "3f3f687a620f656fe2ac54f01306e00e6bbc0e9797db284a8d272648d427e640" => :el_capitan - end - - option "with-icu4c", "Build regexp engine with icu support" - option "without-single", "Disable building single-threading variant" - option "without-static", "Disable building static library variant" - - deprecated_option "with-icu" => "with-icu4c" - - depends_on "icu4c" => :optional - - def install - # Force boost to compile with the desired compiler - open("user-config.jam", "a") do |file| - file.write "using darwin : : #{ENV.cxx} ;\n" - end - - # libdir should be set by --prefix but isn't - bootstrap_args = ["--prefix=#{prefix}", "--libdir=#{lib}"] - - if build.with? "icu4c" - icu4c_prefix = Formula["icu4c"].opt_prefix - bootstrap_args << "--with-icu=#{icu4c_prefix}" - else - bootstrap_args << "--without-icu" - end - - # Handle libraries that will not be built. - without_libraries = ["python", "mpi"] - - # Boost.Log cannot be built using Apple GCC at the moment. Disabled - # on such systems. - without_libraries << "log" if ENV.compiler == :gcc - - bootstrap_args << "--without-libraries=#{without_libraries.join(",")}" - - # layout should be synchronized with boost-python and boost-mpi - args = ["--prefix=#{prefix}", - "--libdir=#{lib}", - "-d2", - "-j#{ENV.make_jobs}", - "--layout=tagged", - "--user-config=user-config.jam", - "-sNO_LZMA=1", - "install"] - - if build.with? "single" - args << "threading=multi,single" - else - args << "threading=multi" - end - - if build.with? "static" - args << "link=shared,static" - else - args << "link=shared" - end - - # Trunk starts using "clang++ -x c" to select C compiler which breaks C++11 - # handling using ENV.cxx11. Using "cxxflags" and "linkflags" still works. - args << "cxxflags=-std=c++11" - if ENV.compiler == :clang - args << "cxxflags=-stdlib=libc++" << "linkflags=-stdlib=libc++" - end - - system "./bootstrap.sh", *bootstrap_args - system "./b2", "headers" - system "./b2", *args - end - - def caveats - s = "" - # ENV.compiler doesn't exist in caveats. Check library availability - # instead. - if Dir["#{lib}/libboost_log*"].empty? - s += <<~EOS - Building of Boost.Log is disabled because it requires newer GCC or Clang. - EOS - end - - s - end - - test do - (testpath/"test.cpp").write <<~EOS - #include - #include - #include - #include - using namespace boost::algorithm; - using namespace std; - - int main() - { - string str("a,b"); - vector strVec; - split(strVec, str, is_any_of(",")); - assert(strVec.size()==2); - assert(strVec[0]=="a"); - assert(strVec[1]=="b"); - return 0; - } - EOS - system ENV.cxx, "test.cpp", "-std=c++1y", "-L#{lib}", "-lboost_system", "-o", "test" - system "./test" - end -end diff --git a/scripts/eosio_build_darwin.sh b/scripts/eosio_build_darwin.sh index a7ec32ff7de..11bbbc37d99 100755 --- a/scripts/eosio_build_darwin.sh +++ b/scripts/eosio_build_darwin.sh @@ -174,7 +174,8 @@ if [ "${BOOSTVERSION}" != "${BOOST_VERSION_MAJOR}0${BOOST_VERSION_MINOR}0${BOOST && tar -xjf boost_$BOOST_VERSION.tar.bz2 \ && cd $BOOST_ROOT \ && ./bootstrap.sh --prefix=$BOOST_ROOT \ - && ./b2 -q -j$(sysctl -in machdep.cpu.core_count) install \ + && ./b2 -q -j$(sysctl -in machdep.cpu.core_count) --with-iostreams --with-date_time --with-filesystem \ + --with-system --with-program_options --with-chrono --with-test install \ && cd .. \ && rm -f boost_$BOOST_VERSION.tar.bz2 \ && rm -rf $BOOST_LINK_LOCATION \ diff --git a/unittests/misc_tests.cpp b/unittests/misc_tests.cpp index 607c78859fd..5ed82c742c0 100644 --- a/unittests/misc_tests.cpp +++ b/unittests/misc_tests.cpp @@ -833,29 +833,40 @@ BOOST_AUTO_TEST_CASE(transaction_metadata_test) { try { BOOST_CHECK( !mtrx->signing_keys_future.valid() ); BOOST_CHECK( !mtrx2->signing_keys_future.valid() ); - transaction_metadata::create_signing_keys_future( mtrx, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); - transaction_metadata::create_signing_keys_future( mtrx2, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); + transaction_metadata::start_recover_keys( mtrx, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); + transaction_metadata::start_recover_keys( mtrx2, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); BOOST_CHECK( mtrx->signing_keys_future.valid() ); BOOST_CHECK( mtrx2->signing_keys_future.valid() ); // no-op - transaction_metadata::create_signing_keys_future( mtrx, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); - transaction_metadata::create_signing_keys_future( mtrx2, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); + transaction_metadata::start_recover_keys( mtrx, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); + transaction_metadata::start_recover_keys( mtrx2, thread_pool, test.control->get_chain_id(), fc::microseconds::maximum() ); auto keys = mtrx->recover_keys( test.control->get_chain_id() ); - BOOST_CHECK_EQUAL(1u, keys.size()); - BOOST_CHECK_EQUAL(public_key, *keys.begin()); + BOOST_CHECK_EQUAL(1u, keys.second.size()); + BOOST_CHECK_EQUAL(public_key, *keys.second.begin()); // again - keys = mtrx->recover_keys( test.control->get_chain_id() ); - BOOST_CHECK_EQUAL(1u, keys.size()); - BOOST_CHECK_EQUAL(public_key, *keys.begin()); + auto keys2 = mtrx->recover_keys( test.control->get_chain_id() ); + BOOST_CHECK_EQUAL(1u, keys2.second.size()); + BOOST_CHECK_EQUAL(public_key, *keys2.second.begin()); - auto keys2 = mtrx2->recover_keys( test.control->get_chain_id() ); - BOOST_CHECK_EQUAL(1u, keys.size()); - BOOST_CHECK_EQUAL(public_key, *keys.begin()); + auto keys3 = mtrx2->recover_keys( test.control->get_chain_id() ); + BOOST_CHECK_EQUAL(1u, keys3.second.size()); + BOOST_CHECK_EQUAL(public_key, *keys3.second.begin()); + // recover keys without first calling start_recover_keys + transaction_metadata_ptr mtrx4 = std::make_shared( std::make_shared( trx, packed_transaction::none) ); + transaction_metadata_ptr mtrx5 = std::make_shared( std::make_shared( trx, packed_transaction::zlib) ); + + auto keys4 = mtrx4->recover_keys( test.control->get_chain_id() ); + BOOST_CHECK_EQUAL(1u, keys4.second.size()); + BOOST_CHECK_EQUAL(public_key, *keys4.second.begin()); + + auto keys5 = mtrx5->recover_keys( test.control->get_chain_id() ); + BOOST_CHECK_EQUAL(1u, keys5.second.size()); + BOOST_CHECK_EQUAL(public_key, *keys5.second.begin()); } FC_LOG_AND_RETHROW() }