diff --git a/.gitmodules b/.gitmodules index 205a731ffce..0b46282acfc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "libraries/chainbase"] path = libraries/chainbase - url = https://github.com/eosio/chainbase + url = https://github.com/boscore/chainbase ignore = dirty [submodule "libraries/appbase"] path = libraries/appbase diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d1504122e5..47405e2daa5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,12 +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) - if (LLVM_DIR STREQUAL "" OR NOT LLVM_DIR) - set(LLVM_DIR "/usr/local/opt/llvm@4/lib/cmake/llvm/") - endif() - endif() +if (UNIX AND APPLE) + list(APPEND CMAKE_PREFIX_PATH "/usr/local/opt/llvm@4" "/usr/local/opt/gettext") endif() include( GNUInstallDirs ) @@ -35,7 +31,7 @@ set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 3) set(VERSION_MINOR 0) -set(VERSION_PATCH 4) +set(VERSION_PATCH 5) if(VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") @@ -52,8 +48,8 @@ set( INSTALLER_APP_ID "68ad7005-8eee-49c9-95ce-9eed97e5b347" ) # http://stackoverflow.com/a/18369825 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - message(FATAL_ERROR "GCC version must be at least 6.0!") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) + message(FATAL_ERROR "GCC version must be at least 7.0!") endif() if ("${CMAKE_GENERATOR}" STREQUAL "Ninja") add_compile_options(-fdiagnostics-color=always) @@ -112,24 +108,18 @@ IF( WIN32 ) set(Boost_USE_MULTITHREADED ON) set(BOOST_ALL_DYN_LINK OFF) # force dynamic linking for all libraries ENDIF(WIN32) -FIND_PACKAGE(Boost 1.67 REQUIRED COMPONENTS +set( Boost_NO_BOOST_CMAKE ON CACHE STRING "ON or OFF" ) +FIND_PACKAGE(Boost 1.71 REQUIRED COMPONENTS thread date_time filesystem system program_options - signals - 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() +add_definitions(-DBOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) if( WIN32 ) @@ -169,11 +159,11 @@ else( WIN32 ) # Apple AND Linux if( APPLE ) # Apple Specific Options Here message( STATUS "Configuring EOSIO on OS X" ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated-declarations" ) + set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} -Wall -Wno-deprecated-declarations" ) else( APPLE ) # Linux Specific Options Here message( STATUS "Configuring EOSIO on Linux" ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall" ) + set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} -Wall" ) if ( FULL_STATIC_BUILD ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") endif ( FULL_STATIC_BUILD ) @@ -262,27 +252,24 @@ install(FILES ${CMAKE_BINARY_DIR}/modules/eosio-config.cmake DESTINATION ${CMAKE configure_file(${CMAKE_SOURCE_DIR}/CMakeModules/EosioTester.cmake.in ${CMAKE_BINARY_DIR}/modules/EosioTester.cmake @ONLY) install(FILES ${CMAKE_BINARY_DIR}/modules/EosioTester.cmake DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/eosio) -configure_file(${CMAKE_SOURCE_DIR}/LICENSE +configure_file(${CMAKE_SOURCE_DIR}/LICENSE ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/libraries/wabt/LICENSE +configure_file(${CMAKE_SOURCE_DIR}/libraries/wabt/LICENSE ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.wabt COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/libraries/softfloat/COPYING.txt +configure_file(${CMAKE_SOURCE_DIR}/libraries/softfloat/COPYING.txt ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.softfloat COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/libraries/wasm-jit/LICENSE +configure_file(${CMAKE_SOURCE_DIR}/libraries/wasm-jit/LICENSE ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.wavm COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/secp256k1/upstream/COPYING +configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/secp256k1/upstream/COPYING ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.secp256k1 COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/src/network/LICENSE.go +configure_file(${CMAKE_SOURCE_DIR}/libraries/fc/src/network/LICENSE.go ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.go COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/externals/binaryen/LICENSE - ${CMAKE_BINARY_DIR}/licenses/eosio/LICENSE.binaryen COPYONLY) install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/) install(FILES libraries/wabt/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ RENAME LICENSE.wabt) install(FILES libraries/softfloat/COPYING.txt DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ RENAME LICENSE.softfloat) install(FILES libraries/wasm-jit/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ RENAME LICENSE.wavm) install(FILES libraries/fc/secp256k1/upstream/COPYING DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ RENAME LICENSE.secp256k1) -install(FILES externals/binaryen/LICENSE DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ RENAME LICENSE.binaryen) install(FILES libraries/fc/src/network/LICENSE.go DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/eosio/ ) include(package) diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 3ccc4bd0e62..5bf987b7c5f 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -1,11 +1,11 @@ -FROM boscore/builder as builder +FROM boscore/builder:v2.0.4 as builder ARG branch=master ARG symbol=SYS ENV OPENSSL_ROOT_DIR /usr/include/openssl RUN git clone -b $branch https://github.com/boscore/bos.git --recursive \ - && cd bos && echo "$branch:$(git rev-parse HEAD)" > /etc/eosio-version \ + && cd bos && echo "$branch:$(git rev-parse HEAD)" > /etc/boscore-version \ && cmake -H. -B"/tmp/build" -GNinja -DCMAKE_BUILD_TYPE=Release -DWASM_ROOT=/opt/wasm -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_COMPILER=clang -DCMAKE_INSTALL_PREFIX=/tmp/build -DBUILD_MONGO_DB_PLUGIN=true -DCORE_SYMBOL_NAME=$symbol \ -DOPENSSL_ROOT_DIR="${OPENSSL_ROOT_DIR}" -DCMAKE_CXX_STANDARD_LIBRARIES="-lpthread" \ @@ -22,4 +22,4 @@ COPY --from=builder /bos/Docker/nodeosd.sh /opt/eosio/bin/nodeosd.sh ENV EOSIO_ROOT=/opt/eosio RUN chmod +x /opt/eosio/bin/nodeosd.sh ENV LD_LIBRARY_PATH /usr/local/lib -ENV PATH /opt/eosio/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ No newline at end of file +ENV PATH /opt/eosio/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin diff --git a/Docker/README.md b/Docker/README.md index b30685382c4..2f23146cb33 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -20,10 +20,10 @@ cd bos/Docker docker build . -t boscore/bos -s BOS ``` -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 v3.0.4 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 v3.0.5 tag, you could do the following: ```bash -docker build -t boscore/bos:v3.0.4 --build-arg branch=v3.0.4 . +docker build -t boscore/bos:v3.0.5 --build-arg branch=v3.0.5 . ``` diff --git a/Docker/builder/Dockerfile b/Docker/builder/Dockerfile index 39ce643f4d1..ba356ea5eb1 100644 --- a/Docker/builder/Dockerfile +++ b/Docker/builder/Dockerfile @@ -26,13 +26,13 @@ RUN wget https://cmake.org/files/v3.9/cmake-3.9.6-Linux-x86_64.sh \ ENV CC clang ENV CXX clang++ -RUN wget https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2 -O - | tar -xj \ - && cd boost_1_67_0 \ +RUN wget https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2 -O - | tar -xj \ + && cd boost_1_71_0 \ && ./bootstrap.sh --prefix=/usr/local \ && echo 'using clang : 4.0 : clang++-4.0 ;' >> project-config.jam \ && ./b2 -d0 -j$(nproc) --with-thread --with-date_time --with-system --with-filesystem --with-program_options \ - --with-signals --with-serialization --with-chrono --with-test --with-context --with-locale --with-coroutine --with-iostreams toolset=clang link=static install \ - && cd .. && rm -rf boost_1_67_0 + --with-serialization --with-chrono --with-test --with-context --with-locale --with-coroutine --with-iostreams toolset=clang link=static install \ + && cd .. && rm -rf boost_1_71_0 RUN wget https://github.com/mongodb/mongo-c-driver/releases/download/1.10.2/mongo-c-driver-1.10.2.tar.gz -O - | tar -xz \ && cd mongo-c-driver-1.10.2 \ diff --git a/Docker/config.ini b/Docker/config.ini index 9014d16a888..eb88235177c 100644 --- a/Docker/config.ini +++ b/Docker/config.ini @@ -1,15 +1,3 @@ -# the endpoint upon which to listen for incoming connections (eosio::bnet_plugin) -bnet-endpoint = 0.0.0.0:4321 - -# the number of threads to use to process network messages (eosio::bnet_plugin) -# bnet-threads = - -# remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network (eosio::bnet_plugin) -# bnet-connect = - -# this peer will request no pending transactions from other nodes (eosio::bnet_plugin) -bnet-no-trx = false - # the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin) blocks-dir = "blocks" diff --git a/README.md b/README.md index 1e7c08f698b..c8f6380148b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# BOSCore - Born for DApps. Born for Usability. +# BOSCore - Using technology to create a trusted business ecosystem -## BOSCore Version: v3.0.4 -### Basic EOSIO Version: v1.6.6 (support REX, part 1.8.x) +## BOSCore Version: v3.0.5 +### Basic EOSIO Version: v1.6.6 (support REX, part 2.0.x) # Background The emergence of EOS has brought new imagination to the blockchain. In just a few months since the main network was launched, the version has undergone dozens of upgrades, not only the stability has been greatly improved, but also the new functions have been gradually realized. The node team is also actively involved in building the EOSIO ecosystem. What is even more exciting is that EOS has attracted more and more development teams. There are already hundreds of DApp running on the EOS main network. The transaction volume and circulation market value far exceed Ethereum, and the space for development is growing broader. diff --git a/README_CN.md b/README_CN.md index a6465826236..ce47f8b538d 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,7 +1,7 @@ -# BOSCore - 更可用的链,为DApp而生。 +# BOSCore - 用技术打造可信商业生态 -## BOSCore Version: v3.0.4 -### Basic EOSIO Version: v1.6.6 (support REX, part 1.8.x) +## BOSCore Version: v3.0.5 +### Basic EOSIO Version: v1.6.6 (support REX, part 2.0.x) # 背景 EOS的出现给区块链带来了新的想象力,主网启动短短几个月以来,版本经历了几十次升级,不仅稳定性得到了很大提高,并且新功能也逐步实现,各个节点团队也积极参与建设EOSIO生态。让人更加兴奋的是,EOS已经吸引了越来越多的开发团队,当前已经有数百个DApp在EOS主网上面运行,其交易量和流通市值远超以太坊,可发展的空间愈来愈广阔。 diff --git a/eosio_build.sh b/eosio_build.sh index eba45661cdd..a60352e23a7 100755 --- a/eosio_build.sh +++ b/eosio_build.sh @@ -187,8 +187,8 @@ ;; "elementary OS") FILE="${SOURCE_DIR}/scripts/eosio_build_ubuntu.sh" - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 + CXX_COMPILER=clang++ + C_COMPILER=clang MONGOD_CONF=${HOME}/opt/mongodb/mongod.conf export PATH=${HOME}/opt/mongodb/bin:$PATH ;; @@ -201,22 +201,22 @@ ;; "Linux Mint") FILE="${SOURCE_DIR}/scripts/eosio_build_ubuntu.sh" - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 + CXX_COMPILER=clang++ + C_COMPILER=clang MONGOD_CONF=${HOME}/opt/mongodb/mongod.conf export PATH=${HOME}/opt/mongodb/bin:$PATH ;; "Ubuntu") FILE="${SOURCE_DIR}/scripts/eosio_build_ubuntu.sh" - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 + CXX_COMPILER=clang++ + C_COMPILER=clang MONGOD_CONF=${HOME}/opt/mongodb/mongod.conf export PATH=${HOME}/opt/mongodb/bin:$PATH ;; "Debian GNU/Linux") FILE=${SOURCE_DIR}/scripts/eosio_build_ubuntu.sh - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 + CXX_COMPILER=clang++ + C_COMPILER=clang MONGOD_CONF=${HOME}/opt/mongodb/mongod.conf export PATH=${HOME}/opt/mongodb/bin:$PATH ;; diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index c198d037f9c..e9afa759c9f 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -236,7 +236,10 @@ struct controller_impl { template void emit( const Signal& s, Arg&& a ) { try { - s(std::forward(a)); + s( std::forward( a )); + } catch (std::bad_alloc& e) { + wlog( "std::bad_alloc" ); + throw e; } catch (boost::interprocess::bad_alloc& e) { wlog( "bad alloc" ); throw e; @@ -466,9 +469,6 @@ struct controller_impl { ~controller_impl() { pending.reset(); - - db.flush(); - reversible_blocks.flush(); } void add_indices() { @@ -671,7 +671,6 @@ struct controller_impl { return enc.result(); } - /** * Sets fork database head to the genesis state. */ @@ -1651,7 +1650,22 @@ struct controller_impl { if (!pbft_enabled) return; if ( pending_pbft_lib ) { + //this is a temp solution for getting current lib, should not use anywhere else; + auto current_lib = fork_db.get_block_in_current_chain_by_num(head->bft_irreversible_blocknum)->id; fork_db.set_bft_irreversible(*pending_pbft_lib); + if (!replaying) { + auto libs_to_be_emitted = vector{}; + auto b = fork_db.get_block(*pending_pbft_lib); + while (b->id != current_lib) { + libs_to_be_emitted.emplace_back(b); + b = fork_db.get_block(b->prev()); + } + while (!libs_to_be_emitted.empty()) { + emit( self.new_irreversible_block, libs_to_be_emitted.back() ); + libs_to_be_emitted.pop_back(); + } + } + pending_pbft_lib.reset(); if (!pending && read_mode != db_read_mode::IRREVERSIBLE) { diff --git a/libraries/chain/include/eosio/chain/asset.hpp b/libraries/chain/include/eosio/chain/asset.hpp index 5c9bb9669bc..85222652a02 100644 --- a/libraries/chain/include/eosio/chain/asset.hpp +++ b/libraries/chain/include/eosio/chain/asset.hpp @@ -18,7 +18,7 @@ with amount = 10 and symbol(4,"CUR") */ -struct asset +struct asset : fc::reflect_init { static constexpr int64_t max_amount = (1LL << 62) - 1; diff --git a/libraries/chain/include/eosio/chain/chain_id_type.hpp b/libraries/chain/include/eosio/chain/chain_id_type.hpp index a16fc143ae6..59ab8f248b0 100644 --- a/libraries/chain/include/eosio/chain/chain_id_type.hpp +++ b/libraries/chain/include/eosio/chain/chain_id_type.hpp @@ -47,8 +47,6 @@ namespace chain { friend class eosio::net_plugin_impl; friend struct eosio::handshake_message; - - friend struct ::hello; // TODO: Rushed hack to support bnet_plugin. Need a better solution. }; } } // namespace eosio::chain diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 05c5c925e59..ad827f54f73 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -301,6 +301,7 @@ namespace eosio { namespace chain { signal accepted_block_header; signal accepted_block; signal irreversible_block; + signal new_irreversible_block; signal accepted_transaction; signal applied_transaction; signal accepted_confirmation; diff --git a/libraries/chain/include/eosio/chain/symbol.hpp b/libraries/chain/include/eosio/chain/symbol.hpp index 437b1d36ab7..de4a37514a6 100644 --- a/libraries/chain/include/eosio/chain/symbol.hpp +++ b/libraries/chain/include/eosio/chain/symbol.hpp @@ -58,7 +58,7 @@ namespace eosio { operator uint64_t()const { return value; } }; - class symbol { + class symbol : fc::reflect_init { public: static constexpr uint8_t max_precision = 18; diff --git a/libraries/chain/include/eosio/chain/transaction.hpp b/libraries/chain/include/eosio/chain/transaction.hpp index a8b53b98e0d..10ffaab9018 100644 --- a/libraries/chain/include/eosio/chain/transaction.hpp +++ b/libraries/chain/include/eosio/chain/transaction.hpp @@ -102,7 +102,7 @@ namespace eosio { namespace chain { bool allow_duplicate_keys = false )const; }; - struct packed_transaction { + struct packed_transaction : fc::reflect_init { enum compression_type { none = 0, zlib = 1, @@ -158,6 +158,7 @@ namespace eosio { namespace chain { friend struct fc::reflector; friend struct fc::reflector_init_visitor; + friend struct fc::has_reflector_init; void reflector_init(); private: vector signatures; diff --git a/libraries/chain/transaction.cpp b/libraries/chain/transaction.cpp index 08cd6a0222c..23d762d34a2 100644 --- a/libraries/chain/transaction.cpp +++ b/libraries/chain/transaction.cpp @@ -99,10 +99,11 @@ fc::microseconds transaction::get_signature_keys( const vector& std::unique_lock lock(cache_mtx, std::defer_lock); fc::microseconds sig_cpu_usage; + const auto digest_time = fc::time_point::now() - start; for(const signature_type& sig : signatures) { - auto now = fc::time_point::now(); - EOS_ASSERT( now < deadline, tx_cpu_usage_exceeded, "transaction signature verification executed for too long", - ("now", now)("deadline", deadline)("start", start) ); + auto sig_start = fc::time_point::now(); + EOS_ASSERT( sig_start < deadline, tx_cpu_usage_exceeded, "transaction signature verification executed for too long", + ("now", sig_start)("deadline", deadline)("start", start) ); public_key_type recov; const auto& tid = id(); lock.lock(); @@ -110,7 +111,7 @@ fc::microseconds transaction::get_signature_keys( const vector& if( it == recovery_cache.get().end() || it->trx_id != tid ) { lock.unlock(); recov = public_key_type( sig, digest ); - fc::microseconds cpu_usage = fc::time_point::now() - start; + fc::microseconds cpu_usage = fc::time_point::now() - sig_start; lock.lock(); recovery_cache.emplace_back( cached_pub_key{tid, recov, sig, cpu_usage} ); //could fail on dup signatures; not a problem sig_cpu_usage += cpu_usage; @@ -131,7 +132,7 @@ fc::microseconds transaction::get_signature_keys( const vector& recovery_cache.erase( recovery_cache.begin()); lock.unlock(); - return sig_cpu_usage; + return sig_cpu_usage + digest_time; } FC_CAPTURE_AND_RETHROW() } @@ -327,7 +328,6 @@ packed_transaction::packed_transaction( transaction&& t, vector& void packed_transaction::reflector_init() { // called after construction, but always on the same thread and before packed_transaction passed to any other threads - static_assert(&fc::reflector_init_visitor::reflector_init, "FC with reflector_init required"); static_assert(fc::raw::has_feature_reflector_init_on_unpacked_reflected_types, "FC unpack needs to call reflector_init otherwise unpacked_trx will not be initialized"); EOS_ASSERT( unpacked_trx.expiration == time_point_sec(), tx_decompression_error, "packed_transaction already unpacked" ); diff --git a/libraries/chainbase b/libraries/chainbase index 8ca96ad6b18..751fb6eeee6 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 8ca96ad6b18709d65a7d1f67f8893978f25babcf +Subproject commit 751fb6eeee627ac4333d69c9355e35ca08fcf104 diff --git a/libraries/fc b/libraries/fc index b2fa419ddf6..5ac1fd76872 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit b2fa419ddf68c6b5fc902de53cf8e691206cc8f3 +Subproject commit 5ac1fd7687261511c4a6a1866c5ade4b867390f8 diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8eb52950702..c52c1545959 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(bnet_plugin) add_subdirectory(net_plugin) add_subdirectory(net_api_plugin) add_subdirectory(http_plugin) diff --git a/plugins/bnet_plugin/CMakeLists.txt b/plugins/bnet_plugin/CMakeLists.txt deleted file mode 100644 index d49438298cf..00000000000 --- a/plugins/bnet_plugin/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -file(GLOB HEADERS "include/eosio/bnet_plugin/*.hpp") -add_library( bnet_plugin - bnet_plugin.cpp - ${HEADERS} ) - -target_link_libraries( bnet_plugin chain_plugin eosio_chain appbase ) -target_include_directories( bnet_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) diff --git a/plugins/bnet_plugin/bnet_plugin.cpp b/plugins/bnet_plugin/bnet_plugin.cpp deleted file mode 100644 index b25631cbabc..00000000000 --- a/plugins/bnet_plugin/bnet_plugin.cpp +++ /dev/null @@ -1,1562 +0,0 @@ -/** - * The purpose of this protocol is to synchronize (and keep synchronized) two - * blockchains using a very simple algorithm: - * - * 1. find the last block id on our local chain that the remote peer knows about - * 2. if we have the next block send it to them - * 3. if we don't have the next block send them a the oldest unexpired transaction - * - * There are several input events: - * - * 1. new block accepted by local chain - * 2. block deemed irreversible by local chain - * 3. new block header accepted by local chain - * 4. transaction accepted by local chain - * 5. block received from remote peer - * 6. transaction received from remote peer - * 7. socket ready for next write - * - * Each session is responsible for maintaining the following - * - * 1. the most recent block on our current best chain which we know - * with certainty that the remote peer has. - * - this could be the peers last irreversible block - * - a block ID after the LIB that the peer has notified us of - * - a block which we have sent to the remote peer - * - a block which the peer has sent us - * 2. the block IDs we have received from the remote peer so that - * we can disconnect peer if one of those blocks is deemed invalid - * - we can clear these IDs once the block becomes reversible - * 3. the transactions we have received from the remote peer so that - * we do not send them something that they already know. - * - this includes transactions sent as part of blocks - * - we clear this cache after we have applied a block that - * includes the transactions because we know the controller - * should not notify us again (they would be dupe) - * - * Assumptions: - * 1. all blocks we send the peer are valid and will be held in the - * peers fork database until they become irreversible or are replaced - * by an irreversible alternative. - * 2. we don't care what fork the peer is on, so long as we know they have - * the block prior to the one we want to send. The peer will sort it out - * with its fork database and hopfully come to our conclusion. - * 3. the peer will send us blocks on the same basis - * - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using tcp = boost::asio::ip::tcp; -namespace ws = boost::beast::websocket; - -namespace eosio { - using namespace chain; - - static appbase::abstract_plugin& _bnet_plugin = app().register_plugin(); - -} /// namespace eosio - -namespace fc { - extern std::unordered_map& get_logger_map(); -} - -const fc::string logger_name("bnet_plugin"); -fc::logger plugin_logger; -std::string peer_log_format; - -#define peer_dlog( PEER, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( plugin_logger.is_enabled( fc::log_level::debug ) ) \ - plugin_logger.log( FC_LOG_MESSAGE( debug, peer_log_format + FORMAT, __VA_ARGS__ (PEER->get_logger_variant()) ) ); \ - FC_MULTILINE_MACRO_END - -#define peer_ilog( PEER, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( plugin_logger.is_enabled( fc::log_level::info ) ) \ - plugin_logger.log( FC_LOG_MESSAGE( info, peer_log_format + FORMAT, __VA_ARGS__ (PEER->get_logger_variant()) ) ); \ - FC_MULTILINE_MACRO_END - -#define peer_wlog( PEER, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( plugin_logger.is_enabled( fc::log_level::warn ) ) \ - plugin_logger.log( FC_LOG_MESSAGE( warn, peer_log_format + FORMAT, __VA_ARGS__ (PEER->get_logger_variant()) ) ); \ - FC_MULTILINE_MACRO_END - -#define peer_elog( PEER, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( plugin_logger.is_enabled( fc::log_level::error ) ) \ - plugin_logger.log( FC_LOG_MESSAGE( error, peer_log_format + FORMAT, __VA_ARGS__ (PEER->get_logger_variant())) ); \ - FC_MULTILINE_MACRO_END - - -using eosio::public_key_type; -using eosio::chain_id_type; -using eosio::block_id_type; -using eosio::block_timestamp_type; -using std::string; -using eosio::sha256; -using eosio::signed_block_ptr; -using eosio::packed_transaction_ptr; -using std::vector; - -struct hello { - public_key_type peer_id; - string network_version; - string agent; - string protocol_version = "1.0.1"; - string user; - string password; - chain_id_type chain_id; - bool request_transactions = false; - uint32_t last_irr_block_num = 0; - vector pending_block_ids; -}; -FC_REFLECT( hello, (peer_id)(network_version)(user)(password)(agent)(protocol_version)(chain_id)(request_transactions)(last_irr_block_num)(pending_block_ids) ) - -struct hello_extension_irreversible_only {}; - -FC_REFLECT( hello_extension_irreversible_only, BOOST_PP_SEQ_NIL ) - -using hello_extension = fc::static_variant; - -/** - * This message is sent upon successful speculative application of a transaction - * and informs a peer not to send this message. - */ -struct trx_notice { - vector signed_trx_id; ///< hash of trx + sigs -}; - -FC_REFLECT( trx_notice, (signed_trx_id) ) - -/** - * This message is sent upon successfully adding a transaction to the fork database - * and informs the remote peer that there is no need to send this block. - */ -struct block_notice { - vector block_ids; -}; - -FC_REFLECT( block_notice, (block_ids) ); - -struct ping { - fc::time_point sent; - fc::sha256 code; - uint32_t lib; ///< the last irreversible block -}; -FC_REFLECT( ping, (sent)(code)(lib) ) - -struct pong { - fc::time_point sent; - fc::sha256 code; -}; -FC_REFLECT( pong, (sent)(code) ) - -using bnet_message = fc::static_variant; - - -struct by_id; -struct by_num; -struct by_received; -struct by_expired; - -namespace eosio { - using namespace chain::plugin_interface; - - class bnet_plugin_impl; - - template - void verify_strand_in_this_thread(const Strand& strand, const char* func, int line) { - if( !strand.running_in_this_thread() ) { - elog( "wrong strand: ${f} : line ${n}, exiting", ("f", func)("n", line) ); - app().quit(); - } - } - - /** - * Each session is presumed to operate in its own strand so that - * operations can execute in parallel. - */ - class session : public std::enable_shared_from_this - { - public: - enum session_state { - hello_state, - sending_state, - idle_state - }; - - struct block_status { - block_status( block_id_type i, bool kby_peer, bool rfrom_peer) - { - known_by_peer = kby_peer; - received_from_peer = rfrom_peer; - id = i; - } - - bool known_by_peer = false; ///< we sent block to peer or peer sent us notice - bool received_from_peer = false; ///< peer sent us this block and considers full block valid - block_id_type id; ///< the block id; - // block_id_type prev; ///< the prev block id - - // shared_ptr< vector > block_msg; ///< packed bnet_message for this block - - uint32_t block_num()const { return block_header::num_from_id(id); } - }; - - typedef boost::multi_index_container, member >, - ordered_non_unique< tag, const_mem_fun > - > - > block_status_index; - - - struct transaction_status { - time_point received; - time_point expired; /// 5 seconds from last accepted - transaction_id_type id; - transaction_metadata_ptr trx; - - void mark_known_by_peer() { received = fc::time_point::maximum(); trx.reset(); } - bool known_by_peer()const { return received == fc::time_point::maximum(); } - }; - - typedef boost::multi_index_container, member >, - ordered_non_unique< tag, member >, - ordered_non_unique< tag, member > - > - > transaction_status_index; - - block_status_index _block_status; - transaction_status_index _transaction_status; - const uint32_t _max_block_status_range = 2048; // limit tracked block_status known_by_peer - - public_key_type _local_peer_id; - uint32_t _local_lib = 0; - block_id_type _local_lib_id; - uint32_t _local_head_block_num = 0; - block_id_type _local_head_block_id; /// the last block id received on local channel - - - public_key_type _remote_peer_id; - uint32_t _remote_lib = 0; - block_id_type _remote_lib_id; - bool _remote_request_trx = false; - bool _remote_request_irreversible_only = false; - - uint32_t _last_sent_block_num = 0; - block_id_type _last_sent_block_id; /// the id of the last block sent - bool _recv_remote_hello = false; - bool _sent_remote_hello = false; - - - fc::sha256 _current_code; - fc::time_point _last_recv_ping_time = fc::time_point::now(); - ping _last_recv_ping; - ping _last_sent_ping; - - - int _session_num = 0; - session_state _state = hello_state; - tcp::resolver _resolver; - bnet_ptr _net_plugin; - boost::asio::io_service& _ios; - unique_ptr> _ws; - boost::asio::strand< boost::asio::io_context::executor_type> _strand; - boost::asio::io_service& _app_ios; - - methods::get_block_by_number::method_type& _get_block_by_number; - - - string _peer; - string _remote_host; - string _remote_port; - - vector _out_buffer; - //boost::beast::multi_buffer _in_buffer; - boost::beast::flat_buffer _in_buffer; - flat_set _block_header_notices; - fc::optional _logger_variant; - - - int next_session_id()const { - static std::atomic session_count(0); - return ++session_count; - } - - /** - * Creating session from server socket acceptance - */ - explicit session( tcp::socket socket, bnet_ptr net_plug ) - :_resolver(socket.get_io_service()), - _net_plugin( std::move(net_plug) ), - _ios(socket.get_io_service()), - _ws( new ws::stream(move(socket)) ), - _strand(_ws->get_executor() ), - _app_ios( app().get_io_service() ), - _get_block_by_number( app().get_method() ) - { - _session_num = next_session_id(); - set_socket_options(); - _ws->binary(true); - wlog( "open session ${n}",("n",_session_num) ); - } - - - /** - * Creating outgoing session - */ - explicit session( boost::asio::io_context& ioc, bnet_ptr net_plug ) - :_resolver(ioc), - _net_plugin( std::move(net_plug) ), - _ios(ioc), - _ws( new ws::stream(ioc) ), - _strand( _ws->get_executor() ), - _app_ios( app().get_io_service() ), - _get_block_by_number( app().get_method() ) - { - _session_num = next_session_id(); - _ws->binary(true); - wlog( "open session ${n}",("n",_session_num) ); - } - - ~session(); - - - void set_socket_options() { - try { - /** to minimize latency when sending short messages */ - _ws->next_layer().set_option( boost::asio::ip::tcp::no_delay(true) ); - - /** to minimize latency when sending large 1MB blocks, the send buffer should not have to - * wait for an "ack", making this larger could result in higher latency for smaller urgent - * messages. - */ - _ws->next_layer().set_option( boost::asio::socket_base::send_buffer_size( 1024*1024 ) ); - _ws->next_layer().set_option( boost::asio::socket_base::receive_buffer_size( 1024*1024 ) ); - } catch ( ... ) { - elog( "uncaught exception on set socket options" ); - } - } - - void run() { - _ws->async_accept( boost::asio::bind_executor( - _strand, - std::bind( &session::on_accept, - shared_from_this(), - std::placeholders::_1) ) ); - } - - void run( const string& peer ) { - auto c = peer.find(':'); - auto host = peer.substr( 0, c ); - auto port = peer.substr( c+1, peer.size() ); - - _peer = peer; - _remote_host = host; - _remote_port = port; - - _resolver.async_resolve( _remote_host, _remote_port, - boost::asio::bind_executor( _strand, - std::bind( &session::on_resolve, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2 ) ) ); - } - - void on_resolve( boost::system::error_code ec, - tcp::resolver::results_type results ) { - if( ec ) return on_fail( ec, "resolve" ); - - boost::asio::async_connect( _ws->next_layer(), - results.begin(), results.end(), - boost::asio::bind_executor( _strand, - std::bind( &session::on_connect, - shared_from_this(), - std::placeholders::_1 ) ) ); - } - - void on_connect( boost::system::error_code ec ) { - if( ec ) return on_fail( ec, "connect" ); - - set_socket_options(); - - _ws->async_handshake( _remote_host, "/", - boost::asio::bind_executor( _strand, - std::bind( &session::on_handshake, - shared_from_this(), - std::placeholders::_1 ) ) ); - } - - void on_handshake( boost::system::error_code ec ) { - if( ec ) return on_fail( ec, "handshake" ); - - do_hello(); - do_read(); - } - - /** - * This will be called "every time" a the transaction is accepted which happens - * on the speculative block (potentially several such blocks) and when a block - * that contains the transaction is applied and/or when switching forks. - * - * We will add it to the transaction status table as "received now" to be the - * basis of sending it to the peer. When we send it to the peer "received now" - * will be set to the infinite future to mark it as sent so we don't resend it - * when it is accepted again. - * - * Each time the transaction is "accepted" we extend the time we cache it by - * 5 seconds from now. Every time a block is applied we purge all accepted - * transactions that have reached 5 seconds without a new "acceptance". - */ - void on_accepted_transaction( transaction_metadata_ptr t ) { - //ilog( "accepted ${t}", ("t",t->id) ); - auto itr = _transaction_status.find( t->id ); - if( itr != _transaction_status.end() ) { - if( !itr->known_by_peer() ) { - _transaction_status.modify( itr, [&]( auto& stat ) { - stat.expired = std::min( fc::time_point::now() + fc::seconds(5), t->packed_trx->expiration() ); - }); - } - return; - } - - transaction_status stat; - stat.received = fc::time_point::now(); - stat.expired = stat.received + fc::seconds(5); - stat.id = t->id; - stat.trx = t; - _transaction_status.insert( stat ); - - maybe_send_next_message(); - } - - /** - * Remove all transactions that expired from cache prior to now - */ - void purge_transaction_cache() { - auto& idx = _transaction_status.get(); - auto itr = idx.begin(); - auto now = fc::time_point::now(); - while( itr != idx.end() && itr->expired < now ) { - idx.erase(itr); - itr = idx.begin(); - } - } - - /** - * When our local LIB advances we can purge our known history up to - * the LIB or up to the last block known by the remote peer. - */ - void on_new_lib( block_state_ptr s ) { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - _local_lib = s->block_num; - _local_lib_id = s->id; - - auto purge_to = std::min( _local_lib, _last_sent_block_num ); - - auto& idx = _block_status.get(); - auto itr = idx.begin(); - while( itr != idx.end() && itr->block_num() < purge_to ) { - idx.erase(itr); - itr = idx.begin(); - } - - if( _remote_request_irreversible_only ) { - auto bitr = _block_status.find(s->id); - if ( bitr == _block_status.end() || !bitr->received_from_peer ) { - _block_header_notices.insert(s->id); - } - } - - maybe_send_next_message(); - } - - - void on_bad_block( signed_block_ptr b ) { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - try { - auto id = b->id(); - auto itr = _block_status.find( id ); - if( itr == _block_status.end() ) return; - if( itr->received_from_peer ) { - peer_elog(this, "bad signed_block_ptr : unknown" ); - elog( "peer sent bad block #${b} ${i}, disconnect", ("b", b->block_num())("i",b->id()) ); - _ws->next_layer().close(); - } - } catch ( ... ) { - elog( "uncaught exception" ); - } - } - - void on_accepted_block_header( const block_state_ptr& s ) { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - // ilog( "accepted block header ${n}", ("n",s->block_num) ); - const auto& id = s->id; - - if( fc::time_point::now() - s->block->timestamp < fc::seconds(6) ) { - // ilog( "queue notice to peer that we have this block so hopefully they don't send it to us" ); - auto itr = _block_status.find( id ); - if( !_remote_request_irreversible_only && ( itr == _block_status.end() || !itr->received_from_peer ) ) { - _block_header_notices.insert( id ); - } - if( itr == _block_status.end() ) { - _block_status.insert( block_status(id, false, false) ); - } - } - } - - void on_accepted_block( const block_state_ptr& s ) { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - //idump((_block_status.size())(_transaction_status.size())); - //ilog( "accepted block ${n}", ("n",s->block_num) ); - - const auto& id = s->id; - - _local_head_block_id = id; - _local_head_block_num = block_header::num_from_id(id); - - if( _local_head_block_num < _last_sent_block_num ) { - _last_sent_block_num = _local_lib; - _last_sent_block_id = _local_lib_id; - } - - purge_transaction_cache(); - - /** purge all transactions from cache, I will send them as part of a block - * in the future unless peer tells me they already have block. - */ - for( const auto& receipt : s->block->transactions ) { - if( receipt.trx.which() == 1 ) { - const auto& pt = receipt.trx.get(); - const auto& tid = pt.id(); - auto itr = _transaction_status.find( tid ); - if( itr != _transaction_status.end() ) - _transaction_status.erase(itr); - } - } - - maybe_send_next_message(); /// attempt to send if we are idle - } - - - template - void async_get_pending_block_ids( L&& callback ) { - /// send peer my head block status which is read from chain plugin - _app_ios.post( [self = shared_from_this(),callback]{ - auto& control = app().get_plugin().chain(); - auto lib = control.last_irreversible_block_num(); - auto head = control.fork_db_head_block_id(); - auto head_num = block_header::num_from_id(head); - - - std::vector ids; - if( lib > 0 ) { - ids.reserve((head_num-lib)+1); - for( auto i = lib; i <= head_num; ++i ) { - ids.emplace_back(control.get_block_id_for_num(i)); - } - } - self->_ios.post( boost::asio::bind_executor( - self->_strand, - [callback,ids,lib](){ - callback(ids,lib); - } - )); - }); - } - - template - void async_get_block_num( uint32_t blocknum, L&& callback ) { - _app_ios.post( [self = shared_from_this(), blocknum, callback]{ - auto& control = app().get_plugin().chain(); - signed_block_ptr sblockptr; - try { - //ilog( "fetch block ${n}", ("n",blocknum) ); - sblockptr = control.fetch_block_by_number( blocknum ); - } catch ( const fc::exception& e ) { - edump((e.to_detail_string())); - } - - self->_ios.post( boost::asio::bind_executor( - self->_strand, - [callback,sblockptr](){ - callback(sblockptr); - } - )); - }); - } - - void do_hello(); - - - void send( const bnet_message& msg ) { try { - auto ps = fc::raw::pack_size(msg); - _out_buffer.resize(ps); - fc::datastream ds(_out_buffer.data(), ps); - fc::raw::pack(ds, msg); - send(); - } FC_LOG_AND_RETHROW() } - - template - void send( const bnet_message& msg, const T& ex ) { try { - auto ex_size = fc::raw::pack_size(ex); - auto ps = fc::raw::pack_size(msg) + fc::raw::pack_size(unsigned_int(ex_size)) + ex_size; - _out_buffer.resize(ps); - fc::datastream ds(_out_buffer.data(), ps); - fc::raw::pack( ds, msg ); - fc::raw::pack( ds, unsigned_int(ex_size) ); - fc::raw::pack( ds, ex ); - send(); - } FC_LOG_AND_RETHROW() } - - void send() { try { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - - _state = sending_state; - _ws->async_write( boost::asio::buffer(_out_buffer), - boost::asio::bind_executor( - _strand, - std::bind( &session::on_write, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2 ) ) ); - } FC_LOG_AND_RETHROW() } - - void mark_block_status( const block_id_type& id, bool known_by_peer, bool recv_from_peer ) { - auto itr = _block_status.find(id); - if( itr == _block_status.end() ) { - // optimization to avoid sending blocks to nodes that already know about them - // to avoid unbounded memory growth limit number tracked - const auto min_block_num = std::min( _local_lib, _last_sent_block_num ); - const auto max_block_num = min_block_num + _max_block_status_range; - const auto block_num = block_header::num_from_id( id ); - if( block_num > min_block_num && block_num < max_block_num && _block_status.size() < _max_block_status_range ) - _block_status.insert( block_status( id, known_by_peer, recv_from_peer ) ); - } else { - _block_status.modify( itr, [&]( auto& item ) { - item.known_by_peer = known_by_peer; - if (recv_from_peer) item.received_from_peer = true; - }); - } - } - - /** - * This method will determine whether there is a message in the - * out queue, if so it returns. Otherwise it determines the best - * message to send. - */ - void maybe_send_next_message() { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - if( _state == sending_state ) return; /// in process of sending - if( _out_buffer.size() ) return; /// in process of sending - if( !_recv_remote_hello || !_sent_remote_hello ) return; - - clear_expired_trx(); - - if( send_block_notice() ) return; - if( send_pong() ) return; - if( send_ping() ) return; - - /// we don't know where we are (waiting on accept block localhost) - if( _local_head_block_id == block_id_type() ) return ; - if( send_next_block() ) return; - if( send_next_trx() ) return; - } - - bool send_block_notice() { - if( _block_header_notices.size() == 0 ) - return false; - - block_notice notice; - notice.block_ids.reserve( _block_header_notices.size() ); - for( auto& id : _block_header_notices ) - notice.block_ids.emplace_back(id); - send(notice); - _block_header_notices.clear(); - return true; - } - - bool send_pong() { - if( _last_recv_ping.code == fc::sha256() ) - return false; - - send( pong{ fc::time_point::now(), _last_recv_ping.code } ); - _last_recv_ping.code = fc::sha256(); - return true; - } - - bool send_ping() { - auto delta_t = fc::time_point::now() - _last_sent_ping.sent; - if( delta_t < fc::seconds(3) ) return false; - - if( _last_sent_ping.code == fc::sha256() ) { - _last_sent_ping.sent = fc::time_point::now(); - _last_sent_ping.code = fc::sha256::hash(_last_sent_ping.sent); /// TODO: make this more random - _last_sent_ping.lib = _local_lib; - send( _last_sent_ping ); - } - - /// we expect the peer to send us a ping every 3 seconds, so if we haven't gotten one - /// in the past 6 seconds then the connection is likely hung. Unfortunately, we cannot - /// use the round-trip time of ping/pong to measure latency because during syncing the - /// remote peer can be stuck doing CPU intensive tasks that block its reading of the - /// buffer. This buffer gets filled with perhaps 100 blocks taking .1 seconds each for - /// a total processing time of 10+ seconds. That said, the peer should come up for air - /// every .1 seconds so should still be able to send out a ping every 3 seconds. - // - // We don't want to wait a RTT for each block because that could also slow syncing for - // empty blocks... - // - //if( fc::time_point::now() - _last_recv_ping_time > fc::seconds(6) ) { - // do_goodbye( "no ping from peer in last 6 seconds...." ); - //} - return true; - } - - bool is_known_by_peer( block_id_type id ) { - auto itr = _block_status.find(id); - if( itr == _block_status.end() ) return false; - return itr->known_by_peer; - } - - void clear_expired_trx() { - auto& idx = _transaction_status.get(); - auto itr = idx.begin(); - while( itr != idx.end() && itr->expired < fc::time_point::now() ) { - idx.erase(itr); - itr = idx.begin(); - } - } - - bool send_next_trx() { try { - if( !_remote_request_trx ) return false; - - auto& idx = _transaction_status.get(); - auto start = idx.begin(); - if( start == idx.end() || start->known_by_peer() ) - return false; - - - auto ptrx_ptr = start->trx->packed_trx; - - idx.modify( start, [&]( auto& stat ) { - stat.mark_known_by_peer(); - }); - - // wlog("sending trx ${id}", ("id",start->id) ); - send(ptrx_ptr); - - return true; - - } FC_LOG_AND_RETHROW() } - - void on_async_get_block( const signed_block_ptr& nextblock ) { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - if( !nextblock) { - _state = idle_state; - maybe_send_next_message(); - return; - } - - /// if something changed, the next block doesn't link to the last - /// block we sent, local chain must have switched forks - if( nextblock->previous != _last_sent_block_id && _last_sent_block_id != block_id_type() ) { - if( !is_known_by_peer( nextblock->previous ) ) { - _last_sent_block_id = _local_lib_id; - _last_sent_block_num = _local_lib; - _state = idle_state; - maybe_send_next_message(); - return; - } - } - - /// at this point we know the peer can link this block - - auto next_id = nextblock->id(); - - /// if the peer already knows about this block, great no need to - /// send it, mark it as 'sent' and move on. - if( is_known_by_peer( next_id ) ) { - _last_sent_block_id = next_id; - _last_sent_block_num = nextblock->block_num(); - - _state = idle_state; - maybe_send_next_message(); - return; - } - - mark_block_status( next_id, true, false ); - - _last_sent_block_id = next_id; - _last_sent_block_num = nextblock->block_num(); - - send( nextblock ); - status( "sending block " + std::to_string( block_header::num_from_id(next_id) ) ); - - if( nextblock->timestamp > (fc::time_point::now() - fc::seconds(5)) ) { - mark_block_transactions_known_by_peer( nextblock ); - } - } - - /** - * Send the next block after the last block in our current fork that - * we know the remote peer knows. - */ - bool send_next_block() { - - if ( _remote_request_irreversible_only && _last_sent_block_id == _local_lib_id ) { - return false; - } - - if( _last_sent_block_id == _local_head_block_id ) /// we are caught up - return false; - - ///< set sending state because this callback may result in sending a message - _state = sending_state; - async_get_block_num( _last_sent_block_num + 1, - [self=shared_from_this()]( auto sblockptr ) { - self->on_async_get_block( sblockptr ); - }); - - return true; - } - - void on_fail( boost::system::error_code ec, const char* what ) { - try { - verify_strand_in_this_thread(_strand, __func__, __LINE__); - elog( "${w}: ${m}", ("w", what)("m", ec.message() ) ); - _ws->next_layer().close(); - } catch ( ... ) { - elog( "uncaught exception on close" ); - } - } - - void on_accept( boost::system::error_code ec ) { - if( ec ) { - return on_fail( ec, "accept" ); - } - - do_hello(); - do_read(); - } - - void do_read() { - _ws->async_read( _in_buffer, - boost::asio::bind_executor( - _strand, - std::bind( &session::on_read, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2))); - } - - void on_read( boost::system::error_code ec, std::size_t bytes_transferred ) { - boost::ignore_unused(bytes_transferred); - - if( ec == ws::error::closed ) - return on_fail( ec, "close on read" ); - - if( ec ) { - return on_fail( ec, "read" );; - } - - try { - auto d = boost::asio::buffer_cast(boost::beast::buffers_front(_in_buffer.data())); - auto s = boost::asio::buffer_size(_in_buffer.data()); - fc::datastream ds(d,s); - - bnet_message msg; - fc::raw::unpack( ds, msg ); - on_message( msg, ds ); - _in_buffer.consume( ds.tellp() ); - - wait_on_app(); - return; - - } catch ( ... ) { - wlog( "close bad payload" ); - } - try { - _ws->close( boost::beast::websocket::close_code::bad_payload ); - } catch ( ... ) { - elog( "uncaught exception on close" ); - } - } - - /** if we just call do_read here then this thread might run ahead of - * the main thread, instead we post an event to main which will then - * post a new read event when ready. - * - * This also keeps the "shared pointer" alive in the callback preventing - * the connection from being closed. - */ - void wait_on_app() { - app().get_io_service().post( - boost::asio::bind_executor( _strand, [self=shared_from_this()]{ self->do_read(); } ) - ); - } - - void on_message( const bnet_message& msg, fc::datastream& ds ) { - try { - switch( msg.which() ) { - case bnet_message::tag::value: - on( msg.get(), ds ); - break; - case bnet_message::tag::value: - on( msg.get() ); - break; - case bnet_message::tag::value: - on( msg.get() ); - break; - case bnet_message::tag::value: - on( msg.get() ); - break; - case bnet_message::tag::value: - on( msg.get() ); - break; - case bnet_message::tag::value: - on( msg.get() ); - break; - default: - wlog( "bad message received" ); - _ws->close( boost::beast::websocket::close_code::bad_payload ); - return; - } - maybe_send_next_message(); - } catch( const fc::exception& e ) { - elog( "${e}", ("e",e.to_detail_string())); - _ws->close( boost::beast::websocket::close_code::bad_payload ); - } - } - - void on( const block_notice& notice ) { - peer_ilog(this, "received block_notice"); - for( const auto& id : notice.block_ids ) { - status( "received notice " + std::to_string( block_header::num_from_id(id) ) ); - mark_block_status( id, true, false ); - } - } - - void on( const hello& hi, fc::datastream& ds ); - - void on( const ping& p ) { - peer_ilog(this, "received ping"); - _last_recv_ping = p; - _remote_lib = p.lib; - _last_recv_ping_time = fc::time_point::now(); - } - - void on( const pong& p ) { - peer_ilog(this, "received pong"); - if( p.code != _last_sent_ping.code ) { - peer_elog(this, "bad ping : invalid pong code"); - return do_goodbye( "invalid pong code" ); - } - _last_sent_ping.code = fc::sha256(); - } - - void do_goodbye( const string& reason ) { - try { - status( "goodbye - " + reason ); - _ws->next_layer().close(); - } catch ( ... ) { - elog( "uncaught exception on close" ); - } - } - - void check_for_redundant_connection(); - - void on( const signed_block_ptr& b ) { - peer_ilog(this, "received signed_block_ptr"); - if (!b) { - peer_elog(this, "bad signed_block_ptr : null pointer"); - EOS_THROW(block_validate_exception, "bad block" ); - } - status( "received block " + std::to_string(b->block_num()) ); - //ilog( "recv block ${n}", ("n", b->block_num()) ); - auto id = b->id(); - mark_block_status( id, true, true ); - - app().get_channel().publish(b); - - mark_block_transactions_known_by_peer( b ); - } - - void mark_block_transactions_known_by_peer( const signed_block_ptr& b ) { - for( const auto& receipt : b->transactions ) { - if( receipt.trx.which() == 1 ) { - const auto& pt = receipt.trx.get(); - const auto& id = pt.id(); - mark_transaction_known_by_peer(id); - } - } - } - - /** - * @return true if trx is known by local host, false if new to this host - */ - bool mark_transaction_known_by_peer( const transaction_id_type& id ) { - auto itr = _transaction_status.find( id ); - if( itr != _transaction_status.end() ) { - _transaction_status.modify( itr, [&]( auto& stat ) { - stat.mark_known_by_peer(); - }); - return true; - } else { - transaction_status stat; - stat.id = id; - stat.mark_known_by_peer(); - stat.expired = fc::time_point::now()+fc::seconds(5); - _transaction_status.insert(stat); - } - return false; - } - - void on( const packed_transaction_ptr& p ); - - void on_write( boost::system::error_code ec, std::size_t bytes_transferred ) { - boost::ignore_unused(bytes_transferred); - verify_strand_in_this_thread(_strand, __func__, __LINE__); - if( ec ) { - _ws->next_layer().close(); - return on_fail( ec, "write" ); - } - _state = idle_state; - _out_buffer.resize(0); - maybe_send_next_message(); - } - - void status( const string& msg ) { - // ilog( "${remote_peer}: ${msg}", ("remote_peer",fc::variant(_remote_peer_id).as_string().substr(3,5) )("msg",msg) ); - } - - const fc::variant_object& get_logger_variant() { - if (!_logger_variant) { - boost::system::error_code ec; - auto rep = _ws->lowest_layer().remote_endpoint(ec); - string ip = ec ? "" : rep.address().to_string(); - string port = ec ? "" : std::to_string(rep.port()); - - auto lep = _ws->lowest_layer().local_endpoint(ec); - string lip = ec ? "" : lep.address().to_string(); - string lport = ec ? "" : std::to_string(lep.port()); - - _logger_variant.emplace(fc::mutable_variant_object() - ("_name", _peer) - ("_id", _remote_peer_id) - ("_ip", ip) - ("_port", port) - ("_lip", lip) - ("_lport", lport) - ); - } - return *_logger_variant; - } - }; - - - /** - * Accepts incoming connections and launches the sessions - */ - class listener : public std::enable_shared_from_this { - private: - tcp::acceptor _acceptor; - tcp::socket _socket; - bnet_ptr _net_plugin; - - public: - listener( boost::asio::io_context& ioc, tcp::endpoint endpoint, bnet_ptr np ) - :_acceptor(ioc), _socket(ioc), _net_plugin(std::move(np)) - { - boost::system::error_code ec; - - _acceptor.open( endpoint.protocol(), ec ); - if( ec ) { on_fail( ec, "open" ); return; } - - _acceptor.set_option( boost::asio::socket_base::reuse_address(true) ); - - _acceptor.bind( endpoint, ec ); - if( ec ) { on_fail( ec, "bind" ); return; } - - _acceptor.listen( boost::asio::socket_base::max_listen_connections, ec ); - if( ec ) on_fail( ec, "listen" ); - } - - void run() { - EOS_ASSERT( _acceptor.is_open(), plugin_exception, "unable top open listen socket" ); - do_accept(); - } - - void do_accept() { - _acceptor.async_accept( _socket, [self=shared_from_this()]( auto ec ){ self->on_accept(ec); } ); - } - - void on_fail( boost::system::error_code ec, const char* what ) { - elog( "${w}: ${m}", ("w", what)("m", ec.message() ) ); - } - - void on_accept( boost::system::error_code ec ); - }; - - - class bnet_plugin_impl : public std::enable_shared_from_this { - public: - bnet_plugin_impl() = default; - - const private_key_type _peer_pk = fc::crypto::private_key::generate(); /// one time random key to identify this process - public_key_type _peer_id = _peer_pk.get_public_key(); - string _bnet_endpoint_address = "0.0.0.0"; - uint16_t _bnet_endpoint_port = 4321; - bool _request_trx = true; - bool _follow_irreversible = false; - - std::vector _connect_to_peers; /// list of peers to connect to - std::vector _socket_threads; - int32_t _num_threads = 1; - - std::unique_ptr _ioc; // lifetime guarded by shared_ptr of bnet_plugin_impl - std::shared_ptr _listener; - std::shared_ptr _timer; // only access on app io_service - std::map > _sessions; // only access on app io_service - - channels::irreversible_block::channel_type::handle _on_irb_handle; - channels::accepted_block::channel_type::handle _on_accepted_block_handle; - channels::accepted_block_header::channel_type::handle _on_accepted_block_header_handle; - channels::rejected_block::channel_type::handle _on_bad_block_handle; - channels::accepted_transaction::channel_type::handle _on_appled_trx_handle; - - void async_add_session( std::weak_ptr wp ) { - app().get_io_service().post( [wp,this]{ - if( auto l = wp.lock() ) { - _sessions[l.get()] = wp; - } - }); - } - - void on_session_close( const session* s ) { - verify_strand_in_this_thread(app().get_io_service().get_executor(), __func__, __LINE__); - auto itr = _sessions.find(s); - if( _sessions.end() != itr ) - _sessions.erase(itr); - } - - template - void for_each_session( Call callback ) { - app().get_io_service().post([this, callback = callback] { - for (const auto& item : _sessions) { - if (auto ses = item.second.lock()) { - ses->_ios.post(boost::asio::bind_executor( - ses->_strand, - [ses, cb = callback]() { cb(ses); } - )); - } - } - }); - } - - void on_accepted_transaction( transaction_metadata_ptr trx ) { - if( trx->implicit || trx->scheduled ) return; - for_each_session( [trx]( auto ses ){ ses->on_accepted_transaction( trx ); } ); - } - - /** - * Notify all active connection of the new irreversible block so they - * can purge their block cache - */ - void on_irreversible_block( block_state_ptr s ) { - for_each_session( [s]( auto ses ){ ses->on_new_lib( s ); } ); - } - - /** - * Notify all active connections of the new accepted block so - * they can relay it. This method also pre-packages the block - * as a packed bnet_message so the connections can simply relay - * it on. - */ - void on_accepted_block( block_state_ptr s ) { - _ioc->post( [s,this] { /// post this to the thread pool because packing can be intensive - for_each_session( [s]( auto ses ){ ses->on_accepted_block( s ); } ); - }); - } - - void on_accepted_block_header( block_state_ptr s ) { - _ioc->post( [s,this] { /// post this to the thread pool because packing can be intensive - for_each_session( [s]( auto ses ){ ses->on_accepted_block_header( s ); } ); - }); - } - - /** - * We received a bad block which either - * 1. didn't link to known chain - * 2. violated the consensus rules - * - * Any peer which sent us this block (not noticed) - * should be disconnected as they are objectively bad - */ - void on_bad_block( signed_block_ptr s ) { - for_each_session( [s]( auto ses ) { ses->on_bad_block(s); } ); - }; - - void on_reconnect_peers() { - verify_strand_in_this_thread(app().get_io_service().get_executor(), __func__, __LINE__); - for( const auto& peer : _connect_to_peers ) { - bool found = false; - for( const auto& con : _sessions ) { - auto ses = con.second.lock(); - if( ses && (ses->_peer == peer) ) { - found = true; - break; - } - } - - if( !found ) { - wlog( "attempt to connect to ${p}", ("p",peer) ); - auto s = std::make_shared( *_ioc, shared_from_this() ); - s->_local_peer_id = _peer_id; - _sessions[s.get()] = s; - s->run( peer ); - } - } - - start_reconnect_timer(); - } - - - void start_reconnect_timer() { - /// add some random delay so that all my peers don't attempt to reconnect to me - /// at the same time after shutting down.. - _timer->expires_from_now( boost::posix_time::microseconds( 1000000*(10+rand()%5) ) ); - _timer->async_wait([=](const boost::system::error_code& ec) { - if( ec ) { return; } - on_reconnect_peers(); - }); - } - }; - - - void listener::on_accept( boost::system::error_code ec ) { - if( ec ) { - if( ec == boost::system::errc::too_many_files_open ) - do_accept(); - return; - } - std::shared_ptr newsession; - try { - newsession = std::make_shared( move( _socket ), _net_plugin ); - } - catch( std::exception& e ) { - //making a session creates an instance of std::random_device which may open /dev/urandom - // for example. Unfortuately the only defined error is a std::exception derivative - _socket.close(); - } - if( newsession ) { - _net_plugin->async_add_session( newsession ); - newsession->_local_peer_id = _net_plugin->_peer_id; - newsession->run(); - } - do_accept(); - } - - - bnet_plugin::bnet_plugin() - :my(std::make_shared()) { - } - - bnet_plugin::~bnet_plugin() { - } - - void bnet_plugin::set_program_options(options_description& cli, options_description& cfg) { - cfg.add_options() - ("bnet-endpoint", bpo::value()->default_value("0.0.0.0:4321"), "the endpoint upon which to listen for incoming connections" ) - ("bnet-follow-irreversible", bpo::value()->default_value(false), "this peer will request only irreversible blocks from other nodes" ) - ("bnet-threads", bpo::value(), "the number of threads to use to process network messages" ) - ("bnet-connect", bpo::value>()->composing(), "remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network" ) - ("bnet-no-trx", bpo::bool_switch()->default_value(false), "this peer will request no pending transactions from other nodes" ) - ("bnet-peer-log-format", bpo::value()->default_value( "[\"${_name}\" ${_ip}:${_port}]" ), - "The string used to format peers when logging messages about them. Variables are escaped with ${}.\n" - "Available Variables:\n" - " _name \tself-reported name\n\n" - " _id \tself-reported ID (Public Key)\n\n" - " _ip \tremote IP address of peer\n\n" - " _port \tremote port number of peer\n\n" - " _lip \tlocal IP address connected to peer\n\n" - " _lport \tlocal port number connected to peer\n\n") - ; - } - - void bnet_plugin::plugin_initialize(const variables_map& options) { - ilog( "Initialize bnet plugin" ); - - try { - peer_log_format = options.at( "bnet-peer-log-format" ).as(); - - if( options.count( "bnet-endpoint" )) { - auto ip_port = options.at( "bnet-endpoint" ).as(); - - //auto host = boost::asio::ip::host_name(ip_port); - auto port = ip_port.substr( ip_port.find( ':' ) + 1, ip_port.size()); - auto host = ip_port.substr( 0, ip_port.find( ':' )); - my->_bnet_endpoint_address = host; - my->_bnet_endpoint_port = std::stoi( port ); - idump((ip_port)( host )( port )( my->_follow_irreversible )); - } - if( options.count( "bnet-follow-irreversible" )) { - my->_follow_irreversible = options.at( "bnet-follow-irreversible" ).as(); - } - - - if( options.count( "bnet-connect" )) { - my->_connect_to_peers = options.at( "bnet-connect" ).as>(); - } - if( options.count( "bnet-threads" )) { - my->_num_threads = options.at( "bnet-threads" ).as(); - if( my->_num_threads > 8 ) - my->_num_threads = 8; - } - my->_request_trx = !options.at( "bnet-no-trx" ).as(); - - } FC_LOG_AND_RETHROW() - } - - void bnet_plugin::plugin_startup() { - if(fc::get_logger_map().find(logger_name) != fc::get_logger_map().end()) - plugin_logger = fc::get_logger_map()[logger_name]; - - wlog( "bnet startup " ); - - auto& chain = app().get_plugin().chain(); - FC_ASSERT ( chain.get_read_mode() != chain::db_read_mode::IRREVERSIBLE, "bnet is not compatible with \"irreversible\" read_mode"); - - my->_on_appled_trx_handle = app().get_channel() - .subscribe( [this]( transaction_metadata_ptr t ){ - my->on_accepted_transaction(t); - }); - - my->_on_irb_handle = app().get_channel() - .subscribe( [this]( block_state_ptr s ){ - my->on_irreversible_block(s); - }); - - my->_on_accepted_block_handle = app().get_channel() - .subscribe( [this]( block_state_ptr s ){ - my->on_accepted_block(s); - }); - - my->_on_accepted_block_header_handle = app().get_channel() - .subscribe( [this]( block_state_ptr s ){ - my->on_accepted_block_header(s); - }); - - my->_on_bad_block_handle = app().get_channel() - .subscribe( [this]( signed_block_ptr b ){ - my->on_bad_block(b); - }); - - - if( app().get_plugin().chain().get_read_mode() == chain::db_read_mode::READ_ONLY ) { - if (my->_request_trx) { - my->_request_trx = false; - ilog( "forced bnet-no-trx to true since in read-only mode" ); - } - } - - const auto address = boost::asio::ip::make_address( my->_bnet_endpoint_address ); - my->_ioc.reset( new boost::asio::io_context{my->_num_threads} ); - - - auto& ioc = *my->_ioc; - my->_timer = std::make_shared( app().get_io_service() ); - - my->start_reconnect_timer(); - - my->_listener = std::make_shared( ioc, - tcp::endpoint{ address, my->_bnet_endpoint_port }, - my ); - my->_listener->run(); - - my->_socket_threads.reserve( my->_num_threads ); - for( auto i = 0; i < my->_num_threads; ++i ) { - my->_socket_threads.emplace_back( [&ioc]{ wlog( "start thread" ); ioc.run(); wlog( "end thread" ); } ); - } - - for( const auto& peer : my->_connect_to_peers ) { - auto s = std::make_shared( ioc, my ); - s->_local_peer_id = my->_peer_id; - my->_sessions[s.get()] = s; - s->run( peer ); - } - } - - void bnet_plugin::plugin_shutdown() { - try { - my->_timer->cancel(); - my->_timer.reset(); - } catch ( ... ) { - elog( "exception thrown on timer shutdown" ); - } - - /// shut down all threads and close all connections - - my->for_each_session([](auto ses){ - ses->do_goodbye( "shutting down" ); - }); - - my->_listener.reset(); - my->_ioc->stop(); - - wlog( "joining bnet threads" ); - for( auto& t : my->_socket_threads ) { - t.join(); - } - wlog( "done joining threads" ); - - my->for_each_session([](auto ses){ - EOS_ASSERT( false, plugin_exception, "session ${ses} still active", ("ses", ses->_session_num) ); - }); - - // lifetime of _ioc is guarded by shared_ptr of bnet_plugin_impl - } - - - session::~session() { - wlog( "close session ${n}",("n",_session_num) ); - std::weak_ptr netp = _net_plugin; - _app_ios.post( [netp,ses=this]{ - if( auto net = netp.lock() ) - net->on_session_close(ses); - }); - } - - void session::do_hello() { - /// TODO: find more effecient way to move large array of ids in event of fork - async_get_pending_block_ids( [self = shared_from_this() ]( const vector& ids, uint32_t lib ){ - hello hello_msg; - hello_msg.peer_id = self->_local_peer_id; - hello_msg.last_irr_block_num = lib; - hello_msg.pending_block_ids = ids; - hello_msg.request_transactions = self->_net_plugin->_request_trx; - hello_msg.chain_id = app().get_plugin().get_chain_id(); // TODO: Quick fix in a rush. Maybe a better solution is needed. - - self->_local_lib = lib; - if ( self->_net_plugin->_follow_irreversible ) { - self->send( hello_msg, hello_extension(hello_extension_irreversible_only()) ); - } else { - self->send( hello_msg ); - } - self->_sent_remote_hello = true; - }); - } - - void session::check_for_redundant_connection() { - app().get_io_service().post( [self=shared_from_this()]{ - self->_net_plugin->for_each_session( [self]( auto ses ){ - if( ses != self && ses->_remote_peer_id == self->_remote_peer_id ) { - self->do_goodbye( "redundant connection" ); - } - }); - }); - } - - void session::on( const hello& hi, fc::datastream& ds ) { - peer_ilog(this, "received hello"); - _recv_remote_hello = true; - - if( hi.chain_id != app().get_plugin().get_chain_id() ) { // TODO: Quick fix in a rush. Maybe a better solution is needed. - peer_elog(this, "bad hello : wrong chain id"); - return do_goodbye( "disconnecting due to wrong chain id" ); - } - - if( hi.peer_id == _local_peer_id ) { - return do_goodbye( "connected to self" ); - } - - if ( _net_plugin->_follow_irreversible && hi.protocol_version <= "1.0.0") { - return do_goodbye( "need newer protocol version that supports sending only irreversible blocks" ); - } - - if ( hi.protocol_version >= "1.0.1" ) { - //optional extensions - while ( 0 < ds.remaining() ) { - unsigned_int size; - fc::raw::unpack( ds, size ); // next extension size - auto ex_start = ds.pos(); - fc::datastream dsw( ex_start, size ); - unsigned_int wich; - fc::raw::unpack( dsw, wich ); - hello_extension ex; - if ( wich < ex.count() ) { //know extension - fc::datastream dsx( ex_start, size ); //unpack needs to read static_variant _tag again - fc::raw::unpack( dsx, ex ); - if ( ex.which() == hello_extension::tag::value ) { - _remote_request_irreversible_only = true; - } - } else { - //unsupported extension, we just ignore it - //another side does know our protocol version, i.e. it know which extensions we support - //so, it some extensions were crucial, another side will close the connection - } - ds.skip(size); //move to next extension - } - } - - _last_sent_block_num = hi.last_irr_block_num; - _remote_request_trx = hi.request_transactions; - _remote_peer_id = hi.peer_id; - _remote_lib = hi.last_irr_block_num; - - for( const auto& id : hi.pending_block_ids ) - mark_block_status( id, true, false ); - - check_for_redundant_connection(); - - } - - void session::on( const packed_transaction_ptr& p ) { - peer_ilog(this, "received packed_transaction_ptr"); - if (!p) { - peer_elog(this, "bad packed_transaction_ptr : null pointer"); - EOS_THROW(transaction_exception, "bad transaction"); - } - if( !_net_plugin->_request_trx ) - return; - - // ilog( "recv trx ${n}", ("n", id) ); - if( p->expiration() < fc::time_point::now() ) return; - - const auto& id = p->id(); - - if( mark_transaction_known_by_peer( id ) ) - return; - - auto ptr = std::make_shared(p); - - app().get_channel().publish(ptr); - } -} /// namespace eosio diff --git a/plugins/bnet_plugin/include/eosio/bnet_plugin/bnet_plugin.hpp b/plugins/bnet_plugin/include/eosio/bnet_plugin/bnet_plugin.hpp deleted file mode 100644 index 9eb3a54c9a4..00000000000 --- a/plugins/bnet_plugin/include/eosio/bnet_plugin/bnet_plugin.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE - */ -#pragma once -#include - -#include - -namespace fc { class variant; } - -namespace eosio { - using chain::transaction_id_type; - using std::shared_ptr; - using namespace appbase; - using chain::name; - using fc::optional; - using chain::uint128_t; - - typedef shared_ptr bnet_ptr; - typedef shared_ptr bnet_const_ptr; - - - -/** - * This plugin tracks all actions and keys associated with a set of configured accounts. It enables - * wallets to paginate queries for bnet. - * - * An action will be included in the account's bnet if any of the following: - * - receiver - * - any account named in auth list - * - * A key will be linked to an account if the key is referneced in authorities of updateauth or newaccount - */ -class bnet_plugin : public plugin { - public: - APPBASE_PLUGIN_REQUIRES((chain_plugin)) - - bnet_plugin(); - virtual ~bnet_plugin(); - - virtual void set_program_options(options_description& cli, options_description& cfg) override; - - void plugin_initialize(const variables_map& options); - void plugin_startup(); - void plugin_shutdown(); - - private: - bnet_ptr my; -}; - -} /// namespace eosio - - diff --git a/plugins/chain_api_plugin/chain_api_plugin.cpp b/plugins/chain_api_plugin/chain_api_plugin.cpp index 8b9fd3f843c..8243765783d 100644 --- a/plugins/chain_api_plugin/chain_api_plugin.cpp +++ b/plugins/chain_api_plugin/chain_api_plugin.cpp @@ -28,10 +28,10 @@ chain_api_plugin::~chain_api_plugin(){} void chain_api_plugin::set_program_options(options_description&, options_description&) {} void chain_api_plugin::plugin_initialize(const variables_map&) {} -struct async_result_visitor : public fc::visitor { +struct async_result_visitor : public fc::visitor { template - std::string operator()(const T& v) const { - return fc::json::to_string(v); + fc::variant operator()(const T& v) const { + return fc::variant(v); } }; @@ -41,8 +41,8 @@ struct async_result_visitor : public fc::visitor { api_handle.validate(); \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp index 9a3212a56fd..cb99e7130f4 100644 --- a/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp +++ b/plugins/chain_interface/include/eosio/chain/plugin_interface.hpp @@ -28,6 +28,7 @@ namespace eosio { namespace chain { namespace plugin_interface { using accepted_block_header = channel_decl; using accepted_block = channel_decl; using irreversible_block = channel_decl; + using new_irreversible_block = channel_decl; using accepted_transaction = channel_decl; using applied_transaction = channel_decl; using accepted_confirmation = channel_decl; diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index df43dc312ce..093480135bd 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -144,6 +144,7 @@ class chain_plugin_impl { ,accepted_block_header_channel(app().get_channel()) ,accepted_block_channel(app().get_channel()) ,irreversible_block_channel(app().get_channel()) + ,new_irreversible_block_channel(app().get_channel()) ,accepted_transaction_channel(app().get_channel()) ,applied_transaction_channel(app().get_channel()) ,accepted_confirmation_channel(app().get_channel()) @@ -189,10 +190,11 @@ class chain_plugin_impl { channels::accepted_block_header::channel_type& accepted_block_header_channel; channels::accepted_block::channel_type& accepted_block_channel; channels::irreversible_block::channel_type& irreversible_block_channel; + channels::new_irreversible_block::channel_type& new_irreversible_block_channel; channels::accepted_transaction::channel_type& accepted_transaction_channel; channels::applied_transaction::channel_type& applied_transaction_channel; channels::accepted_confirmation::channel_type& accepted_confirmation_channel; - incoming::channels::block::channel_type& incoming_block_channel; + incoming::channels::block::channel_type& incoming_block_channel; // retained references to methods for easy calling incoming::methods::block_sync::method_type& incoming_block_sync_method; @@ -209,6 +211,7 @@ class chain_plugin_impl { fc::optional accepted_block_header_connection; fc::optional accepted_block_connection; fc::optional irreversible_block_connection; + fc::optional new_irreversible_block_connection; fc::optional accepted_transaction_connection; fc::optional applied_transaction_connection; fc::optional accepted_confirmation_connection; @@ -787,6 +790,10 @@ void chain_plugin::plugin_initialize(const variables_map& options) { my->irreversible_block_channel.publish( blk ); } ); + my->new_irreversible_block_connection = my->chain->new_irreversible_block.connect( [this]( const block_state_ptr& blk ) { + my->new_irreversible_block_channel.publish( blk ); + } ); + my->accepted_transaction_connection = my->chain->accepted_transaction.connect( [this]( const transaction_metadata_ptr& meta ) { my->accepted_transaction_channel.publish( meta ); @@ -911,6 +918,7 @@ void chain_plugin::plugin_shutdown() { my->accepted_block_header_connection.reset(); my->accepted_block_connection.reset(); my->irreversible_block_connection.reset(); + my->new_irreversible_block_connection.reset(); my->accepted_transaction_connection.reset(); my->applied_transaction_connection.reset(); my->accepted_confirmation_connection.reset(); diff --git a/plugins/db_size_api_plugin/db_size_api_plugin.cpp b/plugins/db_size_api_plugin/db_size_api_plugin.cpp index 8eed8b388ed..8c6df9566fe 100644 --- a/plugins/db_size_api_plugin/db_size_api_plugin.cpp +++ b/plugins/db_size_api_plugin/db_size_api_plugin.cpp @@ -18,7 +18,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp index d6f8f53e7b3..32db7146f6d 100644 --- a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp +++ b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp @@ -60,7 +60,7 @@ using results_pair = std::pair; try { \ if (body.empty()) body = "{}"; \ const auto result = api_handle->invoke_cb(body); \ - response_cb(result.first, fc::json::to_string(result.second)); \ + response_cb(result.first, fc::variant(result.second)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, response_cb); \ } \ diff --git a/plugins/history_api_plugin/history_api_plugin.cpp b/plugins/history_api_plugin/history_api_plugin.cpp index 67321fa58d0..1a610d7a395 100644 --- a/plugins/history_api_plugin/history_api_plugin.cpp +++ b/plugins/history_api_plugin/history_api_plugin.cpp @@ -24,8 +24,8 @@ void history_api_plugin::plugin_initialize(const variables_map&) {} [api_handle](string, string body, url_response_callback cb) mutable { \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(200, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(200, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index c808c5bb99f..94d749deb34 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -138,6 +138,9 @@ namespace eosio { websocket_server_type server; + std::atomic bytes_in_flight{0}; + size_t max_bytes_in_flight = 0; + optional https_listen_endpoint; string https_cert_chain; string https_key; @@ -150,10 +153,6 @@ namespace eosio { bool validate_host; set valid_hosts; - string unix_socket_path_option_name = "unix-socket-path"; - string http_server_address_option_name = "http-server-address"; - string https_server_address_option_name = "https-server-address"; - bool host_port_is_valid( const std::string& header_host_port, const string& endpoint_local_host_port ) { return !validate_host || header_host_port == endpoint_local_host_port || valid_hosts.find(header_host_port) != valid_hosts.end(); } @@ -281,15 +280,30 @@ namespace eosio { } con->append_header( "Content-type", "application/json" ); - auto body = con->get_request_body(); - auto resource = con->get_uri()->get_resource(); + + if( bytes_in_flight > max_bytes_in_flight ) { + dlog( "503 - too many bytes in flight: ${bytes}", ("bytes", bytes_in_flight.load()) ); + error_results results{websocketpp::http::status_code::too_many_requests, "Busy", error_results::error_info()}; + con->set_body( fc::json::to_string( results )); + con->set_status( websocketpp::http::status_code::too_many_requests ); + return; + } + + std::string body = con->get_request_body(); + std::string resource = con->get_uri()->get_resource(); auto handler_itr = url_handlers.find( resource ); if( handler_itr != url_handlers.end()) { con->defer_http_response(); - handler_itr->second( resource, body, [con]( auto code, auto&& body ) { - con->set_body( std::move( body )); - con->set_status( websocketpp::http::status_code::value( code )); + bytes_in_flight += body.size(); + handler_itr->second( resource, body, [&bytes_in_flight = this->bytes_in_flight, con]( int code, fc::variant response_body ) { + std::string json = fc::json::to_string( response_body ); + response_body.clear(); + const size_t json_size = json.size(); + bytes_in_flight += json_size; + con->set_body( std::move( json ) ); + con->set_status( websocketpp::http::status_code::value( code ) ); con->send_http_response(); + bytes_in_flight -= json_size; } ); } else { @@ -328,14 +342,6 @@ namespace eosio { valid_hosts.emplace(host + ":" + port); valid_hosts.emplace(host + ":" + resolved_port_str); } - - void mangle_option_names() { - if(current_http_plugin_defaults.address_config_prefix.empty()) - return; - unix_socket_path_option_name.insert(0, current_http_plugin_defaults.address_config_prefix+"-"); - http_server_address_option_name.insert(0, current_http_plugin_defaults.address_config_prefix+"-"); - https_server_address_option_name.insert(0, current_http_plugin_defaults.address_config_prefix+"-"); - } }; template<> @@ -347,23 +353,22 @@ namespace eosio { http_plugin::~http_plugin(){} void http_plugin::set_program_options(options_description&, options_description& cfg) { - my->mangle_option_names(); if(current_http_plugin_defaults.default_unix_socket_path.length()) cfg.add_options() - (my->unix_socket_path_option_name.c_str(), bpo::value()->default_value(current_http_plugin_defaults.default_unix_socket_path), + ("unix-socket-path", bpo::value()->default_value(current_http_plugin_defaults.default_unix_socket_path), "The filename (relative to data-dir) to create a unix socket for HTTP RPC; set blank to disable."); if(current_http_plugin_defaults.default_http_port) cfg.add_options() - (my->http_server_address_option_name.c_str(), bpo::value()->default_value("127.0.0.1:" + std::to_string(current_http_plugin_defaults.default_http_port)), + ("http-server-address", bpo::value()->default_value("127.0.0.1:" + std::to_string(current_http_plugin_defaults.default_http_port)), "The local IP and port to listen for incoming http connections; set blank to disable."); else cfg.add_options() - (my->http_server_address_option_name.c_str(), bpo::value(), + ("http-server-address", bpo::value(), "The local IP and port to listen for incoming http connections; leave blank to disable."); cfg.add_options() - (my->https_server_address_option_name.c_str(), bpo::value(), + ("https-server-address", bpo::value(), "The local IP and port to listen for incoming https connections; leave blank to disable.") ("https-certificate-chain-file", bpo::value(), @@ -396,10 +401,16 @@ namespace eosio { if (v) ilog("configured http with Access-Control-Allow-Credentials: true"); })->default_value(false), "Specify if Access-Control-Allow-Credentials: true should be returned on each request.") - ("max-body-size", bpo::value()->default_value(1024*1024), "The maximum body size in bytes allowed for incoming RPC requests") - ("verbose-http-errors", bpo::bool_switch()->default_value(false), "Append the error log to HTTP responses") - ("http-validate-host", boost::program_options::value()->default_value(true), "If set to false, then any incoming \"Host\" header is considered valid") - ("http-alias", bpo::value>()->composing(), "Additionaly acceptable values for the \"Host\" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default.") + ("max-body-size", bpo::value()->default_value(1024*1024), + "The maximum body size in bytes allowed for incoming RPC requests") + ("http-max-bytes-in-flight-mb", bpo::value()->default_value(500), + "Maximum size in megabytes http_plugin should use for processing http requests. 503 error response when exceeded." ) + ("verbose-http-errors", bpo::bool_switch()->default_value(false), + "Append the error log to HTTP responses") + ("http-validate-host", boost::program_options::value()->default_value(true), + "If set to false, then any incoming \"Host\" header is considered valid") + ("http-alias", bpo::value>()->composing(), + "Additionaly acceptable values for the \"Host\" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default.") ; } @@ -412,8 +423,8 @@ namespace eosio { } tcp::resolver resolver( app().get_io_service()); - if( options.count( my->http_server_address_option_name ) && options.at( my->http_server_address_option_name ).as().length()) { - string lipstr = options.at( my->http_server_address_option_name ).as(); + if( options.count( "http-server-address" ) && options.at( "http-server-address" ).as().length()) { + string lipstr = options.at( "http-server-address" ).as(); string host = lipstr.substr( 0, lipstr.find( ':' )); string port = lipstr.substr( host.size() + 1, lipstr.size()); tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str()); @@ -431,14 +442,14 @@ namespace eosio { } } - if( options.count( my->unix_socket_path_option_name ) && !options.at( my->unix_socket_path_option_name ).as().empty()) { - boost::filesystem::path sock_path = options.at(my->unix_socket_path_option_name).as(); + if( options.count( "unix-socket-path" ) && !options.at( "unix-socket-path" ).as().empty()) { + boost::filesystem::path sock_path = options.at("unix-socket-path").as(); if (sock_path.is_relative()) sock_path = app().data_dir() / sock_path; my->unix_endpoint = asio::local::stream_protocol::endpoint(sock_path.string()); } - if( options.count( my->https_server_address_option_name ) && options.at( my->https_server_address_option_name ).as().length()) { + if( options.count( "https-server-address" ) && options.at( "https-server-address" ).as().length()) { if( !options.count( "https-certificate-chain-file" ) || options.at( "https-certificate-chain-file" ).as().empty()) { elog( "https-certificate-chain-file is required for HTTPS" ); @@ -450,7 +461,7 @@ namespace eosio { return; } - string lipstr = options.at( my->https_server_address_option_name ).as(); + string lipstr = options.at( "https-server-address" ).as(); string host = lipstr.substr( 0, lipstr.find( ':' )); string port = lipstr.substr( host.size() + 1, lipstr.size()); tcp::resolver::query query( tcp::v4(), host.c_str(), port.c_str()); @@ -474,7 +485,9 @@ namespace eosio { my->max_body_size = options.at( "max-body-size" ).as(); verbose_http_errors = options.at( "verbose-http-errors" ).as(); - //watch out for the returns above when adding new code here + my->max_bytes_in_flight = options.at( "http-max-bytes-in-flight-mb" ).as() * 1024 * 1024; + + //watch out for the returns above when adding new code here } FC_LOG_AND_RETHROW() } @@ -541,6 +554,19 @@ namespace eosio { throw; } } + + add_api({{ + std::string("/v1/node/get_supported_apis"), + [&](string, string body, url_response_callback cb) mutable { + try { + if (body.empty()) body = "{}"; + auto result = (*this).get_supported_apis(); + cb(200, fc::variant(result)); + } catch (...) { + handle_exception("node", "get_supported_apis", body, cb); + } + } + }}); } void http_plugin::plugin_shutdown() { @@ -554,9 +580,7 @@ namespace eosio { void http_plugin::add_handler(const string& url, const url_handler& handler) { ilog( "add api url: ${c}", ("c",url) ); - app().get_io_service().post([=](){ - my->url_handlers.insert(std::make_pair(url,handler)); - }); + my->url_handlers.insert(std::make_pair(url,handler)); } void http_plugin::handle_exception( const char *api_name, const char *call_name, const string& body, url_response_callback cb ) { @@ -565,21 +589,21 @@ namespace eosio { throw; } catch (chain::unknown_block_exception& e) { error_results results{400, "Unknown Block", error_results::error_info(e, verbose_http_errors)}; - cb( 400, fc::json::to_string( results )); + cb( 400, fc::variant( results )); } catch (chain::unsatisfied_authorization& e) { error_results results{401, "UnAuthorized", error_results::error_info(e, verbose_http_errors)}; - cb( 401, fc::json::to_string( results )); + cb( 401, fc::variant( results )); } catch (chain::tx_duplicate& e) { error_results results{409, "Conflict", error_results::error_info(e, verbose_http_errors)}; - cb( 409, fc::json::to_string( results )); + cb( 409, fc::variant( results )); } catch (fc::eof_exception& e) { error_results results{422, "Unprocessable Entity", error_results::error_info(e, verbose_http_errors)}; - cb( 422, fc::json::to_string( results )); + cb( 422, fc::variant( results )); elog( "Unable to parse arguments to ${api}.${call}", ("api", api_name)( "call", call_name )); dlog("Bad arguments: ${args}", ("args", body)); } catch (fc::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(e, verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); if (e.code() != chain::greylist_net_usage_exceeded::code_value && e.code() != chain::greylist_cpu_usage_exceeded::code_value) { elog( "FC Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); @@ -587,14 +611,14 @@ namespace eosio { } } catch (std::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, e.what())), verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); elog( "STD Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); dlog( "Exception Details: ${e}", ("e", e.what())); } catch (...) { error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, "Unknown Exception" )), verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); elog( "Unknown Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); } @@ -615,4 +639,14 @@ namespace eosio { return verbose_http_errors; } + http_plugin::get_supported_apis_result http_plugin::get_supported_apis()const { + get_supported_apis_result result; + + for (const auto& handler : my->url_handlers) { + if (handler.first != "/v1/node/get_supported_apis") + result.apis.emplace_back(handler.first); + } + + return result; + } } diff --git a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp index c7bc1ebb2b6..d89ee72ffc8 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -17,7 +17,7 @@ namespace eosio { * * Arguments: response_code, response_body */ - using url_response_callback = std::function; + using url_response_callback = std::function; /** * @brief Callback type for a URL handler @@ -41,9 +41,6 @@ namespace eosio { using api_description = std::map; struct http_plugin_defaults { - //If not empty, this string is prepended on to the various configuration - // items for setting listen addresses - string address_config_prefix; //If empty, unix socket support will be completely disabled. If not empty, // unix socket support is enabled with the given default path (treated relative // to the datadir) @@ -97,6 +94,12 @@ namespace eosio { bool verbose_errors()const; + struct get_supported_apis_result { + vector apis; + }; + + get_supported_apis_result get_supported_apis()const; + private: std::unique_ptr my; }; @@ -152,3 +155,4 @@ namespace eosio { FC_REFLECT(eosio::error_results::error_info::error_detail, (message)(file)(line_number)(method)) FC_REFLECT(eosio::error_results::error_info, (code)(name)(what)(details)) FC_REFLECT(eosio::error_results, (code)(message)(error)) +FC_REFLECT(eosio::http_plugin::get_supported_apis_result, (apis)) diff --git a/plugins/http_plugin/include/eosio/http_plugin/local_endpoint.hpp b/plugins/http_plugin/include/eosio/http_plugin/local_endpoint.hpp index 4664d1d378a..3f646237e9f 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/local_endpoint.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/local_endpoint.hpp @@ -82,8 +82,7 @@ class local_connection : public lib::enable_shared_from_this { return socket::make_error_code(socket::error::invalid_state); } - m_socket = lib::make_shared( - lib::ref(*service)); + m_socket = lib::make_shared(*service); m_state = READY; @@ -266,8 +265,7 @@ class local_endpoint : public config::socket_type { m_alog->write(log::alevel::devel,"asio::init_asio"); m_io_service = ptr; - m_acceptor = lib::make_shared( - lib::ref(*m_io_service)); + m_acceptor = lib::make_shared(*m_io_service); m_state = READY; ec = lib::error_code(); diff --git a/plugins/login_plugin/login_plugin.cpp b/plugins/login_plugin/login_plugin.cpp index 0aeac67dce4..374a04b25dc 100644 --- a/plugins/login_plugin/login_plugin.cpp +++ b/plugins/login_plugin/login_plugin.cpp @@ -68,8 +68,8 @@ void login_plugin::plugin_initialize(const variables_map& options) { try { \ if (body.empty()) \ body = "{}"; \ - auto result = call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception("login", #call_name, body, cb); \ } \ diff --git a/plugins/net_api_plugin/net_api_plugin.cpp b/plugins/net_api_plugin/net_api_plugin.cpp index 3b7327c4313..315ea2816e9 100644 --- a/plugins/net_api_plugin/net_api_plugin.cpp +++ b/plugins/net_api_plugin/net_api_plugin.cpp @@ -29,7 +29,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 5ab0ca6b918..56d5df43a2d 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -835,7 +835,7 @@ namespace eosio { : blk_state(), trx_state(), peer_requested(), - socket( std::make_shared( std::ref(app().get_io_service()) )), + socket( std::make_shared( app().get_io_service()) ), node_id(), last_handshake_recv(), last_handshake_sent(), @@ -917,7 +917,7 @@ namespace eosio { void connection::close() { if(socket) { socket->close(); - socket.reset( new tcp::socket( std::ref(app().get_io_service())) ); + socket.reset( new tcp::socket( app().get_io_service()) ); } else { wlog("no socket to close!"); @@ -2180,7 +2180,7 @@ namespace eosio { connection_wptr weak_conn = c; // Note: need to add support for IPv6 too - auto resolver = std::make_shared( std::ref(app().get_io_service()) ); + auto resolver = std::make_shared( app().get_io_service() ); resolver->async_resolve( query, [weak_conn, resolver, this]( const boost::system::error_code& err, tcp::resolver::results_type endpoints ) { auto c = weak_conn.lock(); @@ -2276,7 +2276,7 @@ namespace eosio { void net_plugin_impl::start_listen_loop() { - auto socket = std::make_shared( std::ref( app().get_io_service() ) ); + auto socket = std::make_shared( app().get_io_service() ); acceptor->async_accept( *socket, [socket,this]( boost::system::error_code ec ) { if( !ec ) { uint32_t visitors = 0; @@ -3676,7 +3676,7 @@ namespace eosio { try { my->producer_plug = app().find_plugin(); - auto resolver = std::make_shared( std::ref(app().get_io_service()) ); + auto resolver = std::make_shared( app().get_io_service() ); if( my->p2p_address.size() > 0 ) { auto host = my->p2p_address.substr( 0, my->p2p_address.find( ':' )); auto port = my->p2p_address.substr( host.size() + 1, my->p2p_address.size()); @@ -3685,7 +3685,7 @@ namespace eosio { my->listen_endpoint = *resolver->resolve( query ); - my->acceptor.reset( new tcp::acceptor( std::ref(app().get_io_service())) ); + my->acceptor.reset( new tcp::acceptor( app().get_io_service()) ); if( !my->p2p_server_address.empty() ) { my->p2p_address = my->p2p_server_address; diff --git a/plugins/producer_api_plugin/producer_api_plugin.cpp b/plugins/producer_api_plugin/producer_api_plugin.cpp index 7fcde1ac98c..0ef7631c868 100644 --- a/plugins/producer_api_plugin/producer_api_plugin.cpp +++ b/plugins/producer_api_plugin/producer_api_plugin.cpp @@ -30,7 +30,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/test_control_api_plugin/test_control_api_plugin.cpp b/plugins/test_control_api_plugin/test_control_api_plugin.cpp index 307cccc197e..a932a27cad9 100644 --- a/plugins/test_control_api_plugin/test_control_api_plugin.cpp +++ b/plugins/test_control_api_plugin/test_control_api_plugin.cpp @@ -40,8 +40,8 @@ struct async_result_visitor : public fc::visitor { [api_handle](string, string body, url_response_callback cb) mutable { \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ 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 06b6f437cdb..265d24bd167 100644 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -46,7 +46,7 @@ using namespace eosio::chain; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ @@ -78,7 +78,7 @@ using namespace eosio::chain; http_plugin::handle_exception(#api_name, #call_name, body, cb);\ }\ } else {\ - cb(http_response_code, fc::json::to_string(eosio::detail::txn_test_gen_empty())); \ + cb(http_response_code, fc::variant(eosio::detail::txn_test_gen_empty())); \ }\ };\ INVOKE \ diff --git a/plugins/wallet_api_plugin/wallet_api_plugin.cpp b/plugins/wallet_api_plugin/wallet_api_plugin.cpp index 0d88ec2966d..1750150885c 100644 --- a/plugins/wallet_api_plugin/wallet_api_plugin.cpp +++ b/plugins/wallet_api_plugin/wallet_api_plugin.cpp @@ -30,7 +30,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/programs/eosio-launcher/main.cpp b/programs/eosio-launcher/main.cpp index 677d0a56235..63fa376a133 100644 --- a/programs/eosio-launcher/main.cpp +++ b/programs/eosio-launcher/main.cpp @@ -328,12 +328,6 @@ struct last_run_def { vector running_nodes; }; - -enum class p2p_plugin { - NET, - BNET -}; - enum launch_modes { LM_NONE, LM_LOCAL, @@ -396,7 +390,6 @@ struct launcher_def { size_t producers; size_t next_node; string shape; - p2p_plugin p2p; allowed_connection allowed_connections = PC_NONE; bfs::path genesis; bfs::path output; @@ -486,7 +479,6 @@ launcher_def::set_options (bpo::options_description &cfg) { ("producers",bpo::value(&producers)->default_value(21),"total number of non-bios producer instances in this network") ("mode,m",bpo::value>()->multitoken()->default_value({"any"}, "any"),"connection mode, combination of \"any\", \"producers\", \"specified\", \"none\"") ("shape,s",bpo::value(&shape)->default_value("star"),"network topology, use \"star\" \"mesh\" or give a filename for custom") - ("p2p-plugin", bpo::value()->default_value("net"),"select a p2p plugin to use (either net or bnet). Defaults to net.") ("genesis,g",bpo::value()->default_value("./genesis.json"),"set the path to genesis.json") ("skip-signature", bpo::bool_switch(&skip_transaction_signatures)->default_value(false), "nodeos does not require transaction signatures.") ("nodeos", bpo::value(&eosd_extra_args), "forward nodeos command line argument(s) to each instance of nodeos, enclose arg(s) in quotes") @@ -587,20 +579,6 @@ launcher_def::initialize (const variables_map &vmap) { host_map_file = src.stem().string() + "_hosts.json"; } - string nc = vmap["p2p-plugin"].as(); - if ( !nc.empty() ) { - if (boost::iequals(nc,"net")) - p2p = p2p_plugin::NET; - else if (boost::iequals(nc,"bnet")) - p2p = p2p_plugin::BNET; - else { - p2p = p2p_plugin::NET; - } - } - else { - p2p = p2p_plugin::NET; - } - if( !host_map_file.empty() ) { try { fc::json::from_file(host_map_file).as>(bindings); @@ -1070,14 +1048,9 @@ launcher_def::write_config_file (tn_node_def &node) { cfg << "blocks-dir = " << block_dir << "\n"; cfg << "http-server-address = " << host->host_name << ":" << instance.http_port << "\n"; cfg << "http-validate-host = false\n"; - if (p2p == p2p_plugin::NET) { - cfg << "p2p-listen-endpoint = " << host->listen_addr << ":" << instance.p2p_port << "\n"; - cfg << "p2p-server-address = " << host->public_name << ":" << instance.p2p_port << "\n"; - } else { - cfg << "bnet-endpoint = " << host->listen_addr << ":" << instance.p2p_port << "\n"; - // Include the net_plugin endpoint, because the plugin is always loaded (even if not used). - cfg << "p2p-listen-endpoint = " << host->listen_addr << ":" << instance.p2p_port + 1000 << "\n"; - } + cfg << "p2p-listen-endpoint = " << host->listen_addr << ":" << instance.p2p_port << "\n"; + cfg << "p2p-server-address = " << host->public_name << ":" << instance.p2p_port << "\n"; + if (is_bios) { cfg << "enable-stale-production = true\n"; @@ -1103,18 +1076,10 @@ launcher_def::write_config_file (tn_node_def &node) { if(!is_bios) { auto &bios_node = network.nodes["bios"]; - if (p2p == p2p_plugin::NET) { - cfg << "p2p-peer-address = " << bios_node.instance->p2p_endpoint<< "\n"; - } else { - cfg << "bnet-connect = " << bios_node.instance->p2p_endpoint<< "\n"; - } + cfg << "p2p-peer-address = " << bios_node.instance->p2p_endpoint<< "\n"; } for (const auto &p : node.peers) { - if (p2p == p2p_plugin::NET) { - cfg << "p2p-peer-address = " << network.nodes.find(p)->second.instance->p2p_endpoint << "\n"; - } else { - cfg << "bnet-connect = " << network.nodes.find(p)->second.instance->p2p_endpoint << "\n"; - } + cfg << "p2p-peer-address = " << network.nodes.find(p)->second.instance->p2p_endpoint << "\n"; } if (instance.has_db || node.producers.size()) { for (const auto &kp : node.keys ) { @@ -1129,11 +1094,7 @@ launcher_def::write_config_file (tn_node_def &node) { if( instance.has_db ) { cfg << "plugin = eosio::mongo_db_plugin\n"; } - if ( p2p == p2p_plugin::NET ) { - cfg << "plugin = eosio::net_plugin\n"; - } else { - cfg << "plugin = eosio::bnet_plugin\n"; - } + cfg << "plugin = eosio::net_plugin\n"; cfg << "plugin = eosio::chain_api_plugin\n" << "plugin = eosio::history_api_plugin\n"; cfg.close(); diff --git a/programs/keosd/main.cpp b/programs/keosd/main.cpp index efbf2d567f2..196b722e5a5 100644 --- a/programs/keosd/main.cpp +++ b/programs/keosd/main.cpp @@ -41,7 +41,6 @@ int main(int argc, char** argv) app().set_default_data_dir(home / "eosio-wallet"); app().set_default_config_dir(home / "eosio-wallet"); http_plugin::set_defaults({ - .address_config_prefix = "", .default_unix_socket_path = keosd::config::key_store_executable_name + ".sock", .default_http_port = 0 }); @@ -49,7 +48,7 @@ int main(int argc, char** argv) if(!app().initialize(argc, argv)) return -1; auto& http = app().get_plugin(); - http.add_handler("/v1/keosd/stop", [](string, string, url_response_callback cb) { cb(200, "{}"); std::raise(SIGTERM); } ); + http.add_handler("/v1/keosd/stop", [](string, string, url_response_callback cb) { cb(200, fc::variant(fc::variant_object())); std::raise(SIGTERM); } ); app().startup(); app().exec(); } catch (const fc::exception& e) { diff --git a/programs/nodeos/CMakeLists.txt b/programs/nodeos/CMakeLists.txt index 4714803f680..744d0ab36c5 100644 --- a/programs/nodeos/CMakeLists.txt +++ b/programs/nodeos/CMakeLists.txt @@ -52,7 +52,6 @@ target_link_libraries( ${NODE_EXECUTABLE_NAME} PRIVATE -Wl,${whole_archive_flag} login_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} history_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} state_history_plugin -Wl,${no_whole_archive_flag} - PRIVATE -Wl,${whole_archive_flag} bnet_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} history_api_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} chain_api_plugin -Wl,${no_whole_archive_flag} PRIVATE -Wl,${whole_archive_flag} net_plugin -Wl,${no_whole_archive_flag} diff --git a/programs/nodeos/main.cpp b/programs/nodeos/main.cpp index a21babac350..5e6f9b63368 100644 --- a/programs/nodeos/main.cpp +++ b/programs/nodeos/main.cpp @@ -98,7 +98,6 @@ int main(int argc, char** argv) app().set_default_data_dir(root / "eosio/nodeos/data" ); app().set_default_config_dir(root / "eosio/nodeos/config" ); http_plugin::set_defaults({ - .address_config_prefix = "", .default_unix_socket_path = "", .default_http_port = 8888 }); diff --git a/scripts/boost.rb b/scripts/boost.rb index a322acbdd11..8911f8a50f4 100644 --- a/scripts/boost.rb +++ b/scripts/boost.rb @@ -1,37 +1,19 @@ class Boost < Formula desc "Collection of portable C++ source libraries" homepage "https://www.boost.org/" - revision 1 + url "https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2" + sha256 "d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee" 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 + rebuild 1 + sha256 "41a5d38f5a7c626a064f5c5a9f8d620b76e9b5f2cf7eda85a52998a86b33bc85" => :catalina + sha256 "9e026db92f0a38c7c222227c39d54c350490046e7e86920668f300ba4a773a32" => :mojave + sha256 "8bd88f7245f35545ea5b3091408660148e6e819effe29191161da4968f15800d" => :high_sierra 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 + depends_on "icu4c" def install # Force boost to compile with the desired compiler @@ -40,14 +22,12 @@ def install 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 + icu4c_prefix = Formula["icu4c"].opt_prefix + bootstrap_args = %W[ + --prefix=#{prefix} + --libdir=#{lib} + --with-icu=#{icu4c_prefix} + ] # Handle libraries that will not be built. without_libraries = ["python", "mpi"] @@ -59,30 +39,23 @@ def install 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" + args = %W[ + --prefix=#{prefix} + --libdir=#{lib} + -d2 + -j#{ENV.make_jobs} + --layout=tagged-1.66 + --user-config=user-config.jam + -sNO_LZMA=1 + -sNO_ZSTD=1 + install + threading=multi,single + link=shared,static + ] + + # Boost is using "clang++ -x c" to select C compiler which breaks C++14 + # handling using ENV.cxx14. Using "cxxflags" and "linkflags" still works. + args << "cxxflags=-std=c++14" if ENV.compiler == :clang args << "cxxflags=-stdlib=libc++" << "linkflags=-stdlib=libc++" end @@ -113,7 +86,6 @@ def caveats #include using namespace boost::algorithm; using namespace std; - int main() { string str("a,b"); @@ -125,7 +97,7 @@ def caveats return 0; } EOS - system ENV.cxx, "test.cpp", "-std=c++1y", "-L#{lib}", "-lboost_system", "-o", "test" + system ENV.cxx, "test.cpp", "-std=c++14", "-stdlib=libc++", "-o", "test" system "./test" end -end +end \ No newline at end of file diff --git a/scripts/eosio_build_amazon.sh b/scripts/eosio_build_amazon.sh index ea690973846..a6dac190959 100644 --- a/scripts/eosio_build_amazon.sh +++ b/scripts/eosio_build_amazon.sh @@ -218,10 +218,10 @@ printf "\\tCMAKE found @ %s.\\n" "${CMAKE}" fi - if [ -d "${HOME}/opt/boost_1_67_0" ]; then - if ! mv "${HOME}/opt/boost_1_67_0" "$BOOST_ROOT" + if [ -d "${HOME}/opt/boost_1_71_0" ]; then + if ! mv "${HOME}/opt/boost_1_71_0" "$BOOST_ROOT" then - printf "\\n\\tUnable to move directory %s/opt/boost_1_67_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" + printf "\\n\\tUnable to move directory %s/opt/boost_1_71_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" printf "\\n\\tExiting now.\\n" exit 1 fi @@ -238,7 +238,7 @@ printf "\\n\\tChecking boost library installation.\\n" BVERSION=$( grep "BOOST_LIB_VERSION" "${BOOST_ROOT}/include/boost/version.hpp" 2>/dev/null \ | tail -1 | tr -s ' ' | cut -d\ -f3 | sed 's/[^0-9\._]//gI' ) - if [ "${BVERSION}" != "1_67" ]; then + if [ "${BVERSION}" != "1_71" ]; then printf "\\tRemoving existing boost libraries in %s/opt/boost*.\\n" "${HOME}" if ! rm -rf "${HOME}"/opt/boost* then @@ -254,27 +254,27 @@ exit 1 fi STATUS=$(curl -LO -w '%{http_code}' --connect-timeout 30 \ - "https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2" ) + "https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2" ) if [ "${STATUS}" -ne 200 ]; then printf "\\tUnable to download Boost libraries at this time.\\n" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! tar xf "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! tar xf "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\tUnable to decompress Boost libraries @ %s/boost_1_67_0.tar.bz2 at this time.\\n" "${TEMP_DIR}" + printf "\\tUnable to decompress Boost libraries @ %s/boost_1_71_0.tar.bz2 at this time.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! rm -f "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! rm -f "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\tUnable to remove Boost libraries @ %s/boost_1_67_0.tar.bz2 at this time.\\n" "${TEMP_DIR}" + printf "\\tUnable to remove Boost libraries @ %s/boost_1_71_0.tar.bz2 at this time.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! cd "${TEMP_DIR}/boost_1_67_0/" + if ! cd "${TEMP_DIR}/boost_1_71_0/" then - printf "\\tUnable to change directory into %s/boost_1_67_0/ at this time.\\n" "${TEMP_DIR}" + printf "\\tUnable to change directory into %s/boost_1_71_0/ at this time.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi @@ -284,15 +284,15 @@ printf "\\n\\tExiting now.\\n" exit 1 fi - if ! "${TEMP_DIR}"/boost_1_67_0/b2 -j"${CPU_CORE}" install + if ! "${TEMP_DIR}"/boost_1_71_0/b2 -j"${CPU_CORE}" install then printf "\\n\\tInstallation of boost libraries failed. 1\\n" printf "\\n\\tExiting now.\\n" exit 1 fi - if ! rm -rf "${TEMP_DIR}/boost_1_67_0/" + if ! rm -rf "${TEMP_DIR}/boost_1_71_0/" then - printf "\\n\\tUnable to remove boost libraries directory @ %s/boost_1_67_0/.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to remove boost libraries directory @ %s/boost_1_71_0/.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n" exit 1 fi diff --git a/scripts/eosio_build_centos.sh b/scripts/eosio_build_centos.sh index 49debdf68e8..f392fe5ef53 100644 --- a/scripts/eosio_build_centos.sh +++ b/scripts/eosio_build_centos.sh @@ -314,7 +314,7 @@ printf "\\t - CMAKE found @ %s.\\n" "${CMAKE}" fi - BOOSTTGZ="boost_1_67_0.tar.bz2" + BOOSTTGZ="boost_1_71_0.tar.bz2" BOOSTFOLDER=$(echo "${BOOSTTGZ}" | sed 's/.tar.bz2//g') if [ -d "${HOME}/opt/${BOOSTFOLDER}" ]; then if ! mv "${HOME}/opt/${BOOSTFOLDER}" "${BOOST_ROOT}"; then @@ -334,7 +334,7 @@ printf "\\tChecking boost library installation...\\n" BOOSTVERSION=$( grep "#define BOOST_VERSION" "${BOOST_ROOT}/include/boost/version.hpp" 2>/dev/null \ | tail -1 | tr -s ' ' | cut -d\ -f3) - if [ "${BOOSTVERSION}" != "106700" ]; then + if [ "${BOOSTVERSION}" != "107100" ]; then printf "\\tRemoving existing boost libraries in %s/opt/boost*...\\n" "${HOME}" if ! rm -rf "${HOME}"/opt/boost*; then printf "\\t!! Unable to remove deprecated boost libraries at %s/opt/boost* !!\\n" "${HOME}" @@ -347,7 +347,7 @@ printf "\\tExiting now.\\n" exit 1; fi - BOOSTURL="https://dl.bintray.com/boostorg/release/1.67.0/source/${BOOSTTGZ}" + BOOSTURL="https://dl.bintray.com/boostorg/release/1.71.0/source/${BOOSTTGZ}" STATUS=$(curl -LO -w '%{http_code}' --connect-timeout 30 "${BOOSTURL}") if [ "${STATUS}" -ne 200 ]; then printf "\\t!! Unable to download Boost libraries from ${BOOSTURL} !!\\n" @@ -380,7 +380,7 @@ exit 1; fi if ! rm -rf "${TEMP_DIR}/${BOOSTFOLDER}/"; then - printf "\\t!! Unable to remove directory %s/boost_1_67_0 !!\\n" "${TEMP_DIR}" + printf "\\t!! Unable to remove directory %s/boost_1_71_0 !!\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n" exit 1; fi diff --git a/scripts/eosio_build_darwin.sh b/scripts/eosio_build_darwin.sh index bc4a20ebd58..6eb48083a54 100644 --- a/scripts/eosio_build_darwin.sh +++ b/scripts/eosio_build_darwin.sh @@ -180,11 +180,11 @@ printf "\\n\\tChecking boost library installation.\\n" BVERSION=$( grep "#define BOOST_VERSION" "/usr/local/include/boost/version.hpp" 2>/dev/null | tail -1 | tr -s ' ' | cut -d\ -f3 ) - if [ "${BVERSION}" != "106700" ]; then + if [ "${BVERSION}" != "107100" ]; then if [ ! -z "${BVERSION}" ]; then printf "\\tFound Boost Version %s.\\n" "${BVERSION}" - printf "\\tEOS.IO requires Boost version 1.67.\\n" - printf "\\tWould you like to uninstall version %s and install Boost version 1.67.\\n" "${BVERSION}" + printf "\\tEOS.IO requires Boost version 1.71.\\n" + printf "\\tWould you like to uninstall version %s and install Boost version 1.71.\\n" "${BVERSION}" if is_noninteractive; then exec <<< "1"; fi select yn in "Yes" "No"; do case $yn in @@ -222,7 +222,7 @@ printf "\\tInstalling boost libraries.\\n" if ! "${BREW}" install "${SOURCE_DIR}/scripts/boost.rb" then - printf "\\tUnable to install boost 1.67 libraries at this time. 0\\n" + printf "\\tUnable to install boost 1.71 libraries at this time. 0\\n" printf "\\tExiting now.\\n\\n" exit 1; fi @@ -234,9 +234,9 @@ exit 1; fi fi - printf "\\tBoost 1.67.0 successfully installed @ /usr/local.\\n" + printf "\\tBoost 1.71.0 successfully installed @ /usr/local.\\n" else - printf "\\tBoost 1.67.0 found at /usr/local.\\n" + printf "\\tBoost 1.71.0 found at /usr/local.\\n" fi printf "\\n\\tChecking MongoDB C++ driver installation.\\n" diff --git a/scripts/eosio_build_dep b/scripts/eosio_build_dep index 7123baf02f5..eed29b19ab3 100644 --- a/scripts/eosio_build_dep +++ b/scripts/eosio_build_dep @@ -3,7 +3,7 @@ Libtool,-x,/usr/local/bin/glibtool,libtool,http://gnu.askapache.com/libtool/libt OpenSSL,-f,/usr/local/opt/openssl/lib/libssl.a,openssl,https://www.openssl.org/source/openssl-1.0.2n.tar.gz llvm,-x,/usr/local/opt/llvm@4/bin/clang-4.0,llvm@4,http://releases.llvm.org/5.0.1/llvm-5.0.1.src.tar.xz wget,-x,/usr/local/bin/wget,wget,https://ftp.gnu.org/gnu/wget/wget-1.19.2.tar.gz -CMake,-x,/usr/local/bin/cmake,cmake,https://cmake.org/files/v3.10/cmake-3.10.1-Darwin-x86_64.tar.gz +CMake,-x,/usr/local/bin/cmake,cmake,https://cmake.org/files/v3.15/cmake-3.15.4-Darwin-x86_64.tar.gz GMP,-f,/usr/local/opt/gmp/include/gmpxx.h,gmp,https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2 gettext,-x,/usr/local/opt/gettext/bin/gettext,gettext,https://ftp.gnu.org/pub/gnu/gettext/gettext-latest.tar.gz MongoDB,-x,/usr/local/opt/mongodb/bin/mongod,mongodb,https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.6.3.tgz diff --git a/scripts/eosio_build_fedora.sh b/scripts/eosio_build_fedora.sh index b608cf00978..ca201600116 100644 --- a/scripts/eosio_build_fedora.sh +++ b/scripts/eosio_build_fedora.sh @@ -156,10 +156,10 @@ fi fi - if [ -d "${HOME}/opt/boost_1_67_0" ]; then - if ! mv "${HOME}/opt/boost_1_67_0" "$BOOST_ROOT" + if [ -d "${HOME}/opt/boost_1_71_0" ]; then + if ! mv "${HOME}/opt/boost_1_71_0" "$BOOST_ROOT" then - printf "\\n\\tUnable to move directory %s/opt/boost_1_67_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" + printf "\\n\\tUnable to move directory %s/opt/boost_1_71_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" printf "\\n\\tExiting now.\\n" exit 1 fi @@ -176,7 +176,7 @@ printf "\\n\\tChecking boost library installation.\\n" BVERSION=$( grep "BOOST_LIB_VERSION" "${BOOST_ROOT}/include/boost/version.hpp" 2>/dev/null \ | tail -1 | tr -s ' ' | cut -d\ -f3 | sed 's/[^0-9\._]//gI' ) - if [ "${BVERSION}" != "1_67" ]; then + if [ "${BVERSION}" != "1_71" ]; then printf "\\tRemoving existing boost libraries in %s/opt/boost* .\\n" "${HOME}" if ! rm -rf "${HOME}"/opt/boost* then @@ -191,45 +191,45 @@ printf "\\tExiting now.\\n\\n" exit 1; fi - STATUS=$( curl -LO -w '%{http_code}' --connect-timeout 30 https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2 ) + STATUS=$( curl -LO -w '%{http_code}' --connect-timeout 30 https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2 ) if [ "${STATUS}" -ne 200 ]; then printf "\\tUnable to download Boost libraries at this time.\\n" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! tar xf "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! tar xf "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\n\\tUnable to unarchive file %s/boost_1_67_0.tar.bz2.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to unarchive file %s/boost_1_71_0.tar.bz2.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! rm -f "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! rm -f "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\n\\tUnable to remove file %s/boost_1_67_0.tar.bz2.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to remove file %s/boost_1_71_0.tar.bz2.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! cd "${TEMP_DIR}/boost_1_67_0/" + if ! cd "${TEMP_DIR}/boost_1_71_0/" then - printf "\\n\\tUnable to enter directory %s/boost_1_67_0.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to enter directory %s/boost_1_71_0.\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! "${TEMP_DIR}"/boost_1_67_0/bootstrap.sh "--prefix=${BOOST_ROOT}" + if ! "${TEMP_DIR}"/boost_1_71_0/bootstrap.sh "--prefix=${BOOST_ROOT}" then printf "\\n\\tInstallation of boost libraries failed. 0\\n" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! "${TEMP_DIR}"/boost_1_67_0/b2 -j"${CPU_CORE}" install + if ! "${TEMP_DIR}"/boost_1_71_0/b2 -j"${CPU_CORE}" install then printf "\\n\\tInstallation of boost libraries failed. 1\\n" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! rm -rf "${TEMP_DIR}/boost_1_67_0" + if ! rm -rf "${TEMP_DIR}/boost_1_71_0" then - printf "\\n\\tUnable to remove directory %s/boost_1_67_0. 1\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to remove directory %s/boost_1_71_0. 1\\n" "${TEMP_DIR}" printf "\\tExiting now.\\n\\n" exit 1; fi @@ -241,9 +241,9 @@ exit 1; fi fi - printf "\\n\\tBoost 1.67.0 successfully installed at %s/opt/boost_1_67_0.\\n\\n" "${HOME}" + printf "\\n\\tBoost 1.71.0 successfully installed at %s/opt/boost_1_71_0.\\n\\n" "${HOME}" else - printf "\\tBoost 1.67.0 found at %s/opt/boost_1_67_0.\\n" "${HOME}" + printf "\\tBoost 1.71.0 found at %s/opt/boost_1_71_0.\\n" "${HOME}" fi printf "\\n\\tChecking MongoDB C++ driver installation.\\n" diff --git a/scripts/eosio_build_ubuntu.sh b/scripts/eosio_build_ubuntu.sh index 373093e237d..95217846946 100644 --- a/scripts/eosio_build_ubuntu.sh +++ b/scripts/eosio_build_ubuntu.sh @@ -60,7 +60,7 @@ exit 1 fi - DEP_ARRAY=(clang-4.0 lldb-4.0 libclang-4.0-dev cmake make automake libbz2-dev libssl-dev \ + DEP_ARRAY=(clang lldb-4.0 libclang-4.0-dev cmake make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev python3-dev \ autoconf libtool curl zlib1g-dev doxygen graphviz) COUNT=1 @@ -114,10 +114,10 @@ printf "\\n\\tNo required dpkg dependencies to install.\\n" fi - if [ -d "${HOME}/opt/boost_1_67_0" ]; then - if ! mv "${HOME}/opt/boost_1_67_0" "$BOOST_ROOT" + if [ -d "${HOME}/opt/boost_1_71_0" ]; then + if ! mv "${HOME}/opt/boost_1_71_0" "$BOOST_ROOT" then - printf "\\n\\tUnable to move directory %s/opt/boost_1_67_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" + printf "\\n\\tUnable to move directory %s/opt/boost_1_71_0 to %s.\\n" "${HOME}" "${BOOST_ROOT}" printf "\\n\\tExiting now.\\n" exit 1 fi @@ -134,7 +134,7 @@ printf "\\n\\tChecking boost library installation.\\n" BVERSION=$( grep BOOST_LIB_VERSION "${BOOST_ROOT}/include/boost/version.hpp" 2>/dev/null \ | tail -1 | tr -s ' ' | cut -d\ -f3 | sed 's/[^0-9\._]//gI') - if [ "${BVERSION}" != "1_67" ]; then + if [ "${BVERSION}" != "1_71" ]; then printf "\\tRemoving existing boost libraries in %s/opt/boost* .\\n" "${HOME}" if ! rm -rf "${HOME}"/opt/boost* then @@ -149,27 +149,27 @@ printf "\\n\\tExiting now.\\n\\n" exit 1; fi - STATUS=$(curl -LO -w '%{http_code}' --connect-timeout 30 https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2) + STATUS=$(curl -LO -w '%{http_code}' --connect-timeout 30 https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2) if [ "${STATUS}" -ne 200 ]; then printf "\\tUnable to download Boost libraries at this time.\\n" printf "\\tExiting now.\\n\\n" exit 1; fi - if ! tar xf "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! tar xf "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\n\\tUnable to unarchive file %s/boost_1_67_0.tar.bz2.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to unarchive file %s/boost_1_71_0.tar.bz2.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n\\n" exit 1; fi - if ! rm -f "${TEMP_DIR}/boost_1_67_0.tar.bz2" + if ! rm -f "${TEMP_DIR}/boost_1_71_0.tar.bz2" then - printf "\\n\\tUnable to remove file %s/boost_1_67_0.tar.bz2.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to remove file %s/boost_1_71_0.tar.bz2.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n\\n" exit 1; fi - if ! cd "${TEMP_DIR}/boost_1_67_0/" + if ! cd "${TEMP_DIR}/boost_1_71_0/" then - printf "\\n\\tUnable to enter directory %s/boost_1_67_0.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to enter directory %s/boost_1_71_0.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n\\n" exit 1; fi @@ -185,9 +185,9 @@ printf "\\n\\tExiting now.\\n\\n" exit 1 fi - if ! rm -rf "${TEMP_DIR}"/boost_1_67_0 + if ! rm -rf "${TEMP_DIR}"/boost_1_71_0 then - printf "\\n\\tUnable to remove %s/boost_1_67_0.\\n" "${TEMP_DIR}" + printf "\\n\\tUnable to remove %s/boost_1_71_0.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n\\n" exit 1 fi