From 8c41338d113e4cf981b4dc568f0aa070dd3bdb0b Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Thu, 7 Nov 2019 18:50:47 +0100 Subject: [PATCH 1/4] Get rid of fc/io/fstream.hpp --- libraries/app/application.cpp | 8 +-- libraries/chain/CMakeLists.txt | 2 +- libraries/chain/db_management.cpp | 12 ++--- libraries/plugins/snapshot/snapshot.cpp | 8 +-- libraries/plugins/witness/witness.cpp | 8 +-- libraries/utilities/CMakeLists.txt | 1 + libraries/utilities/file_util.cpp | 49 +++++++++++++++++++ .../include/graphene/utilities/file_util.hpp | 34 +++++++++++++ libraries/wallet/wallet_api_impl.cpp | 14 ++++-- programs/genesis_util/genesis_update.cpp | 11 ++--- tests/common/genesis_file_util.hpp | 4 +- tests/generate_empty_blocks/main.cpp | 11 ++--- 12 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 libraries/utilities/file_util.cpp create mode 100644 libraries/utilities/include/graphene/utilities/file_util.hpp diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index de5bf8a334..953755f64b 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -36,11 +36,11 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -392,8 +392,8 @@ void application_impl::startup() ilog("Initializing database..."); if( _options->count("genesis-json") ) { - std::string genesis_str; - fc::read_file_contents( _options->at("genesis-json").as(), genesis_str ); + const std::string genesis_file = _options->at("genesis-json").as(); + std::string genesis_str = graphene::utilities::read_file_contents( genesis_file ); graphene::chain::genesis_state_type genesis = fc::json::from_string( genesis_str ).as( 20 ); bool modified_genesis = false; if( _options->count("genesis-timestamp") ) @@ -1039,7 +1039,7 @@ void application::set_program_options(boost::program_options::options_descriptio "Endpoint for TLS websocket RPC to listen on") ("server-pem,p", bpo::value()->implicit_value("server.pem"), "The TLS certificate file for this server") ("server-pem-password,P", bpo::value()->implicit_value(""), "Password for this certificate") - ("genesis-json", bpo::value(), "File to read Genesis State from") + ("genesis-json", bpo::value(), "File to read Genesis State from") ("dbg-init-key", bpo::value(), "Block signing key to use for init witnesses, overrides genesis file") ("api-access", bpo::value(), "JSON file specifying API permissions") ("io-threads", bpo::value()->implicit_value(0), "Number of IO threads, default to 0 for auto-configuration") diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index df07034a28..d15c98c56e 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -70,7 +70,7 @@ add_library( graphene_chain ) add_dependencies( graphene_chain build_hardfork_hpp ) -target_link_libraries( graphene_chain fc graphene_db graphene_protocol ) +target_link_libraries( graphene_chain fc graphene_db graphene_protocol graphene_utilities ) target_include_directories( graphene_chain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" ) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index 9ca657ef6f..faa2446195 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -30,8 +30,7 @@ #include #include - -#include +#include #include #include @@ -182,15 +181,16 @@ void database::open( wipe_object_db = true; else { - std::string version_string; - fc::read_file_contents( data_dir / "db_version", version_string ); + std::string version_string = graphene::utilities::read_file_contents( (data_dir / "db_version").string() ); wipe_object_db = ( version_string != db_version ); } if( wipe_object_db ) { ilog("Wiping object_database due to missing or wrong version"); object_database::wipe( data_dir ); - std::ofstream version_file( (data_dir / "db_version").generic_string().c_str(), - std::ios::out | std::ios::binary | std::ios::trunc ); + std::ofstream version_file( (data_dir / "db_version").generic_string(), + std::ios::binary | std::ios::trunc ); + FC_ASSERT( !version_file.fail() && !version_file.bad(), "Failed to open file '${f}'", + ("f",(data_dir / "db_version").string()) ); version_file.write( db_version.c_str(), db_version.size() ); version_file.close(); } diff --git a/libraries/plugins/snapshot/snapshot.cpp b/libraries/plugins/snapshot/snapshot.cpp index f74ad5894a..b82e196cfe 100644 --- a/libraries/plugins/snapshot/snapshot.cpp +++ b/libraries/plugins/snapshot/snapshot.cpp @@ -25,7 +25,8 @@ #include -#include +#include +#include using namespace graphene::snapshot_plugin; using std::string; @@ -87,10 +88,11 @@ void snapshot_plugin::plugin_shutdown() {} static void create_snapshot( const graphene::chain::database& db, const fc::path& dest ) { ilog("snapshot plugin: creating snapshot"); - fc::ofstream out; + std::ofstream out; try { - out.open( dest ); + out.open( dest.string(), std::ios_base::binary | std::ios_base::trunc ); + FC_ASSERT( !out.fail() && !out.bad(), "Failed to open file '${f}'", ("f",dest.string()) ); } catch ( fc::exception& e ) { diff --git a/libraries/plugins/witness/witness.cpp b/libraries/plugins/witness/witness.cpp index d2609625ab..dd91796118 100644 --- a/libraries/plugins/witness/witness.cpp +++ b/libraries/plugins/witness/witness.cpp @@ -29,10 +29,10 @@ #include #include -#include #include +#include #include using namespace graphene::witness_plugin; @@ -138,9 +138,9 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m { if (fc::exists(key_id_to_wif_pair_file)) { - std::string file_content; - fc::read_file_contents(key_id_to_wif_pair_file, file_content); - std::istringstream file_content_as_stream(file_content); + std::ifstream file_content_as_stream( key_id_to_wif_pair_file.string() ); + FC_ASSERT( !file_content_as_stream.fail() && !file_content_as_stream.bad(), + "Failed to open file '${f}'", ("f",key_id_to_wif_pair_file.string()) ); std::string line; // key_id_to_wif_pair_string while (std::getline(file_content_as_stream, line)) diff --git a/libraries/utilities/CMakeLists.txt b/libraries/utilities/CMakeLists.txt index 66ed0358f5..5df6b9a33b 100644 --- a/libraries/utilities/CMakeLists.txt +++ b/libraries/utilities/CMakeLists.txt @@ -10,6 +10,7 @@ endif(NOT GRAPHENE_GIT_REVISION_DESCRIPTION) file(GLOB HEADERS "include/graphene/utilities/*.hpp") set(sources + file_util.cpp key_conversion.cpp string_escape.cpp tempdir.cpp diff --git a/libraries/utilities/file_util.cpp b/libraries/utilities/file_util.cpp new file mode 100644 index 0000000000..46f78f27f7 --- /dev/null +++ b/libraries/utilities/file_util.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include + +#include +#include + +namespace graphene { namespace utilities { + + std::string read_file_contents( const std::string& path ) + { + std::ifstream input( path ); + FC_ASSERT( !input.fail() && !input.bad(), "Failed to open file '${f}'", ("f",path) ); + input.seekg( 0, std::ios_base::end ); + const auto size = input.tellg(); + input.seekg( 0 ); + std::vector result; + result.resize( size ); + input.read( result.data(), size ); + FC_ASSERT( size == input.gcount(), "Incomplete file read from '${f}', expected ${s} but got ${c}?!", + ("f",path)("s",size)("c",input.gcount()) ); + return std::string( result.begin(), result.end() ); + } + +} } // graphene::utilities diff --git a/libraries/utilities/include/graphene/utilities/file_util.hpp b/libraries/utilities/include/graphene/utilities/file_util.hpp new file mode 100644 index 0000000000..f6ef25d0fd --- /dev/null +++ b/libraries/utilities/include/graphene/utilities/file_util.hpp @@ -0,0 +1,34 @@ +#pragma once + +/* + * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +namespace graphene { namespace utilities { + + std::string read_file_contents( const std::string& path ); + +} } // graphene::utilities diff --git a/libraries/wallet/wallet_api_impl.cpp b/libraries/wallet/wallet_api_impl.cpp index 5d23c20be4..7ca4d6d0a4 100644 --- a/libraries/wallet/wallet_api_impl.cpp +++ b/libraries/wallet/wallet_api_impl.cpp @@ -28,10 +28,11 @@ #include #include #include -#include #include #include "wallet_api_impl.hpp" + +#include #include #ifndef WIN32 @@ -39,6 +40,9 @@ # include #endif +#include +#include + // explicit instantiation for later use namespace fc { template class api; @@ -440,16 +444,16 @@ namespace graphene { namespace wallet { namespace detail { // http://en.wikipedia.org/wiki/Most_vexing_parse // std::string tmp_wallet_filename = wallet_filename + ".tmp"; - fc::ofstream outfile{ fc::path( tmp_wallet_filename ) }; + std::ofstream outfile( tmp_wallet_filename, std::ios_base::trunc ); + FC_ASSERT( !outfile.fail() && !outfile.bad(), "Failed to open file '${f}'", + ("f",tmp_wallet_filename) ); outfile.write( data.c_str(), data.length() ); outfile.flush(); outfile.close(); wlog( "saved successfully wallet to tmp file ${fn}", ("fn", tmp_wallet_filename) ); - std::string wallet_file_content; - fc::read_file_contents(tmp_wallet_filename, wallet_file_content); - + std::string wallet_file_content = graphene::utilities::read_file_contents( tmp_wallet_filename ); if (wallet_file_content == data) { wlog( "validated successfully tmp wallet file ${fn}", ("fn", tmp_wallet_filename) ); diff --git a/programs/genesis_util/genesis_update.cpp b/programs/genesis_util/genesis_update.cpp index 3100e2dd46..f41797dc05 100644 --- a/programs/genesis_util/genesis_update.cpp +++ b/programs/genesis_util/genesis_update.cpp @@ -27,13 +27,13 @@ #include #include -#include #include #include #include #include #include +#include #include #include @@ -61,7 +61,7 @@ int main( int argc, char** argv ) bpo::options_description cli_options("BitShares empty blocks"); cli_options.add_options() ("help,h", "Print this help message and exit.") - ("genesis-json,g", bpo::value(), "File to read genesis state from") + ("genesis-json,g", bpo::value(), "File to read genesis state from") ("out,o", bpo::value(), "File to output new genesis to") ("dev-account-prefix", bpo::value()->default_value("devacct"), "Prefix for dev accounts") ("dev-key-prefix", bpo::value()->default_value("devkey-"), "Prefix for dev key") @@ -102,10 +102,9 @@ int main( int argc, char** argv ) genesis_state_type genesis; if( options.count("genesis-json") ) { - fc::path genesis_json_filename = options["genesis-json"].as(); - std::cerr << "update_genesis: Reading genesis from file " << genesis_json_filename.preferred_string() << "\n"; - std::string genesis_json; - read_file_contents( genesis_json_filename, genesis_json ); + std::string genesis_json_filename = options["genesis-json"].as(); + std::cerr << "update_genesis: Reading genesis from file " << genesis_json_filename << "\n"; + std::string genesis_json = graphene::utilities::read_file_contents( genesis_json_filename ); genesis = fc::json::from_string( genesis_json ).as< genesis_state_type >(20); } else diff --git a/tests/common/genesis_file_util.hpp b/tests/common/genesis_file_util.hpp index a87d9585af..1194f6e7b5 100644 --- a/tests/common/genesis_file_util.hpp +++ b/tests/common/genesis_file_util.hpp @@ -13,7 +13,7 @@ namespace graphene { namespace app { namespace detail { /// @param directory the directory to place the file "genesis.json" /// @returns the full path to the file //////// -boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { +std::string create_genesis_file(fc::temp_directory& directory) { boost::filesystem::path genesis_path = boost::filesystem::path{directory.path().generic_string()} / "genesis.json"; fc::path genesis_out = genesis_path; graphene::chain::genesis_state_type genesis_state = graphene::app::detail::create_example_genesis(); @@ -42,5 +42,5 @@ boost::filesystem::path create_genesis_file(fc::temp_directory& directory) { */ fc::json::save_to_file(genesis_state, genesis_out); - return genesis_path; + return genesis_path.string(); } diff --git a/tests/generate_empty_blocks/main.cpp b/tests/generate_empty_blocks/main.cpp index bcb831725c..3dad354043 100644 --- a/tests/generate_empty_blocks/main.cpp +++ b/tests/generate_empty_blocks/main.cpp @@ -27,12 +27,12 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -61,7 +61,7 @@ int main( int argc, char** argv ) cli_options.add_options() ("help,h", "Print this help message and exit.") ("data-dir", bpo::value()->default_value("empty_blocks_data_dir"), "Directory containing generator database") - ("genesis-json,g", bpo::value(), "File to read genesis state from") + ("genesis-json,g", bpo::value(), "File to read genesis state from") ("genesis-time,t", bpo::value()->default_value(0), "Timestamp for genesis state (0=use value from file/example)") ("num-blocks,n", bpo::value()->default_value(1000000), "Number of blocks to generate") ("miss-rate,r", bpo::value()->default_value(3), "Percentage of blocks to miss") @@ -96,10 +96,9 @@ int main( int argc, char** argv ) genesis_state_type genesis; if( options.count("genesis-json") ) { - fc::path genesis_json_filename = options["genesis-json"].as(); - std::cerr << "embed_genesis: Reading genesis from file " << genesis_json_filename.preferred_string() << "\n"; - std::string genesis_json; - read_file_contents( genesis_json_filename, genesis_json ); + std::string genesis_json_filename = options["genesis-json"].as(); + std::cerr << "generate_empty_blocks: Reading genesis from file " << genesis_json_filename << "\n"; + std::string genesis_json = graphene::utilities::read_file_contents( genesis_json_filename ); genesis = fc::json::from_string( genesis_json ).as< genesis_state_type >(20); } else From 406c4f50e7c93b3bd0f3a68475fc8fbe4690f8f3 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Fri, 8 Nov 2019 08:43:54 +0100 Subject: [PATCH 2/4] Missed one --- libraries/wallet/wallet.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 927e4a803d..1f2a2c0d52 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -49,7 +49,6 @@ #include #include -#include #include #include #include From a7152eac4ee3e00a4842c8efd50368cf0d611389 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Sat, 9 Nov 2019 10:46:17 +0100 Subject: [PATCH 3/4] Addressed comments --- libraries/plugins/witness/witness.cpp | 6 +++--- libraries/utilities/file_util.cpp | 2 +- .../utilities/include/graphene/utilities/file_util.hpp | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/plugins/witness/witness.cpp b/libraries/plugins/witness/witness.cpp index dd91796118..36713becbe 100644 --- a/libraries/plugins/witness/witness.cpp +++ b/libraries/plugins/witness/witness.cpp @@ -138,9 +138,9 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m { if (fc::exists(key_id_to_wif_pair_file)) { - std::ifstream file_content_as_stream( key_id_to_wif_pair_file.string() ); - FC_ASSERT( !file_content_as_stream.fail() && !file_content_as_stream.bad(), - "Failed to open file '${f}'", ("f",key_id_to_wif_pair_file.string()) ); + std::ifstream file_content_as_stream( key_id_to_wif_pair_file.string() ); + FC_ASSERT( !file_content_as_stream.fail() && !file_content_as_stream.bad(), + "Failed to open file '${f}'", ("f",key_id_to_wif_pair_file.string()) ); std::string line; // key_id_to_wif_pair_string while (std::getline(file_content_as_stream, line)) diff --git a/libraries/utilities/file_util.cpp b/libraries/utilities/file_util.cpp index 46f78f27f7..ad33401d13 100644 --- a/libraries/utilities/file_util.cpp +++ b/libraries/utilities/file_util.cpp @@ -27,7 +27,7 @@ #include #include -#include +#include namespace graphene { namespace utilities { diff --git a/libraries/utilities/include/graphene/utilities/file_util.hpp b/libraries/utilities/include/graphene/utilities/file_util.hpp index f6ef25d0fd..bd8a887489 100644 --- a/libraries/utilities/include/graphene/utilities/file_util.hpp +++ b/libraries/utilities/include/graphene/utilities/file_util.hpp @@ -1,5 +1,3 @@ -#pragma once - /* * Copyright (c) 2015 Cryptonomex, Inc., and contributors. * @@ -23,12 +21,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#pragma once -#include #include namespace graphene { namespace utilities { + /** + * @brief Reads the file at the given path and returns the full contents in a string. Note that the result + * will contain non-printable characters if the file does. + * @param path the pathname of the file to read + * @return the file contents as a string + */ std::string read_file_contents( const std::string& path ); } } // graphene::utilities From f30f0518b4204bd7a7879c56a913defe277aa9bc Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Sat, 9 Nov 2019 17:17:41 +0100 Subject: [PATCH 4/4] Clarification --- libraries/utilities/include/graphene/utilities/file_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/utilities/include/graphene/utilities/file_util.hpp b/libraries/utilities/include/graphene/utilities/file_util.hpp index bd8a887489..a60d20c40b 100644 --- a/libraries/utilities/include/graphene/utilities/file_util.hpp +++ b/libraries/utilities/include/graphene/utilities/file_util.hpp @@ -29,7 +29,7 @@ namespace graphene { namespace utilities { /** * @brief Reads the file at the given path and returns the full contents in a string. Note that the result - * will contain non-printable characters if the file does. + * will contain non-printable characters (including 0-bytes) if the file does. * @param path the pathname of the file to read * @return the file contents as a string */