diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..18d8e5589b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Set the default behavior of genesis.json, in case core.autocrlf is set incorrectly +genesis.json eol=lf diff --git a/.travis.yml b/.travis.yml index 76424128a0..77e0407a33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,17 +29,14 @@ script: - ccache -s - programs/build_helpers/buildstep Prepare 1 "sed -i '/tests/d' libraries/fc/CMakeLists.txt" - programs/build_helpers/buildstep cmake 5 "cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=--coverage -DCMAKE_CXX_FLAGS=--coverage -DBoost_USE_STATIC_LIBS=OFF -DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON ." - - programs/build_helpers/buildstep make.cli_wallet 1600 "programs/build_helpers/make_with_sonar bw-output -j 2 cli_wallet" - - programs/build_helpers/buildstep make.witness_node 300 "programs/build_helpers/make_with_sonar bw-output -j 2 witness_node" - - programs/build_helpers/buildstep make.serializer 45 "programs/build_helpers/make_with_sonar bw-output -j 2 js_operation_serializer" - - programs/build_helpers/buildstep make.get_dev_key 10 "programs/build_helpers/make_with_sonar bw-output -j 2 get_dev_key" - - programs/build_helpers/buildstep make.chain_test 900 "programs/build_helpers/make_with_sonar bw-output -j 2 chain_test" - - programs/build_helpers/buildstep make.cli_test 200 "programs/build_helpers/make_with_sonar bw-output -j 2 cli_test" - - programs/build_helpers/buildstep make.perf_test 120 "programs/build_helpers/make_with_sonar bw-output -j 2 performance_test" + - programs/build_helpers/buildstep make.cli_wallet 2200 "programs/build_helpers/make_with_sonar bw-output -j 2 cli_wallet witness_node js_operation_serializer get_dev_key network_mapper" + - programs/build_helpers/buildstep make.chain_test 1000 "make -j 2 chain_test" + - programs/build_helpers/buildstep make.cli_test 200 "make -j 2 cli_test" + - programs/build_helpers/buildstep make.perf_test 120 "make -j 2 performance_test" - set -o pipefail - programs/build_helpers/buildstep run.chain_test 240 "libraries/fc/tests/run-parallel-tests.sh tests/chain_test" - - programs/build_helpers/buildstep run.cli_test 30 "libraries/fc/tests/run-parallel-tests.sh tests/cli_test" - - programs/build_helpers/buildstep prepare.sonar 20 'find libraries/[acdenptuw]*/CMakeFiles/*.dir programs/[cdgjsw]*/CMakeFiles/*.dir -type d | while read d; do gcov -o "$d" "${d/CMakeFiles*.dir//}"/*.cpp; done >/dev/null' - - programs/build_helpers/buildstep run.sonar 400 "which sonar-scanner && sonar-scanner || true" + - programs/build_helpers/buildstep run.cli_test 60 "libraries/fc/tests/run-parallel-tests.sh tests/cli_test" + - 'programs/build_helpers/buildstep prepare.sonar 20 "find libraries/[acdenptuw]*/CMakeFiles/*.dir programs/[cdgjsw]*/CMakeFiles/*.dir -type d | while read d; do gcov -o \"\$d\" \"\${d/CMakeFiles*.dir//}\"/*.cpp; done >/dev/null; programs/build_helpers/set_sonar_branch sonar-project.properties" || true' + - 'programs/build_helpers/buildstep run.sonar 1200 "which sonar-scanner && sonar-scanner" || true' - programs/build_helpers/buildstep end 0 - ccache -s diff --git a/CMakeLists.txt b/CMakeLists.txt index 1944af4dcb..6052748601 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # Defines BitShares library target. project( BitShares ) -cmake_minimum_required( VERSION 2.8.12 ) +cmake_minimum_required( VERSION 3.1 ) set( BLOCKCHAIN_NAME "BitShares" ) @@ -9,6 +9,10 @@ set( GUI_CLIENT_EXECUTABLE_NAME BitShares ) set( CUSTOM_URL_SCHEME "gcs" ) set( INSTALLER_APP_ID "68ad7005-8eee-49c9-95ce-9eed97e5b347" ) +set( CMAKE_CXX_STANDARD 14 ) +set( CMAKE_CXX_STANDARD_REQUIRED ON ) +set( CMAKE_CXX_EXTENSIONS OFF ) + # http://stackoverflow.com/a/18369825 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) @@ -23,7 +27,7 @@ endif() list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" ) set(CMAKE_EXPORT_COMPILE_COMMANDS "ON") -set(GRAPHENE_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/genesis.json" ) +set(GRAPHENE_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/libraries/egenesis/genesis.json" ) #set (ENABLE_INSTALLER 1) #set (USE_PCH 1) @@ -51,6 +55,7 @@ LIST(APPEND BOOST_COMPONENTS thread chrono unit_test_framework context) +# boost::endian is also required, but FindBoost can't handle header-only libs SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) IF( WIN32 ) @@ -80,6 +85,7 @@ if( WIN32 ) set(CRYPTO_LIB) if( MSVC ) + add_definitions(-DWIN32_LEAN_AND_MEAN) #looks like this flag can have different default on some machines. SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") @@ -108,11 +114,11 @@ else( WIN32 ) # Apple AND Linux if( APPLE ) # Apple Specific Options Here message( STATUS "Configuring BitShares on OS X" ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -stdlib=libc++ -Wall" ) + set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -stdlib=libc++ -Wall" ) else( APPLE ) # Linux Specific Options Here message( STATUS "Configuring BitShares on Linux" ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -Wall" ) + set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall" ) if(USE_PROFILER) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg" ) endif( USE_PROFILER ) diff --git a/Doxyfile b/Doxyfile index c3c45a913c..ebf009e2ff 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Bitshares-Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "2.0.180823" +PROJECT_NUMBER = "3.0.1" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/README.md b/README.md index a1e64b09dd..91c3dcb024 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ We recommend building on Ubuntu 16.04 LTS (64-bit) git submodule sync --recursive git submodule update --init --recursive -**NOTE:** Versions of [Boost](http://www.boost.org/) 1.57 through 1.69 are supported. Newer versions may work, but +**NOTE:** Versions of [Boost](http://www.boost.org/) 1.58 through 1.69 are supported. Newer versions may work, but have not been tested. If your system came pre-installed with a version of Boost that you do not wish to use, you may manually build your preferred version and use it with BitShares by specifying it on the CMake command line. diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 35b768460f..0069bca13e 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory( utilities ) add_subdirectory( app ) add_subdirectory( plugins ) add_subdirectory( wallet ) +add_subdirectory( protocol ) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index e68c70d155..d661bf4735 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -29,16 +29,28 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include +#include #include +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; +template class fc::api; + + namespace graphene { namespace app { login_api::login_api(application& a) @@ -317,7 +329,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT( limit <= 100 ); + uint64_t api_limit_get_account_history=_app.get_options().api_limit_get_account_history; + FC_ASSERT( limit <= api_limit_get_account_history ); vector result; account_id_type account; try { @@ -353,7 +366,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT( limit <= 100 ); + uint64_t api_limit_get_account_history_operations=_app.get_options().api_limit_get_account_history_operations; + FC_ASSERT(limit <= api_limit_get_account_history_operations); vector result; account_id_type account; try { @@ -392,7 +406,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT(limit <= 100); + uint64_t api_limit_get_relative_account_history=_app.get_options().api_limit_get_relative_account_history; + FC_ASSERT(limit <= api_limit_get_relative_account_history); vector result; account_id_type account; try { @@ -402,7 +417,7 @@ namespace graphene { namespace app { if( start == 0 ) start = stats.total_ops; else - start = min( stats.total_ops, start ); + start = std::min( stats.total_ops, start ); if( start >= stop && start > stats.removed_ops && limit > 0 ) { @@ -431,7 +446,8 @@ namespace graphene { namespace app { history_operation_detail history_api::get_account_history_by_operations(const std::string account_id_or_name, vector operation_types, uint32_t start, unsigned limit) { - FC_ASSERT(limit <= 100); + uint64_t api_limit_get_account_history_by_operations=_app.get_options().api_limit_get_account_history_by_operations; + FC_ASSERT(limit <= api_limit_get_account_history_by_operations); history_operation_detail result; vector objs = get_relative_account_history(account_id_or_name, start, limit, limit + start - 1); std::for_each(objs.begin(), objs.end(), [&](const operation_history_object &o) { @@ -530,82 +546,79 @@ namespace graphene { namespace app { // asset_api asset_api::asset_api(graphene::app::application& app) : - _db( *app.chain_database()), - database_api( std::ref(*app.chain_database()), &(app.get_options()) - ) { } + _app(app), + _db( *app.chain_database()), + database_api( std::ref(*app.chain_database()), &(app.get_options()) + ) { } asset_api::~asset_api() { } vector asset_api::get_asset_holders( std::string asset, uint32_t start, uint32_t limit ) const { - FC_ASSERT(limit <= 100); - - asset_id_type asset_id = database_api.get_asset_id_from_string( asset ); + uint64_t api_limit_get_asset_holders=_app.get_options().api_limit_get_asset_holders; + FC_ASSERT(limit <= api_limit_get_asset_holders); + asset_id_type asset_id = database_api.get_asset_id_from_string( asset ); + const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); + auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); - const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); - auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); + vector result; - vector result; - - uint32_t index = 0; - for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) ) - { - if( result.size() >= limit ) - break; + uint32_t index = 0; + for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) ) + { + if( result.size() >= limit ) + break; - if( bal.balance.value == 0 ) - continue; + if( bal.balance.value == 0 ) + continue; - if( index++ < start ) - continue; + if( index++ < start ) + continue; - const auto account = _db.find(bal.owner); + const auto account = _db.find(bal.owner); - account_asset_balance aab; - aab.name = account->name; - aab.account_id = account->id; - aab.amount = bal.balance.value; + account_asset_balance aab; + aab.name = account->name; + aab.account_id = account->id; + aab.amount = bal.balance.value; - result.push_back(aab); - } + result.push_back(aab); + } - return result; + return result; } // get number of asset holders. int asset_api::get_asset_holders_count( std::string asset ) const { + const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); + asset_id_type asset_id = database_api.get_asset_id_from_string( asset ); + auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); - const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); - asset_id_type asset_id = database_api.get_asset_id_from_string( asset ); - auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); + int count = boost::distance(range) - 1; - int count = boost::distance(range) - 1; - - return count; + return count; } // function to get vector of system assets with holders count. vector asset_api::get_all_asset_holders() const { + vector result; + vector total_assets; + for( const asset_object& asset_obj : _db.get_index_type().indices() ) + { + const auto& dasset_obj = asset_obj.dynamic_asset_data_id(_db); - vector result; - - vector total_assets; - for( const asset_object& asset_obj : _db.get_index_type().indices() ) - { - const auto& dasset_obj = asset_obj.dynamic_asset_data_id(_db); - - asset_id_type asset_id; - asset_id = dasset_obj.id; + asset_id_type asset_id; + asset_id = dasset_obj.id; - const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); - auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); + const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); + auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); - int count = boost::distance(range) - 1; + int count = boost::distance(range) - 1; - asset_holders ah; - ah.asset_id = asset_id; - ah.count = count; + asset_holders ah; + ah.asset_id = asset_id; + ah.count = count; - result.push_back(ah); - } + result.push_back(ah); + } - return result; + return result; } // orders_api @@ -622,8 +635,9 @@ namespace graphene { namespace app { optional start, uint32_t limit )const { - FC_ASSERT( limit <= 101 ); - auto plugin = _app.get_plugin( "grouped_orders" ); + uint64_t api_limit_get_grouped_limit_orders=_app.get_options().api_limit_get_grouped_limit_orders; + FC_ASSERT( limit <= api_limit_get_grouped_limit_orders ); + auto plugin = _app.get_plugin( "grouped_orders" ); FC_ASSERT( plugin ); const auto& limit_groups = plugin->limit_order_groups(); vector< limit_order_group > result; diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index f6607a5e2f..cdb75f57fe 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -28,8 +28,8 @@ #include #include -#include -#include +#include +#include #include @@ -81,7 +81,7 @@ namespace detail { auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key))); graphene::chain::genesis_state_type initial_state; - initial_state.initial_parameters.current_fees = fee_schedule::get_default();//->set_all_fees(GRAPHENE_BLOCKCHAIN_PRECISION); + initial_state.initial_parameters.get_mutable_fees() = fee_schedule::get_default(); initial_state.initial_active_witnesses = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT; initial_state.initial_timestamp = time_point_sec(time_point::now().sec_since_epoch() / initial_state.initial_parameters.block_interval * @@ -246,7 +246,7 @@ std::vector application_impl::resolve_string_to_ip_endpoints(c void application_impl::new_connection( const fc::http::websocket_connection_ptr& c ) { - auto wsc = std::make_shared(*c, GRAPHENE_NET_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(c, GRAPHENE_NET_MAX_NESTED_OBJECTS); auto login = std::make_shared( std::ref(*_self) ); login->enable_api("database_api"); @@ -316,6 +316,56 @@ void application_impl::set_dbg_init_key( graphene::chain::genesis_state_type& ge genesis.initial_witness_candidates[i].block_signing_key = init_pubkey; } + + +void application_impl::set_api_limit() { + if (_options->count("api-limit-get-account-history-operations")) { + _app_options.api_limit_get_account_history_operations = _options->at("api-limit-get-account-history-operations").as(); + } + if(_options->count("api-limit-get-account-history")){ + _app_options.api_limit_get_account_history = _options->at("api-limit-get-account-history").as(); + } + if(_options->count("api-limit-get-grouped-limit-orders")){ + _app_options.api_limit_get_grouped_limit_orders = _options->at("api-limit-get-grouped-limit-orders").as(); + } + if(_options->count("api-limit-get-relative-account-history")){ + _app_options.api_limit_get_relative_account_history = _options->at("api-limit-get-relative-account-history").as(); + } + if(_options->count("api-limit-get-account-history-by-operations")){ + _app_options.api_limit_get_account_history_by_operations = _options->at("api-limit-get-account-history-by-operations").as(); + } + if(_options->count("api-limit-get-asset-holders")){ + _app_options.api_limit_get_asset_holders = _options->at("api-limit-get-asset-holders").as(); + } + if(_options->count("api-limit-get-key-references")){ + _app_options.api_limit_get_key_references = _options->at("api-limit-get-key-references").as(); + } + if(_options->count("api-limit-get-htlc-by")) { + _app_options.api_limit_get_htlc_by = _options->at("api-limit-get-htlc-by").as(); + } + if(_options->count("api-limit-get-full-accounts")) { + _app_options.api_limit_get_full_accounts = _options->at("api-limit-get-full-accounts").as(); + } + if(_options->count("api-limit-get-full-accounts-lists")) { + _app_options.api_limit_get_full_accounts_lists = _options->at("api-limit-get-full-accounts-lists").as(); + } + if(_options->count("api-limit-get-call-orders")) { + _app_options.api_limit_get_call_orders = _options->at("api-limit-get-call-orders").as(); + } + if(_options->count("api-limit-get-settle-orders")) { + _app_options.api_limit_get_settle_orders = _options->at("api-limit-get-settle-orders").as(); + } + if(_options->count("api-limit-get-assets")) { + _app_options.api_limit_get_assets = _options->at("api-limit-get-assets").as(); + } + if(_options->count("api-limit-get-limit-orders")){ + _app_options.api_limit_get_limit_orders = _options->at("api-limit-get-limit-orders").as(); + } + if(_options->count("api-limit-get-order-book")){ + _app_options.api_limit_get_order_book = _options->at("api-limit-get-order-book").as(); + } +} + void application_impl::startup() { try { fc::create_directories(_data_dir / "blockchain"); @@ -437,6 +487,8 @@ void application_impl::startup() if ( _options->count("enable-subscribe-to-all") ) _app_options.enable_subscribe_to_all = _options->at( "enable-subscribe-to-all" ).as(); + set_api_limit(); + if( _active_plugins.find( "market_history" ) != _active_plugins.end() ) _app_options.has_market_history_plugin = true; @@ -975,6 +1027,36 @@ void application::set_program_options(boost::program_options::options_descriptio ("enable-standby-votes-tracking", bpo::value()->implicit_value(true), "Whether to enable tracking of votes of standby witnesses and committee members. " "Set it to true to provide accurate data to API clients, set to false for slightly better performance.") + ("api-limit-get-account-history-operations",boost::program_options::value()->default_value(100), + "For history_api::get_account_history_operations to set its default limit value as 100") + ("api-limit-get-account-history",boost::program_options::value()->default_value(100), + "For history_api::get_account_history to set its default limit value as 100") + ("api-limit-get-grouped-limit-orders",boost::program_options::value()->default_value(101), + "For orders_api::get_grouped_limit_orders to set its default limit value as 101") + ("api-limit-get-relative-account-history",boost::program_options::value()->default_value(100), + "For history_api::get_relative_account_history to set its default limit value as 100") + ("api-limit-get-account-history-by-operations",boost::program_options::value()->default_value(100), + "For history_api::get_account_history_by_operations to set its default limit value as 100") + ("api-limit-get-asset-holders",boost::program_options::value()->default_value(100), + "For asset_api::get_asset_holders to set its default limit value as 100") + ("api-limit-get-key-references",boost::program_options::value()->default_value(100), + "For database_api_impl::get_key_references to set its default limit value as 100") + ("api-limit-get-htlc-by",boost::program_options::value()->default_value(100), + "For database_api_impl::get_htlc_by_from and get_htlc_by_to to set its default limit value as 100") + ("api-limit-get-full-accounts",boost::program_options::value()->default_value(10), + "For database_api_impl::get_full_accounts to set its account default limit values as 10") + ("api-limit-get-full-accounts-lists",boost::program_options::value()->default_value(100), + "For database_api_impl::get_full_accounts to set its lists default limit values as 100") + ("api-limit-get-call-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_call_orders and get_call_orders_by_account to set its default limit values as 300") + ("api-limit-get-settle-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_settle_orders and get_settle_orders_by_account to set its default limit values as 300") + ("api-limit-get-assets",boost::program_options::value()->default_value(101), + "For database_api_impl::list_assets and get_assets_by_issuer to set its default limit values as 101") + ("api-limit-get-limit-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_limit_orders to set its default limit value as 300") + ("api-limit-get-order-book",boost::program_options::value()->default_value(50), + "For database_api_impl::get_order_book to set its default limit value as 50") ; command_line_options.add(configuration_file_options); command_line_options.add_options() @@ -1014,6 +1096,18 @@ void application::startup() } } +void application::set_api_limit() +{ + try { + my->set_api_limit(); + } catch ( const fc::exception& e ) { + elog( "${e}", ("e",e.to_detail_string()) ); + throw; + } catch ( ... ) { + elog( "unexpected exception" ); + throw; + } +} std::shared_ptr application::get_plugin(const string& name) const { return my->_active_plugins[name]; diff --git a/libraries/app/application_impl.hxx b/libraries/app/application_impl.hxx index 2d5d48080d..175648e10f 100644 --- a/libraries/app/application_impl.hxx +++ b/libraries/app/application_impl.hxx @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace graphene { namespace app { namespace detail { @@ -41,6 +41,7 @@ class application_impl : public net::node_delegate } void set_dbg_init_key( graphene::chain::genesis_state_type& genesis, const std::string& init_key ); + void set_api_limit(); void startup(); @@ -66,7 +67,7 @@ class application_impl : public net::node_delegate virtual void handle_transaction(const graphene::net::trx_message& transaction_message) override; - void handle_message(const graphene::net::message& message_to_process); + void handle_message(const graphene::net::message& message_to_process) override; bool is_included_block(const graphene::chain::block_id_type& block_id); diff --git a/libraries/app/config_util.cpp b/libraries/app/config_util.cpp index 6bfe946bd7..f06291b788 100644 --- a/libraries/app/config_util.cpp +++ b/libraries/app/config_util.cpp @@ -258,11 +258,22 @@ static void create_new_config_file(const fc::path& config_ini_path, const fc::pa }; deduplicator dedup(modify_option_defaults); std::ofstream out_cfg(config_ini_path.preferred_string()); + std::string plugin_header_surrounding( 78, '=' ); for( const boost::shared_ptr opt : cfg_options.options() ) { const boost::shared_ptr od = dedup.next(opt); if( !od ) continue; + if( od->long_name().find("plugin-cfg-header-") == 0 ) // it's a plugin header + { + out_cfg << "\n"; + out_cfg << "# " << plugin_header_surrounding << "\n"; + out_cfg << "# " << od->description() << "\n"; + out_cfg << "# " << plugin_header_surrounding << "\n"; + out_cfg << "\n"; + continue; + } + if( !od->description().empty() ) out_cfg << "# " << od->description() << "\n"; boost::any store; @@ -284,6 +295,10 @@ static void create_new_config_file(const fc::path& config_ini_path, const fc::pa } out_cfg << "\n" + << "# " << plugin_header_surrounding << "\n" + << "# logging options\n" + << "# " << plugin_header_surrounding << "\n" + << "#\n" << "# Logging configuration is loaded from logging.ini by default.\n" << "# If logging.ini exists, logging configuration added in this file will be ignored.\n"; out_cfg.close(); diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index e9c1f58bd3..6c12eeecf5 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -26,10 +26,12 @@ #include #include #include +#include +#include #include - #include +#include #include #include @@ -45,6 +47,8 @@ typedef std::map< std::pair, std::vector > market_queue_type; +template class fc::api; + namespace graphene { namespace app { class database_api_impl : public std::enable_shared_from_this @@ -59,6 +63,7 @@ class database_api_impl : public std::enable_shared_from_this // Subscriptions void set_subscribe_callback( std::function cb, bool notify_remove_create ); + void set_auto_subscription( bool enable ); void set_pending_transaction_callback( std::function cb ); void set_block_applied_callback( std::function cb ); void cancel_all_subscriptions(bool reset_callback, bool reset_market_subscriptions); @@ -77,7 +82,7 @@ class database_api_impl : public std::enable_shared_from_this dynamic_global_property_object get_dynamic_global_properties()const; // Keys - vector> get_key_references( vector key )const; + vector> get_key_references( vector key )const; bool is_public_key_registered(string public_key) const; // Accounts @@ -103,6 +108,8 @@ class database_api_impl : public std::enable_shared_from_this vector list_assets(const string& lower_bound_symbol, uint32_t limit)const; vector> lookup_asset_symbols(const vector& symbols_or_ids)const; uint64_t get_asset_count()const; + vector get_assets_by_issuer(const std::string& issuer_name_or_id, + asset_id_type start, uint32_t limit)const; // Markets / feeds vector get_limit_orders(const std::string& a, const std::string& b, uint32_t limit)const; @@ -112,7 +119,11 @@ class database_api_impl : public std::enable_shared_from_this optional ostart_id, optional ostart_price ); vector get_call_orders(const std::string& a, uint32_t limit)const; + vector get_call_orders_by_account(const std::string& account_name_or_id, + asset_id_type start, uint32_t limit)const; vector get_settle_orders(const std::string& a, uint32_t limit)const; + vector get_settle_orders_by_account(const std::string& account_name_or_id, + force_settlement_id_type start, uint32_t limit)const; vector get_margin_positions( const std::string account_id_or_name )const; vector get_collateral_bids(const std::string& asset, uint32_t limit, uint32_t start)const; @@ -168,27 +179,49 @@ class database_api_impl : public std::enable_shared_from_this vector get_withdraw_permissions_by_giver(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; vector get_withdraw_permissions_by_recipient(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; + // HTLC + optional get_htlc(htlc_id_type id) const; + vector get_htlc_by_from(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const; + vector get_htlc_by_to(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const; + //private: static string price_to_string( const price& _price, const asset_object& _base, const asset_object& _quote ); + // Note: + // Different type of object_id objects could become identical after packed. + // For example, both `account_id_type a=1.2.0` and `asset_id_type b=1.3.0` will become `0` after packed. + // In order to avoid collision, we don't use a template function here, instead, we implicitly convert all + // object IDs to `object_id_type` when subscribing. + // + // If need to subscribe to other data types, override this function with the types as parameter. + // For example, we had a `get_subscription_key( const public_key_type& item )` function here, which was + // removed lately since we no longer subscribe to public keys. + vector get_subscription_key( const object_id_type& item )const + { + return fc::raw::pack(item); + } + template - void subscribe_to_item( const T& i )const + void subscribe_to_item( const T& item )const { - auto vec = fc::raw::pack(i); if( !_subscribe_callback ) return; - if( !is_subscribed_to_item(i) ) - _subscribe_filter.insert( vec.data(), vec.size() ); + vector key = get_subscription_key( item ); + if( !_subscribe_filter.contains( key.data(), key.size() ) ) + { + _subscribe_filter.insert( key.data(), key.size() ); + } } template - bool is_subscribed_to_item( const T& i )const + bool is_subscribed_to_item( const T& item )const { if( !_subscribe_callback ) return false; - return _subscribe_filter.contains( i ); + vector key = get_subscription_key( item ); + return _subscribe_filter.contains( key.data(), key.size() ); } bool is_impacted_account( const flat_set& accounts) @@ -210,7 +243,7 @@ class database_api_impl : public std::enable_shared_from_this return tmp; } - const account_object* get_account_from_string( const std::string& name_or_id ) const + const account_object* get_account_from_string( const std::string& name_or_id, bool throw_if_not_found = true ) const { // TODO cache the result to avoid repeatly fetching from db FC_ASSERT( name_or_id.size() > 0); @@ -224,11 +257,12 @@ class database_api_impl : public std::enable_shared_from_this if (itr != idx.end()) account = &*itr; } - FC_ASSERT( account, "no such account" ); + if(throw_if_not_found) + FC_ASSERT( account, "no such account" ); return account; } - const asset_object* get_asset_from_string( const std::string& symbol_or_id ) const + const asset_object* get_asset_from_string( const std::string& symbol_or_id, bool throw_if_not_found = true ) const { // TODO cache the result to avoid repeatly fetching from db FC_ASSERT( symbol_or_id.size() > 0); @@ -242,7 +276,8 @@ class database_api_impl : public std::enable_shared_from_this if (itr != idx.end()) asset = &*itr; } - FC_ASSERT( asset, "no such asset" ); + if(throw_if_not_found) + FC_ASSERT( asset, "no such asset" ); return asset; } vector> get_assets(const vector& asset_ids)const @@ -252,7 +287,8 @@ class database_api_impl : public std::enable_shared_from_this [this](asset_id_type id) -> optional { if(auto o = _db.find(id)) { - subscribe_to_item( id ); + if( _enabled_auto_subscription ) + subscribe_to_item( id ); return *o; } return {}; @@ -261,7 +297,8 @@ class database_api_impl : public std::enable_shared_from_this } vector get_limit_orders(const asset_id_type a, const asset_id_type b, const uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + uint64_t api_limit_get_limit_orders=_app_options->api_limit_get_limit_orders; + FC_ASSERT( limit <= api_limit_get_limit_orders ); const auto& limit_order_idx = _db.get_index_type(); const auto& limit_price_idx = limit_order_idx.indices().get(); @@ -327,6 +364,7 @@ class database_api_impl : public std::enable_shared_from_this std::function _subscribe_callback; std::function _pending_trx_callback; std::function _block_applied_callback; + bool _enabled_auto_subscription = true; boost::signals2::scoped_connection _new_connection; boost::signals2::scoped_connection _change_connection; @@ -352,7 +390,7 @@ database_api::~database_api() {} database_api_impl::database_api_impl( graphene::chain::database& db, const application_options* app_options ) :_db(db), _app_options(app_options) { - wlog("creating database api ${x}", ("x",int64_t(this)) ); + dlog("creating database api ${x}", ("x",int64_t(this)) ); _new_connection = _db.new_objects.connect([this](const vector& ids, const flat_set& impacted_accounts) { on_objects_new(ids, impacted_accounts); }); @@ -371,7 +409,7 @@ database_api_impl::database_api_impl( graphene::chain::database& db, const appli database_api_impl::~database_api_impl() { - elog("freeing database api ${x}", ("x",int64_t(this)) ); + dlog("freeing database api ${x}", ("x",int64_t(this)) ); } ////////////////////////////////////////////////////////////////////// @@ -452,12 +490,12 @@ fc::variants database_api::get_objects(const vector& ids)const fc::variants database_api_impl::get_objects(const vector& ids)const { - if( _subscribe_callback ) { + if( _subscribe_callback && _enabled_auto_subscription ) + { for( auto id : ids ) { if( id.type() == operation_history_object_type && id.space() == protocol_ids ) continue; if( id.type() == impl_account_transaction_history_object_type && id.space() == implementation_ids ) continue; - this->subscribe_to_item( id ); } } @@ -500,6 +538,16 @@ void database_api_impl::set_subscribe_callback( std::functionset_auto_subscription( enable ); +} + +void database_api_impl::set_auto_subscription( bool enable ) +{ + _enabled_auto_subscription = enable; +} + void database_api::set_pending_transaction_callback( std::function cb ) { my->set_pending_transaction_callback( cb ); @@ -666,41 +714,34 @@ dynamic_global_property_object database_api_impl::get_dynamic_global_properties( // // ////////////////////////////////////////////////////////////////////// -vector> database_api::get_key_references( vector key )const +vector> database_api::get_key_references( vector key )const { - FC_ASSERT(key.size() <= 100, "Number of keys must be 100 or less"); return my->get_key_references( key ); } /** * @return all accounts that referr to the key or account id in their owner or active authorities. */ -vector> database_api_impl::get_key_references( vector keys )const +vector> database_api_impl::get_key_references( vector keys )const { + uint64_t api_limit_get_key_references=_app_options->api_limit_get_key_references; + FC_ASSERT(keys.size() <= api_limit_get_key_references); const auto& idx = _db.get_index_type(); const auto& aidx = dynamic_cast(idx); const auto& refs = aidx.get_secondary_index(); - vector< vector > final_result; + vector< flat_set > final_result; final_result.reserve(keys.size()); for( auto& key : keys ) { - address a1( pts_address(key, false, 56) ); address a2( pts_address(key, true, 56) ); address a3( pts_address(key, false, 0) ); address a4( pts_address(key, true, 0) ); address a5( key ); - subscribe_to_item( key ); - subscribe_to_item( a1 ); - subscribe_to_item( a2 ); - subscribe_to_item( a3 ); - subscribe_to_item( a4 ); - subscribe_to_item( a5 ); - - vector result; + flat_set result; for( auto& a : {a1,a2,a3,a4,a5} ) { @@ -710,7 +751,7 @@ vector> database_api_impl::get_key_references( vectorsecond.size() ); for( auto item : itr->second ) { - result.push_back(item); + result.insert(item); } } } @@ -719,7 +760,7 @@ vector> database_api_impl::get_key_references( vectorsecond.size() ); - for( auto item : itr->second ) result.push_back(item); + for( auto item : itr->second ) result.insert(item); } final_result.emplace_back( std::move(result) ); } @@ -778,14 +819,12 @@ vector> database_api_impl::get_accounts(const vector optional { - const account_object* account = get_account_from_string(id_or_name); - account_id_type id = account->id; - if(auto o = _db.find(id)) - { - subscribe_to_item( id ); - return *o; - } - return {}; + const account_object *account = get_account_from_string(id_or_name, false); + if(account == nullptr) + return {}; + if( _enabled_auto_subscription ) + subscribe_to_item( account->id ); + return *account; }); return result; } @@ -883,15 +922,16 @@ std::map database_api::get_full_accounts( const vector database_api_impl::get_full_accounts( const vector& names_or_ids, bool subscribe) { - const auto& proposal_idx = _db.get_index_type(); - const auto& pidx = dynamic_cast(proposal_idx); - const auto& proposals_by_account = pidx.get_secondary_index(); + FC_ASSERT( names_or_ids.size() <= _app_options->api_limit_get_full_accounts ); + + const auto& proposal_idx = _db.get_index_type< primary_index< proposal_index > >(); + const auto& proposals_by_account = proposal_idx.get_secondary_index(); std::map results; for (const std::string& account_name_or_id : names_or_ids) { - const account_object* account = get_account_from_string(account_name_or_id); + const account_object* account = get_account_from_string(account_name_or_id, false); if (account == nullptr) continue; @@ -915,59 +955,127 @@ std::map database_api_impl::get_full_accounts( const { acnt.cashback_balance = account->cashback_balance(_db); } + + size_t api_limit_get_full_accounts_lists = static_cast(_app_options->api_limit_get_full_accounts_lists); + // Add the account's proposals - auto required_approvals_itr = proposals_by_account._account_to_proposals.find( account->id ); + auto required_approvals_itr = proposals_by_account._account_to_proposals.find( account->id ); if( required_approvals_itr != proposals_by_account._account_to_proposals.end() ) { - acnt.proposals.reserve( required_approvals_itr->second.size() ); + acnt.proposals.reserve( std::min(required_approvals_itr->second.size(), api_limit_get_full_accounts_lists) ); for( auto proposal_id : required_approvals_itr->second ) - acnt.proposals.push_back( proposal_id(_db) ); + { + if(acnt.proposals.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.proposals = true; + break; + } + acnt.proposals.push_back(proposal_id(_db)); + } } - // Add the account's balances - const auto& balances = _db.get_index_type< primary_index< account_balance_index > >().get_secondary_index< balances_by_account_index >().get_account_balances( account->id ); + const auto& balances = _db.get_index_type< primary_index< account_balance_index > >(). + get_secondary_index< balances_by_account_index >().get_account_balances( account->id ); for( const auto balance : balances ) - acnt.balances.emplace_back( *balance.second ); + { + if(acnt.balances.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.balances = true; + break; + } + acnt.balances.emplace_back(*balance.second); + } // Add the account's vesting balances auto vesting_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(vesting_range.first, vesting_range.second, - [&acnt](const vesting_balance_object& balance) { - acnt.vesting_balances.emplace_back(balance); - }); + for(auto itr = vesting_range.first; itr != vesting_range.second; ++itr) + { + if(acnt.vesting_balances.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.vesting_balances = true; + break; + } + acnt.vesting_balances.emplace_back(*itr); + } // Add the account's orders auto order_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(order_range.first, order_range.second, - [&acnt] (const limit_order_object& order) { - acnt.limit_orders.emplace_back(order); - }); + for(auto itr = order_range.first; itr != order_range.second; ++itr) + { + if(acnt.limit_orders.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.limit_orders = true; + break; + } + acnt.limit_orders.emplace_back(*itr); + } auto call_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(call_range.first, call_range.second, - [&acnt] (const call_order_object& call) { - acnt.call_orders.emplace_back(call); - }); + for(auto itr = call_range.first; itr != call_range.second; ++itr) + { + if(acnt.call_orders.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.call_orders = true; + break; + } + acnt.call_orders.emplace_back(*itr); + } auto settle_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(settle_range.first, settle_range.second, - [&acnt] (const force_settlement_object& settle) { - acnt.settle_orders.emplace_back(settle); - }); + for(auto itr = settle_range.first; itr != settle_range.second; ++itr) + { + if(acnt.settle_orders.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.settle_orders = true; + break; + } + acnt.settle_orders.emplace_back(*itr); + } // get assets issued by user auto asset_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(asset_range.first, asset_range.second, - [&acnt] (const asset_object& asset) { - acnt.assets.emplace_back(asset.id); - }); + for(auto itr = asset_range.first; itr != asset_range.second; ++itr) + { + if(acnt.assets.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.assets = true; + break; + } + acnt.assets.emplace_back(itr->id); + } // get withdraws permissions - auto withdraw_range = _db.get_index_type().indices().get().equal_range(account->id); - std::for_each(withdraw_range.first, withdraw_range.second, - [&acnt] (const withdraw_permission_object& withdraw) { - acnt.withdraws.emplace_back(withdraw); - }); + auto withdraw_indices = _db.get_index_type().indices(); + auto withdraw_from_range = withdraw_indices.get().equal_range(account->id); + for(auto itr = withdraw_from_range.first; itr != withdraw_from_range.second; ++itr) + { + if(acnt.withdraws_from.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.withdraws_from = true; + break; + } + acnt.withdraws_from.emplace_back(*itr); + } + auto withdraw_authorized_range = withdraw_indices.get().equal_range(account->id); + for(auto itr = withdraw_authorized_range.first; itr != withdraw_authorized_range.second; ++itr) + { + if(acnt.withdraws_to.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.withdraws_to = true; + break; + } + acnt.withdraws_to.emplace_back(*itr); + } + // get htlcs + auto htlc_from_range = _db.get_index_type().indices().get().equal_range(account->id); + for(auto itr = htlc_from_range.first; itr != htlc_from_range.second; ++itr) + { + if(acnt.htlcs_from.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.htlcs_from = true; + break; + } + acnt.htlcs_from.emplace_back(*itr); + } + auto htlc_to_range = _db.get_index_type().indices().get().equal_range(account->id); + for(auto itr = htlc_to_range.first; itr != htlc_to_range.second; ++itr) + { + if(acnt.htlcs_to.size() >= api_limit_get_full_accounts_lists) { + acnt.more_data_available.htlcs_to = true; + break; + } + acnt.htlcs_to.emplace_back(*itr); + } results[account_name_or_id] = acnt; } @@ -1039,13 +1147,17 @@ map database_api_impl::lookup_accounts(const string& low const auto& accounts_by_name = _db.get_index_type().indices().get(); map result; + if( limit == 0 ) // shortcut to save a database query + return result; + + bool to_subscribe = (limit == 1 && _enabled_auto_subscription); // auto-subscribe if only look for one account for( auto itr = accounts_by_name.lower_bound(lower_bound_name); limit-- && itr != accounts_by_name.end(); ++itr ) { result.insert(make_pair(itr->name, itr->get_id())); - if( limit == 1 ) - subscribe_to_item( itr->get_id() ); + if( to_subscribe ) + subscribe_to_item( itr->id ); } return result; @@ -1117,7 +1229,6 @@ vector database_api_impl::get_balance_objects( const vectorowner == owner ) { @@ -1190,14 +1301,13 @@ vector> database_api_impl::get_assets(const vector> result; result.reserve(asset_symbols_or_ids.size()); std::transform(asset_symbols_or_ids.begin(), asset_symbols_or_ids.end(), std::back_inserter(result), [this](std::string id_or_name) -> optional { - const asset_object* asset = get_asset_from_string(id_or_name); - asset_id_type id = asset->id; - if(auto o = _db.find(id)) - { - subscribe_to_item( id ); - return *o; - } - return {}; + + const asset_object* asset_obj = get_asset_from_string( id_or_name, false ); + if( asset_obj == nullptr ) + return {}; + if( _enabled_auto_subscription ) + subscribe_to_item( asset_obj->id ); + return *asset_obj; }); return result; } @@ -1209,7 +1319,9 @@ vector database_api::list_assets(const string& lower_bound_symbol, vector database_api_impl::list_assets(const string& lower_bound_symbol, uint32_t limit)const { - FC_ASSERT( limit <= 101 ); + uint64_t api_limit_get_assets = _app_options->api_limit_get_assets; + FC_ASSERT( limit <= api_limit_get_assets ); + const auto& assets_by_symbol = _db.get_index_type().indices().get(); vector result; result.reserve(limit); @@ -1235,6 +1347,31 @@ uint64_t database_api_impl::get_asset_count()const return _db.get_index_type().indices().size(); } +vector database_api::get_assets_by_issuer(const std::string& issuer_name_or_id, + asset_id_type start, uint32_t limit)const +{ + return my->get_assets_by_issuer(issuer_name_or_id, start, limit); +} + +vector database_api_impl::get_assets_by_issuer(const std::string& issuer_name_or_id, + asset_id_type start, uint32_t limit)const +{ + uint64_t api_limit_get_assets = _app_options->api_limit_get_assets; + FC_ASSERT( limit <= api_limit_get_assets ); + + vector result; + const account_id_type account = get_account_from_string(issuer_name_or_id)->id; + const auto& asset_idx = _db.get_index_type().indices().get(); + auto asset_index_end = asset_idx.end(); + auto asset_itr = asset_idx.lower_bound(boost::make_tuple(account, start)); + while(asset_itr != asset_index_end && asset_itr->issuer == account && result.size() < limit) + { + result.push_back(*asset_itr); + ++asset_itr; + } + return result; +} + vector> database_api::lookup_asset_symbols(const vector& symbols_or_ids)const { return my->lookup_asset_symbols( symbols_or_ids ); @@ -1274,7 +1411,8 @@ vector database_api::get_limit_orders(std::string a, std::st */ vector database_api_impl::get_limit_orders(const std::string& a, const std::string& b, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + uint64_t api_limit_get_limit_orders=_app_options->api_limit_get_limit_orders; + FC_ASSERT( limit <= api_limit_get_limit_orders ); const asset_id_type asset_a_id = get_asset_from_string(a)->id; const asset_id_type asset_b_id = get_asset_from_string(b)->id; @@ -1289,16 +1427,17 @@ vector database_api::get_call_orders(const std::string& a, ui vector database_api_impl::get_call_orders(const std::string& a, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + uint64_t api_limit_get_call_orders = _app_options->api_limit_get_call_orders; + FC_ASSERT( limit <= api_limit_get_call_orders ); const asset_object* mia = get_asset_from_string(a); const auto& call_index = _db.get_index_type().indices().get(); price index_price = price::min( mia->bitasset_data(_db).options.short_backing_asset, mia->get_id() ); - + vector< call_order_object> result; auto itr_min = call_index.lower_bound(index_price); auto itr_max = call_index.upper_bound(index_price.max()); - while( itr_min != itr_max && result.size() < limit ) + while( itr_min != itr_max && result.size() < limit ) { result.emplace_back(*itr_min); ++itr_min; @@ -1306,6 +1445,31 @@ vector database_api_impl::get_call_orders(const std::string& return result; } +vector database_api::get_call_orders_by_account(const std::string& account_name_or_id, + asset_id_type start, uint32_t limit)const +{ + return my->get_call_orders_by_account( account_name_or_id, start, limit ); +} + +vector database_api_impl::get_call_orders_by_account(const std::string& account_name_or_id, + asset_id_type start, uint32_t limit)const +{ + uint64_t api_limit_get_call_orders = _app_options->api_limit_get_call_orders; + FC_ASSERT( limit <= api_limit_get_call_orders ); + + vector result; + const account_id_type account = get_account_from_string(account_name_or_id)->id; + const auto& call_idx = _db.get_index_type().indices().get(); + auto call_index_end = call_idx.end(); + auto call_itr = call_idx.lower_bound(boost::make_tuple(account, start)); + while(call_itr != call_index_end && call_itr->borrower == account && result.size() < limit) + { + result.push_back(*call_itr); + ++call_itr; + } + return result; +} + vector database_api::get_settle_orders(const std::string& a, uint32_t limit)const { return my->get_settle_orders( a, limit ); @@ -1313,7 +1477,8 @@ vector database_api::get_settle_orders(const std::strin vector database_api_impl::get_settle_orders(const std::string& a, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + uint64_t api_limit_get_settle_orders = _app_options->api_limit_get_settle_orders; + FC_ASSERT( limit <= api_limit_get_settle_orders ); const asset_id_type asset_a_id = get_asset_from_string(a)->id; const auto& settle_index = _db.get_index_type().indices().get(); @@ -1330,6 +1495,32 @@ vector database_api_impl::get_settle_orders(const std:: return result; } +vector database_api::get_settle_orders_by_account(const std::string& account_name_or_id, + force_settlement_id_type start, uint32_t limit)const +{ + return my->get_settle_orders_by_account( account_name_or_id, start, limit); +} + +vector database_api_impl::get_settle_orders_by_account(const std::string& account_name_or_id, + force_settlement_id_type start, uint32_t limit)const +{ + uint64_t api_limit_get_settle_orders = _app_options->api_limit_get_settle_orders; + FC_ASSERT( limit <= api_limit_get_settle_orders ); + + vector result; + const account_id_type account = get_account_from_string(account_name_or_id)->id; + const auto& settle_idx = _db.get_index_type().indices().get(); + auto settle_index_end = settle_idx.end(); + auto settle_itr = settle_idx.lower_bound(boost::make_tuple(account, start)); + while(settle_itr != settle_index_end && settle_itr->owner == account && result.size() < limit) + { + result.push_back(*settle_itr); + ++settle_itr; + } + return result; +} + + vector database_api::get_margin_positions( const std::string account_id_or_name )const { return my->get_margin_positions( account_id_or_name ); @@ -1482,7 +1673,8 @@ order_book database_api::get_order_book( const string& base, const string& quote order_book database_api_impl::get_order_book( const string& base, const string& quote, unsigned limit )const { using boost::multiprecision::uint128_t; - FC_ASSERT( limit <= 50 ); + uint64_t api_limit_get_order_book=_app_options->api_limit_get_order_book; + FC_ASSERT( limit <= api_limit_get_order_book ); order_book result; result.base = base; @@ -2216,7 +2408,7 @@ struct get_required_fees_helper fc::variant set_op_fees( operation& op ) { - if( op.which() == operation::tag::value ) + if( op.is_type() ) { return set_proposal_create_op_fees( op ); } @@ -2287,22 +2479,23 @@ vector database_api::get_proposed_transactions( const std::stri return my->get_proposed_transactions( account_id_or_name ); } -/** TODO: add secondary index that will accelerate this process */ vector database_api_impl::get_proposed_transactions( const std::string account_id_or_name )const { - const auto& idx = _db.get_index_type(); + const auto& proposal_idx = _db.get_index_type< primary_index< proposal_index > >(); + const auto& proposals_by_account = proposal_idx.get_secondary_index(); + vector result; const account_id_type id = get_account_from_string(account_id_or_name)->id; - idx.inspect_all_objects( [&](const object& obj){ - const proposal_object& p = static_cast(obj); - if( p.required_active_approvals.find( id ) != p.required_active_approvals.end() ) - result.push_back(p); - else if ( p.required_owner_approvals.find( id ) != p.required_owner_approvals.end() ) - result.push_back(p); - else if ( p.available_active_approvals.find( id ) != p.available_active_approvals.end() ) - result.push_back(p); - }); + auto required_approvals_itr = proposals_by_account._account_to_proposals.find( id ); + if( required_approvals_itr != proposals_by_account._account_to_proposals.end() ) + { + result.reserve( required_approvals_itr->second.size() ); + for( auto proposal_id : required_approvals_itr->second ) + { + result.push_back( proposal_id(_db) ); + } + } return result; } @@ -2381,6 +2574,74 @@ vector database_api_impl::get_withdraw_permissions_b return result; } +////////////////////////////////////////////////////////////////////// +// // +// HTLC // +// // +////////////////////////////////////////////////////////////////////// + +optional database_api::get_htlc(htlc_id_type id)const +{ + return my->get_htlc(id); +} + +fc::optional database_api_impl::get_htlc(htlc_id_type id) const +{ + auto obj = get_objects( { id }).front(); + if ( !obj.is_null() ) + { + return fc::optional(obj.template as(GRAPHENE_MAX_NESTED_OBJECTS)); + } + return fc::optional(); +} + +vector database_api::get_htlc_by_from(const std::string account_id_or_name, htlc_id_type start, uint32_t limit)const +{ + return my->get_htlc_by_from(account_id_or_name, start, limit); +} + +vector database_api_impl::get_htlc_by_from(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const +{ + FC_ASSERT( limit <= _app_options->api_limit_get_htlc_by ); + vector result; + + const auto& htlc_idx = _db.get_index_type< htlc_index >().indices().get< by_from_id >(); + auto htlc_index_end = htlc_idx.end(); + const account_id_type account = get_account_from_string(account_id_or_name)->id; + auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, start)); + + while(htlc_itr != htlc_index_end && htlc_itr->transfer.from == account && result.size() < limit) + { + result.push_back(*htlc_itr); + ++htlc_itr; + } + return result; +} + +vector database_api::get_htlc_by_to(const std::string account_id_or_name, htlc_id_type start, uint32_t limit)const +{ + return my->get_htlc_by_to(account_id_or_name, start, limit); +} + +vector database_api_impl::get_htlc_by_to(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const +{ + + FC_ASSERT( limit <= _app_options->api_limit_get_htlc_by ); + vector result; + + const auto& htlc_idx = _db.get_index_type< htlc_index >().indices().get< by_to_id >(); + auto htlc_index_end = htlc_idx.end(); + const account_id_type account = get_account_from_string(account_id_or_name)->id; + auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, start)); + + while(htlc_itr != htlc_index_end && htlc_itr->transfer.to == account && result.size() < limit) + { + result.push_back(*htlc_itr); + ++htlc_itr; + } + return result; +} + ////////////////////////////////////////////////////////////////////// // // // Private methods // diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index 7e1dc1552f..c7e0f7f9bc 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -25,8 +25,8 @@ #include -#include -#include +#include +#include #include @@ -53,7 +53,9 @@ namespace graphene { namespace app { using namespace graphene::market_history; using namespace graphene::grouped_orders; using namespace fc::ecc; - using namespace std; + using std::string; + using std::vector; + using std::map; class application; @@ -464,6 +466,7 @@ namespace graphene { namespace app { vector get_all_asset_holders() const; private: + graphene::app::application& _app; graphene::chain::database& _db; graphene::app::database_api database_api; }; @@ -503,7 +506,18 @@ namespace graphene { namespace app { application& _app; graphene::app::database_api database_api; }; +} } // graphene::app +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; +extern template class fc::api; + +namespace graphene { namespace app { /** * @brief The login_api class implements the bottom layer of the RPC API * @@ -562,6 +576,8 @@ namespace graphene { namespace app { }} // graphene::app +extern template class fc::api; + FC_REFLECT( graphene::app::network_broadcast_api::transaction_confirmation, (id)(block_num)(trx_num)(trx) ) FC_REFLECT( graphene::app::verify_range_result, diff --git a/libraries/app/include/graphene/app/application.hpp b/libraries/app/include/graphene/app/application.hpp index 66a73f3999..30dfc53f2a 100644 --- a/libraries/app/include/graphene/app/application.hpp +++ b/libraries/app/include/graphene/app/application.hpp @@ -40,6 +40,21 @@ namespace graphene { namespace app { public: bool enable_subscribe_to_all = false; bool has_market_history_plugin = false; + uint64_t api_limit_get_account_history_operations = 100; + uint64_t api_limit_get_account_history = 100; + uint64_t api_limit_get_grouped_limit_orders = 101; + uint64_t api_limit_get_relative_account_history = 100; + uint64_t api_limit_get_account_history_by_operations = 100; + uint64_t api_limit_get_asset_holders = 100; + uint64_t api_limit_get_key_references = 100; + uint64_t api_limit_get_htlc_by = 100; + uint64_t api_limit_get_full_accounts = 10; + uint64_t api_limit_get_full_accounts_lists = 100; + uint64_t api_limit_get_call_orders = 300; + uint64_t api_limit_get_settle_orders = 300; + uint64_t api_limit_get_assets = 101; + uint64_t api_limit_get_limit_orders = 300; + uint64_t api_limit_get_order_book = 50; }; class application @@ -62,13 +77,20 @@ namespace graphene { namespace app { auto plug = std::make_shared(); plug->plugin_set_app(this); - boost::program_options::options_description plugin_cli_options(plug->plugin_name() + " plugin. " + plug->plugin_description() + "\nOptions"), plugin_cfg_options; - //boost::program_options::options_description plugin_cli_options("Options for plugin " + plug->plugin_name()), plugin_cfg_options; + string cli_plugin_desc = plug->plugin_name() + " plugin. " + plug->plugin_description() + "\nOptions"; + boost::program_options::options_description plugin_cli_options( cli_plugin_desc ), plugin_cfg_options; plug->plugin_set_program_options(plugin_cli_options, plugin_cfg_options); + if( !plugin_cli_options.options().empty() ) _cli_options.add(plugin_cli_options); + if( !plugin_cfg_options.options().empty() ) + { + std::string header_name = "plugin-cfg-header-" + plug->plugin_name(); + std::string header_desc = plug->plugin_name() + " plugin options"; + _cfg_options.add_options()(header_name.c_str(), header_desc.c_str()); _cfg_options.add(plugin_cfg_options); + } add_available_plugin( plug ); @@ -90,7 +112,7 @@ namespace graphene { namespace app { net::node_ptr p2p_node(); std::shared_ptr chain_database()const; - + void set_api_limit(); void set_block_production(bool producing_blocks); fc::optional< api_access_info > get_api_access_info( const string& username )const; void set_api_access_info(const string& username, api_access_info&& permissions); diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index fe97083956..13734e751b 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -25,7 +25,7 @@ #include -#include +#include #include @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -60,7 +61,9 @@ namespace graphene { namespace app { using namespace graphene::chain; using namespace graphene::market_history; -using namespace std; +using std::string; +using std::vector; +using std::map; class database_api_impl; @@ -160,8 +163,24 @@ class database_api * newly removed objects to the client, no matter whether client subscribed to the objects. * By default, API servers don't allow subscribing to universal events, which can be changed * on server startup. + * + * Note: auto-subscription is enabled by default and can be disabled with "set_auto_subscription" API. */ void set_subscribe_callback( std::function cb, bool notify_remove_create ); + /** + * @brief Set auto-subscription behavior of follow-up API queries + * @param enable whether follow-up API queries will automatically subscribe to queried objects + * + * Impacts behavior of these APIs: + * - get_accounts + * - get_assets + * - get_objects + * - lookup_accounts + * + * Does not impact this API: + * - get_full_accounts + */ + void set_auto_subscription( bool enable ); /** * @brief Register a callback handle which will get notified when a transaction is pushed to database * @param cb The callback handle to register @@ -254,7 +273,7 @@ class database_api // Keys // ////////// - vector> get_key_references( vector key )const; + vector> get_key_references( vector key )const; /** * Determine whether a textual representation of a public key @@ -422,6 +441,16 @@ class database_api */ uint64_t get_asset_count()const; + /** + * @brief Get asset objects issued from a given account + * @param account_name_or_id Account name or ID to get objects from + * @param start Asset objects(1.3.X) before this ID will be skipped in results. Pagination purposes. + * @param limit Maximum number of orders to retrieve + * @return The assets issued by the account + */ + vector get_assets_by_issuer(const std::string& issuer_name_or_id, + asset_id_type start, uint32_t limit)const; + ///////////////////// // Markets / feeds // ///////////////////// @@ -443,6 +472,16 @@ class database_api */ vector get_call_orders(const std::string& a, uint32_t limit)const; + /** + * @brief Get call orders from a given account + * @param account_name_or_id Account name or ID to get objects from + * @param start Asset objects(1.3.X) before this ID will be skipped in results. Pagination purposes. + * @param limit Maximum number of objects to retrieve + * @return The call orders of the account + */ + vector get_call_orders_by_account(const std::string& account_name_or_id, + asset_id_type start, uint32_t limit)const; + /** * @brief Get forced settlement orders in a given asset * @param a Symbol or ID of asset being settled @@ -451,6 +490,16 @@ class database_api */ vector get_settle_orders(const std::string& a, uint32_t limit)const; + /** + * @brief Get forced settlement orders of a given account + * @param account_name_or_id Account name or ID to get objects from + * @param start Force settlement objects(1.4.X) before this ID will be skipped in results. Pagination purposes. + * @param limit Maximum number of orders to retrieve + * @return The settle orders of the account + */ + vector get_settle_orders_by_account(const std::string& account_name_or_id, + force_settlement_id_type start, uint32_t limit)const; + /** * @brief Get collateral_bid_objects for a given asset * @param a Symbol or ID of asset @@ -743,12 +792,43 @@ class database_api */ vector get_withdraw_permissions_by_recipient(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit)const; - private: + ////////// + // HTLC // + ////////// + + /** + * @brief Get HTLC object + * @param id HTLC contract id + * @return HTLC object for the id + */ + optional get_htlc(htlc_id_type id) const; + + /** + * @brief Get non expired HTLC objects using the sender account + * @param account_id_or_name Account ID or name to get objects from + * @param start htlc objects before this ID will be skipped in results. Pagination purposes. + * @param limit Maximum number of objects to retrieve + * @return HTLC objects for the account + */ + vector get_htlc_by_from(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const; + + /** + * @brief Get non expired HTLC objects using the receiver account + * @param account_id_or_name Account ID or name to get objects from + * @param start htlc objects before this ID will be skipped in results. Pagination purposes. + * @param limit Maximum number of objects to retrieve + * @return HTLC objects for the account + */ + vector get_htlc_by_to(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const; + +private: std::shared_ptr< database_api_impl > my; }; } } +extern template class fc::api; + FC_REFLECT( graphene::app::order, (price)(quote)(base) ); FC_REFLECT( graphene::app::order_book, (base)(quote)(bids)(asks) ); FC_REFLECT( graphene::app::market_ticker, @@ -762,6 +842,7 @@ FC_API(graphene::app::database_api, // Subscriptions (set_subscribe_callback) + (set_auto_subscription) (set_pending_transaction_callback) (set_block_applied_callback) (cancel_all_subscriptions) @@ -806,6 +887,7 @@ FC_API(graphene::app::database_api, (list_assets) (lookup_asset_symbols) (get_asset_count) + (get_assets_by_issuer) (get_asset_id_from_string) // Markets / feeds @@ -813,7 +895,9 @@ FC_API(graphene::app::database_api, (get_limit_orders) (get_account_limit_orders) (get_call_orders) + (get_call_orders_by_account) (get_settle_orders) + (get_settle_orders_by_account) (get_margin_positions) (get_collateral_bids) (subscribe_to_market) @@ -865,4 +949,8 @@ FC_API(graphene::app::database_api, (get_withdraw_permissions_by_giver) (get_withdraw_permissions_by_recipient) + // HTLC + (get_htlc) + (get_htlc_by_from) + (get_htlc_by_to) ) diff --git a/libraries/app/include/graphene/app/full_account.hpp b/libraries/app/include/graphene/app/full_account.hpp index dea5eb7e6a..4618ef84a1 100644 --- a/libraries/app/include/graphene/app/full_account.hpp +++ b/libraries/app/include/graphene/app/full_account.hpp @@ -26,11 +26,29 @@ #include #include #include +#include +#include #include +#include namespace graphene { namespace app { using namespace graphene::chain; + struct more_data + { + bool balances = false; + bool vesting_balances = false; + bool limit_orders = false; + bool call_orders = false; + bool settle_orders = false; + bool proposals = false; + bool assets = false; + bool withdraws_from = false; + bool withdraws_to = false; + bool htlcs_from = false; + bool htlcs_to = false; + }; + struct full_account { account_object account; @@ -47,11 +65,20 @@ namespace graphene { namespace app { vector settle_orders; vector proposals; vector assets; - vector withdraws; + vector withdraws_from; + vector withdraws_to; + vector htlcs_from; + vector htlcs_to; + more_data more_data_available; }; } } +FC_REFLECT( graphene::app::more_data, + (balances) (vesting_balances) (limit_orders) (call_orders) + (settle_orders) (proposals) (assets) (withdraws_from) (withdraws_to) (htlcs_from) (htlcs_to) + ) + FC_REFLECT( graphene::app::full_account, (account) (statistics) @@ -67,5 +94,9 @@ FC_REFLECT( graphene::app::full_account, (settle_orders) (proposals) (assets) - (withdraws) + (withdraws_from) + (withdraws_to) + (htlcs_from) + (htlcs_to) + (more_data_available) ) diff --git a/libraries/app/include/graphene/app/util.hpp b/libraries/app/include/graphene/app/util.hpp index 520ce6c502..038771015c 100644 --- a/libraries/app/include/graphene/app/util.hpp +++ b/libraries/app/include/graphene/app/util.hpp @@ -27,10 +27,10 @@ #include -#include +#include namespace graphene { namespace app { - using namespace graphene::chain; + using namespace graphene::protocol; typedef boost::multiprecision::uint256_t u256; diff --git a/libraries/app/plugin.cpp b/libraries/app/plugin.cpp index cae488a666..02d1fdb828 100644 --- a/libraries/app/plugin.cpp +++ b/libraries/app/plugin.cpp @@ -23,7 +23,7 @@ */ #include -#include +#include namespace graphene { namespace app { diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index 71d2fd2d2e..fbcd6ab866 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -6,7 +6,6 @@ set_source_files_properties( "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain add_dependencies( build_hardfork_hpp cat-parts ) file(GLOB HEADERS "include/graphene/chain/*.hpp") -file(GLOB PROTOCOL_HEADERS "include/graphene/chain/protocol/*.hpp") if( GRAPHENE_DISABLE_UNITY_BUILD ) set( GRAPHENE_DB_FILES @@ -36,33 +35,9 @@ add_library( graphene_chain ${GRAPHENE_DB_FILES} fork_database.cpp - protocol/types.cpp - protocol/address.cpp - protocol/authority.cpp - protocol/asset.cpp - protocol/assert.cpp - protocol/account.cpp - protocol/transfer.cpp - protocol/committee_member.cpp - protocol/witness.cpp - protocol/market.cpp - protocol/proposal.cpp - protocol/withdraw_permission.cpp - protocol/asset_ops.cpp - protocol/memo.cpp - protocol/worker.cpp - protocol/custom.cpp - protocol/operations.cpp - protocol/transaction.cpp - protocol/block.cpp - protocol/fee_schedule.cpp - protocol/confidential.cpp - protocol/vote.cpp - protocol/htlc.cpp genesis_state.cpp get_config.cpp - - pts_address.cpp + exceptions.cpp evaluator.cpp balance_evaluator.cpp @@ -79,7 +54,7 @@ add_library( graphene_chain worker_evaluator.cpp htlc_evaluator.cpp confidential_evaluator.cpp - special_authority.cpp + special_authority_evaluation.cpp buyback.cpp account_object.cpp @@ -88,18 +63,18 @@ add_library( graphene_chain market_object.cpp proposal_object.cpp vesting_balance_object.cpp + small_objects.cpp block_database.cpp is_authorized_asset.cpp ${HEADERS} - ${PROTOCOL_HEADERS} "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" ) add_dependencies( graphene_chain build_hardfork_hpp ) -target_link_libraries( graphene_chain fc graphene_db ) +target_link_libraries( graphene_chain fc graphene_db graphene_protocol ) target_include_directories( graphene_chain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" ) @@ -115,4 +90,3 @@ INSTALL( TARGETS ARCHIVE DESTINATION lib ) INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/chain" ) -INSTALL( FILES ${PROTOCOL_HEADERS} DESTINATION "include/graphene/chain/protocol" ) diff --git a/libraries/chain/account_evaluator.cpp b/libraries/chain/account_evaluator.cpp index 98e0766652..674de46c43 100644 --- a/libraries/chain/account_evaluator.cpp +++ b/libraries/chain/account_evaluator.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -125,13 +125,6 @@ void_result account_create_evaluator::do_evaluate( const account_create_operatio FC_ASSERT( !op.extensions.value.owner_special_authority.valid() ); FC_ASSERT( !op.extensions.value.active_special_authority.valid() ); } - if( d.head_block_time() < HARDFORK_599_TIME ) - { - FC_ASSERT( !op.extensions.value.null_ext.valid() ); - FC_ASSERT( !op.extensions.value.owner_special_authority.valid() ); - FC_ASSERT( !op.extensions.value.active_special_authority.valid() ); - FC_ASSERT( !op.extensions.value.buyback_options.valid() ); - } FC_ASSERT( fee_paying_account->is_lifetime_member(), "Only Lifetime members may register an account." ); FC_ASSERT( op.referrer(d).is_member(d.head_block_time()), "The referrer must be either a lifetime or annual subscriber." ); @@ -240,7 +233,7 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio && global_properties.parameters.account_fee_scale_bitshifts != 0 ) { d.modify(global_properties, [](global_property_object& p) { - p.parameters.current_fees->get().basic_fee <<= p.parameters.account_fee_scale_bitshifts; + p.parameters.get_mutable_fees().get().basic_fee <<= p.parameters.account_fee_scale_bitshifts; }); } @@ -280,12 +273,6 @@ void_result account_update_evaluator::do_evaluate( const account_update_operatio FC_ASSERT( !o.extensions.value.owner_special_authority.valid() ); FC_ASSERT( !o.extensions.value.active_special_authority.valid() ); } - if( d.head_block_time() < HARDFORK_599_TIME ) - { - FC_ASSERT( !o.extensions.value.null_ext.valid() ); - FC_ASSERT( !o.extensions.value.owner_special_authority.valid() ); - FC_ASSERT( !o.extensions.value.active_special_authority.valid() ); - } try { diff --git a/libraries/chain/account_object.cpp b/libraries/chain/account_object.cpp index 7acaf10b21..8ec70a6a4f 100644 --- a/libraries/chain/account_object.cpp +++ b/libraries/chain/account_object.cpp @@ -22,9 +22,9 @@ * THE SOFTWARE. */ #include -#include #include -#include + +#include #include namespace graphene { namespace chain { @@ -320,3 +320,37 @@ const account_balance_object* balances_by_account_index::get_account_balance( co } } } // graphene::chain + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_object, + (graphene::db::object), + (membership_expiration_date)(registrar)(referrer)(lifetime_referrer) + (network_fee_percentage)(lifetime_referrer_fee_percentage)(referrer_rewards_percentage) + (name)(owner)(active)(options)(statistics)(whitelisting_accounts)(blacklisting_accounts) + (whitelisted_accounts)(blacklisted_accounts) + (cashback_vb) + (owner_special_authority)(active_special_authority) + (top_n_control_flags) + (allowed_assets) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_balance_object, + (graphene::db::object), + (owner)(asset_type)(balance)(maintenance_flag) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_statistics_object, + (graphene::chain::object), + (owner)(name) + (most_recent_op) + (total_ops)(removed_ops) + (total_core_in_orders) + (core_in_balance) + (has_cashback_vb) + (is_voting) + (last_vote_time) + (lifetime_fees_paid) + (pending_fees)(pending_vested_fees) + ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::account_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::account_balance_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::account_statistics_object ) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index d809983283..e970790c7d 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -83,11 +83,6 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}", ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) ); } - - if(d.head_block_time() <= HARDFORK_CORE_620_TIME ) { // TODO: remove this check after hf_620 - static const std::locale& loc = std::locale::classic(); - FC_ASSERT(isalpha(op.symbol.back(), loc), "Asset ${s} must end with alpha character before hardfork 620", ("s",op.symbol)); - } } else { @@ -375,12 +370,6 @@ void_result asset_update_issuer_evaluator::do_evaluate(const asset_update_issuer "Incorrect issuer for asset! (${o.issuer} != ${a.issuer})", ("o.issuer", o.issuer)("a.issuer", a.issuer) ); - if( d.head_block_time() < HARDFORK_CORE_199_TIME ) - { - // TODO: remove after HARDFORK_CORE_199_TIME has passed - FC_ASSERT(false, "Not allowed until hardfork 199"); - } - return void_result(); } FC_CAPTURE_AND_RETHROW((o)) } @@ -1043,7 +1032,6 @@ void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_ope void_result asset_claim_fees_evaluator::do_evaluate( const asset_claim_fees_operation& o ) { try { - FC_ASSERT( db().head_block_time() > HARDFORK_413_TIME ); FC_ASSERT( o.amount_to_claim.asset_id(db()).issuer == o.issuer, "Asset fees may only be claimed by the issuer" ); return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } @@ -1069,8 +1057,6 @@ void_result asset_claim_fees_evaluator::do_apply( const asset_claim_fees_operati void_result asset_claim_pool_evaluator::do_evaluate( const asset_claim_pool_operation& o ) { try { - FC_ASSERT( db().head_block_time() >= HARDFORK_CORE_188_TIME, - "This operation is only available after Hardfork #188!" ); FC_ASSERT( o.asset_id(db()).issuer == o.issuer, "Asset fee pool may only be claimed by the issuer" ); return void_result(); diff --git a/libraries/chain/asset_object.cpp b/libraries/chain/asset_object.cpp index c6b6ca0d82..549159da72 100644 --- a/libraries/chain/asset_object.cpp +++ b/libraries/chain/asset_object.cpp @@ -25,10 +25,9 @@ #include #include +#include #include -#include - using namespace graphene::chain; share_type asset_bitasset_data_object::max_force_settlement_volume(share_type current_supply) const @@ -176,3 +175,35 @@ string asset_object::amount_to_string(share_type amount) const } return result; } + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::asset_dynamic_data_object, (graphene::db::object), + (current_supply)(confidential_supply)(accumulated_fees)(fee_pool) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::asset_bitasset_data_object, (graphene::db::object), + (asset_id) + (feeds) + (current_feed) + (current_feed_publication_time) + (current_maintenance_collateralization) + (options) + (force_settled_volume) + (is_prediction_market) + (settlement_price) + (settlement_fund) + (asset_cer_updated) + (feed_cer_updated) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::asset_object, (graphene::db::object), + (symbol) + (precision) + (issuer) + (options) + (dynamic_asset_data_id) + (bitasset_data_id) + (buyback_account) + ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::asset_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::asset_bitasset_data_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::asset_dynamic_data_object ) diff --git a/libraries/chain/balance_evaluator.cpp b/libraries/chain/balance_evaluator.cpp index 8c0a48c95c..7c8b8b3ff1 100644 --- a/libraries/chain/balance_evaluator.cpp +++ b/libraries/chain/balance_evaluator.cpp @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include +#include namespace graphene { namespace chain { diff --git a/libraries/chain/block_database.cpp b/libraries/chain/block_database.cpp index c5fa6636a8..134ca833b6 100644 --- a/libraries/chain/block_database.cpp +++ b/libraries/chain/block_database.cpp @@ -22,16 +22,21 @@ * THE SOFTWARE. */ #include -#include +#include #include +#include namespace graphene { namespace chain { struct index_entry { - uint64_t block_pos = 0; - uint32_t block_size = 0; - block_id_type block_id; + index_entry() { + block_pos = 0; + block_size = 0; + }; + boost::endian::little_uint64_buf_t block_pos; + boost::endian::little_uint32_buf_t block_size; + block_id_type block_id; }; }} FC_REFLECT( graphene::chain::index_entry, (block_pos)(block_size)(block_id) ); @@ -125,7 +130,7 @@ bool block_database::contains( const block_id_type& id )const _block_num_to_pos.seekg( index_pos ); _block_num_to_pos.read( (char*)&e, sizeof(e) ); - return e.block_id == id && e.block_size > 0; + return e.block_id == id && e.block_size.value() > 0; } block_id_type block_database::fetch_block_id( uint32_t block_num )const @@ -159,10 +164,10 @@ optional block_database::fetch_optional( const block_id_type& id ) if( e.block_id != id ) return optional(); - vector data( e.block_size ); - _blocks.seekg( e.block_pos ); - if (e.block_size) - _blocks.read( data.data(), e.block_size ); + vector data( e.block_size.value() ); + _blocks.seekg( e.block_pos.value() ); + if (e.block_size.value()) + _blocks.read( data.data(), e.block_size.value() ); auto result = fc::raw::unpack(data); FC_ASSERT( result.id() == e.block_id ); return result; @@ -189,9 +194,9 @@ optional block_database::fetch_by_number( uint32_t block_num )cons _block_num_to_pos.seekg( index_pos, _block_num_to_pos.beg ); _block_num_to_pos.read( (char*)&e, sizeof(e) ); - vector data( e.block_size ); - _blocks.seekg( e.block_pos ); - _blocks.read( data.data(), e.block_size ); + vector data( e.block_size.value() ); + _blocks.seekg( e.block_pos.value() ); + _blocks.read( data.data(), e.block_size.value() ); auto result = fc::raw::unpack(data); FC_ASSERT( result.id() == e.block_id ); return result; @@ -224,14 +229,14 @@ optional block_database::last_index_entry()const { pos -= sizeof(index_entry); _block_num_to_pos.seekg( pos ); _block_num_to_pos.read( (char*)&e, sizeof(e) ); - if( _block_num_to_pos.gcount() == sizeof(e) && e.block_size > 0 - && int64_t(e.block_pos + e.block_size) <= blocks_size ) + if( _block_num_to_pos.gcount() == sizeof(e) && e.block_size.value() > 0 + && int64_t(e.block_pos.value() + e.block_size.value()) <= blocks_size ) try { - vector data( e.block_size ); - _blocks.seekg( e.block_pos ); - _blocks.read( data.data(), e.block_size ); - if( _blocks.gcount() == long(e.block_size) ) + vector data( e.block_size.value() ); + _blocks.seekg( e.block_pos.value() ); + _blocks.read( data.data(), e.block_size.value() ); + if( _blocks.gcount() == long(e.block_size.value()) ) { const signed_block block = fc::raw::unpack(data); if( block.id() == e.block_id ) diff --git a/libraries/chain/buyback.cpp b/libraries/chain/buyback.cpp index 09341fe7ca..dfe5f09027 100644 --- a/libraries/chain/buyback.cpp +++ b/libraries/chain/buyback.cpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -#include +#include #include #include #include @@ -31,7 +31,6 @@ namespace graphene { namespace chain { void evaluate_buyback_account_options( const database& db, const buyback_account_options& bbo ) { - FC_ASSERT( db.head_block_time() >= HARDFORK_538_TIME ); const asset_object& a = bbo.asset_to_buy(db); GRAPHENE_ASSERT( a.issuer == bbo.asset_to_buy_issuer, account_create_buyback_incorrect_issuer, "Incorrect asset issuer specified in buyback_account_options", ("asset", a)("bbo", bbo) ); diff --git a/libraries/chain/committee_member_evaluator.cpp b/libraries/chain/committee_member_evaluator.cpp index e81737e161..90620fc010 100644 --- a/libraries/chain/committee_member_evaluator.cpp +++ b/libraries/chain/committee_member_evaluator.cpp @@ -26,8 +26,8 @@ #include #include #include -#include -#include +#include +#include #include namespace graphene { namespace chain { @@ -42,7 +42,7 @@ object_id_type committee_member_create_evaluator::do_apply( const committee_memb { try { vote_id_type vote_id; db().modify(db().get_global_properties(), [&vote_id](global_property_object& p) { - vote_id = get_next_vote_id(p, vote_id_type::committee); + vote_id = vote_id_type(vote_id_type::committee, p.next_available_vote_id++); }); const auto& new_del_object = db().create( [&]( committee_member_object& obj ){ diff --git a/libraries/chain/confidential_evaluator.cpp b/libraries/chain/confidential_evaluator.cpp index 9946b492d0..4be4d0e14e 100644 --- a/libraries/chain/confidential_evaluator.cpp +++ b/libraries/chain/confidential_evaluator.cpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include -#include +#include #include #include #include diff --git a/libraries/chain/db_balance.cpp b/libraries/chain/db_balance.cpp index 2a48679e3e..a75464e474 100644 --- a/libraries/chain/db_balance.cpp +++ b/libraries/chain/db_balance.cpp @@ -139,7 +139,7 @@ void database::deposit_market_fee_vesting_balance(const account_id_type &account if( vbo_it == vesting_balances.end() ) { - create([&account_id, &delta, &block_time](vesting_balance_object &vbo) { + create([&account_id, &delta](vesting_balance_object &vbo) { vbo.owner = account_id; vbo.balance = delta; vbo.balance_type = vesting_balance_type::market_fee_sharing; @@ -172,7 +172,7 @@ optional< vesting_balance_id_type > database::deposit_lazy_vesting( const vesting_balance_object& vbo = (*ovbid)(*this); if( vbo.owner != req_owner ) break; - if( vbo.policy.which() != vesting_policy::tag< cdd_vesting_policy >::value ) + if( !vbo.policy.is_type< cdd_vesting_policy >() ) break; if( vbo.policy.get< cdd_vesting_policy >().vesting_seconds != req_vesting_seconds ) break; diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index f3ebec3a1c..ace071ec0d 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -31,12 +31,14 @@ #include #include -#include +#include #include -#include #include #include +#include + +#include #include namespace graphene { namespace chain { @@ -552,6 +554,12 @@ void database::_apply_block( const signed_block& next_block ) const auto& dynamic_global_props = get_dynamic_global_properties(); bool maint_needed = (dynamic_global_props.next_maintenance_time <= next_block.timestamp); + // trx_in_block starts from 0. + // For real operations which are explicitly included in a transaction, op_in_trx starts from 0, virtual_op is 0. + // For virtual operations that are derived directly from a real operation, + // use the real operation's (block_num,trx_in_block,op_in_trx), virtual_op starts from 1. + // For virtual operations created after processed all transactions, + // trx_in_block = the_block.trsanctions.size(), op_in_trx is 0, virtual_op starts from 0. _current_block_num = next_block_num; _current_trx_in_block = 0; @@ -569,6 +577,9 @@ void database::_apply_block( const signed_block& next_block ) ++_current_trx_in_block; } + _current_op_in_trx = 0; + _current_virtual_op = 0; + const uint32_t missed = update_witness_missed_blocks( next_block ); update_global_dynamic_data( next_block, missed ); update_signing_witness(signing_witness, next_block); @@ -651,7 +662,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx const auto& tapos_block_summary = block_summary_id_type( trx.ref_block_num )(*this); //Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration - FC_ASSERT( trx.ref_block_prefix == tapos_block_summary.block_id._hash[1] ); + FC_ASSERT( trx.ref_block_prefix == tapos_block_summary.block_id._hash[1].value() ); } fc::time_point_sec now = head_block_time(); @@ -659,15 +670,16 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx FC_ASSERT( trx.expiration <= now + chain_parameters.maximum_time_until_expiration, "", ("trx.expiration",trx.expiration)("now",now)("max_til_exp",chain_parameters.maximum_time_until_expiration)); FC_ASSERT( now <= trx.expiration, "", ("now",now)("trx.exp",trx.expiration) ); - FC_ASSERT( head_block_time() <= HARDFORK_CORE_1573_TIME - || trx.get_packed_size() <= chain_parameters.maximum_transaction_size, - "Transaction exceeds maximum transaction size." ); + if ( !(skip & skip_block_size_check ) ) // don't waste time on replay + FC_ASSERT( head_block_time() <= HARDFORK_CORE_1573_TIME + || trx.get_packed_size() <= chain_parameters.maximum_transaction_size, + "Transaction exceeds maximum transaction size." ); } //Insert transaction into unique transactions database. if( !(skip & skip_transaction_dupe_check) ) { - create([&trx](transaction_object& transaction) { + create([&trx](transaction_history_object& transaction) { transaction.trx_id = trx.id(); transaction.trx = trx; }); @@ -680,6 +692,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx _current_op_in_trx = 0; for( const auto& op : ptrx.operations ) { + _current_virtual_op = 0; eval_state.operation_results.emplace_back(apply_operation(eval_state, op)); ++_current_op_in_trx; } @@ -754,7 +767,8 @@ void database::_precompute_parallel( const Trx* trx, const size_t count, const u for( size_t i = 0; i < count; ++i, ++trx ) { trx->validate(); // TODO - parallelize wrt confidential operations - trx->get_packed_size(); + if ( !(skip & skip_block_size_check) ) + trx->get_packed_size(); if( !(skip&skip_transaction_dupe_check) ) trx->id(); if( !(skip&skip_transaction_signatures) ) diff --git a/libraries/chain/db_getter.cpp b/libraries/chain/db_getter.cpp index 0de635c0e5..3a4ff98c18 100644 --- a/libraries/chain/db_getter.cpp +++ b/libraries/chain/db_getter.cpp @@ -57,7 +57,7 @@ const dynamic_global_property_object& database::get_dynamic_global_properties() const fee_schedule& database::current_fee_schedule()const { - return get_global_properties().parameters.current_fees; + return get_global_properties().parameters.get_current_fees(); } time_point_sec database::head_block_time()const diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 36e19f2ac5..3d0aaf8c04 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include @@ -64,8 +64,6 @@ #include #include -#include - #include #include @@ -112,8 +110,8 @@ const uint8_t operation_history_object::type_id; const uint8_t proposal_object::space_id; const uint8_t proposal_object::type_id; -const uint8_t transaction_object::space_id; -const uint8_t transaction_object::type_id; +const uint8_t transaction_history_object::space_id; +const uint8_t transaction_history_object::type_id; const uint8_t vesting_balance_object::space_id; const uint8_t vesting_balance_object::type_id; @@ -422,7 +420,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) p.parameters = genesis_state.initial_parameters; // Set fees to zero initially, so that genesis initialization needs not pay them // We'll fix it at the end of the function - p.parameters.current_fees->zero_all_fees(); + p.parameters.get_mutable_fees().zero_all_fees(); }); _p_dyn_global_prop_obj = & create([&genesis_state](dynamic_global_property_object& p) { @@ -692,7 +690,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) // Enable fees modify(get_global_properties(), [&genesis_state](global_property_object& p) { - p.parameters.current_fees = genesis_state.initial_parameters.current_fees; + p.parameters.get_mutable_fees() = genesis_state.initial_parameters.get_current_fees(); }); // Create witness scheduler diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index d7f5c3f5b8..7bba8beff5 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -304,14 +306,14 @@ void database::update_active_committee_members() assert( _committee_count_histogram_buffer.size() > 0 ); share_type stake_target = (_total_voting_stake-_committee_count_histogram_buffer[0]) / 2; - /// accounts that vote for 0 or 1 witness do not get to express an opinion on - /// the number of witnesses to have (they abstain and are non-voting accounts) - uint64_t stake_tally = 0; // _committee_count_histogram_buffer[0]; + /// accounts that vote for 0 or 1 committee member do not get to express an opinion on + /// the number of committee members to have (they abstain and are non-voting accounts) + share_type stake_tally = 0; size_t committee_member_count = 0; if( stake_target > 0 ) { while( (committee_member_count < _committee_count_histogram_buffer.size() - 1) - && (stake_tally <= stake_target) ) + && (stake_tally <= stake_target.value) ) { stake_tally += _committee_count_histogram_buffer[++committee_member_count]; } @@ -553,11 +555,11 @@ void visit_special_authorities( const database& db, Visitor visit ) for( const special_authority_object& sao : sa_idx ) { const account_object& acct = sao.account(db); - if( acct.owner_special_authority.which() != special_authority::tag< no_special_authority >::value ) + if( !acct.owner_special_authority.is_type< no_special_authority >() ) { visit( acct, true, acct.owner_special_authority ); } - if( acct.active_special_authority.which() != special_authority::tag< no_special_authority >::value ) + if( !acct.active_special_authority.is_type< no_special_authority >() ) { visit( acct, false, acct.active_special_authority ); } @@ -569,7 +571,7 @@ void update_top_n_authorities( database& db ) visit_special_authorities( db, [&]( const account_object& acct, bool is_owner, const special_authority& auth ) { - if( auth.which() == special_authority::tag< top_holders_special_authority >::value ) + if( auth.is_type< top_holders_special_authority >() ) { // use index to grab the top N holders of the asset and vote_counter to obtain the weights @@ -1232,11 +1234,11 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g update_active_committee_members(); update_worker_votes(); - const dynamic_global_property_object& dgpo = get_dynamic_global_properties(); - + const auto& dgpo = get_dynamic_global_properties(); + modify(gpo, [&dgpo](global_property_object& p) { // Remove scaling of account registration fee - p.parameters.current_fees->get().basic_fee >>= p.parameters.account_fee_scale_bitshifts * + p.parameters.get_mutable_fees().get().basic_fee >>= p.parameters.account_fee_scale_bitshifts * (dgpo.accounts_registered_this_interval / p.parameters.accounts_per_fee_scale); if( p.pending_parameters ) diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index d09533b92c..9ca657ef6f 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -28,7 +28,8 @@ #include #include #include -#include + +#include #include @@ -64,8 +65,7 @@ void database::reindex( fc::path data_dir ) ilog( "reindexing blockchain" ); auto start = fc::time_point::now(); const auto last_block_num = last_block->block_num(); - uint32_t flush_point = last_block_num < 10000 ? 0 : last_block_num - 10000; - uint32_t undo_point = last_block_num < 50 ? 0 : last_block_num - 50; + uint32_t undo_point = last_block_num < GRAPHENE_MAX_UNDO_HISTORY ? 0 : last_block_num - GRAPHENE_MAX_UNDO_HISTORY; ilog( "Replaying blocks, starting at ${next}...", ("next",head_block_num() + 1) ); if( head_block_num() >= undo_point ) @@ -123,17 +123,21 @@ void database::reindex( fc::path data_dir ) if( i % 10000 == 0 ) { + std::stringstream bysize; + std::stringstream bynum; + bysize << std::fixed << std::setprecision(5) << double(std::get<0>(blocks.front())) / total_block_size * 100; + bynum << std::fixed << std::setprecision(5) << double(i*100)/last_block_num; ilog( " [by size: ${size}% ${processed} of ${total}] [by num: ${num}% ${i} of ${last}]", - ("size", double(std::get<0>(blocks.front())) / total_block_size * 100) + ("size", bysize.str()) ("processed", std::get<0>(blocks.front())) ("total", total_block_size) - ("num", double(i*100)/last_block_num) + ("num", bynum.str()) ("i", i) ("last", last_block_num) ); } - if( i == flush_point ) + if( i == undo_point ) { ilog( "Writing database to disk at block ${i}", ("i",i) ); flush(); diff --git a/libraries/chain/db_market.cpp b/libraries/chain/db_market.cpp index 3d42f9abc9..c009d0b830 100644 --- a/libraries/chain/db_market.cpp +++ b/libraries/chain/db_market.cpp @@ -30,16 +30,17 @@ #include #include -#include +#include namespace graphene { namespace chain { namespace detail { - uint64_t calculate_percent(const share_type& value, uint16_t percent) + share_type calculate_percent(const share_type& value, uint16_t percent) { - fc::uint128 a(value.value); + boost::multiprecision::uint128_t a(value.value); a *= percent; a /= GRAPHENE_100_PERCENT; - return a.to_uint64(); + FC_ASSERT( a <= GRAPHENE_MAX_SHARE_SUPPLY, "overflow when calculating percent" ); + return a.convert_to(); } } //detail @@ -255,13 +256,13 @@ void database::cancel_limit_order( const limit_order_object& order, bool create_ } else { - fc::uint128 fee128( deferred_paid_fee.amount.value ); + boost::multiprecision::uint128_t fee128( deferred_paid_fee.amount.value ); fee128 *= core_cancel_fee.amount.value; // to round up fee128 += order.deferred_fee.value; fee128 -= 1; fee128 /= order.deferred_fee.value; - share_type cancel_fee_amount = fee128.to_uint64(); + share_type cancel_fee_amount = fee128.convert_to(); // cancel_fee should be positive, pay it to asset's accumulated_fees fee_asset_dyn_data = &deferred_paid_fee.asset_id(*this).dynamic_asset_data_id(*this); modify( *fee_asset_dyn_data, [&](asset_dynamic_data_object& addo) { @@ -641,25 +642,16 @@ int database::match( const limit_order_object& bid, const call_order_object& ask // TODO remove when we're sure it's always false bool before_core_hardfork_342 = ( maint_time <= HARDFORK_CORE_342_TIME ); // better rounding // TODO remove when we're sure it's always false - bool before_core_hardfork_834 = ( maint_time <= HARDFORK_CORE_834_TIME ); // target collateral ratio option if( before_core_hardfork_184 ) ilog( "match(limit,call) is called before hardfork core-184 at block #${block}", ("block",head_block_num()) ); if( before_core_hardfork_342 ) ilog( "match(limit,call) is called before hardfork core-342 at block #${block}", ("block",head_block_num()) ); - if( before_core_hardfork_834 ) - ilog( "match(limit,call) is called before hardfork core-834 at block #${block}", ("block",head_block_num()) ); bool cull_taker = false; asset usd_for_sale = bid.amount_for_sale(); - // TODO if we're sure `before_core_hardfork_834` is always false, remove the check - asset usd_to_buy = ( before_core_hardfork_834 ? - ask.get_debt() : - asset( ask.get_max_debt_to_cover( match_price, - feed_price, - maintenance_collateral_ratio, - maintenance_collateralization ), - ask.debt_type() ) ); + asset usd_to_buy = asset( ask.get_max_debt_to_cover( match_price, feed_price, + maintenance_collateral_ratio, maintenance_collateralization ), ask.debt_type() ); asset call_pays, call_receives, order_pays, order_receives; if( usd_to_buy > usd_for_sale ) @@ -1256,16 +1248,20 @@ asset database::pay_market_fees(const account_object& seller, const asset_object reward = recv_asset.amount(reward_value); FC_ASSERT( reward < issuer_fees, "Market reward should be less than issuer fees"); // cut referrer percent from reward - const auto referrer_rewards_percentage = seller.referrer_rewards_percentage; - const auto referrer_rewards_value = detail::calculate_percent(reward.amount, referrer_rewards_percentage); auto registrar_reward = reward; - - if ( referrer_rewards_value > 0 && is_authorized_asset(*this, seller.referrer(*this), recv_asset)) + if( seller.referrer != seller.registrar ) { - FC_ASSERT ( referrer_rewards_value <= reward.amount, "Referrer reward shouldn't be greater than total reward" ); - const asset referrer_reward = recv_asset.amount(referrer_rewards_value); - registrar_reward -= referrer_reward; - deposit_market_fee_vesting_balance(seller.referrer, referrer_reward); + const auto referrer_rewards_value = detail::calculate_percent( reward.amount, + seller.referrer_rewards_percentage ); + + if ( referrer_rewards_value > 0 && is_authorized_asset(*this, seller.referrer(*this), recv_asset) ) + { + FC_ASSERT ( referrer_rewards_value <= reward.amount.value, + "Referrer reward shouldn't be greater than total reward" ); + const asset referrer_reward = recv_asset.amount(referrer_rewards_value); + registrar_reward -= referrer_reward; + deposit_market_fee_vesting_balance(seller.referrer, referrer_reward); + } } deposit_market_fee_vesting_balance(seller.registrar, registrar_reward); } diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 1347026428..d17bec6821 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -1,8 +1,9 @@ #include -#include -#include -#include +#include +#include +#include + #include #include #include @@ -14,7 +15,7 @@ #include #include #include -#include +#include #include using namespace fc; @@ -264,11 +265,13 @@ struct get_impacted_account_visitor } void operator()( const htlc_redeem_operation& op ) { - _impacted.insert( op.fee_payer() ); + _impacted.insert( op.fee_payer() ); } void operator()( const htlc_redeemed_operation& op ) { _impacted.insert( op.from ); + if ( op.to != op.redeemer ) + _impacted.insert( op.to ); } void operator()( const htlc_extend_operation& op ) { @@ -300,7 +303,6 @@ void get_relevant_accounts( const object* obj, flat_set& accoun { case null_object_type: case base_object_type: - case OBJECT_TYPE_COUNT: return; case account_object_type:{ accounts.insert( obj->id ); @@ -385,9 +387,9 @@ void get_relevant_accounts( const object* obj, flat_set& accoun break; case impl_reserved0_object_type: break; - case impl_asset_dynamic_data_type: + case impl_asset_dynamic_data_object_type: break; - case impl_asset_bitasset_data_type: + case impl_asset_bitasset_data_object_type: break; case impl_account_balance_object_type:{ const auto& aobj = dynamic_cast(obj); @@ -399,8 +401,8 @@ void get_relevant_accounts( const object* obj, flat_set& accoun FC_ASSERT( aobj != nullptr ); accounts.insert( aobj->owner ); break; - } case impl_transaction_object_type:{ - const auto& aobj = dynamic_cast(obj); + } case impl_transaction_history_object_type:{ + const auto& aobj = dynamic_cast(obj); FC_ASSERT( aobj != nullptr ); transaction_get_impacted_accounts( aobj->trx, accounts ); break; diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index 48dea9fb49..cf767b5d89 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -31,11 +31,11 @@ #include #include #include -#include +#include #include #include -#include +#include #include @@ -145,7 +145,8 @@ void database::clear_expired_transactions() { try { //Look for expired transactions in the deduplication list, and remove them. //Transactions must have expired by at least two forking windows in order to be removed. - auto& transaction_idx = static_cast(get_mutable_index(implementation_ids, impl_transaction_object_type)); + auto& transaction_idx = static_cast(get_mutable_index(implementation_ids, + impl_transaction_history_object_type)); const auto& dedupe_index = transaction_idx.indices().get(); while( (!dedupe_index.empty()) && (head_block_time() > dedupe_index.begin()->trx.expiration) ) transaction_idx.remove(*dedupe_index.begin()); diff --git a/libraries/chain/evaluator.cpp b/libraries/chain/evaluator.cpp index a4127c25b6..482d9a01e0 100644 --- a/libraries/chain/evaluator.cpp +++ b/libraries/chain/evaluator.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include @@ -61,11 +61,11 @@ database& generic_evaluator::db()const { return trx_state->db(); } fee_asset = &fee.asset_id(d); fee_asset_dyn_data = &fee_asset->dynamic_asset_data_id(d); - if( d.head_block_time() > HARDFORK_419_TIME ) - { - FC_ASSERT( is_authorized_asset( d, *fee_paying_account, *fee_asset ), "Account ${acct} '${name}' attempted to pay fee by using asset ${a} '${sym}', which is unauthorized due to whitelist / blacklist", - ("acct", fee_paying_account->id)("name", fee_paying_account->name)("a", fee_asset->id)("sym", fee_asset->symbol) ); - } + FC_ASSERT( is_authorized_asset( d, *fee_paying_account, *fee_asset ), + "Account ${acct} '${name}' attempted to pay fee by using asset ${a} '${sym}', " + "which is unauthorized due to whitelist / blacklist", + ( "acct", fee_paying_account->id)("name", fee_paying_account->name)("a", fee_asset->id) + ("sym", fee_asset->symbol) ); if( fee_from_account.asset_id == asset_id_type() ) core_fee_paid = fee_from_account.amount; diff --git a/libraries/chain/exceptions.cpp b/libraries/chain/exceptions.cpp new file mode 100644 index 0000000000..68606a91f6 --- /dev/null +++ b/libraries/chain/exceptions.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019 BitShares Blockchain Foundation, 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 chain { + + // Internal exceptions + + FC_IMPLEMENT_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000, "internal exception" ) + + GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_max_auth_exceeded, 1, "Exceeds max authority fan-out" ) + GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_account_not_found, 2, "Auth account not found" ) + + + // Public exceptions + + FC_IMPLEMENT_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) + + FC_IMPLEMENT_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000, "database query exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000, "block validation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000, "operation validation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000, "operation evaluation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000, "utility method exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000, "undo database exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000, "unlinkable block" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000, "black swan" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( plugin_exception, chain_exception, 3100000, "plugin exception" ) + + FC_IMPLEMENT_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006, "insufficient feeds" ) + + FC_IMPLEMENT_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001, "there are no blocks to pop" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( to_account_not_whitelisted, transfer, 2, "owner mismatch" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( restricted_transfer_asset, transfer, 3, "restricted transfer asset" ) + + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_cancel ); + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( call_order_update ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1, "Updating call order would trigger a margin call that cannot be fully filled" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_create ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_create, 1, "Exceeds max authority fan-out" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_create, 2, "Auth account not found" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3, "Incorrect issuer specified for account" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4, "Cannot create buyback for asset which already has buyback" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_too_many_markets, account_create, 5, "Too many buyback markets" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_update ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_update, 1, "Exceeds max authority fan-out" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_update, 2, "Auth account not found" ) + + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_whitelist ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_upgrade ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_transfer ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_bitasset ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_feed_producers ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_issue ); + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_reserve ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( invalid_on_mia, asset_reserve, 1, "invalid on mia" ) + + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_fund_fee_pool ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_settle ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_global_settle ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_publish_feed ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( committee_member_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( witness_create ); + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_create ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_required, proposal_create, 1, "review_period required" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2, "review_period insufficient" ) + + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_update ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_delete ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_update ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_claim ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_delete ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( fill_order ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( global_parameters_update ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( vesting_balance_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( vesting_balance_withdraw ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( worker_create ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( custom ); + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( assert ); + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( balance_claim ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( claimed_too_often, balance_claim, 1, "balance claimed too often" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( invalid_claim_amount, balance_claim, 2, "invalid claim amount" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( owner_mismatch, balance_claim, 3, "owner mismatch" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( override_transfer ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( blind_transfer ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); + + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer_from_blind_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_claim_fees_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( bid_collateral_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_claim_pool_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_issuer_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( htlc_create_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( htlc_redeem_operation ) + //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( htlc_extend_operation ) + + #define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \ + catch( const cause_type& e ) \ + { throw( effect_type( e.what(), e.get_log() ) ); } + +} } // graphene::chain diff --git a/libraries/chain/fba_object.cpp b/libraries/chain/fba_object.cpp index 2febca45d7..0ea3ab8318 100644 --- a/libraries/chain/fba_object.cpp +++ b/libraries/chain/fba_object.cpp @@ -70,12 +70,12 @@ bool fba_accumulator_object::is_configured( const database& db )const } const account_object& issuer_acct = dasset->issuer(db); - if( issuer_acct.owner_special_authority.which() != special_authority::tag< top_holders_special_authority >::value ) + if( !issuer_acct.owner_special_authority.is_type< top_holders_special_authority >() ) { ilog( "FBA fee in block ${b} not paid because of FBA misconfiguration: designated asset issuer has not set owner top_n control", ("b", db.head_block_num()) ); return false; } - if( issuer_acct.active_special_authority.which() != special_authority::tag< top_holders_special_authority >::value ) + if( !issuer_acct.active_special_authority.is_type< top_holders_special_authority >() ) { ilog( "FBA fee in block ${b} not paid because of FBA misconfiguration: designated asset issuer has not set active top_n control", ("b", db.head_block_num()) ); return false; diff --git a/libraries/chain/genesis_state.cpp b/libraries/chain/genesis_state.cpp index 7c53c36ae3..90df17af01 100644 --- a/libraries/chain/genesis_state.cpp +++ b/libraries/chain/genesis_state.cpp @@ -23,9 +23,7 @@ */ #include - -// this is required to serialize a genesis_state -#include +#include namespace graphene { namespace chain { @@ -35,3 +33,44 @@ chain_id_type genesis_state_type::compute_chain_id() const } } } // graphene::chain + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_account_type, BOOST_PP_SEQ_NIL, + (name)(owner_key)(active_key)(is_lifetime_member) ) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type, BOOST_PP_SEQ_NIL, + (symbol)(issuer_name)(description)(precision)(max_supply)(accumulated_fees)(is_bitasset) + (collateral_records)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position, + BOOST_PP_SEQ_NIL, (owner)(collateral)(debt)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_balance_type, BOOST_PP_SEQ_NIL, + (owner)(asset_symbol)(amount)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_vesting_balance_type, BOOST_PP_SEQ_NIL, + (owner)(asset_symbol)(amount)(begin_timestamp)(vesting_duration_seconds)(begin_balance)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_witness_type, BOOST_PP_SEQ_NIL, + (owner_name)(block_signing_key)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_committee_member_type, BOOST_PP_SEQ_NIL, + (owner_name)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type::initial_worker_type, BOOST_PP_SEQ_NIL, + (owner_name)(daily_pay)) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::chain::genesis_state_type, BOOST_PP_SEQ_NIL, + (initial_timestamp)(max_core_supply)(initial_parameters)(initial_accounts)(initial_assets) + (initial_balances)(initial_vesting_balances)(initial_active_witnesses)(initial_witness_candidates) + (initial_committee_candidates)(initial_worker_candidates) + (immutable_parameters)) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_account_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_asset_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_balance_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_vesting_balance_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_witness_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_committee_member_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_worker_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type ) diff --git a/libraries/chain/get_config.cpp b/libraries/chain/get_config.cpp index b8fc7a93c7..48c781f638 100644 --- a/libraries/chain/get_config.cpp +++ b/libraries/chain/get_config.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include namespace graphene { namespace chain { @@ -69,7 +69,6 @@ fc::variant_object get_config() result[ "GRAPHENE_MAX_COLLATERAL_RATIO" ] = GRAPHENE_MAX_COLLATERAL_RATIO; result[ "GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO" ] = GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO; result[ "GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO" ] = GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO; - result[ "GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC" ] = GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC; result[ "GRAPHENE_DEFAULT_MAX_WITNESSES" ] = GRAPHENE_DEFAULT_MAX_WITNESSES; result[ "GRAPHENE_DEFAULT_MAX_COMMITTEE" ] = GRAPHENE_DEFAULT_MAX_COMMITTEE; result[ "GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC" ] = GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC; diff --git a/libraries/chain/hardfork.d/23.hf b/libraries/chain/hardfork.d/23.hf deleted file mode 100644 index a44b070590..0000000000 --- a/libraries/chain/hardfork.d/23.hf +++ /dev/null @@ -1,4 +0,0 @@ -// Issue #23: Withdrawal claims made before the first withdrawal period are incorrectly allowed -#ifndef HARDFORK_23_TIME -#define HARDFORK_23_TIME (fc::time_point_sec( 1512747600 )) -#endif diff --git a/libraries/chain/hardfork.d/357.hf b/libraries/chain/hardfork.d/357.hf deleted file mode 100644 index 650b9a7a91..0000000000 --- a/libraries/chain/hardfork.d/357.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #357 Disallow publishing certain malformed price feeds -#ifndef HARDFORK_357_TIME -#define HARDFORK_357_TIME (fc::time_point_sec( 1444416300 )) -#endif diff --git a/libraries/chain/hardfork.d/359.hf b/libraries/chain/hardfork.d/359.hf deleted file mode 100644 index c52576d0fe..0000000000 --- a/libraries/chain/hardfork.d/359.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #359 Allow digits in asset name -#ifndef HARDFORK_359_TIME -#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 )) -#endif diff --git a/libraries/chain/hardfork.d/409.hf b/libraries/chain/hardfork.d/409.hf deleted file mode 100644 index 87629140a7..0000000000 --- a/libraries/chain/hardfork.d/409.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #409 Allow creation of sub-assets -#ifndef HARDFORK_409_TIME -#define HARDFORK_409_TIME (fc::time_point_sec( 1446652800 )) -#endif diff --git a/libraries/chain/hardfork.d/413.hf b/libraries/chain/hardfork.d/413.hf deleted file mode 100644 index c0ce369017..0000000000 --- a/libraries/chain/hardfork.d/413.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #413 Add operation to claim asset fees -#ifndef HARDFORK_413_TIME -#define HARDFORK_413_TIME (fc::time_point_sec( 1446652800 )) -#endif diff --git a/libraries/chain/hardfork.d/415.hf b/libraries/chain/hardfork.d/415.hf deleted file mode 100644 index 94645270aa..0000000000 --- a/libraries/chain/hardfork.d/415.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #415 Default accept policy for asset with no whitelist authorities -#ifndef HARDFORK_415_TIME -#define HARDFORK_415_TIME (fc::time_point_sec( 1446652800 )) -#endif diff --git a/libraries/chain/hardfork.d/416.hf b/libraries/chain/hardfork.d/416.hf deleted file mode 100644 index 2c3319d133..0000000000 --- a/libraries/chain/hardfork.d/416.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #416 enforce_white_list is inconsistently applied -#ifndef HARDFORK_416_TIME -#define HARDFORK_416_TIME (fc::time_point_sec( 1446652800 )) -#endif diff --git a/libraries/chain/hardfork.d/419.hf b/libraries/chain/hardfork.d/419.hf deleted file mode 100644 index c5bbf68d07..0000000000 --- a/libraries/chain/hardfork.d/419.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #419 Account can pay fees in blacklisted asset -#ifndef HARDFORK_419_TIME -#define HARDFORK_419_TIME (fc::time_point_sec( 1446652800 )) -#endif diff --git a/libraries/chain/hardfork.d/538.hf b/libraries/chain/hardfork.d/538.hf deleted file mode 100644 index 99a27537b1..0000000000 --- a/libraries/chain/hardfork.d/538.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #538 Buyback accounts -#ifndef HARDFORK_538_TIME -#define HARDFORK_538_TIME (fc::time_point_sec( 1456250400 )) -#endif diff --git a/libraries/chain/hardfork.d/599.hf b/libraries/chain/hardfork.d/599.hf deleted file mode 100644 index 6249101d43..0000000000 --- a/libraries/chain/hardfork.d/599.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #599 Unpacking of extension is incorrect -#ifndef HARDFORK_599_TIME -#define HARDFORK_599_TIME (fc::time_point_sec( 1459789200 )) -#endif diff --git a/libraries/chain/hardfork.d/CORE_1040.hf b/libraries/chain/hardfork.d/CORE_1040.hf deleted file mode 100644 index 1689f1e793..0000000000 --- a/libraries/chain/hardfork.d/CORE_1040.hf +++ /dev/null @@ -1,4 +0,0 @@ -// bitshares-core issue #1040 Remove temp-account balance check -#ifndef HARDFORK_CORE_1040_TIME -#define HARDFORK_CORE_1040_TIME (fc::time_point_sec( 1532008920 )) // Thu, 19 Jul 2018 14:02:00 UTC -#endif diff --git a/libraries/chain/hardfork.d/CORE_188.hf b/libraries/chain/hardfork.d/CORE_188.hf deleted file mode 100644 index 8c1be5c4bc..0000000000 --- a/libraries/chain/hardfork.d/CORE_188.hf +++ /dev/null @@ -1,4 +0,0 @@ -// #188 Add operation to allow claiming of funds in an asset's fee pool -#ifndef HARDFORK_CORE_188_TIME -#define HARDFORK_CORE_188_TIME (fc::time_point_sec( 1532008920 )) // Thu, 19 Jul 2018 14:02:00 UTC -#endif diff --git a/libraries/chain/hardfork.d/CORE_620.hf b/libraries/chain/hardfork.d/CORE_620.hf deleted file mode 100644 index d322b8c934..0000000000 --- a/libraries/chain/hardfork.d/CORE_620.hf +++ /dev/null @@ -1,4 +0,0 @@ -// bitshares-core issue #620 Allow numbers at the end of asset symbol -#ifndef HARDFORK_CORE_620_TIME -#define HARDFORK_CORE_620_TIME (fc::time_point_sec( 1532008920 )) // Thu, 19 Jul 2018 14:02:00 UTC -#endif diff --git a/libraries/chain/hardfork.d/CORE_942.hf b/libraries/chain/hardfork.d/CORE_942.hf deleted file mode 100644 index 085f3cfcd3..0000000000 --- a/libraries/chain/hardfork.d/CORE_942.hf +++ /dev/null @@ -1,5 +0,0 @@ -// bitshares-core issue #942 -// Incorrectly checking asset authorization for withdraw_from_account in withdraw_permission_claim_evaluator -#ifndef HARDFORK_CORE_942_TIME -#define HARDFORK_CORE_942_TIME (fc::time_point_sec( 1532008920 )) // Thu, 19 Jul 2018 14:02:00 UTC -#endif diff --git a/libraries/chain/htlc_evaluator.cpp b/libraries/chain/htlc_evaluator.cpp index 9bd71e630b..1009a75c53 100644 --- a/libraries/chain/htlc_evaluator.cpp +++ b/libraries/chain/htlc_evaluator.cpp @@ -45,7 +45,7 @@ namespace graphene { // make sure the expiration is reasonable FC_ASSERT( o.claim_period_seconds <= htlc_options->max_timeout_secs, "HTLC Timeout exceeds allowed length" ); // make sure the preimage length is reasonable - FC_ASSERT( o.preimage_size <= htlc_options->max_preimage_size, "HTLC preimage length exceeds allowed length" ); + FC_ASSERT( o.preimage_size <= htlc_options->max_preimage_size, "HTLC preimage length exceeds allowed length" ); // make sure the sender has the funds for the HTLC FC_ASSERT( d.get_balance( o.from, o.amount.asset_id) >= (o.amount), "Insufficient funds") ; const auto& asset_to_transfer = o.amount.asset_id( d ); @@ -102,9 +102,9 @@ namespace graphene { htlc_obj = &db().get(o.htlc_id); FC_ASSERT(o.preimage.size() == htlc_obj->conditions.hash_lock.preimage_size, "Preimage size mismatch."); - const htlc_redeem_visitor vtor( o.preimage ); - FC_ASSERT( htlc_obj->conditions.hash_lock.preimage_hash.visit( vtor ), "Provided preimage does not generate correct hash."); + FC_ASSERT( htlc_obj->conditions.hash_lock.preimage_hash.visit( vtor ), + "Provided preimage does not generate correct hash."); return void_result(); } @@ -113,8 +113,8 @@ namespace graphene { { db().adjust_balance(htlc_obj->transfer.to, asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id) ); // notify related parties - htlc_redeemed_operation virt_op( htlc_obj->id, htlc_obj->transfer.from, htlc_obj->transfer.to, - asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id ) ); + htlc_redeemed_operation virt_op( htlc_obj->id, htlc_obj->transfer.from, htlc_obj->transfer.to, + o.redeemer, asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id ) ); db().push_applied_operation( virt_op ); db().remove(*htlc_obj); return void_result(); @@ -123,6 +123,14 @@ namespace graphene { void_result htlc_extend_evaluator::do_evaluate(const htlc_extend_operation& o) { htlc_obj = &db().get(o.htlc_id); + FC_ASSERT(o.update_issuer == htlc_obj->transfer.from, "HTLC may only be extended by its creator."); + optional htlc_options = get_committee_htlc_options(db()); + FC_ASSERT( htlc_obj->conditions.time_lock.expiration.sec_since_epoch() + + static_cast(o.seconds_to_add) < fc::time_point_sec::maximum().sec_since_epoch(), + "Extension would cause an invalid date"); + FC_ASSERT( htlc_obj->conditions.time_lock.expiration + o.seconds_to_add + <= db().head_block_time() + htlc_options->max_timeout_secs, + "Extension pushes contract too far into the future" ); return void_result(); } diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index cb52552eae..70aa0f78e9 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -22,12 +22,17 @@ * THE SOFTWARE. */ #pragma once -#include + +#include #include +#include + #include namespace graphene { namespace chain { class database; + class account_object; + class vesting_balance_object; /** * @class account_statistics_object @@ -252,8 +257,8 @@ namespace graphene { namespace chain { bool has_special_authority()const { - return (owner_special_authority.which() != special_authority::tag< no_special_authority >::value) - || (active_special_authority.which() != special_authority::tag< no_special_authority >::value); + return (!owner_special_authority.is_type< no_special_authority >()) + || (!active_special_authority.is_type< no_special_authority >()); } template @@ -391,7 +396,7 @@ namespace graphene { namespace chain { */ typedef generic_index account_balance_index; - struct by_name{}; + struct by_name; /** * @ingroup object_index @@ -438,33 +443,14 @@ namespace graphene { namespace chain { }} -FC_REFLECT_DERIVED( graphene::chain::account_object, - (graphene::db::object), - (membership_expiration_date)(registrar)(referrer)(lifetime_referrer) - (network_fee_percentage)(lifetime_referrer_fee_percentage)(referrer_rewards_percentage) - (name)(owner)(active)(options)(statistics)(whitelisting_accounts)(blacklisting_accounts) - (whitelisted_accounts)(blacklisted_accounts) - (cashback_vb) - (owner_special_authority)(active_special_authority) - (top_n_control_flags) - (allowed_assets) - ) - -FC_REFLECT_DERIVED( graphene::chain::account_balance_object, - (graphene::db::object), - (owner)(asset_type)(balance)(maintenance_flag) ) - -FC_REFLECT_DERIVED( graphene::chain::account_statistics_object, - (graphene::chain::object), - (owner)(name) - (most_recent_op) - (total_ops)(removed_ops) - (total_core_in_orders) - (core_in_balance) - (has_cashback_vb) - (is_voting) - (last_vote_time) - (lifetime_fees_paid) - (pending_fees)(pending_vested_fees) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_balance_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_statistics_object) + +FC_REFLECT_TYPENAME( graphene::chain::account_object ) +FC_REFLECT_TYPENAME( graphene::chain::account_balance_object ) +FC_REFLECT_TYPENAME( graphene::chain::account_statistics_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::account_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::account_balance_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::account_statistics_object ) diff --git a/libraries/chain/include/graphene/chain/assert_evaluator.hpp b/libraries/chain/include/graphene/chain/assert_evaluator.hpp index b985a8498c..e4bfdd00ad 100644 --- a/libraries/chain/include/graphene/chain/assert_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/assert_evaluator.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include +#include #include #include diff --git a/libraries/chain/include/graphene/chain/asset_evaluator.hpp b/libraries/chain/include/graphene/chain/asset_evaluator.hpp index e2573356b0..544b4b8b21 100644 --- a/libraries/chain/include/graphene/chain/asset_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/asset_evaluator.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include +#include #include #include diff --git a/libraries/chain/include/graphene/chain/asset_object.hpp b/libraries/chain/include/graphene/chain/asset_object.hpp index 38081dc40f..1a4ad3e47d 100644 --- a/libraries/chain/include/graphene/chain/asset_object.hpp +++ b/libraries/chain/include/graphene/chain/asset_object.hpp @@ -22,9 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include #include +#include + +#include /** * @defgroup prediction_market Prediction Market @@ -37,7 +39,7 @@ */ namespace graphene { namespace chain { - class account_object; + class asset_bitasset_data_object; class database; using namespace graphene::db; @@ -57,7 +59,7 @@ namespace graphene { namespace chain { { public: static const uint8_t space_id = implementation_ids; - static const uint8_t type_id = impl_asset_dynamic_data_type; + static const uint8_t type_id = impl_asset_dynamic_data_object_type; /// The number of shares currently in existence share_type current_supply; @@ -106,13 +108,13 @@ namespace graphene { namespace chain { string amount_to_string(share_type amount)const; /// Convert an asset to a textual representation, i.e. "123.45" string amount_to_string(const asset& amount)const - { FC_ASSERT(amount.asset_id == id); return amount_to_string(amount.amount); } + { FC_ASSERT(amount.asset_id == get_id()); return amount_to_string(amount.amount); } /// Convert an asset to a textual representation with symbol, i.e. "123.45 USD" string amount_to_pretty_string(share_type amount)const { return amount_to_string(amount) + " " + symbol; } /// Convert an asset to a textual representation with symbol, i.e. "123.45 USD" string amount_to_pretty_string(const asset &amount)const - { FC_ASSERT(amount.asset_id == id); return amount_to_pretty_string(amount.amount); } + { FC_ASSERT(amount.asset_id == get_id()); return amount_to_pretty_string(amount.amount); } /// Ticker symbol for this asset, i.e. "USD" string symbol; @@ -174,7 +176,7 @@ namespace graphene { namespace chain { { public: static const uint8_t space_id = implementation_ids; - static const uint8_t type_id = impl_asset_bitasset_data_type; + static const uint8_t type_id = impl_asset_bitasset_data_object_type; /// The asset this object belong to asset_id_type asset_id; @@ -299,12 +301,17 @@ namespace graphene { namespace chain { indexed_by< ordered_unique< tag, member< object, object_id_type, &object::id > >, ordered_unique< tag, member >, - ordered_non_unique< tag, member >, ordered_unique< tag, composite_key< asset_object, const_mem_fun, member< object, object_id_type, &object::id > > + >, + ordered_unique< tag, + composite_key< asset_object, + member< asset_object, account_id_type, &asset_object::issuer >, + member< object, object_id_type, &object::id > + > > > > asset_object_multi_index_type; @@ -312,30 +319,14 @@ namespace graphene { namespace chain { } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::asset_dynamic_data_object, (graphene::db::object), - (current_supply)(confidential_supply)(accumulated_fees)(fee_pool) ) - -FC_REFLECT_DERIVED( graphene::chain::asset_bitasset_data_object, (graphene::db::object), - (asset_id) - (feeds) - (current_feed) - (current_feed_publication_time) - (current_maintenance_collateralization) - (options) - (force_settled_volume) - (is_prediction_market) - (settlement_price) - (settlement_fund) - (asset_cer_updated) - (feed_cer_updated) - ) - -FC_REFLECT_DERIVED( graphene::chain::asset_object, (graphene::db::object), - (symbol) - (precision) - (issuer) - (options) - (dynamic_asset_data_id) - (bitasset_data_id) - (buyback_account) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_dynamic_data_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_bitasset_data_object) + +FC_REFLECT_TYPENAME( graphene::chain::asset_object ) +FC_REFLECT_TYPENAME( graphene::chain::asset_bitasset_data_object ) +FC_REFLECT_TYPENAME( graphene::chain::asset_dynamic_data_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::asset_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::asset_bitasset_data_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::asset_dynamic_data_object ) diff --git a/libraries/chain/include/graphene/chain/balance_evaluator.hpp b/libraries/chain/include/graphene/chain/balance_evaluator.hpp index 9458b1734b..ef1491b982 100644 --- a/libraries/chain/include/graphene/chain/balance_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/balance_evaluator.hpp @@ -23,7 +23,7 @@ */ #pragma once -#include +#include #include #include #include diff --git a/libraries/chain/include/graphene/chain/balance_object.hpp b/libraries/chain/include/graphene/chain/balance_object.hpp index 8d531d0c5a..ef385a0642 100644 --- a/libraries/chain/include/graphene/chain/balance_object.hpp +++ b/libraries/chain/include/graphene/chain/balance_object.hpp @@ -71,5 +71,8 @@ namespace graphene { namespace chain { using balance_index = generic_index; } } -FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object), - (owner)(balance)(vesting_policy)(last_claim_date) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::balance_object) + +FC_REFLECT_TYPENAME( graphene::chain::balance_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::balance_object ) diff --git a/libraries/chain/include/graphene/chain/block_database.hpp b/libraries/chain/include/graphene/chain/block_database.hpp index ccae46cf04..278ea3f447 100644 --- a/libraries/chain/include/graphene/chain/block_database.hpp +++ b/libraries/chain/include/graphene/chain/block_database.hpp @@ -23,10 +23,13 @@ */ #pragma once #include -#include +#include + +#include namespace graphene { namespace chain { struct index_entry; + using namespace graphene::protocol; class block_database { diff --git a/libraries/chain/include/graphene/chain/block_summary_object.hpp b/libraries/chain/include/graphene/chain/block_summary_object.hpp index f002c030bb..2206843c47 100644 --- a/libraries/chain/include/graphene/chain/block_summary_object.hpp +++ b/libraries/chain/include/graphene/chain/block_summary_object.hpp @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #pragma once +#include #include namespace graphene { namespace chain { @@ -47,4 +48,8 @@ namespace graphene { namespace chain { } } -FC_REFLECT_DERIVED( graphene::chain::block_summary_object, (graphene::db::object), (block_id) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::block_summary_object) + +FC_REFLECT_TYPENAME( graphene::chain::block_summary_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::block_summary_object ) diff --git a/libraries/chain/include/graphene/chain/budget_record_object.hpp b/libraries/chain/include/graphene/chain/budget_record_object.hpp index 49544793a6..3f8ec3cbcf 100644 --- a/libraries/chain/include/graphene/chain/budget_record_object.hpp +++ b/libraries/chain/include/graphene/chain/budget_record_object.hpp @@ -22,8 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include #include namespace graphene { namespace chain { @@ -54,8 +53,6 @@ struct budget_record share_type supply_delta = 0; }; -class budget_record_object; - class budget_record_object : public graphene::db::abstract_object { public: @@ -68,23 +65,10 @@ class budget_record_object : public graphene::db::abstract_object +#include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/buyback_object.hpp b/libraries/chain/include/graphene/chain/buyback_object.hpp index 79b4886b76..a17f6a9ed3 100644 --- a/libraries/chain/include/graphene/chain/buyback_object.hpp +++ b/libraries/chain/include/graphene/chain/buyback_object.hpp @@ -23,8 +23,7 @@ */ #pragma once -#include -#include +#include #include namespace graphene { namespace chain { @@ -64,4 +63,8 @@ typedef generic_index< buyback_object, buyback_multi_index_type > buyback_index; } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::buyback_object, (graphene::db::object), (asset_to_buy) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::buyback_object) + +FC_REFLECT_TYPENAME( graphene::chain::buyback_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::buyback_object ) diff --git a/libraries/chain/include/graphene/chain/chain_property_object.hpp b/libraries/chain/include/graphene/chain/chain_property_object.hpp index 3d2c82a68c..86dba6b8fd 100644 --- a/libraries/chain/include/graphene/chain/chain_property_object.hpp +++ b/libraries/chain/include/graphene/chain/chain_property_object.hpp @@ -27,8 +27,6 @@ namespace graphene { namespace chain { -class chain_property_object; - /** * Contains invariants which are set at genesis and never changed. */ @@ -44,7 +42,8 @@ class chain_property_object : public abstract_object } } -FC_REFLECT_DERIVED( graphene::chain::chain_property_object, (graphene::db::object), - (chain_id) - (immutable_parameters) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::chain_property_object) + +FC_REFLECT_TYPENAME( graphene::chain::chain_property_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::chain_property_object ) diff --git a/libraries/chain/include/graphene/chain/committee_member_object.hpp b/libraries/chain/include/graphene/chain/committee_member_object.hpp index 7b0d8e7547..8812222fc0 100644 --- a/libraries/chain/include/graphene/chain/committee_member_object.hpp +++ b/libraries/chain/include/graphene/chain/committee_member_object.hpp @@ -22,15 +22,13 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include #include +#include namespace graphene { namespace chain { using namespace graphene::db; - class account_object; - /** * @brief tracks information about a committee_member account. * @ingroup object @@ -73,5 +71,8 @@ namespace graphene { namespace chain { using committee_member_index = generic_index; } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::committee_member_object, (graphene::db::object), - (committee_member_account)(vote_id)(total_votes)(url) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::committee_member_object) + +FC_REFLECT_TYPENAME( graphene::chain::committee_member_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::committee_member_object ) diff --git a/libraries/chain/include/graphene/chain/confidential_evaluator.hpp b/libraries/chain/include/graphene/chain/confidential_evaluator.hpp index bc877faf3d..136519c739 100644 --- a/libraries/chain/include/graphene/chain/confidential_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/confidential_evaluator.hpp @@ -23,13 +23,10 @@ */ #pragma once #include +#include namespace graphene { namespace chain { -struct transfer_to_blind_operation; -struct transfer_from_blind_operation; -struct blind_transfer_operation; - class transfer_to_blind_evaluator : public evaluator { public: diff --git a/libraries/chain/include/graphene/chain/confidential_object.hpp b/libraries/chain/include/graphene/chain/confidential_object.hpp index f98e20a9a7..9c8fba2150 100644 --- a/libraries/chain/include/graphene/chain/confidential_object.hpp +++ b/libraries/chain/include/graphene/chain/confidential_object.hpp @@ -23,10 +23,9 @@ */ #pragma once -#include -#include +#include +#include -#include #include #include @@ -50,8 +49,6 @@ class blinded_balance_object : public graphene::db::abstract_object #define GRAPHENE_MIN_UNDO_HISTORY 10 #define GRAPHENE_MAX_UNDO_HISTORY 10000 -#define GRAPHENE_MIN_BLOCK_SIZE_LIMIT (GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT*5) // 5 transactions per block -#define GRAPHENE_BLOCKCHAIN_PRECISION uint64_t( 100000 ) - -#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS 5 -/** percentage fields are fixed point with a denominator of 10,000 */ -#define GRAPHENE_100_PERCENT 10000 -#define GRAPHENE_1_PERCENT (GRAPHENE_100_PERCENT/100) -/** NOTE: making this a power of 2 (say 2^15) would greatly accelerate fee calcs */ -#define GRAPHENE_MAX_MARKET_FEE_PERCENT GRAPHENE_100_PERCENT -#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_DELAY (60*60*24) ///< 1 day -#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_OFFSET 0 ///< 1% -#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_MAX_VOLUME (20* GRAPHENE_1_PERCENT) ///< 20% -#define GRAPHENE_DEFAULT_PRICE_FEED_LIFETIME (60*60*24) ///< 1 day -#define GRAPHENE_DEFAULT_MAX_AUTHORITY_MEMBERSHIP 10 -#define GRAPHENE_DEFAULT_MAX_ASSET_WHITELIST_AUTHORITIES 10 -#define GRAPHENE_DEFAULT_MAX_ASSET_FEED_PUBLISHERS 10 - -/** - * These ratios are fixed point numbers with a denominator of GRAPHENE_COLLATERAL_RATIO_DENOM, the - * minimum maitenance collateral is therefore 1.001x and the default - * maintenance ratio is 1.75x - */ -///@{ -#define GRAPHENE_COLLATERAL_RATIO_DENOM 1000 -#define GRAPHENE_MIN_COLLATERAL_RATIO 1001 ///< lower than this could result in divide by 0 -#define GRAPHENE_MAX_COLLATERAL_RATIO 32000 ///< higher than this is unnecessary and may exceed int16 storage -#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO 1750 ///< Call when collateral only pays off 175% the debt -#define GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO 1500 ///< Stop calling when collateral only pays off 150% of the debt -///@} -#define GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC (30*60*60*24) - -#define GRAPHENE_DEFAULT_MIN_WITNESS_COUNT (11) -#define GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT (11) -#define GRAPHENE_DEFAULT_MAX_WITNESSES (1001) // SHOULD BE ODD -#define GRAPHENE_DEFAULT_MAX_COMMITTEE (1001) // SHOULD BE ODD -#define GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC (60*60*24*7*4) // Four weeks -#define GRAPHENE_DEFAULT_COMMITTEE_PROPOSAL_REVIEW_PERIOD_SEC (60*60*24*7*2) // Two weeks -#define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT) -#define GRAPHENE_DEFAULT_LIFETIME_REFERRER_PERCENT_OF_FEE (30*GRAPHENE_1_PERCENT) -#define GRAPHENE_DEFAULT_CASHBACK_VESTING_PERIOD_SEC (60*60*24*365) ///< 1 year -#define GRAPHENE_DEFAULT_CASHBACK_VESTING_THRESHOLD (GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(100)) -#define GRAPHENE_DEFAULT_BURN_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT) -#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1 -#define GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD GRAPHENE_BLOCKCHAIN_PRECISION * 100; -#define GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE 1000 -#define GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS 4 -#define GRAPHENE_DEFAULT_MAX_BUYBACK_MARKETS 4 - -#define GRAPHENE_MAX_WORKER_NAME_LENGTH 63 - -#define GRAPHENE_MAX_URL_LENGTH 127 - - -/** - * every second, the fraction of burned core asset which cycles is - * GRAPHENE_CORE_ASSET_CYCLE_RATE / (1 << GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS) - */ -#define GRAPHENE_CORE_ASSET_CYCLE_RATE 17 -#define GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS 32 - -#define GRAPHENE_DEFAULT_WITNESS_PAY_PER_BLOCK (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t( 10) ) -#define GRAPHENE_DEFAULT_WITNESS_PAY_VESTING_SECONDS (60*60*24) -#define GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(500) * 1000 ) +#define GRAPHENE_MAX_NESTED_OBJECTS (200) -#define GRAPHENE_DEFAULT_MINIMUM_FEEDS 7 +#define GRAPHENE_CURRENT_DB_VERSION "20190503" #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 -#define GRAPHENE_CURRENT_DB_VERSION "20190323" - -#define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT) - -/** - * Reserved Account IDs with special meaning - */ -///@{ -/// Represents the current committee members, two-week review period -#define GRAPHENE_COMMITTEE_ACCOUNT (graphene::chain::account_id_type(0)) -/// Represents the current witnesses -#define GRAPHENE_WITNESS_ACCOUNT (graphene::chain::account_id_type(1)) -/// Represents the current committee members -#define GRAPHENE_RELAXED_COMMITTEE_ACCOUNT (graphene::chain::account_id_type(2)) -/// Represents the canonical account with NO authority (nobody can access funds in null account) -#define GRAPHENE_NULL_ACCOUNT (graphene::chain::account_id_type(3)) -/// Represents the canonical account with WILDCARD authority (anybody can access funds in temp account) -#define GRAPHENE_TEMP_ACCOUNT (graphene::chain::account_id_type(4)) -/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy) -#define GRAPHENE_PROXY_TO_SELF_ACCOUNT (graphene::chain::account_id_type(5)) -/// Sentinel value used in the scheduler. -#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0)) -///@} - -#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743)) - -#define GRAPHENE_MAX_NESTED_OBJECTS (200) diff --git a/libraries/chain/include/graphene/chain/custom_evaluator.hpp b/libraries/chain/include/graphene/chain/custom_evaluator.hpp index 968f6e4857..f9efe76edb 100644 --- a/libraries/chain/include/graphene/chain/custom_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/custom_evaluator.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include +#include #include #include diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 437c50d8dd..395818389b 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -22,6 +22,9 @@ * THE SOFTWARE. */ #pragma once + +#include + #include #include #include @@ -45,6 +48,15 @@ namespace graphene { namespace chain { using graphene::db::object; class op_evaluator; class transaction_evaluation_state; + class proposal_object; + class operation_history_object; + class chain_property_object; + class witness_schedule_object; + class witness_object; + class force_settlement_object; + class limit_order_object; + class collateral_bid_object; + class call_order_object; struct budget_record; enum class vesting_balance_type; @@ -553,7 +565,7 @@ namespace graphene { namespace chain { uint32_t _current_block_num = 0; uint16_t _current_trx_in_block = 0; uint16_t _current_op_in_trx = 0; - uint16_t _current_virtual_op = 0; + uint32_t _current_virtual_op = 0; vector _vote_tally_buffer; vector _witness_count_histogram_buffer; diff --git a/libraries/chain/include/graphene/chain/evaluator.hpp b/libraries/chain/include/graphene/chain/evaluator.hpp index 786fea1b2b..8fb356916d 100644 --- a/libraries/chain/include/graphene/chain/evaluator.hpp +++ b/libraries/chain/include/graphene/chain/evaluator.hpp @@ -24,14 +24,17 @@ #pragma once #include #include -#include +#include namespace graphene { namespace chain { class database; - struct signed_transaction; class generic_evaluator; class transaction_evaluation_state; + class account_object; + class account_statistics_object; + class asset_object; + class asset_dynamic_data_object; class generic_evaluator { diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index 14931bc196..0aa9b3db4a 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -24,23 +24,31 @@ #pragma once #include -#include - -#define GRAPHENE_ASSERT( expr, exc_type, FORMAT, ... ) \ - FC_MULTILINE_MACRO_BEGIN \ - if( !(expr) ) \ - FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \ - FC_MULTILINE_MACRO_END - +#include +#include +#include +#include #define GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \ FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _validate_exception, \ + graphene::chain::operation_validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value \ + ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _evaluate_exception, \ + graphene::chain::operation_evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value \ + ) + +#define GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( op_name ) \ + FC_IMPLEMENT_DERIVED_EXCEPTION( \ op_name ## _validate_exception, \ graphene::chain::operation_validate_exception, \ 3040000 + 100 * operation::tag< op_name ## _operation >::value, \ #op_name "_operation validation exception" \ ) \ - FC_DECLARE_DERIVED_EXCEPTION( \ + FC_IMPLEMENT_DERIVED_EXCEPTION( \ op_name ## _evaluate_exception, \ graphene::chain::operation_evaluate_exception, \ 3050000 + 100 * operation::tag< op_name ## _operation >::value, \ @@ -49,6 +57,14 @@ #define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + graphene::chain::op_name ## _validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum \ + ) + +#define GRAPHENE_IMPLEMENT_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_IMPLEMENT_DERIVED_EXCEPTION( \ op_name ## _ ## exc_name, \ graphene::chain::op_name ## _validate_exception, \ 3040000 + 100 * operation::tag< op_name ## _operation >::value \ @@ -58,6 +74,14 @@ #define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + graphene::chain::op_name ## _evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum \ + ) + +#define GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_IMPLEMENT_DERIVED_EXCEPTION( \ op_name ## _ ## exc_name, \ graphene::chain::op_name ## _evaluate_exception, \ 3050000 + 100 * operation::tag< op_name ## _operation >::value \ @@ -82,30 +106,21 @@ namespace graphene { namespace chain { - FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) - FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, graphene::chain::chain_exception, 3010000, "database query exception" ) - FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, graphene::chain::chain_exception, 3020000, "block validation exception" ) - FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, graphene::chain::chain_exception, 3030000, "transaction validation exception" ) - FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, graphene::chain::chain_exception, 3040000, "operation validation exception" ) - FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, graphene::chain::chain_exception, 3050000, "operation evaluation exception" ) - FC_DECLARE_DERIVED_EXCEPTION( utility_exception, graphene::chain::chain_exception, 3060000, "utility method exception" ) - FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, graphene::chain::chain_exception, 3070000, "undo database exception" ) - FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, graphene::chain::chain_exception, 3080000, "unlinkable block" ) - FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, graphene::chain::chain_exception, 3090000, "black swan" ) - FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, graphene::chain::chain_exception, 3100000, "plugin exception" ) + FC_DECLARE_EXCEPTION( chain_exception, 3000000 ) - FC_DECLARE_DERIVED_EXCEPTION( tx_missing_active_auth, graphene::chain::transaction_exception, 3030001, "missing required active authority" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_missing_owner_auth, graphene::chain::transaction_exception, 3030002, "missing required owner authority" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_missing_other_auth, graphene::chain::transaction_exception, 3030003, "missing required other authority" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_irrelevant_sig, graphene::chain::transaction_exception, 3030004, "irrelevant signature included" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_duplicate_sig, graphene::chain::transaction_exception, 3030005, "duplicate signature included" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_approval, graphene::chain::transaction_exception, 3030006, "committee account cannot directly approve transaction" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::transaction_exception, 3030007, "insufficient fee" ) + FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000 ) + FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000 ) + FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000 ) + FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000 ) + FC_DECLARE_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000 ) + FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000 ) + FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000 ) + FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000 ) + FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, chain_exception, 3100000 ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::utility_exception, 3060001, "invalid pts address" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::chain_exception, 37006, "insufficient feeds" ) + FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006 ) - FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, graphene::chain::undo_database_exception, 3070001, "there are no blocks to pop" ) + FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer ); GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" ) @@ -176,93 +191,14 @@ namespace graphene { namespace chain { GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( blind_transfer ); GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); - /* - FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" ) - FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" ) - FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" ) - FC_DECLARE_DERIVED_EXCEPTION( unsupported_chain_operation, graphene::chain::chain_exception, 30005, "unsupported chain operation" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_transaction, graphene::chain::chain_exception, 30006, "unknown transaction" ) - FC_DECLARE_DERIVED_EXCEPTION( duplicate_transaction, graphene::chain::chain_exception, 30007, "duplicate transaction" ) - FC_DECLARE_DERIVED_EXCEPTION( zero_amount, graphene::chain::chain_exception, 30008, "zero amount" ) - FC_DECLARE_DERIVED_EXCEPTION( zero_price, graphene::chain::chain_exception, 30009, "zero price" ) - FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_self, graphene::chain::chain_exception, 30010, "asset divide by self" ) - FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_zero, graphene::chain::chain_exception, 30011, "asset divide by zero" ) - FC_DECLARE_DERIVED_EXCEPTION( new_database_version, graphene::chain::chain_exception, 30012, "new database version" ) - FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block, graphene::chain::chain_exception, 30013, "unlinkable block" ) - FC_DECLARE_DERIVED_EXCEPTION( price_out_of_range, graphene::chain::chain_exception, 30014, "price out of range" ) - - FC_DECLARE_DERIVED_EXCEPTION( block_numbers_not_sequential, graphene::chain::chain_exception, 30015, "block numbers not sequential" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_previous_block_id, graphene::chain::chain_exception, 30016, "invalid previous block" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_block_time, graphene::chain::chain_exception, 30017, "invalid block time" ) - FC_DECLARE_DERIVED_EXCEPTION( time_in_past, graphene::chain::chain_exception, 30018, "time is in the past" ) - FC_DECLARE_DERIVED_EXCEPTION( time_in_future, graphene::chain::chain_exception, 30019, "time is in the future" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_block_digest, graphene::chain::chain_exception, 30020, "invalid block digest" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_member_signee, graphene::chain::chain_exception, 30021, "invalid committee_member signee" ) - FC_DECLARE_DERIVED_EXCEPTION( failed_checkpoint_verification, graphene::chain::chain_exception, 30022, "failed checkpoint verification" ) - FC_DECLARE_DERIVED_EXCEPTION( wrong_chain_id, graphene::chain::chain_exception, 30023, "wrong chain id" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_block, graphene::chain::chain_exception, 30024, "unknown block" ) - FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::chain::chain_exception, 30025, "block is older than our undo history allows us to process" ) - - FC_DECLARE_EXCEPTION( evaluation_error, 31000, "Evaluation Error" ) - FC_DECLARE_DERIVED_EXCEPTION( negative_deposit, graphene::chain::evaluation_error, 31001, "negative deposit" ) - FC_DECLARE_DERIVED_EXCEPTION( not_a_committee_member, graphene::chain::evaluation_error, 31002, "not a committee_member" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_balance_record, graphene::chain::evaluation_error, 31003, "unknown balance record" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_funds, graphene::chain::evaluation_error, 31004, "insufficient funds" ) - FC_DECLARE_DERIVED_EXCEPTION( missing_signature, graphene::chain::evaluation_error, 31005, "missing signature" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_password, graphene::chain::evaluation_error, 31006, "invalid claim password" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_withdraw_condition, graphene::chain::evaluation_error, 31007, "invalid withdraw condition" ) - FC_DECLARE_DERIVED_EXCEPTION( negative_withdraw, graphene::chain::evaluation_error, 31008, "negative withdraw" ) - FC_DECLARE_DERIVED_EXCEPTION( not_an_active_committee_member, graphene::chain::evaluation_error, 31009, "not an active committee_member" ) - FC_DECLARE_DERIVED_EXCEPTION( expired_transaction, graphene::chain::evaluation_error, 31010, "expired transaction" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_transaction_expiration, graphene::chain::evaluation_error, 31011, "invalid transaction expiration" ) - FC_DECLARE_DERIVED_EXCEPTION( oversized_transaction, graphene::chain::evaluation_error, 31012, "transaction exceeded the maximum transaction size" ) - - FC_DECLARE_DERIVED_EXCEPTION( invalid_account_name, graphene::chain::evaluation_error, 32001, "invalid account name" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_account_id, graphene::chain::evaluation_error, 32002, "unknown account id" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_account_name, graphene::chain::evaluation_error, 32003, "unknown account name" ) - FC_DECLARE_DERIVED_EXCEPTION( missing_parent_account_signature, graphene::chain::evaluation_error, 32004, "missing parent account signature" ) - FC_DECLARE_DERIVED_EXCEPTION( parent_account_retracted, graphene::chain::evaluation_error, 32005, "parent account retracted" ) - FC_DECLARE_DERIVED_EXCEPTION( account_expired, graphene::chain::evaluation_error, 32006, "account expired" ) - FC_DECLARE_DERIVED_EXCEPTION( account_already_registered, graphene::chain::evaluation_error, 32007, "account already registered" ) - FC_DECLARE_DERIVED_EXCEPTION( account_key_in_use, graphene::chain::evaluation_error, 32008, "account key already in use" ) - FC_DECLARE_DERIVED_EXCEPTION( account_retracted, graphene::chain::evaluation_error, 32009, "account retracted" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_parent_account_name, graphene::chain::evaluation_error, 32010, "unknown parent account name" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_committee_member_slate, graphene::chain::evaluation_error, 32011, "unknown committee_member slate" ) - FC_DECLARE_DERIVED_EXCEPTION( too_may_committee_members_in_slate, graphene::chain::evaluation_error, 32012, "too many committee_members in slate" ) - FC_DECLARE_DERIVED_EXCEPTION( pay_balance_remaining, graphene::chain::evaluation_error, 32013, "pay balance remaining" ) - - FC_DECLARE_DERIVED_EXCEPTION( not_a_committee_member_signature, graphene::chain::evaluation_error, 33002, "not committee_members signature" ) - - FC_DECLARE_DERIVED_EXCEPTION( invalid_precision, graphene::chain::evaluation_error, 35001, "invalid precision" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_symbol, graphene::chain::evaluation_error, 35002, "invalid asset symbol" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_id, graphene::chain::evaluation_error, 35003, "unknown asset id" ) - FC_DECLARE_DERIVED_EXCEPTION( asset_symbol_in_use, graphene::chain::evaluation_error, 35004, "asset symbol in use" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_amount, graphene::chain::evaluation_error, 35005, "invalid asset amount" ) - FC_DECLARE_DERIVED_EXCEPTION( negative_issue, graphene::chain::evaluation_error, 35006, "negative issue" ) - FC_DECLARE_DERIVED_EXCEPTION( over_issue, graphene::chain::evaluation_error, 35007, "over issue" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_symbol, graphene::chain::evaluation_error, 35008, "unknown asset symbol" ) - FC_DECLARE_DERIVED_EXCEPTION( asset_id_in_use, graphene::chain::evaluation_error, 35009, "asset id in use" ) - FC_DECLARE_DERIVED_EXCEPTION( not_user_issued, graphene::chain::evaluation_error, 35010, "not user issued" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_name, graphene::chain::evaluation_error, 35011, "invalid asset name" ) - - FC_DECLARE_DERIVED_EXCEPTION( committee_member_vote_limit, graphene::chain::evaluation_error, 36001, "committee_member_vote_limit" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::evaluation_error, 36002, "insufficient fee" ) - FC_DECLARE_DERIVED_EXCEPTION( negative_fee, graphene::chain::evaluation_error, 36003, "negative fee" ) - FC_DECLARE_DERIVED_EXCEPTION( missing_deposit, graphene::chain::evaluation_error, 36004, "missing deposit" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::chain::evaluation_error, 36005, "insufficient relay fee" ) - - FC_DECLARE_DERIVED_EXCEPTION( invalid_market, graphene::chain::evaluation_error, 37001, "invalid market" ) - FC_DECLARE_DERIVED_EXCEPTION( unknown_market_order, graphene::chain::evaluation_error, 37002, "unknown market order" ) - FC_DECLARE_DERIVED_EXCEPTION( shorting_base_shares, graphene::chain::evaluation_error, 37003, "shorting base shares" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_collateral, graphene::chain::evaluation_error, 37004, "insufficient collateral" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_depth, graphene::chain::evaluation_error, 37005, "insufficient depth" ) - FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::evaluation_error, 37006, "insufficient feeds" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_feed_price, graphene::chain::evaluation_error, 37007, "invalid feed price" ) - - FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_overflow, graphene::chain::evaluation_error, 38001, "price multiplication overflow" ) - FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_underflow, graphene::chain::evaluation_error, 38002, "price multiplication underflow" ) - FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" ) - */ + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer_from_blind_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_fees_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( bid_collateral_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_pool_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_update_issuer_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( htlc_create_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( htlc_redeem_operation ) + //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( htlc_extend_operation ) #define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \ catch( const cause_type& e ) \ diff --git a/libraries/chain/include/graphene/chain/fba_accumulator_id.hpp b/libraries/chain/include/graphene/chain/fba_accumulator_id.hpp index 9bc0cf230e..f0eefdbe66 100644 --- a/libraries/chain/include/graphene/chain/fba_accumulator_id.hpp +++ b/libraries/chain/include/graphene/chain/fba_accumulator_id.hpp @@ -23,7 +23,7 @@ */ #pragma once -#include +#include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/fba_object.hpp b/libraries/chain/include/graphene/chain/fba_object.hpp index aec9e9cd86..5558b92a62 100644 --- a/libraries/chain/include/graphene/chain/fba_object.hpp +++ b/libraries/chain/include/graphene/chain/fba_object.hpp @@ -23,8 +23,7 @@ */ #pragma once -#include -#include +#include #include namespace graphene { namespace chain { @@ -49,4 +48,8 @@ class fba_accumulator_object : public graphene::db::abstract_object< fba_accumul } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::fba_accumulator_object, (graphene::db::object), (accumulated_fba_fees)(designated_asset) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::fba_accumulator_object) + +FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::fba_accumulator_object ) diff --git a/libraries/chain/include/graphene/chain/fork_database.hpp b/libraries/chain/include/graphene/chain/fork_database.hpp index 363a21f2ce..f5214a8859 100644 --- a/libraries/chain/include/graphene/chain/fork_database.hpp +++ b/libraries/chain/include/graphene/chain/fork_database.hpp @@ -22,7 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include +#include + +#include #include #include diff --git a/libraries/chain/include/graphene/chain/genesis_state.hpp b/libraries/chain/include/graphene/chain/genesis_state.hpp index df87d1797e..98538e824e 100644 --- a/libraries/chain/include/graphene/chain/genesis_state.hpp +++ b/libraries/chain/include/graphene/chain/genesis_state.hpp @@ -23,8 +23,9 @@ */ #pragma once -#include -#include +#include +#include +#include #include #include @@ -127,29 +128,22 @@ struct genesis_state_type { } } // namespace graphene::chain -FC_REFLECT(graphene::chain::genesis_state_type::initial_account_type, (name)(owner_key)(active_key)(is_lifetime_member)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_asset_type, - (symbol)(issuer_name)(description)(precision)(max_supply)(accumulated_fees)(is_bitasset)(collateral_records)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position, - (owner)(collateral)(debt)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_balance_type, - (owner)(asset_symbol)(amount)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_vesting_balance_type, - (owner)(asset_symbol)(amount)(begin_timestamp)(vesting_duration_seconds)(begin_balance)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_witness_type, (owner_name)(block_signing_key)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_committee_member_type, (owner_name)) - -FC_REFLECT(graphene::chain::genesis_state_type::initial_worker_type, (owner_name)(daily_pay)) - -FC_REFLECT(graphene::chain::genesis_state_type, - (initial_timestamp)(max_core_supply)(initial_parameters)(initial_accounts)(initial_assets)(initial_balances) - (initial_vesting_balances)(initial_active_witnesses)(initial_witness_candidates) - (initial_committee_candidates)(initial_worker_candidates) - (initial_chain_id) - (immutable_parameters)) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_account_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_asset_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_balance_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_vesting_balance_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_witness_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_committee_member_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type::initial_worker_type ) +FC_REFLECT_TYPENAME( graphene::chain::genesis_state_type ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_account_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_asset_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_asset_type::initial_collateral_position ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_balance_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_vesting_balance_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_witness_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_committee_member_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type::initial_worker_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::genesis_state_type ) diff --git a/libraries/chain/include/graphene/chain/global_property_object.hpp b/libraries/chain/include/graphene/chain/global_property_object.hpp index 2c5a1f1272..9141118bd2 100644 --- a/libraries/chain/include/graphene/chain/global_property_object.hpp +++ b/libraries/chain/include/graphene/chain/global_property_object.hpp @@ -22,13 +22,13 @@ * THE SOFTWARE. */ #pragma once -#include -#include -#include -#include +#include +#include #include +#include + namespace graphene { namespace chain { /** @@ -124,26 +124,11 @@ namespace graphene { namespace chain { }; }} -FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object), - (head_block_number) - (head_block_id) - (time) - (current_witness) - (next_maintenance_time) - (last_budget_time) - (witness_budget) - (accounts_registered_this_interval) - (recently_missed_count) - (current_aslot) - (recent_slots_filled) - (dynamic_flags) - (last_irreversible_block_num) - ) - -FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::object), - (parameters) - (pending_parameters) - (next_available_vote_id) - (active_committee_members) - (active_witnesses) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::dynamic_global_property_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::global_property_object) + +FC_REFLECT_TYPENAME( graphene::chain::dynamic_global_property_object ) +FC_REFLECT_TYPENAME( graphene::chain::global_property_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::dynamic_global_property_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::global_property_object ) diff --git a/libraries/chain/include/graphene/chain/htlc_evaluator.hpp b/libraries/chain/include/graphene/chain/htlc_evaluator.hpp index 08a24b2bdc..dfd3c39fad 100644 --- a/libraries/chain/include/graphene/chain/htlc_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/htlc_evaluator.hpp @@ -23,6 +23,7 @@ */ #pragma once #include +#include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/htlc_object.hpp b/libraries/chain/include/graphene/chain/htlc_object.hpp index 5d41eda392..6679c6b636 100644 --- a/libraries/chain/include/graphene/chain/htlc_object.hpp +++ b/libraries/chain/include/graphene/chain/htlc_object.hpp @@ -23,15 +23,13 @@ */ #pragma once -#include -#include -#include -#include -#include -#include +#include #include +#include + namespace graphene { namespace chain { + using namespace protocol; /** * @brief database object to store HTLCs @@ -77,10 +75,18 @@ namespace graphene { namespace chain { const result_type& operator()(const htlc_object& o)const { return o.transfer.from; } }; + /***** + * Index helper for to + */ + struct to_extractor { + typedef account_id_type result_type; + const result_type& operator()(const htlc_object& o)const { return o.transfer.to; } + }; }; struct by_from_id; struct by_expiration; + struct by_to_id; typedef multi_index_container< htlc_object, indexed_by< @@ -94,8 +100,13 @@ namespace graphene { namespace chain { ordered_unique< tag< by_from_id >, composite_key< htlc_object, htlc_object::from_extractor, + member< object, object_id_type, &object::id > > >, + + ordered_unique< tag< by_to_id >, + composite_key< htlc_object, + htlc_object::to_extractor, member< object, object_id_type, &object::id > > > - > + > > htlc_object_index_type; @@ -103,13 +114,11 @@ namespace graphene { namespace chain { } } // namespace graphene::chain -FC_REFLECT( graphene::chain::htlc_object::transfer_info, - (from) (to) (amount) (asset_id) ) -FC_REFLECT( graphene::chain::htlc_object::condition_info::hash_lock_info, - (preimage_hash) (preimage_size) ) -FC_REFLECT( graphene::chain::htlc_object::condition_info::time_lock_info, - (expiration) ) -FC_REFLECT( graphene::chain::htlc_object::condition_info, - (hash_lock)(time_lock) ) -FC_REFLECT_DERIVED( graphene::chain::htlc_object, (graphene::db::object), - (transfer) (conditions) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::htlc_object) + +FC_REFLECT_TYPENAME( graphene::chain::htlc_object::condition_info::hash_lock_info ) +FC_REFLECT_TYPENAME( graphene::chain::htlc_object::condition_info::time_lock_info ) +FC_REFLECT_TYPENAME( graphene::chain::htlc_object::condition_info ) +FC_REFLECT_TYPENAME( graphene::chain::htlc_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::htlc_object ) diff --git a/libraries/chain/include/graphene/chain/immutable_chain_parameters.hpp b/libraries/chain/include/graphene/chain/immutable_chain_parameters.hpp index 0082383c99..aeaca7f8a0 100644 --- a/libraries/chain/include/graphene/chain/immutable_chain_parameters.hpp +++ b/libraries/chain/include/graphene/chain/immutable_chain_parameters.hpp @@ -23,11 +23,8 @@ */ #pragma once -#include - -#include - #include +#include namespace graphene { namespace chain { @@ -41,9 +38,6 @@ struct immutable_chain_parameters } } // graphene::chain -FC_REFLECT( graphene::chain::immutable_chain_parameters, - (min_committee_member_count) - (min_witness_count) - (num_special_accounts) - (num_special_assets) -) +FC_REFLECT_TYPENAME( graphene::chain::immutable_chain_parameters ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::immutable_chain_parameters ) diff --git a/libraries/chain/include/graphene/chain/impacted.hpp b/libraries/chain/include/graphene/chain/impacted.hpp index 2a22cbd123..9d986cb8ab 100644 --- a/libraries/chain/include/graphene/chain/impacted.hpp +++ b/libraries/chain/include/graphene/chain/impacted.hpp @@ -24,9 +24,9 @@ #pragma once #include -#include -#include -#include +#include +#include +#include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/internal_exceptions.hpp b/libraries/chain/include/graphene/chain/internal_exceptions.hpp index 8a57ae23ce..4381c6de68 100644 --- a/libraries/chain/include/graphene/chain/internal_exceptions.hpp +++ b/libraries/chain/include/graphene/chain/internal_exceptions.hpp @@ -23,11 +23,17 @@ */ #pragma once -#include #include #define GRAPHENE_DECLARE_INTERNAL_EXCEPTION( exc_name, seqnum, msg ) \ FC_DECLARE_DERIVED_EXCEPTION( \ + internal_ ## exc_name, \ + graphene::chain::internal_exception, \ + 3990000 + seqnum \ + ) + +#define GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( exc_name, seqnum, msg ) \ + FC_IMPLEMENT_DERIVED_EXCEPTION( \ internal_ ## exc_name, \ graphene::chain::internal_exception, \ 3990000 + seqnum, \ @@ -36,7 +42,7 @@ namespace graphene { namespace chain { -FC_DECLARE_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000, "internal exception" ) +FC_DECLARE_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000 ) GRAPHENE_DECLARE_INTERNAL_EXCEPTION( verify_auth_max_auth_exceeded, 1, "Exceeds max authority fan-out" ) GRAPHENE_DECLARE_INTERNAL_EXCEPTION( verify_auth_account_not_found, 2, "Auth account not found" ) diff --git a/libraries/chain/include/graphene/chain/market_evaluator.hpp b/libraries/chain/include/graphene/chain/market_evaluator.hpp index af66323578..60a37e5bd3 100644 --- a/libraries/chain/include/graphene/chain/market_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/market_evaluator.hpp @@ -23,7 +23,7 @@ */ #pragma once #include -#include +#include namespace graphene { namespace chain { @@ -31,10 +31,8 @@ namespace graphene { namespace chain { class asset_object; class asset_bitasset_data_object; class call_order_object; - struct bid_collateral_operation; - struct call_order_update_operation; - struct limit_order_cancel_operation; - struct limit_order_create_operation; + class limit_order_object; + class collateral_bid_object; class limit_order_create_evaluator : public evaluator { diff --git a/libraries/chain/include/graphene/chain/market_object.hpp b/libraries/chain/include/graphene/chain/market_object.hpp index 168e2b6439..0861f0eccc 100644 --- a/libraries/chain/include/graphene/chain/market_object.hpp +++ b/libraries/chain/include/graphene/chain/market_object.hpp @@ -23,10 +23,9 @@ */ #pragma once -#include -#include +#include #include -#include +#include #include @@ -68,7 +67,6 @@ class limit_order_object : public abstract_object asset_id_type receive_asset_id()const { return sell_price.quote.asset_id; } }; -struct by_id; struct by_price; struct by_expiration; struct by_account; @@ -272,18 +270,17 @@ typedef generic_index + +#include #include + #include namespace graphene { namespace chain { @@ -61,7 +63,7 @@ namespace graphene { namespace chain { /** the operation within the transaction */ uint16_t op_in_trx = 0; /** any virtual operations implied by operation in block */ - uint16_t virtual_op = 0; + uint32_t virtual_op = 0; }; /** @@ -94,13 +96,8 @@ namespace graphene { namespace chain { operation_history_id_type operation_id; uint64_t sequence = 0; /// the operation position within the given account account_transaction_history_id_type next; - - //std::pair account_op()const { return std::tie( account, operation_id ); } - //std::pair account_seq()const { return std::tie( account, sequence ); } }; - struct by_id; - typedef multi_index_container< operation_history_object, indexed_by< @@ -141,8 +138,11 @@ namespace graphene { namespace chain { } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::operation_history_object, (graphene::chain::object), - (op)(result)(block_num)(trx_in_block)(op_in_trx)(virtual_op) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::operation_history_object) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_transaction_history_object) + +FC_REFLECT_TYPENAME( graphene::chain::operation_history_object ) +FC_REFLECT_TYPENAME( graphene::chain::account_transaction_history_object ) -FC_REFLECT_DERIVED( graphene::chain::account_transaction_history_object, (graphene::chain::object), - (account)(operation_id)(sequence)(next) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::operation_history_object ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::account_transaction_history_object ) diff --git a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp index 04b5c62d22..e18ddd4226 100644 --- a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp @@ -23,7 +23,7 @@ */ #pragma once -#include +#include #include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/proposal_object.hpp b/libraries/chain/include/graphene/chain/proposal_object.hpp index 12fae3c89e..8d6bc849da 100644 --- a/libraries/chain/include/graphene/chain/proposal_object.hpp +++ b/libraries/chain/include/graphene/chain/proposal_object.hpp @@ -23,14 +23,14 @@ */ #pragma once -#include -#include - +#include +#include #include + #include namespace graphene { namespace chain { - + class database; /** * @brief tracks the approval of a partially approved transaction @@ -73,12 +73,17 @@ class required_approval_index : public secondary_index public: virtual void object_inserted( const object& obj ) override; virtual void object_removed( const object& obj ) override; - virtual void about_to_modify( const object& before ) override{}; - virtual void object_modified( const object& after ) override{}; - - void remove( account_id_type a, proposal_id_type p ); + virtual void about_to_modify( const object& before ) override; + virtual void object_modified( const object& after ) override; map > _account_to_proposals; + + private: + void remove( account_id_type a, proposal_id_type p ); + void insert_or_remove_delta( proposal_id_type p, const flat_set& before, + const flat_set& after ); + flat_set available_active_before_modify; + flat_set available_owner_before_modify; }; struct by_expiration{}; @@ -99,7 +104,8 @@ typedef generic_index proposal_ } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::proposal_object, (graphene::chain::object), - (expiration_time)(review_period_time)(proposed_transaction)(required_active_approvals) - (available_active_approvals)(required_owner_approvals)(available_owner_approvals) - (available_key_approvals)(proposer) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::proposal_object) + +FC_REFLECT_TYPENAME( graphene::chain::proposal_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::proposal_object ) diff --git a/libraries/chain/include/graphene/chain/protocol/config.hpp b/libraries/chain/include/graphene/chain/protocol/config.hpp deleted file mode 100644 index 870b08fe3e..0000000000 --- a/libraries/chain/include/graphene/chain/protocol/config.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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. - */ -#pragma once -#include diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp deleted file mode 100644 index 87536f42ee..0000000000 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ /dev/null @@ -1,443 +0,0 @@ -/* - * 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. - */ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// TODO: move this to fc -#include -namespace fc { namespace raw { - template - inline void pack( T& ds, const fc::sha1& ep, uint32_t _max_depth = 1 ) { - ds << ep; - } - - template - inline void unpack( T& ds, sha1& ep, uint32_t _max_depth = 1 ) { - ds >> ep; - } - -} } -// /TODO: move to fc - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace graphene { namespace chain { - using namespace graphene::db; - - using std::map; - using std::vector; - using std::unordered_map; - using std::string; - using std::deque; - using std::shared_ptr; - using std::weak_ptr; - using std::unique_ptr; - using std::set; - using std::pair; - using std::enable_shared_from_this; - using std::tie; - using std::make_pair; - - using fc::smart_ref; - using fc::variant_object; - using fc::variant; - using fc::enum_type; - using fc::optional; - using fc::unsigned_int; - using fc::time_point_sec; - using fc::time_point; - using fc::safe; - using fc::flat_map; - using fc::flat_set; - using fc::static_variant; - using fc::ecc::range_proof_type; - using fc::ecc::range_proof_info; - using fc::ecc::commitment_type; - struct void_t{}; - - typedef fc::ecc::private_key private_key_type; - typedef fc::sha256 chain_id_type; - - typedef boost::rational< int32_t > ratio_type; - - enum asset_issuer_permission_flags - { - charge_market_fee = 0x01, /**< an issuer-specified percentage of all market trades in this asset is paid to the issuer */ - white_list = 0x02, /**< accounts must be whitelisted in order to hold this asset */ - override_authority = 0x04, /**< issuer may transfer asset back to himself */ - transfer_restricted = 0x08, /**< require the issuer to be one party to every transfer */ - disable_force_settle = 0x10, /**< disable force settling */ - global_settle = 0x20, /**< allow the bitasset issuer to force a global settling -- this may be set in permissions, but not flags */ - disable_confidential = 0x40, /**< allow the asset to be used with confidential transactions */ - witness_fed_asset = 0x80, /**< allow the asset to be fed by witnesses */ - committee_fed_asset = 0x100 /**< allow the asset to be fed by the committee */ - }; - const static uint32_t ASSET_ISSUER_PERMISSION_MASK = charge_market_fee|white_list|override_authority|transfer_restricted|disable_force_settle|global_settle|disable_confidential - |witness_fed_asset|committee_fed_asset; - const static uint32_t UIA_ASSET_ISSUER_PERMISSION_MASK = charge_market_fee|white_list|override_authority|transfer_restricted|disable_confidential; - - enum reserved_spaces - { - relative_protocol_ids = 0, - protocol_ids = 1, - implementation_ids = 2 - }; - - inline bool is_relative( object_id_type o ){ return o.space() == 0; } - - /** - * List all object types from all namespaces here so they can - * be easily reflected and displayed in debug output. If a 3rd party - * wants to extend the core code then they will have to change the - * packed_object::type field from enum_type to uint16 to avoid - * warnings when converting packed_objects to/from json. - */ - enum object_type - { - null_object_type, - base_object_type, - account_object_type, - asset_object_type, - force_settlement_object_type, - committee_member_object_type, - witness_object_type, - limit_order_object_type, - call_order_object_type, - custom_object_type, - proposal_object_type, - operation_history_object_type, - withdraw_permission_object_type, - vesting_balance_object_type, - worker_object_type, - balance_object_type, - htlc_object_type, - OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types - }; - - enum impl_object_type - { - impl_global_property_object_type, - impl_dynamic_global_property_object_type, - impl_reserved0_object_type, // formerly index_meta_object_type, TODO: delete me - impl_asset_dynamic_data_type, - impl_asset_bitasset_data_type, - impl_account_balance_object_type, - impl_account_statistics_object_type, - impl_transaction_object_type, - impl_block_summary_object_type, - impl_account_transaction_history_object_type, - impl_blinded_balance_object_type, - impl_chain_property_object_type, - impl_witness_schedule_object_type, - impl_budget_record_object_type, - impl_special_authority_object_type, - impl_buyback_object_type, - impl_fba_accumulator_object_type, - impl_collateral_bid_object_type - }; - - //typedef fc::unsigned_int object_id_type; - //typedef uint64_t object_id_type; - class account_object; - class committee_member_object; - class witness_object; - class asset_object; - class force_settlement_object; - class limit_order_object; - class call_order_object; - class custom_object; - class proposal_object; - class operation_history_object; - class withdraw_permission_object; - class vesting_balance_object; - class worker_object; - class balance_object; - class blinded_balance_object; - class htlc_object; - - typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; - typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type; - typedef object_id< protocol_ids, force_settlement_object_type, force_settlement_object> force_settlement_id_type; - typedef object_id< protocol_ids, committee_member_object_type, committee_member_object> committee_member_id_type; - typedef object_id< protocol_ids, witness_object_type, witness_object> witness_id_type; - typedef object_id< protocol_ids, limit_order_object_type, limit_order_object> limit_order_id_type; - typedef object_id< protocol_ids, call_order_object_type, call_order_object> call_order_id_type; - typedef object_id< protocol_ids, custom_object_type, custom_object> custom_id_type; - typedef object_id< protocol_ids, proposal_object_type, proposal_object> proposal_id_type; - typedef object_id< protocol_ids, operation_history_object_type, operation_history_object> operation_history_id_type; - typedef object_id< protocol_ids, withdraw_permission_object_type,withdraw_permission_object> withdraw_permission_id_type; - typedef object_id< protocol_ids, vesting_balance_object_type, vesting_balance_object> vesting_balance_id_type; - typedef object_id< protocol_ids, worker_object_type, worker_object> worker_id_type; - typedef object_id< protocol_ids, balance_object_type, balance_object> balance_id_type; - typedef object_id< protocol_ids, htlc_object_type, htlc_object> htlc_id_type; - - // implementation types - class global_property_object; - class dynamic_global_property_object; - class asset_dynamic_data_object; - class asset_bitasset_data_object; - class account_balance_object; - class account_statistics_object; - class transaction_object; - class block_summary_object; - class account_transaction_history_object; - class chain_property_object; - class witness_schedule_object; - class budget_record_object; - class special_authority_object; - class buyback_object; - class fba_accumulator_object; - class collateral_bid_object; - - typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type; - typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type; - typedef object_id< implementation_ids, impl_asset_dynamic_data_type, asset_dynamic_data_object> asset_dynamic_data_id_type; - typedef object_id< implementation_ids, impl_asset_bitasset_data_type, asset_bitasset_data_object> asset_bitasset_data_id_type; - typedef object_id< implementation_ids, impl_account_balance_object_type, account_balance_object> account_balance_id_type; - typedef object_id< implementation_ids, impl_account_statistics_object_type,account_statistics_object> account_statistics_id_type; - typedef object_id< implementation_ids, impl_transaction_object_type, transaction_object> transaction_obj_id_type; - typedef object_id< implementation_ids, impl_block_summary_object_type, block_summary_object> block_summary_id_type; - - typedef object_id< implementation_ids, - impl_account_transaction_history_object_type, - account_transaction_history_object> account_transaction_history_id_type; - typedef object_id< implementation_ids, impl_chain_property_object_type, chain_property_object> chain_property_id_type; - typedef object_id< implementation_ids, impl_witness_schedule_object_type, witness_schedule_object> witness_schedule_id_type; - typedef object_id< implementation_ids, impl_budget_record_object_type, budget_record_object > budget_record_id_type; - typedef object_id< implementation_ids, impl_blinded_balance_object_type, blinded_balance_object > blinded_balance_id_type; - typedef object_id< implementation_ids, impl_special_authority_object_type, special_authority_object > special_authority_id_type; - typedef object_id< implementation_ids, impl_buyback_object_type, buyback_object > buyback_id_type; - typedef object_id< implementation_ids, impl_fba_accumulator_object_type, fba_accumulator_object > fba_accumulator_id_type; - typedef object_id< implementation_ids, impl_collateral_bid_object_type, collateral_bid_object > collateral_bid_id_type; - - typedef fc::ripemd160 block_id_type; - typedef fc::ripemd160 checksum_type; - typedef fc::ripemd160 transaction_id_type; - typedef fc::sha256 digest_type; - typedef fc::ecc::compact_signature signature_type; - typedef safe share_type; - typedef uint16_t weight_type; - - struct public_key_type - { - struct binary_key - { - binary_key() {} - uint32_t check = 0; - fc::ecc::public_key_data data; - }; - fc::ecc::public_key_data key_data; - public_key_type(); - public_key_type( const fc::ecc::public_key_data& data ); - public_key_type( const fc::ecc::public_key& pubkey ); - explicit public_key_type( const std::string& base58str ); - operator fc::ecc::public_key_data() const; - operator fc::ecc::public_key() const; - explicit operator std::string() const; - friend bool operator == ( const public_key_type& p1, const fc::ecc::public_key& p2); - friend bool operator == ( const public_key_type& p1, const public_key_type& p2); - friend bool operator != ( const public_key_type& p1, const public_key_type& p2); - }; - - class pubkey_comparator { - public: - inline bool operator()( const public_key_type& a, const public_key_type& b )const - { - return a.key_data < b.key_data; - } - }; - - struct extended_public_key_type - { - struct binary_key - { - binary_key() {} - uint32_t check = 0; - fc::ecc::extended_key_data data; - }; - - fc::ecc::extended_key_data key_data; - - extended_public_key_type(); - extended_public_key_type( const fc::ecc::extended_key_data& data ); - extended_public_key_type( const fc::ecc::extended_public_key& extpubkey ); - explicit extended_public_key_type( const std::string& base58str ); - operator fc::ecc::extended_public_key() const; - explicit operator std::string() const; - friend bool operator == ( const extended_public_key_type& p1, const fc::ecc::extended_public_key& p2); - friend bool operator == ( const extended_public_key_type& p1, const extended_public_key_type& p2); - friend bool operator != ( const extended_public_key_type& p1, const extended_public_key_type& p2); - }; - - struct extended_private_key_type - { - struct binary_key - { - binary_key() {} - uint32_t check = 0; - fc::ecc::extended_key_data data; - }; - - fc::ecc::extended_key_data key_data; - - extended_private_key_type(); - extended_private_key_type( const fc::ecc::extended_key_data& data ); - extended_private_key_type( const fc::ecc::extended_private_key& extprivkey ); - explicit extended_private_key_type( const std::string& base58str ); - operator fc::ecc::extended_private_key() const; - explicit operator std::string() const; - friend bool operator == ( const extended_private_key_type& p1, const fc::ecc::extended_private_key& p2); - friend bool operator == ( const extended_private_key_type& p1, const extended_private_key_type& p2); - friend bool operator != ( const extended_private_key_type& p1, const extended_private_key_type& p2); - }; -} } // graphene::chain - -namespace fc -{ - void to_variant( const graphene::chain::public_key_type& var, fc::variant& vo, uint32_t max_depth = 2 ); - void from_variant( const fc::variant& var, graphene::chain::public_key_type& vo, uint32_t max_depth = 2 ); - void to_variant( const graphene::chain::extended_public_key_type& var, fc::variant& vo, uint32_t max_depth = 2 ); - void from_variant( const fc::variant& var, graphene::chain::extended_public_key_type& vo, uint32_t max_depth = 2 ); - void to_variant( const graphene::chain::extended_private_key_type& var, fc::variant& vo, uint32_t max_depth = 2 ); - void from_variant( const fc::variant& var, graphene::chain::extended_private_key_type& vo, uint32_t max_depth = 2 ); -} - -FC_REFLECT( graphene::chain::public_key_type, (key_data) ) -FC_REFLECT( graphene::chain::public_key_type::binary_key, (data)(check) ) -FC_REFLECT( graphene::chain::extended_public_key_type, (key_data) ) -FC_REFLECT( graphene::chain::extended_public_key_type::binary_key, (check)(data) ) -FC_REFLECT( graphene::chain::extended_private_key_type, (key_data) ) -FC_REFLECT( graphene::chain::extended_private_key_type::binary_key, (check)(data) ) - -FC_REFLECT_ENUM( graphene::chain::object_type, - (null_object_type) - (base_object_type) - (account_object_type) - (force_settlement_object_type) - (asset_object_type) - (committee_member_object_type) - (witness_object_type) - (limit_order_object_type) - (call_order_object_type) - (custom_object_type) - (proposal_object_type) - (operation_history_object_type) - (withdraw_permission_object_type) - (vesting_balance_object_type) - (worker_object_type) - (balance_object_type) - (htlc_object_type) - (OBJECT_TYPE_COUNT) - ) -FC_REFLECT_ENUM( graphene::chain::impl_object_type, - (impl_global_property_object_type) - (impl_dynamic_global_property_object_type) - (impl_reserved0_object_type) - (impl_asset_dynamic_data_type) - (impl_asset_bitasset_data_type) - (impl_account_balance_object_type) - (impl_account_statistics_object_type) - (impl_transaction_object_type) - (impl_block_summary_object_type) - (impl_account_transaction_history_object_type) - (impl_blinded_balance_object_type) - (impl_chain_property_object_type) - (impl_witness_schedule_object_type) - (impl_budget_record_object_type) - (impl_special_authority_object_type) - (impl_buyback_object_type) - (impl_fba_accumulator_object_type) - (impl_collateral_bid_object_type) - ) - -FC_REFLECT_TYPENAME( graphene::chain::share_type ) - -FC_REFLECT_TYPENAME( graphene::chain::account_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::asset_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::force_settlement_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::committee_member_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::witness_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::limit_order_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::call_order_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::custom_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::proposal_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::operation_history_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::withdraw_permission_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::vesting_balance_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::worker_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::balance_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::global_property_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::dynamic_global_property_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::asset_dynamic_data_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::asset_bitasset_data_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::account_balance_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::account_statistics_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::transaction_obj_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::block_summary_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::account_transaction_history_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::budget_record_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::special_authority_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::buyback_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::collateral_bid_id_type ) -FC_REFLECT_TYPENAME( graphene::chain::htlc_id_type ) - -FC_REFLECT( graphene::chain::void_t, ) - -FC_REFLECT_ENUM( graphene::chain::asset_issuer_permission_flags, - (charge_market_fee) - (white_list) - (transfer_restricted) - (override_authority) - (disable_force_settle) - (global_settle) - (disable_confidential) - (witness_fed_asset) - (committee_fed_asset) - ) diff --git a/libraries/chain/include/graphene/chain/special_authority.hpp b/libraries/chain/include/graphene/chain/special_authority_evaluation.hpp similarity index 94% rename from libraries/chain/include/graphene/chain/special_authority.hpp rename to libraries/chain/include/graphene/chain/special_authority_evaluation.hpp index f091f73617..931b35a704 100644 --- a/libraries/chain/include/graphene/chain/special_authority.hpp +++ b/libraries/chain/include/graphene/chain/special_authority_evaluation.hpp @@ -23,11 +23,12 @@ */ #pragma once -#include +#include namespace graphene { namespace chain { class database; +using namespace protocol; void evaluate_special_authority( const database& db, const special_authority& auth ); diff --git a/libraries/chain/include/graphene/chain/special_authority_object.hpp b/libraries/chain/include/graphene/chain/special_authority_object.hpp index da9ecc5e0c..1e45bc28dc 100644 --- a/libraries/chain/include/graphene/chain/special_authority_object.hpp +++ b/libraries/chain/include/graphene/chain/special_authority_object.hpp @@ -22,8 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include #include namespace graphene { namespace chain { @@ -63,8 +62,8 @@ typedef generic_index< special_authority_object, special_authority_multi_index_t } } // graphene::chain -FC_REFLECT_DERIVED( - graphene::chain::special_authority_object, - (graphene::db::object), - (account) -) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::special_authority_object) + +FC_REFLECT_TYPENAME( graphene::chain::special_authority_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::special_authority_object ) diff --git a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp index 5ffb4bb7d1..53c6f3eb87 100644 --- a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp +++ b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp @@ -22,11 +22,13 @@ * THE SOFTWARE. */ #pragma once -#include +#include -namespace graphene { namespace chain { +namespace graphene { +namespace protocol { class signed_transaction; } +namespace chain { class database; - struct signed_transaction; + using protocol::signed_transaction; /** * Place holder for state tracked while processing a transaction. This class provides helper methods that are diff --git a/libraries/chain/include/graphene/chain/transaction_object.hpp b/libraries/chain/include/graphene/chain/transaction_history_object.hpp similarity index 67% rename from libraries/chain/include/graphene/chain/transaction_object.hpp rename to libraries/chain/include/graphene/chain/transaction_history_object.hpp index 4f76d6bef6..2f0ebe9fc2 100644 --- a/libraries/chain/include/graphene/chain/transaction_object.hpp +++ b/libraries/chain/include/graphene/chain/transaction_history_object.hpp @@ -22,12 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include -#include -#include +#include #include -#include #include #include @@ -41,14 +38,14 @@ namespace graphene { namespace chain { using namespace boost::multi_index; /** * The purpose of this object is to enable the detection of duplicate transactions. When a transaction is included - * in a block a transaction_object is added. At the end of block processing all transaction_objects that have - * expired can be removed from the index. + * in a block a transaction_history_object is added. At the end of block processing all transaction_history_objects that + * have expired can be removed from the index. */ - class transaction_object : public abstract_object + class transaction_history_object : public abstract_object { public: static const uint8_t space_id = implementation_ids; - static const uint8_t type_id = impl_transaction_object_type; + static const uint8_t type_id = impl_transaction_history_object_type; signed_transaction trx; transaction_id_type trx_id; @@ -57,18 +54,23 @@ namespace graphene { namespace chain { }; struct by_expiration; - struct by_id; struct by_trx_id; typedef multi_index_container< - transaction_object, + transaction_history_object, indexed_by< ordered_unique< tag, member< object, object_id_type, &object::id > >, - hashed_unique< tag, BOOST_MULTI_INDEX_MEMBER(transaction_object, transaction_id_type, trx_id), std::hash >, - ordered_non_unique< tag, const_mem_fun > + hashed_unique< tag, BOOST_MULTI_INDEX_MEMBER(transaction_history_object, transaction_id_type, trx_id), + std::hash >, + ordered_non_unique< tag, const_mem_fun< transaction_history_object, time_point_sec, + &transaction_history_object::get_expiration > > > > transaction_multi_index_type; - typedef generic_index transaction_index; + typedef generic_index transaction_index; } } -FC_REFLECT_DERIVED( graphene::chain::transaction_object, (graphene::db::object), (trx)(trx_id) ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::transaction_history_object) + +FC_REFLECT_TYPENAME( graphene::chain::transaction_history_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::transaction_history_object ) diff --git a/libraries/chain/include/graphene/chain/transfer_evaluator.hpp b/libraries/chain/include/graphene/chain/transfer_evaluator.hpp index 900ab0741f..6c2bc7ee99 100644 --- a/libraries/chain/include/graphene/chain/transfer_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/transfer_evaluator.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include +#include #include #include diff --git a/libraries/chain/include/graphene/chain/types.hpp b/libraries/chain/include/graphene/chain/types.hpp new file mode 100644 index 0000000000..ec3e788219 --- /dev/null +++ b/libraries/chain/include/graphene/chain/types.hpp @@ -0,0 +1,48 @@ +/* + * 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. + */ +#pragma once + +#include + +namespace graphene { namespace chain { using namespace protocol; } } + +GRAPHENE_DEFINE_IDS(chain, implementation_ids, impl_, + (global_property) + (dynamic_global_property) + (reserved0) + (asset_dynamic_data) + (asset_bitasset_data) + (account_balance) + (account_statistics) + (transaction_history) + (block_summary) + (account_transaction_history) + (blinded_balance) + (chain_property) + (witness_schedule) + (budget_record) + (special_authority) + (buyback) + (fba_accumulator) + (collateral_bid)) diff --git a/libraries/chain/include/graphene/chain/vesting_balance_object.hpp b/libraries/chain/include/graphene/chain/vesting_balance_object.hpp index ec3ab0c850..480922fa90 100644 --- a/libraries/chain/include/graphene/chain/vesting_balance_object.hpp +++ b/libraries/chain/include/graphene/chain/vesting_balance_object.hpp @@ -23,9 +23,9 @@ */ #pragma once -#include -#include #include +#include + #include #include #include @@ -33,14 +33,9 @@ #include #include -#include - - - namespace graphene { namespace chain { using namespace graphene::db; - - class vesting_balance_object; + using namespace graphene::protocol; struct vesting_policy_context { @@ -278,6 +273,8 @@ namespace detail { } } // graphene::chain +MAP_OBJECT_ID_TO_TYPE(graphene::chain::vesting_balance_object) + FC_REFLECT(graphene::chain::linear_vesting_policy, (begin_timestamp) (vesting_cliff_seconds) @@ -305,3 +302,6 @@ FC_REFLECT_DERIVED(graphene::chain::vesting_balance_object, (graphene::db::objec FC_REFLECT_ENUM( graphene::chain::vesting_balance_type, (unspecified)(cashback)(worker)(witness)(market_fee_sharing) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::linear_vesting_policy ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::cdd_vesting_policy ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::vesting_balance_object ) diff --git a/libraries/chain/include/graphene/chain/vote_count.hpp b/libraries/chain/include/graphene/chain/vote_count.hpp index f76a784d4b..ed8ed130fe 100644 --- a/libraries/chain/include/graphene/chain/vote_count.hpp +++ b/libraries/chain/include/graphene/chain/vote_count.hpp @@ -24,7 +24,7 @@ #pragma once -#include +#include namespace graphene { namespace chain { diff --git a/libraries/chain/include/graphene/chain/withdraw_permission_object.hpp b/libraries/chain/include/graphene/chain/withdraw_permission_object.hpp index f202ee1b66..cb954ad7f3 100644 --- a/libraries/chain/include/graphene/chain/withdraw_permission_object.hpp +++ b/libraries/chain/include/graphene/chain/withdraw_permission_object.hpp @@ -22,11 +22,15 @@ * THE SOFTWARE. */ #pragma once -#include + +#include #include + #include namespace graphene { namespace chain { + using namespace graphene::protocol; + /** * @class withdraw_permission_object * @brief Grants another account authority to withdraw a limited amount of funds per interval @@ -113,12 +117,8 @@ namespace graphene { namespace chain { } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::withdraw_permission_object, (graphene::db::object), - (withdraw_from_account) - (authorized_account) - (withdrawal_limit) - (withdrawal_period_sec) - (period_start_time) - (expiration) - (claimed_this_period) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::withdraw_permission_object) + +FC_REFLECT_TYPENAME( graphene::chain::withdraw_permission_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::withdraw_permission_object ) diff --git a/libraries/chain/include/graphene/chain/witness_object.hpp b/libraries/chain/include/graphene/chain/witness_object.hpp index 4d41a014c9..0c48f3bc17 100644 --- a/libraries/chain/include/graphene/chain/witness_object.hpp +++ b/libraries/chain/include/graphene/chain/witness_object.hpp @@ -22,15 +22,13 @@ * THE SOFTWARE. */ #pragma once -#include -#include + +#include #include namespace graphene { namespace chain { using namespace graphene::db; - class witness_object; - class witness_object : public abstract_object { public: @@ -70,14 +68,8 @@ namespace graphene { namespace chain { using witness_index = generic_index; } } // graphene::chain -FC_REFLECT_DERIVED( graphene::chain::witness_object, (graphene::db::object), - (witness_account) - (last_aslot) - (signing_key) - (pay_vb) - (vote_id) - (total_votes) - (url) - (total_missed) - (last_confirmed_block_num) - ) +MAP_OBJECT_ID_TO_TYPE(graphene::chain::witness_object) + +FC_REFLECT_TYPENAME( graphene::chain::witness_object ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::chain::witness_object ) diff --git a/libraries/chain/include/graphene/chain/witness_schedule_object.hpp b/libraries/chain/include/graphene/chain/witness_schedule_object.hpp index b5f1ea8ad7..f481e05852 100644 --- a/libraries/chain/include/graphene/chain/witness_schedule_object.hpp +++ b/libraries/chain/include/graphene/chain/witness_schedule_object.hpp @@ -22,14 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include #include namespace graphene { namespace chain { -class witness_schedule_object; - class witness_schedule_object : public graphene::db::abstract_object { public: @@ -41,8 +38,8 @@ class witness_schedule_object : public graphene::db::abstract_object +#include #include +#include namespace graphene { namespace chain { +class database; /** * @defgroup worker_types Implementations of the various worker types in the system @@ -157,20 +159,12 @@ using worker_index = generic_index HARDFORK_415_TIME ) - { - if( asset_obj.options.whitelist_authorities.size() == 0 ) - return true; - } + if( asset_obj.options.whitelist_authorities.size() == 0 ) + return true; for( const auto id : acct.whitelisting_accounts ) { diff --git a/libraries/chain/market_evaluator.cpp b/libraries/chain/market_evaluator.cpp index 17d1164362..18ebbe0180 100644 --- a/libraries/chain/market_evaluator.cpp +++ b/libraries/chain/market_evaluator.cpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include @@ -95,13 +95,12 @@ void limit_order_create_evaluator::pay_fee() object_id_type limit_order_create_evaluator::do_apply(const limit_order_create_operation& op) { try { - const auto& seller_stats = _seller->statistics(db()); - db().modify(seller_stats, [&](account_statistics_object& bal) { - if( op.amount_to_sell.asset_id == asset_id_type() ) - { - bal.total_core_in_orders += op.amount_to_sell.amount; - } - }); + if( op.amount_to_sell.asset_id == asset_id_type() ) + { + db().modify( _seller->statistics(db()), [&op](account_statistics_object& bal) { + bal.total_core_in_orders += op.amount_to_sell.amount; + }); + } db().adjust_balance(op.seller, -op.amount_to_sell); @@ -162,11 +161,6 @@ void_result call_order_update_evaluator::do_evaluate(const call_order_update_ope auto next_maintenance_time = d.get_dynamic_global_properties().next_maintenance_time; - // TODO: remove this check and the assertion after hf_834 - if( next_maintenance_time <= HARDFORK_CORE_834_TIME ) - FC_ASSERT( !o.extensions.value.target_collateral_ratio.valid(), - "Can not set target_collateral_ratio in call_order_update_operation before hardfork 834." ); - _paying_account = &o.funding_account(d); _debt_asset = &o.delta_debt.asset_id(d); FC_ASSERT( _debt_asset->is_market_issued(), "Unable to cover ${sym} as it is not a collateralized asset.", @@ -331,7 +325,7 @@ object_id_type call_order_update_evaluator::do_apply(const call_order_update_ope call_obj = d.find(call_order_id); // we know no black swan event has occurred FC_ASSERT( call_obj, "no margin call was executed and yet the call object was deleted" ); - if( d.head_block_time() <= HARDFORK_CORE_583_TIME ) // TODO remove after hard fork core-583 + if( d.head_block_time() <= HARDFORK_CORE_583_TIME ) { // We didn't fill any call orders. This may be because we // aren't in margin call territory, or it may be because there diff --git a/libraries/chain/market_object.cpp b/libraries/chain/market_object.cpp index 0c2e464906..0cd19b63f5 100644 --- a/libraries/chain/market_object.cpp +++ b/libraries/chain/market_object.cpp @@ -27,6 +27,8 @@ #include +#include + using namespace graphene::chain; /* @@ -300,3 +302,24 @@ share_type call_order_object::get_max_debt_to_cover( price match_price, } } FC_CAPTURE_AND_RETHROW( (*this)(feed_price)(match_price)(maintenance_collateral_ratio) ) } + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::limit_order_object, + (graphene::db::object), + (expiration)(seller)(for_sale)(sell_price)(deferred_fee)(deferred_paid_fee) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::call_order_object, (graphene::db::object), + (borrower)(collateral)(debt)(call_price)(target_collateral_ratio) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::force_settlement_object, + (graphene::db::object), + (owner)(balance)(settlement_date) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::collateral_bid_object, (graphene::db::object), + (bidder)(inv_swan_price) ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::limit_order_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::call_order_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::force_settlement_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::collateral_bid_object ) diff --git a/libraries/chain/proposal_evaluator.cpp b/libraries/chain/proposal_evaluator.cpp index e867e733d7..4e9a3ea656 100644 --- a/libraries/chain/proposal_evaluator.cpp +++ b/libraries/chain/proposal_evaluator.cpp @@ -56,21 +56,9 @@ struct proposal_operation_hardfork_visitor || (v.delta_debt.asset_id( db ).bitasset_data_id && (*(v.delta_debt.asset_id( db ).bitasset_data_id))( db ).is_prediction_market ) , "Soft fork - preventing proposal with call_order_update!" ); - - // TODO review and cleanup code below after hard fork - // hf_834 - if (next_maintenance_time <= HARDFORK_CORE_834_TIME) { - FC_ASSERT( !v.extensions.value.target_collateral_ratio.valid(), - "Can not set target_collateral_ratio in call_order_update_operation before hardfork 834." ); - } } - // hf_620 + // hf_1268 void operator()(const graphene::chain::asset_create_operation &v) const { - if (block_time < HARDFORK_CORE_620_TIME) { - static const std::locale &loc = std::locale::classic(); - FC_ASSERT(isalpha(v.symbol.back(), loc), "Asset ${s} must end with alpha character before hardfork 620", ("s", v.symbol)); - } - detail::check_asset_options_hf_1268(block_time, v.common_options); } // hf_1268 @@ -81,18 +69,6 @@ struct proposal_operation_hardfork_visitor void operator()(const graphene::chain::vesting_balance_create_operation &v) const { detail::check_vesting_balance_policy_hf_1268(block_time, v.policy); } - // hf_199 - void operator()(const graphene::chain::asset_update_issuer_operation &v) const { - if (block_time < HARDFORK_CORE_199_TIME) { - FC_ASSERT(false, "Not allowed until hardfork 199"); - } - } - // hf_188 - void operator()(const graphene::chain::asset_claim_pool_operation &v) const { - if (block_time < HARDFORK_CORE_188_TIME) { - FC_ASSERT(false, "Not allowed until hardfork 188"); - } - } // hf_588 // issue #588 // @@ -142,7 +118,7 @@ struct proposal_operation_hardfork_visitor { op.op.visit(*this); // Do not allow more than 1 proposal_update in a proposal - if ( op.op.which() == operation::tag().value ) + if ( op.op.is_type() ) { FC_ASSERT( !already_contains_proposal_update, "At most one proposal update can be nested in a proposal!" ); already_contains_proposal_update = true; diff --git a/libraries/chain/proposal_object.cpp b/libraries/chain/proposal_object.cpp index 47d4d0db4a..62502e2736 100644 --- a/libraries/chain/proposal_object.cpp +++ b/libraries/chain/proposal_object.cpp @@ -23,6 +23,7 @@ */ #include #include +#include #include namespace graphene { namespace chain { @@ -39,7 +40,7 @@ bool proposal_object::is_authorized_to_execute(database& db) const [&]( account_id_type id ){ return &id(db).owner; }, allow_non_immediate_owner, db.get_global_properties().parameters.max_authority_depth, - true, /* allow committeee */ + true, /* allow committee */ available_active_approvals, available_owner_approvals ); } @@ -91,4 +92,51 @@ void required_approval_index::object_removed( const object& obj ) remove( a, p.id ); } +void required_approval_index::insert_or_remove_delta( proposal_id_type p, + const flat_set& before, + const flat_set& after ) +{ + auto b = before.begin(); + auto a = after.begin(); + while( b != before.end() || a != after.end() ) + { + if( a == after.end() || (b != before.end() && *b < *a) ) + { + remove( *b, p ); + ++b; + } + else if( b == before.end() || (a != after.end() && *a < *b) ) + { + _account_to_proposals[*a].insert( p ); + ++a; + } + else // *a == *b + { + ++a; + ++b; + } + } +} + +void required_approval_index::about_to_modify( const object& before ) +{ + const proposal_object& p = static_cast(before); + available_active_before_modify = p.available_active_approvals; + available_owner_before_modify = p.available_owner_approvals; +} + +void required_approval_index::object_modified( const object& after ) +{ + const proposal_object& p = static_cast(after); + insert_or_remove_delta( p.id, available_active_before_modify, p.available_active_approvals ); + insert_or_remove_delta( p.id, available_owner_before_modify, p.available_owner_approvals ); +} + } } // graphene::chain + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::proposal_object, (graphene::chain::object), + (expiration_time)(review_period_time)(proposed_transaction)(required_active_approvals) + (available_active_approvals)(required_owner_approvals)(available_owner_approvals) + (available_key_approvals)(proposer)(fail_reason) ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::proposal_object ) diff --git a/libraries/chain/protocol/types.cpp b/libraries/chain/protocol/types.cpp deleted file mode 100644 index a51474f0da..0000000000 --- a/libraries/chain/protocol/types.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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 -#include -#include - -namespace graphene { namespace chain { - - public_key_type::public_key_type():key_data(){}; - - public_key_type::public_key_type( const fc::ecc::public_key_data& data ) - :key_data( data ) {}; - - public_key_type::public_key_type( const fc::ecc::public_key& pubkey ) - :key_data( pubkey ) {}; - - public_key_type::public_key_type( const std::string& base58str ) - { - // TODO: Refactor syntactic checks into static is_valid() - // to make public_key_type API more similar to address API - std::string prefix( GRAPHENE_ADDRESS_PREFIX ); - const size_t prefix_len = prefix.size(); - FC_ASSERT( base58str.size() > prefix_len ); - FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); - auto bin = fc::from_base58( base58str.substr( prefix_len ) ); - auto bin_key = fc::raw::unpack(bin); - key_data = bin_key.data; - FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0] == bin_key.check ); - }; - - public_key_type::operator fc::ecc::public_key_data() const - { - return key_data; - }; - - public_key_type::operator fc::ecc::public_key() const - { - return fc::ecc::public_key( key_data ); - }; - - public_key_type::operator std::string() const - { - binary_key k; - k.data = key_data; - k.check = fc::ripemd160::hash( k.data.data, k.data.size() )._hash[0]; - auto data = fc::raw::pack( k ); - return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( data.data(), data.size() ); - } - - bool operator == ( const public_key_type& p1, const fc::ecc::public_key& p2) - { - return p1.key_data == p2.serialize(); - } - - bool operator == ( const public_key_type& p1, const public_key_type& p2) - { - return p1.key_data == p2.key_data; - } - - bool operator != ( const public_key_type& p1, const public_key_type& p2) - { - return p1.key_data != p2.key_data; - } - - // extended_public_key_type - - extended_public_key_type::extended_public_key_type():key_data(){}; - - extended_public_key_type::extended_public_key_type( const fc::ecc::extended_key_data& data ) - :key_data( data ){}; - - extended_public_key_type::extended_public_key_type( const fc::ecc::extended_public_key& extpubkey ) - { - key_data = extpubkey.serialize_extended(); - }; - - extended_public_key_type::extended_public_key_type( const std::string& base58str ) - { - std::string prefix( GRAPHENE_ADDRESS_PREFIX ); - - const size_t prefix_len = prefix.size(); - FC_ASSERT( base58str.size() > prefix_len ); - FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); - auto bin = fc::from_base58( base58str.substr( prefix_len ) ); - auto bin_key = fc::raw::unpack(bin); - FC_ASSERT( fc::ripemd160::hash( bin_key.data.data, bin_key.data.size() )._hash[0] == bin_key.check ); - key_data = bin_key.data; - } - - extended_public_key_type::operator fc::ecc::extended_public_key() const - { - return fc::ecc::extended_public_key::deserialize( key_data ); - } - - extended_public_key_type::operator std::string() const - { - binary_key k; - k.data = key_data; - k.check = fc::ripemd160::hash( k.data.data, k.data.size() )._hash[0]; - auto data = fc::raw::pack( k ); - return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( data.data(), data.size() ); - } - - bool operator == ( const extended_public_key_type& p1, const fc::ecc::extended_public_key& p2) - { - return p1.key_data == p2.serialize_extended(); - } - - bool operator == ( const extended_public_key_type& p1, const extended_public_key_type& p2) - { - return p1.key_data == p2.key_data; - } - - bool operator != ( const extended_public_key_type& p1, const extended_public_key_type& p2) - { - return p1.key_data != p2.key_data; - } - - // extended_private_key_type - - extended_private_key_type::extended_private_key_type():key_data(){}; - - extended_private_key_type::extended_private_key_type( const fc::ecc::extended_key_data& data ) - :key_data( data ){}; - - extended_private_key_type::extended_private_key_type( const fc::ecc::extended_private_key& extprivkey ) - { - key_data = extprivkey.serialize_extended(); - }; - - extended_private_key_type::extended_private_key_type( const std::string& base58str ) - { - std::string prefix( GRAPHENE_ADDRESS_PREFIX ); - - const size_t prefix_len = prefix.size(); - FC_ASSERT( base58str.size() > prefix_len ); - FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); - auto bin = fc::from_base58( base58str.substr( prefix_len ) ); - auto bin_key = fc::raw::unpack(bin); - FC_ASSERT( fc::ripemd160::hash( bin_key.data.data, bin_key.data.size() )._hash[0] == bin_key.check ); - key_data = bin_key.data; - } - - extended_private_key_type::operator fc::ecc::extended_private_key() const - { - return fc::ecc::extended_private_key::deserialize( key_data ); - } - - extended_private_key_type::operator std::string() const - { - binary_key k; - k.data = key_data; - k.check = fc::ripemd160::hash( k.data.data, k.data.size() )._hash[0]; - auto data = fc::raw::pack( k ); - return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( data.data(), data.size() ); - } - - bool operator == ( const extended_private_key_type& p1, const fc::ecc::extended_public_key& p2) - { - return p1.key_data == p2.serialize_extended(); - } - - bool operator == ( const extended_private_key_type& p1, const extended_private_key_type& p2) - { - return p1.key_data == p2.key_data; - } - - bool operator != ( const extended_private_key_type& p1, const extended_private_key_type& p2) - { - return p1.key_data != p2.key_data; - } - -} } // graphene::chain - -namespace fc -{ - using namespace std; - void to_variant( const graphene::chain::public_key_type& var, fc::variant& vo, uint32_t max_depth ) - { - vo = std::string( var ); - } - - void from_variant( const fc::variant& var, graphene::chain::public_key_type& vo, uint32_t max_depth ) - { - vo = graphene::chain::public_key_type( var.as_string() ); - } - - void to_variant( const graphene::chain::extended_public_key_type& var, fc::variant& vo, uint32_t max_depth ) - { - vo = std::string( var ); - } - - void from_variant( const fc::variant& var, graphene::chain::extended_public_key_type& vo, uint32_t max_depth ) - { - vo = graphene::chain::extended_public_key_type( var.as_string() ); - } - - void to_variant( const graphene::chain::extended_private_key_type& var, fc::variant& vo, uint32_t max_depth ) - { - vo = std::string( var ); - } - - void from_variant( const fc::variant& var, graphene::chain::extended_private_key_type& vo, uint32_t max_depth ) - { - vo = graphene::chain::extended_private_key_type( var.as_string() ); - } -} // fc diff --git a/libraries/chain/small_objects.cpp b/libraries/chain/small_objects.cpp new file mode 100644 index 0000000000..ed68a4eaef --- /dev/null +++ b/libraries/chain/small_objects.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2019 BitShares Blockchain Foundation, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::balance_object, (graphene::db::object), + (owner)(balance)(vesting_policy)(last_claim_date) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::block_summary_object, (graphene::db::object), (block_id) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( + graphene::chain::budget_record, BOOST_PP_SEQ_NIL, + (time_since_last_budget) + (from_initial_reserve) + (from_accumulated_fees) + (from_unused_witness_budget) + (requested_witness_budget) + (total_budget) + (witness_budget) + (worker_budget) + (leftover_worker_funds) + (supply_delta) +) + +FC_REFLECT_DERIVED_NO_TYPENAME( + graphene::chain::budget_record_object, + (graphene::db::object), + (time) + (record) +) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::buyback_object, (graphene::db::object), (asset_to_buy) ) + + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::immutable_chain_parameters, BOOST_PP_SEQ_NIL, + (min_committee_member_count) + (min_witness_count) + (num_special_accounts) + (num_special_assets) +) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::chain_property_object, (graphene::db::object), + (chain_id) + (immutable_parameters) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::committee_member_object, (graphene::db::object), + (committee_member_account)(vote_id)(total_votes)(url) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::blinded_balance_object, (graphene::db::object), + (commitment)(asset_id)(owner) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::fba_accumulator_object, (graphene::db::object), + (accumulated_fba_fees)(designated_asset) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::dynamic_global_property_object, (graphene::db::object), + (head_block_number) + (head_block_id) + (time) + (current_witness) + (next_maintenance_time) + (last_budget_time) + (witness_budget) + (accounts_registered_this_interval) + (recently_missed_count) + (current_aslot) + (recent_slots_filled) + (dynamic_flags) + (last_irreversible_block_num) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::global_property_object, (graphene::db::object), + (parameters) + (pending_parameters) + (next_available_vote_id) + (active_committee_members) + (active_witnesses) + ) + +FC_REFLECT( graphene::chain::htlc_object::transfer_info, + (from) (to) (amount) (asset_id) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::htlc_object::condition_info::hash_lock_info, BOOST_PP_SEQ_NIL, + (preimage_hash) (preimage_size) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::htlc_object::condition_info::time_lock_info, BOOST_PP_SEQ_NIL, + (expiration) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::htlc_object::condition_info, BOOST_PP_SEQ_NIL, + (hash_lock)(time_lock) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::htlc_object, (graphene::db::object), + (transfer) (conditions) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::operation_history_object, (graphene::chain::object), + (op)(result)(block_num)(trx_in_block)(op_in_trx)(virtual_op) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::account_transaction_history_object, (graphene::chain::object), + (account)(operation_id)(sequence)(next) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( + graphene::chain::special_authority_object, + (graphene::db::object), + (account) +) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::transaction_history_object, (graphene::db::object), (trx)(trx_id) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::withdraw_permission_object, (graphene::db::object), + (withdraw_from_account) + (authorized_account) + (withdrawal_limit) + (withdrawal_period_sec) + (period_start_time) + (expiration) + (claimed_this_period) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::witness_object, (graphene::db::object), + (witness_account) + (last_aslot) + (signing_key) + (pay_vb) + (vote_id) + (total_votes) + (url) + (total_missed) + (last_confirmed_block_num) + ) + +FC_REFLECT_DERIVED_NO_TYPENAME( + graphene::chain::witness_schedule_object, + (graphene::db::object), + (current_shuffled_witnesses) +) + + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::refund_worker_type, BOOST_PP_SEQ_NIL, (total_burned) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::vesting_balance_worker_type, BOOST_PP_SEQ_NIL, (balance) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::burn_worker_type, BOOST_PP_SEQ_NIL, (total_burned) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::worker_object, (graphene::db::object), + (worker_account) + (work_begin_date) + (work_end_date) + (daily_pay) + (worker) + (vote_for) + (vote_against) + (total_votes_for) + (total_votes_against) + (name) + (url) + ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::balance_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::block_summary_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::budget_record ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::budget_record_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::buyback_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::immutable_chain_parameters ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::chain_property_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::committee_member_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::blinded_balance_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::fba_accumulator_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::dynamic_global_property_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::global_property_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::htlc_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::operation_history_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::account_transaction_history_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::special_authority_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::transaction_history_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::withdraw_permission_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::witness_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::witness_schedule_object ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::worker_object ) diff --git a/libraries/chain/special_authority.cpp b/libraries/chain/special_authority_evaluation.cpp similarity index 78% rename from libraries/chain/special_authority.cpp rename to libraries/chain/special_authority_evaluation.cpp index ca974f3083..2fbc32529d 100644 --- a/libraries/chain/special_authority.cpp +++ b/libraries/chain/special_authority_evaluation.cpp @@ -22,29 +22,11 @@ * THE SOFTWARE. */ -#include +#include #include namespace graphene { namespace chain { -struct special_authority_validate_visitor -{ - typedef void result_type; - - void operator()( const no_special_authority& a ) {} - - void operator()( const top_holders_special_authority& a ) - { - FC_ASSERT( a.num_top_holders > 0 ); - } -}; - -void validate_special_authority( const special_authority& a ) -{ - special_authority_validate_visitor vtor; - a.visit( vtor ); -} - struct special_authority_evaluate_visitor { typedef void result_type; @@ -55,7 +37,7 @@ struct special_authority_evaluate_visitor void operator()( const top_holders_special_authority& a ) { - a.asset(db); // require asset to exist + db.get(a.asset); // require asset to exist } const database& db; diff --git a/libraries/chain/transfer_evaluator.cpp b/libraries/chain/transfer_evaluator.cpp index 60bfbdba99..f681a35741 100644 --- a/libraries/chain/transfer_evaluator.cpp +++ b/libraries/chain/transfer_evaluator.cpp @@ -102,12 +102,6 @@ void_result override_transfer_evaluator::do_evaluate( const override_transfer_op FC_ASSERT( is_authorized_asset( d, to_account, asset_type ) ); FC_ASSERT( is_authorized_asset( d, from_account, asset_type ) ); - if( d.head_block_time() <= HARDFORK_419_TIME ) - { - FC_ASSERT( is_authorized_asset( d, from_account, asset_type ) ); - } - // the above becomes no-op after hardfork because this check will then be performed in evaluator - FC_ASSERT( d.get_balance( from_account, asset_type ).amount >= op.amount.amount, "", ("total_transfer",op.amount)("balance",d.get_balance(from_account, asset_type).amount) ); diff --git a/libraries/chain/vesting_balance_evaluator.cpp b/libraries/chain/vesting_balance_evaluator.cpp index 586045e4e6..5e99c316ea 100644 --- a/libraries/chain/vesting_balance_evaluator.cpp +++ b/libraries/chain/vesting_balance_evaluator.cpp @@ -35,7 +35,7 @@ namespace detail { { if( block_time < HARDFORK_1268_TIME ) { - FC_ASSERT( policy.which() != vesting_policy_initializer::tag::value, + FC_ASSERT( !policy.is_type(), "Instant vesting policy is only available after HARDFORK_1268_TIME!"); } } diff --git a/libraries/chain/vesting_balance_object.cpp b/libraries/chain/vesting_balance_object.cpp index 8735a674f5..2bc8e45a78 100644 --- a/libraries/chain/vesting_balance_object.cpp +++ b/libraries/chain/vesting_balance_object.cpp @@ -24,6 +24,8 @@ #include +#include + namespace graphene { namespace chain { inline bool sum_below_max_shares(const asset& a, const asset& b) @@ -268,3 +270,7 @@ asset vesting_balance_object::get_allowed_withdraw(const time_point_sec& now)con } } } // graphene::chain + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::linear_vesting_policy ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::cdd_vesting_policy ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::chain::vesting_balance_object ) diff --git a/libraries/chain/withdraw_permission_evaluator.cpp b/libraries/chain/withdraw_permission_evaluator.cpp index 4c503c47da..ce3981348e 100644 --- a/libraries/chain/withdraw_permission_evaluator.cpp +++ b/libraries/chain/withdraw_permission_evaluator.cpp @@ -65,9 +65,7 @@ void_result withdraw_permission_claim_evaluator::do_evaluate(const withdraw_perm FC_ASSERT(permit.expiration > head_block_time); FC_ASSERT(permit.authorized_account == op.withdraw_to_account); FC_ASSERT(permit.withdraw_from_account == op.withdraw_from_account); - if (head_block_time >= HARDFORK_23_TIME) { - FC_ASSERT(permit.period_start_time <= head_block_time); - } + FC_ASSERT(permit.period_start_time <= head_block_time); FC_ASSERT(op.amount_to_withdraw <= permit.available_this_period( head_block_time ) ); FC_ASSERT(d.get_balance(op.withdraw_from_account, op.amount_to_withdraw.asset_id) >= op.amount_to_withdraw); @@ -86,17 +84,9 @@ void_result withdraw_permission_claim_evaluator::do_evaluate(const withdraw_perm const account_object& from = op.withdraw_from_account(d); bool from_is_authorized = ( is_authorized_asset( d, from, _asset ) ); - if( head_block_time > HARDFORK_CORE_942_TIME ) // TODO remove this check after hard fork if things in `else` did not occur - { - FC_ASSERT( from_is_authorized, - "Account ${acct} '${name}' is unauthorized to withdraw asset ${a} '${sym}' due to whitelist / blacklist", - ("acct", from.id)("name", from.name)("a", _asset.id)("sym", _asset.symbol) ); - } - else - { - if( !from_is_authorized ) - wlog( "Unauthorized asset withdrawal (issue #942) occurred at block ${b}", ("b", d.head_block_num()) ); - } + FC_ASSERT( from_is_authorized, + "Account ${acct} '${name}' is unauthorized to withdraw asset ${a} '${sym}' due to whitelist / blacklist", + ("acct", from.id)("name", from.name)("a", _asset.id)("sym", _asset.symbol) ); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/witness_evaluator.cpp b/libraries/chain/witness_evaluator.cpp index e5853eb8c4..fea334824c 100644 --- a/libraries/chain/witness_evaluator.cpp +++ b/libraries/chain/witness_evaluator.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace graphene { namespace chain { @@ -41,7 +41,7 @@ object_id_type witness_create_evaluator::do_apply( const witness_create_operatio database& _db = db(); vote_id_type vote_id; _db.modify( _db.get_global_properties(), [&vote_id](global_property_object& p) { - vote_id = get_next_vote_id(p, vote_id_type::witness); + vote_id = vote_id_type(vote_id_type::witness, p.next_available_vote_id++); }); const auto& new_witness_object = _db.create( [&op,&vote_id]( witness_object& obj ){ diff --git a/libraries/chain/worker_evaluator.cpp b/libraries/chain/worker_evaluator.cpp index 240f9723fa..a0463a738a 100644 --- a/libraries/chain/worker_evaluator.cpp +++ b/libraries/chain/worker_evaluator.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include namespace graphene { namespace chain { @@ -85,8 +85,8 @@ object_id_type worker_create_evaluator::do_apply(const worker_create_evaluator:: database& d = db(); vote_id_type for_id, against_id; d.modify(d.get_global_properties(), [&for_id, &against_id](global_property_object& p) { - for_id = get_next_vote_id(p, vote_id_type::worker); - against_id = get_next_vote_id(p, vote_id_type::worker); + for_id = vote_id_type(vote_id_type::worker, p.next_available_vote_id++); + against_id = vote_id_type(vote_id_type::worker, p.next_available_vote_id++); }); return d.create([&](worker_object& w) { diff --git a/libraries/db/CMakeLists.txt b/libraries/db/CMakeLists.txt index 6feb985c6f..b0899d8683 100644 --- a/libraries/db/CMakeLists.txt +++ b/libraries/db/CMakeLists.txt @@ -1,6 +1,6 @@ file(GLOB HEADERS "include/graphene/db/*.hpp") add_library( graphene_db undo_database.cpp index.cpp object_database.cpp ${HEADERS} ) -target_link_libraries( graphene_db fc ) +target_link_libraries( graphene_db graphene_protocol fc ) target_include_directories( graphene_db PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) install( TARGETS diff --git a/libraries/db/include/graphene/db/generic_index.hpp b/libraries/db/include/graphene/db/generic_index.hpp index fb11d44a37..b19fdf0aa7 100644 --- a/libraries/db/include/graphene/db/generic_index.hpp +++ b/libraries/db/include/graphene/db/generic_index.hpp @@ -28,7 +28,7 @@ #include #include -namespace graphene { namespace chain { +namespace graphene { namespace db { using boost::multi_index_container; using namespace boost::multi_index; diff --git a/libraries/db/include/graphene/db/object.hpp b/libraries/db/include/graphene/db/object.hpp index c410e273ee..6da932b029 100644 --- a/libraries/db/include/graphene/db/object.hpp +++ b/libraries/db/include/graphene/db/object.hpp @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #pragma once -#include +#include #include #include #include diff --git a/libraries/db/include/graphene/db/object_database.hpp b/libraries/db/include/graphene/db/object_database.hpp index b5e85d76a3..c7825572fb 100644 --- a/libraries/db/include/graphene/db/object_database.hpp +++ b/libraries/db/include/graphene/db/object_database.hpp @@ -121,11 +121,15 @@ namespace graphene { namespace db { return static_cast(obj); } - template - const T* find( object_id id )const { return find(id); } + template + auto find( object_id id )const -> const object_downcast_t* { + return find>(id); + } - template - const T& get( object_id id )const { return get(id); } + template + auto get( object_id id )const -> const object_downcast_t& { + return get>(id); + } template IndexType* add_index() diff --git a/libraries/egenesis/README-dev.md b/libraries/egenesis/README-dev.md new file mode 100644 index 0000000000..3548a25cd6 --- /dev/null +++ b/libraries/egenesis/README-dev.md @@ -0,0 +1,6 @@ +Use this key to produce blocks with the `genesis-dev.json` Genesis. +The following line may be added directly to `config.ini`: + +``` +private-key = ["BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV","5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"] +``` diff --git a/libraries/egenesis/egenesis_brief.cpp.tmpl b/libraries/egenesis/egenesis_brief.cpp.tmpl index d026c599ad..be2ceab386 100644 --- a/libraries/egenesis/egenesis_brief.cpp.tmpl +++ b/libraries/egenesis/egenesis_brief.cpp.tmpl @@ -23,7 +23,7 @@ ${generated_file_banner} * THE SOFTWARE. */ -#include +#include #include namespace graphene { namespace egenesis { diff --git a/libraries/egenesis/egenesis_full.cpp.tmpl b/libraries/egenesis/egenesis_full.cpp.tmpl index d89a694bc5..0aead4c823 100644 --- a/libraries/egenesis/egenesis_full.cpp.tmpl +++ b/libraries/egenesis/egenesis_full.cpp.tmpl @@ -23,7 +23,7 @@ ${generated_file_banner} * THE SOFTWARE. */ -#include +#include #include namespace graphene { namespace egenesis { diff --git a/libraries/egenesis/egenesis_none.cpp b/libraries/egenesis/egenesis_none.cpp index 825f7f83fe..c7a0dcdde3 100644 --- a/libraries/egenesis/egenesis_none.cpp +++ b/libraries/egenesis/egenesis_none.cpp @@ -24,6 +24,8 @@ #include +#include + namespace graphene { namespace egenesis { using namespace graphene::chain; diff --git a/libraries/egenesis/embed_genesis.cpp b/libraries/egenesis/embed_genesis.cpp index 6854e9f6d3..a23a32b80c 100644 --- a/libraries/egenesis/embed_genesis.cpp +++ b/libraries/egenesis/embed_genesis.cpp @@ -34,10 +34,10 @@ #include #include #include -#include +#include // we need to include the world in order to serialize fee_parameters -#include +#include using namespace graphene::chain; @@ -217,7 +217,7 @@ void load_genesis( } int main( int argc, char** argv ) -{ +{ try { int main_return = 0; boost::program_options::options_description cli_options("Graphene Chain Identifier"); cli_options.add_options() @@ -285,4 +285,4 @@ int main( int argc, char** argv ) } return main_return; -} +} FC_LOG_AND_RETHROW() } diff --git a/libraries/egenesis/genesis-dev.json b/libraries/egenesis/genesis-dev.json new file mode 100644 index 0000000000..dcc2cdd913 --- /dev/null +++ b/libraries/egenesis/genesis-dev.json @@ -0,0 +1,384 @@ +{ + "initial_timestamp": "2019-02-14T20:32:55", + "max_core_supply": "1000000000000000", + "initial_parameters": { + "current_fees": { + "parameters": [[ + 0,{ + "fee": 2000000, + "price_per_kbyte": 1000000 + } + ],[ + 1,{ + "fee": 500000 + } + ],[ + 2,{ + "fee": 0 + } + ],[ + 3,{ + "fee": 2000000 + } + ],[ + 4,{} + ],[ + 5,{ + "basic_fee": 500000, + "premium_fee": 200000000, + "price_per_kbyte": 100000 + } + ],[ + 6,{ + "fee": 2000000, + "price_per_kbyte": 100000 + } + ],[ + 7,{ + "fee": 300000 + } + ],[ + 8,{ + "membership_annual_fee": 200000000, + "membership_lifetime_fee": 1000000000 + } + ],[ + 9,{ + "fee": 50000000 + } + ],[ + 10,{ + "symbol3": "50000000000", + "symbol4": "30000000000", + "long_symbol": 500000000, + "price_per_kbyte": 10 + } + ],[ + 11,{ + "fee": 50000000, + "price_per_kbyte": 10 + } + ],[ + 12,{ + "fee": 50000000 + } + ],[ + 13,{ + "fee": 50000000 + } + ],[ + 14,{ + "fee": 2000000, + "price_per_kbyte": 100000 + } + ],[ + 15,{ + "fee": 2000000 + } + ],[ + 16,{ + "fee": 100000 + } + ],[ + 17,{ + "fee": 10000000 + } + ],[ + 18,{ + "fee": 50000000 + } + ],[ + 19,{ + "fee": 100000 + } + ],[ + 20,{ + "fee": 500000000 + } + ],[ + 21,{ + "fee": 2000000 + } + ],[ + 22,{ + "fee": 2000000, + "price_per_kbyte": 10 + } + ],[ + 23,{ + "fee": 2000000, + "price_per_kbyte": 10 + } + ],[ + 24,{ + "fee": 100000 + } + ],[ + 25,{ + "fee": 100000 + } + ],[ + 26,{ + "fee": 100000 + } + ],[ + 27,{ + "fee": 2000000, + "price_per_kbyte": 10 + } + ],[ + 28,{ + "fee": 0 + } + ],[ + 29,{ + "fee": 500000000 + } + ],[ + 30,{ + "fee": 2000000 + } + ],[ + 31,{ + "fee": 100000 + } + ],[ + 32,{ + "fee": 100000 + } + ],[ + 33,{ + "fee": 2000000 + } + ],[ + 34,{ + "fee": 500000000 + } + ],[ + 35,{ + "fee": 100000, + "price_per_kbyte": 10 + } + ],[ + 36,{ + "fee": 100000 + } + ],[ + 37,{} + ],[ + 38,{ + "fee": 2000000, + "price_per_kbyte": 10 + } + ],[ + 39,{ + "fee": 500000, + "price_per_output": 500000 + } + ],[ + 40,{ + "fee": 500000, + "price_per_output": 500000 + } + ],[ + 41,{ + "fee": 500000 + } + ],[ + 42,{} + ],[ + 43,{ + "fee": 2000000 + } + ],[ + 44,{} + ],[ + 45,{ + "fee": 2000000 + } + ],[ + 46,{} + ],[ + 47,{ + "fee": 2000000 + } + ],[ + 48,{ + "fee": 2000000 + } + ] + ], + "scale": 10000 + }, + "block_interval": 5, + "maintenance_interval": 86400, + "maintenance_skip_slots": 3, + "committee_proposal_review_period": 1209600, + "maximum_transaction_size": 2048, + "maximum_block_size": 2000000, + "maximum_time_until_expiration": 86400, + "maximum_proposal_lifetime": 2419200, + "maximum_asset_whitelist_authorities": 10, + "maximum_asset_feed_publishers": 10, + "maximum_witness_count": 1001, + "maximum_committee_count": 1001, + "maximum_authority_membership": 10, + "reserve_percent_of_fee": 2000, + "network_percent_of_fee": 2000, + "lifetime_referrer_percent_of_fee": 3000, + "cashback_vesting_period_seconds": 31536000, + "cashback_vesting_threshold": 10000000, + "count_non_member_votes": true, + "allow_non_member_whitelists": false, + "witness_pay_per_block": 1000000, + "worker_budget_per_day": "50000000000", + "max_predicate_opcode": 1, + "fee_liquidation_threshold": 10000000, + "accounts_per_fee_scale": 1000, + "account_fee_scale_bitshifts": 4, + "max_authority_depth": 2, + "extensions": { + "updatable_htlc_options": { + "max_timeout_secs": 2592000, + "max_preimage_size": 1024000 + } + } + }, + "initial_accounts": [{ + "name": "init0", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init1", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init2", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init3", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init4", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init5", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init6", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init7", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init8", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init9", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "init10", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": true + },{ + "name": "nathan", + "owner_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "active_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "is_lifetime_member": false + } + ], + "initial_assets": [], + "initial_balances": [{ + "owner": "BTSFAbAx7yuxt725qSZvfwWqkdCwp9ZnUama", + "asset_symbol": "BTS", + "amount": "1000000000000000" + } + ], + "initial_vesting_balances": [], + "initial_active_witnesses": 11, + "initial_witness_candidates": [{ + "owner_name": "init0", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init1", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init2", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init3", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init4", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init5", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init6", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init7", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init8", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init9", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + },{ + "owner_name": "init10", + "block_signing_key": "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + } + ], + "initial_committee_candidates": [{ + "owner_name": "init0" + },{ + "owner_name": "init1" + },{ + "owner_name": "init2" + },{ + "owner_name": "init3" + },{ + "owner_name": "init4" + },{ + "owner_name": "init5" + },{ + "owner_name": "init6" + },{ + "owner_name": "init7" + },{ + "owner_name": "init8" + },{ + "owner_name": "init9" + },{ + "owner_name": "init10" + } + ], + "initial_worker_candidates": [], + "immutable_parameters": { + "min_committee_member_count": 11, + "min_witness_count": 11, + "num_special_accounts": 0, + "num_special_assets": 0 + } +} diff --git a/genesis.json b/libraries/egenesis/genesis.json similarity index 100% rename from genesis.json rename to libraries/egenesis/genesis.json diff --git a/libraries/egenesis/include/graphene/egenesis/egenesis.hpp b/libraries/egenesis/include/graphene/egenesis/egenesis.hpp index 848a4d29c4..8d5753017d 100644 --- a/libraries/egenesis/include/graphene/egenesis/egenesis.hpp +++ b/libraries/egenesis/include/graphene/egenesis/egenesis.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include namespace graphene { namespace egenesis { diff --git a/libraries/fc b/libraries/fc index 8ebd99b786..a87a99bbeb 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 8ebd99b786623bc8d55e89d42df82644a71a6885 +Subproject commit a87a99bbeba9467aa23f1b012e79908e20e87309 diff --git a/libraries/net/CMakeLists.txt b/libraries/net/CMakeLists.txt index 4110098a1f..b533e61a35 100644 --- a/libraries/net/CMakeLists.txt +++ b/libraries/net/CMakeLists.txt @@ -3,14 +3,16 @@ file(GLOB HEADERS "include/graphene/net/*.hpp") set(SOURCES node.cpp stcp_socket.cpp core_messages.cpp + exceptions.cpp peer_database.cpp peer_connection.cpp + message.cpp message_oriented_connection.cpp) add_library( graphene_net ${SOURCES} ${HEADERS} ) target_link_libraries( graphene_net - PUBLIC fc graphene_db ) + PUBLIC fc graphene_db graphene_protocol ) target_include_directories( graphene_net PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" PRIVATE "${CMAKE_SOURCE_DIR}/libraries/chain/include" diff --git a/libraries/net/core_messages.cpp b/libraries/net/core_messages.cpp index efff812d3f..fc3017d243 100644 --- a/libraries/net/core_messages.cpp +++ b/libraries/net/core_messages.cpp @@ -23,6 +23,7 @@ */ #include +#include namespace graphene { namespace net { @@ -48,3 +49,105 @@ namespace graphene { namespace net { } } // graphene::net +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::trx_message, BOOST_PP_SEQ_NIL, (trx) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::block_message, BOOST_PP_SEQ_NIL, (block)(block_id) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::item_id, BOOST_PP_SEQ_NIL, + (item_type) + (item_hash) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::item_ids_inventory_message, BOOST_PP_SEQ_NIL, + (item_type) + (item_hashes_available) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::blockchain_item_ids_inventory_message, BOOST_PP_SEQ_NIL, + (total_remaining_item_count) + (item_type) + (item_hashes_available) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::fetch_blockchain_item_ids_message, BOOST_PP_SEQ_NIL, + (item_type) + (blockchain_synopsis) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::fetch_items_message, BOOST_PP_SEQ_NIL, + (item_type) + (items_to_fetch) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::item_not_available_message, BOOST_PP_SEQ_NIL, (requested_item) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::hello_message, BOOST_PP_SEQ_NIL, + (user_agent) + (core_protocol_version) + (inbound_address) + (inbound_port) + (outbound_port) + (node_public_key) + (signed_shared_secret) + (chain_id) + (user_data) ) + +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::connection_accepted_message, BOOST_PP_SEQ_NIL, BOOST_PP_SEQ_NIL ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::connection_rejected_message, BOOST_PP_SEQ_NIL, + (user_agent) + (core_protocol_version) + (remote_endpoint) + (reason_code) + (reason_string)) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::address_request_message, BOOST_PP_SEQ_NIL, BOOST_PP_SEQ_NIL ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::address_info, BOOST_PP_SEQ_NIL, + (remote_endpoint) + (last_seen_time) + (latency) + (node_id) + (direction) + (firewalled) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::address_message, BOOST_PP_SEQ_NIL, (addresses) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::closing_connection_message, BOOST_PP_SEQ_NIL, + (reason_for_closing) + (closing_due_to_error) + (error) ) + +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::current_time_request_message, BOOST_PP_SEQ_NIL, (request_sent_time)) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::current_time_reply_message, BOOST_PP_SEQ_NIL, + (request_sent_time) + (request_received_time) + (reply_transmitted_time)) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::check_firewall_message, BOOST_PP_SEQ_NIL, (node_id)(endpoint_to_check)) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::check_firewall_reply_message, BOOST_PP_SEQ_NIL, + (node_id)(endpoint_checked)(result)) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::get_current_connections_request_message, + BOOST_PP_SEQ_NIL, BOOST_PP_SEQ_NIL) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::current_connection_data, BOOST_PP_SEQ_NIL, + (connection_duration) + (remote_endpoint) + (node_id) + (clock_offset) + (round_trip_delay) + (connection_direction) + (firewalled) + (user_data)) +FC_REFLECT_DERIVED_NO_TYPENAME(graphene::net::get_current_connections_reply_message, BOOST_PP_SEQ_NIL, + (upload_rate_one_minute) + (download_rate_one_minute) + (upload_rate_fifteen_minutes) + (download_rate_fifteen_minutes) + (upload_rate_one_hour) + (download_rate_one_hour) + (current_connections)) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::trx_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::block_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::item_id ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::item_ids_inventory_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::blockchain_item_ids_inventory_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::fetch_blockchain_item_ids_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::fetch_items_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::item_not_available_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::hello_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::connection_accepted_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::connection_rejected_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::address_request_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::address_info ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::address_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::closing_connection_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::current_time_request_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::current_time_reply_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::check_firewall_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::check_firewall_reply_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::get_current_connections_request_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::current_connection_data ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::get_current_connections_reply_message ) diff --git a/libraries/net/exceptions.cpp b/libraries/net/exceptions.cpp new file mode 100644 index 0000000000..7b6e23dc5d --- /dev/null +++ b/libraries/net/exceptions.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 BitShares Blockchain Foundation, 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 + +namespace graphene { namespace net { + + FC_IMPLEMENT_EXCEPTION( net_exception, 90000, "P2P Networking Exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( send_queue_overflow, net_exception, 90001, + "send queue for this peer exceeded maximum size" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( insufficient_relay_fee, net_exception, 90002, + "insufficient relay fee" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( already_connected_to_requested_peer, net_exception, 90003, + "already connected to requested peer" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( block_older_than_undo_history, net_exception, 90004, + "block is older than our undo history allows us to process" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, net_exception, 90005, + "peer is on another fork" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( unlinkable_block_exception, net_exception, 90006, "unlinkable block" ) + +} } diff --git a/libraries/net/include/graphene/net/core_messages.hpp b/libraries/net/include/graphene/net/core_messages.hpp index 76f74bd253..88d563e683 100644 --- a/libraries/net/include/graphene/net/core_messages.hpp +++ b/libraries/net/include/graphene/net/core_messages.hpp @@ -24,26 +24,25 @@ #pragma once #include -#include #include #include #include #include -#include #include #include #include #include +#include #include namespace graphene { namespace net { - using graphene::chain::signed_transaction; - using graphene::chain::block_id_type; - using graphene::chain::transaction_id_type; - using graphene::chain::signed_block; + using graphene::protocol::signed_transaction; + using graphene::protocol::block_id_type; + using graphene::protocol::transaction_id_type; + using graphene::protocol::signed_block; typedef fc::ecc::public_key_data node_id_t; typedef fc::ripemd160 item_hash_t; @@ -95,9 +94,9 @@ namespace graphene { namespace net { { static const core_message_type_enum type; - graphene::chain::precomputable_transaction trx; + graphene::protocol::precomputable_transaction trx; trx_message() {} - trx_message(graphene::chain::signed_transaction transaction) : + trx_message(graphene::protocol::signed_transaction transaction) : trx(std::move(transaction)) {} }; @@ -400,7 +399,6 @@ namespace graphene { namespace net { std::vector current_connections; }; - } } // graphene::net FC_REFLECT_ENUM( graphene::net::core_message_type_enum, @@ -425,33 +423,6 @@ FC_REFLECT_ENUM( graphene::net::core_message_type_enum, (get_current_connections_request_message_type) (get_current_connections_reply_message_type) (core_message_type_last) ) - -FC_REFLECT( graphene::net::trx_message, (trx) ) -FC_REFLECT( graphene::net::block_message, (block)(block_id) ) - -FC_REFLECT( graphene::net::item_id, (item_type) - (item_hash) ) -FC_REFLECT( graphene::net::item_ids_inventory_message, (item_type) - (item_hashes_available) ) -FC_REFLECT( graphene::net::blockchain_item_ids_inventory_message, (total_remaining_item_count) - (item_type) - (item_hashes_available) ) -FC_REFLECT( graphene::net::fetch_blockchain_item_ids_message, (item_type) - (blockchain_synopsis) ) -FC_REFLECT( graphene::net::fetch_items_message, (item_type) - (items_to_fetch) ) -FC_REFLECT( graphene::net::item_not_available_message, (requested_item) ) -FC_REFLECT( graphene::net::hello_message, (user_agent) - (core_protocol_version) - (inbound_address) - (inbound_port) - (outbound_port) - (node_public_key) - (signed_shared_secret) - (chain_id) - (user_data) ) - -FC_REFLECT_EMPTY( graphene::net::connection_accepted_message ) FC_REFLECT_ENUM(graphene::net::rejection_reason_code, (unspecified) (different_chain) (already_connected) @@ -460,54 +431,61 @@ FC_REFLECT_ENUM(graphene::net::rejection_reason_code, (unspecified) (blocked) (invalid_hello_message) (client_too_old)) -FC_REFLECT( graphene::net::connection_rejected_message, (user_agent) - (core_protocol_version) - (remote_endpoint) - (reason_code) - (reason_string)) -FC_REFLECT_EMPTY( graphene::net::address_request_message ) -FC_REFLECT( graphene::net::address_info, (remote_endpoint) - (last_seen_time) - (latency) - (node_id) - (direction) - (firewalled) ) -FC_REFLECT( graphene::net::address_message, (addresses) ) -FC_REFLECT( graphene::net::closing_connection_message, (reason_for_closing) - (closing_due_to_error) - (error) ) FC_REFLECT_ENUM(graphene::net::peer_connection_direction, (unknown) (inbound) (outbound)) FC_REFLECT_ENUM(graphene::net::firewalled_state, (unknown) (firewalled) (not_firewalled)) - -FC_REFLECT(graphene::net::current_time_request_message, (request_sent_time)) -FC_REFLECT(graphene::net::current_time_reply_message, (request_sent_time) - (request_received_time) - (reply_transmitted_time)) FC_REFLECT_ENUM(graphene::net::firewall_check_result, (unable_to_check) (unable_to_connect) (connection_successful)) -FC_REFLECT(graphene::net::check_firewall_message, (node_id)(endpoint_to_check)) -FC_REFLECT(graphene::net::check_firewall_reply_message, (node_id)(endpoint_checked)(result)) -FC_REFLECT_EMPTY(graphene::net::get_current_connections_request_message) -FC_REFLECT(graphene::net::current_connection_data, (connection_duration) - (remote_endpoint) - (node_id) - (clock_offset) - (round_trip_delay) - (connection_direction) - (firewalled) - (user_data)) -FC_REFLECT(graphene::net::get_current_connections_reply_message, (upload_rate_one_minute) - (download_rate_one_minute) - (upload_rate_fifteen_minutes) - (download_rate_fifteen_minutes) - (upload_rate_one_hour) - (download_rate_one_hour) - (current_connections)) + +FC_REFLECT_TYPENAME( graphene::net::trx_message ) +FC_REFLECT_TYPENAME( graphene::net::block_message ) +FC_REFLECT_TYPENAME( graphene::net::item_id ) +FC_REFLECT_TYPENAME( graphene::net::item_ids_inventory_message ) +FC_REFLECT_TYPENAME( graphene::net::blockchain_item_ids_inventory_message ) +FC_REFLECT_TYPENAME( graphene::net::fetch_blockchain_item_ids_message ) +FC_REFLECT_TYPENAME( graphene::net::fetch_items_message ) +FC_REFLECT_TYPENAME( graphene::net::item_not_available_message ) +FC_REFLECT_TYPENAME( graphene::net::hello_message ) +FC_REFLECT_TYPENAME( graphene::net::connection_accepted_message ) +FC_REFLECT_TYPENAME( graphene::net::connection_rejected_message ) +FC_REFLECT_TYPENAME( graphene::net::address_request_message ) +FC_REFLECT_TYPENAME( graphene::net::address_info ) +FC_REFLECT_TYPENAME( graphene::net::address_message ) +FC_REFLECT_TYPENAME( graphene::net::closing_connection_message ) +FC_REFLECT_TYPENAME( graphene::net::current_time_request_message ) +FC_REFLECT_TYPENAME( graphene::net::current_time_reply_message ) +FC_REFLECT_TYPENAME( graphene::net::check_firewall_message ) +FC_REFLECT_TYPENAME( graphene::net::check_firewall_reply_message ) +FC_REFLECT_TYPENAME( graphene::net::get_current_connections_request_message ) +FC_REFLECT_TYPENAME( graphene::net::current_connection_data ) +FC_REFLECT_TYPENAME( graphene::net::get_current_connections_reply_message ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::trx_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::block_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::item_id ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::item_ids_inventory_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::blockchain_item_ids_inventory_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::fetch_blockchain_item_ids_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::fetch_items_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::item_not_available_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::hello_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::connection_accepted_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::connection_rejected_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::address_request_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::address_info ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::address_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::closing_connection_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::current_time_request_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::current_time_reply_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::check_firewall_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::check_firewall_reply_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::get_current_connections_request_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::current_connection_data ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::get_current_connections_reply_message ) #include #include diff --git a/libraries/net/include/graphene/net/exceptions.hpp b/libraries/net/include/graphene/net/exceptions.hpp index 59da8ccb45..e95eea8759 100644 --- a/libraries/net/include/graphene/net/exceptions.hpp +++ b/libraries/net/include/graphene/net/exceptions.hpp @@ -27,12 +27,12 @@ namespace graphene { namespace net { // registered in node.cpp - FC_DECLARE_EXCEPTION( net_exception, 90000, "P2P Networking Exception" ); - FC_DECLARE_DERIVED_EXCEPTION( send_queue_overflow, graphene::net::net_exception, 90001, "send queue for this peer exceeded maximum size" ); - FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::net::net_exception, 90002, "insufficient relay fee" ); - FC_DECLARE_DERIVED_EXCEPTION( already_connected_to_requested_peer, graphene::net::net_exception, 90003, "already connected to requested peer" ); - FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::net::net_exception, 90004, "block is older than our undo history allows us to process" ); - FC_DECLARE_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, graphene::net::net_exception, 90005, "peer is on another fork" ); - FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, graphene::net::net_exception, 90006, "unlinkable block" ) + FC_DECLARE_EXCEPTION( net_exception, 90000 ) + FC_DECLARE_DERIVED_EXCEPTION( send_queue_overflow, net_exception, 90001 ) + FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, net_exception, 90002 ) + FC_DECLARE_DERIVED_EXCEPTION( already_connected_to_requested_peer, net_exception, 90003 ) + FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, net_exception, 90004 ) + FC_DECLARE_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, net_exception, 90005 ) + FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, net_exception, 90006 ) } } diff --git a/libraries/net/include/graphene/net/message.hpp b/libraries/net/include/graphene/net/message.hpp index 9cbc0af94c..8ebfd8caa3 100644 --- a/libraries/net/include/graphene/net/message.hpp +++ b/libraries/net/include/graphene/net/message.hpp @@ -22,12 +22,16 @@ * THE SOFTWARE. */ #pragma once +#include + +#include + #include #include #include -#include +#include #include -#include +#include namespace graphene { namespace net { @@ -39,8 +43,8 @@ namespace graphene { namespace net { */ struct message_header { - uint32_t size; // number of bytes in message, capped at MAX_MESSAGE_SIZE - uint32_t msg_type; // every channel gets a 16 bit message type specifier + boost::endian::little_uint32_buf_t size; // number of bytes in message, capped at MAX_MESSAGE_SIZE + boost::endian::little_uint32_buf_t msg_type; // every channel gets a 16 bit message type specifier }; typedef fc::uint160_t message_hash_type; @@ -85,7 +89,7 @@ namespace graphene { namespace net { T as()const { try { - FC_ASSERT( msg_type == T::type ); + FC_ASSERT( msg_type.value() == T::type ); T tmp; if( data.size() ) { @@ -103,15 +107,15 @@ namespace graphene { namespace net { "error unpacking network message as a '${type}' ${x} !=? ${msg_type}", ("type", fc::get_typename::name() ) ("x", T::type) - ("msg_type", msg_type) + ("msg_type", msg_type.value()) ); } }; - - - } } // graphene::net -FC_REFLECT( graphene::net::message_header, (size)(msg_type) ) -FC_REFLECT_DERIVED( graphene::net::message, (graphene::net::message_header), (data) ) +FC_REFLECT_TYPENAME( graphene::net::message_header ) +FC_REFLECT_TYPENAME( graphene::net::message ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::message_header) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::message) diff --git a/libraries/net/include/graphene/net/node.hpp b/libraries/net/include/graphene/net/node.hpp index e17af148c2..fe03ac0cb6 100644 --- a/libraries/net/include/graphene/net/node.hpp +++ b/libraries/net/include/graphene/net/node.hpp @@ -27,14 +27,14 @@ #include #include -#include +#include #include namespace graphene { namespace net { using fc::variant_object; - using graphene::chain::chain_id_type; + using graphene::protocol::chain_id_type; namespace detail { @@ -193,7 +193,7 @@ namespace graphene { namespace net { { public: node(const std::string& user_agent); - ~node(); + virtual ~node(); void close(); @@ -272,8 +272,8 @@ namespace graphene { namespace net { void set_advanced_node_parameters(const fc::variant_object& params); fc::variant_object get_advanced_node_parameters(); - message_propagation_data get_transaction_propagation_data(const graphene::chain::transaction_id_type& transaction_id); - message_propagation_data get_block_propagation_data(const graphene::chain::block_id_type& block_id); + message_propagation_data get_transaction_propagation_data(const graphene::protocol::transaction_id_type& transaction_id); + message_propagation_data get_block_propagation_data(const graphene::protocol::block_id_type& block_id); node_id_t get_node_id() const; void set_allowed_peers(const std::vector& allowed_peers); diff --git a/libraries/net/include/graphene/net/peer_connection.hpp b/libraries/net/include/graphene/net/peer_connection.hpp index b6c24ef3de..dd9d6eb774 100644 --- a/libraries/net/include/graphene/net/peer_connection.hpp +++ b/libraries/net/include/graphene/net/peer_connection.hpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -35,9 +34,7 @@ #include #include #include -#include #include -#include #include #include @@ -65,6 +62,7 @@ namespace graphene { namespace net class peer_connection_delegate { public: + virtual ~peer_connection_delegate() = default; virtual void on_message(peer_connection* originating_peer, const message& received_message) = 0; virtual void on_connection_closed(peer_connection* originating_peer) = 0; diff --git a/libraries/net/include/graphene/net/peer_database.hpp b/libraries/net/include/graphene/net/peer_database.hpp index d0a06dd9c6..8b7e18b894 100644 --- a/libraries/net/include/graphene/net/peer_database.hpp +++ b/libraries/net/include/graphene/net/peer_database.hpp @@ -24,13 +24,14 @@ #pragma once #include +#include + #include #include #include #include #include #include -#include namespace graphene { namespace net { @@ -118,5 +119,6 @@ namespace graphene { namespace net { } } // end namespace graphene::net -FC_REFLECT_ENUM(graphene::net::potential_peer_last_connection_disposition, (never_attempted_to_connect)(last_connection_failed)(last_connection_rejected)(last_connection_handshaking_failed)(last_connection_succeeded)) -FC_REFLECT(graphene::net::potential_peer_record, (endpoint)(last_seen_time)(last_connection_disposition)(last_connection_attempt_time)(number_of_successful_connection_attempts)(number_of_failed_connection_attempts)(last_error) ) +FC_REFLECT_TYPENAME( graphene::net::potential_peer_record ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::net::potential_peer_record) diff --git a/libraries/db/include/graphene/db/fwd.hpp b/libraries/net/message.cpp similarity index 70% rename from libraries/db/include/graphene/db/fwd.hpp rename to libraries/net/message.cpp index 36b4e7138d..8acef0ac08 100644 --- a/libraries/db/include/graphene/db/fwd.hpp +++ b/libraries/net/message.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Cryptonomex, Inc., and contributors. + * Copyright (c) 2019 BitShares Blockchain Foundation, and contributors. * * The MIT License * @@ -21,15 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#pragma once -#include +#include -namespace graphene { namespace db { +#include - class peer; - typedef std::shared_ptr peer_ptr; +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::message_header, BOOST_PP_SEQ_NIL, (size)(msg_type) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::message, (graphene::net::message_header), (data) ) - class peer_ram; - typedef std::shared_ptr peer_ram_ptr; - -}} // namespace graphene::db +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::message_header) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::message) diff --git a/libraries/net/message_oriented_connection.cpp b/libraries/net/message_oriented_connection.cpp index 858f615d3f..de3cf0875b 100644 --- a/libraries/net/message_oriented_connection.cpp +++ b/libraries/net/message_oriented_connection.cpp @@ -153,16 +153,15 @@ namespace graphene { namespace net { try { message m; + char buffer[BUFFER_SIZE]; while( true ) { - char buffer[BUFFER_SIZE]; _sock.read(buffer, BUFFER_SIZE); _bytes_received += BUFFER_SIZE; memcpy((char*)&m, buffer, sizeof(message_header)); + FC_ASSERT( m.size.value() <= MAX_MESSAGE_SIZE, "", ("m.size",m.size.value())("MAX_MESSAGE_SIZE",MAX_MESSAGE_SIZE) ); - FC_ASSERT( m.size <= MAX_MESSAGE_SIZE, "", ("m.size",m.size)("MAX_MESSAGE_SIZE",MAX_MESSAGE_SIZE) ); - - size_t remaining_bytes_with_padding = 16 * ((m.size - LEFTOVER + 15) / 16); + size_t remaining_bytes_with_padding = 16 * ((m.size.value() - LEFTOVER + 15) / 16); m.data.resize(LEFTOVER + remaining_bytes_with_padding); //give extra 16 bytes to allow for padding added in send call std::copy(buffer + sizeof(message_header), buffer + sizeof(buffer), m.data.begin()); if (remaining_bytes_with_padding) @@ -170,7 +169,7 @@ namespace graphene { namespace net { _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding); _bytes_received += remaining_bytes_with_padding; } - m.data.resize(m.size); // truncate off the padding bytes + m.data.resize(m.size.value()); // truncate off the padding bytes _last_message_received_time = fc::time_point::now(); @@ -255,14 +254,14 @@ namespace graphene { namespace net { try { - size_t size_of_message_and_header = sizeof(message_header) + message_to_send.size; - if( message_to_send.size > MAX_MESSAGE_SIZE ) + size_t size_of_message_and_header = sizeof(message_header) + message_to_send.size.value(); + if( message_to_send.size.value() > MAX_MESSAGE_SIZE ) elog("Trying to send a message larger than MAX_MESSAGE_SIZE. This probably won't work..."); //pad the message we send to a multiple of 16 bytes size_t size_with_padding = 16 * ((size_of_message_and_header + 15) / 16); std::unique_ptr padded_message(new char[size_with_padding]); memcpy(padded_message.get(), (char*)&message_to_send, sizeof(message_header)); - memcpy(padded_message.get() + sizeof(message_header), message_to_send.data.data(), message_to_send.size ); + memcpy(padded_message.get() + sizeof(message_header), message_to_send.data.data(), message_to_send.size.value() ); _sock.write(padded_message.get(), size_with_padding); _sock.flush(); _bytes_sent += size_with_padding; diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index b2fc5009b7..f570dac5bf 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -78,7 +79,10 @@ #include #include -#include +// Nasty hack: A circular dependency around fee_schedule is resolved by fwd-declaring it and using a shared_ptr +// to it in chain_parameters, which is used in an operation and thus must be serialized by the net library. +// Resolving that forward declaration doesn't happen until now: +#include #include @@ -1254,10 +1258,10 @@ namespace graphene { namespace net { namespace detail { VERIFY_CORRECT_THREAD(); message_hash_type message_hash = received_message.id(); dlog("handling message ${type} ${hash} size ${size} from peer ${endpoint}", - ("type", graphene::net::core_message_type_enum(received_message.msg_type))("hash", message_hash) + ("type", graphene::net::core_message_type_enum(received_message.msg_type.value()))("hash", message_hash) ("size", received_message.size) ("endpoint", originating_peer->get_remote_endpoint())); - switch ( received_message.msg_type ) + switch ( received_message.msg_type.value() ) { case core_message_type_enum::hello_message_type: on_hello_message(originating_peer, received_message.as()); @@ -1317,8 +1321,8 @@ namespace graphene { namespace net { namespace detail { default: // ignore any message in between core_message_type_first and _last that we don't handle above // to allow us to add messages in the future - if (received_message.msg_type < core_message_type_enum::core_message_type_first || - received_message.msg_type > core_message_type_enum::core_message_type_last) + if (received_message.msg_type.value() < core_message_type_enum::core_message_type_first || + received_message.msg_type.value() > core_message_type_enum::core_message_type_last) process_ordinary_message(originating_peer, received_message, message_hash); break; } @@ -2303,7 +2307,7 @@ namespace graphene { namespace net { namespace detail { for (const message& reply : reply_messages) { - if (reply.msg_type == block_message_type) + if (reply.msg_type.value() == block_message_type) originating_peer->send_item(item_id(block_message_type, reply.as().block_id)); else originating_peer->send_message(reply); @@ -3360,7 +3364,7 @@ namespace graphene { namespace net { namespace detail { fc::time_point message_receive_time = fc::time_point::now(); // only process it if we asked for it - auto iter = originating_peer->items_requested_from_peer.find( item_id(message_to_process.msg_type, message_hash) ); + auto iter = originating_peer->items_requested_from_peer.find( item_id(message_to_process.msg_type.value(), message_hash) ); if( iter == originating_peer->items_requested_from_peer.end() ) { wlog( "received a message I didn't ask for from peer ${endpoint}, disconnecting from peer", @@ -3380,7 +3384,7 @@ namespace graphene { namespace net { namespace detail { fc::time_point message_validated_time; try { - if (message_to_process.msg_type == trx_message_type) + if (message_to_process.msg_type.value() == trx_message_type) { trx_message transaction_message_to_process = message_to_process.as(); dlog("passing message containing transaction ${trx} to client", ("trx", transaction_message_to_process.trx.id())); @@ -3398,7 +3402,7 @@ namespace graphene { namespace net { namespace detail { { wlog( "client rejected message sent by peer ${peer}, ${e}", ("peer", originating_peer->get_remote_endpoint() )("e", e) ); // record it so we don't try to fetch this item again - _recently_failed_items.insert(peer_connection::timestamped_item_id(item_id(message_to_process.msg_type, message_hash ), fc::time_point::now())); + _recently_failed_items.insert(peer_connection::timestamped_item_id(item_id(message_to_process.msg_type.value(), message_hash ), fc::time_point::now())); return; } @@ -4431,13 +4435,13 @@ namespace graphene { namespace net { namespace detail { { VERIFY_CORRECT_THREAD(); fc::uint160_t hash_of_message_contents; - if( item_to_broadcast.msg_type == graphene::net::block_message_type ) + if( item_to_broadcast.msg_type.value() == graphene::net::block_message_type ) { graphene::net::block_message block_message_to_broadcast = item_to_broadcast.as(); hash_of_message_contents = block_message_to_broadcast.block_id; // for debugging _most_recent_blocks_accepted.push_back( block_message_to_broadcast.block_id ); } - else if( item_to_broadcast.msg_type == graphene::net::trx_message_type ) + else if( item_to_broadcast.msg_type.value() == graphene::net::trx_message_type ) { graphene::net::trx_message transaction_message_to_broadcast = item_to_broadcast.as(); hash_of_message_contents = transaction_message_to_broadcast.trx.id(); // for debugging @@ -4446,7 +4450,7 @@ namespace graphene { namespace net { namespace detail { message_hash_type hash_of_item_to_broadcast = item_to_broadcast.id(); _message_cache.cache_message( item_to_broadcast, hash_of_item_to_broadcast, propagation_data, hash_of_message_contents ); - _new_inventory.insert( item_id(item_to_broadcast.msg_type, hash_of_item_to_broadcast ) ); + _new_inventory.insert( item_id(item_to_broadcast.msg_type.value(), hash_of_item_to_broadcast ) ); trigger_advertise_inventory_loop(); } @@ -4824,9 +4828,9 @@ namespace graphene { namespace net { namespace detail { try { const message& message_to_deliver = destination_node->messages_to_deliver.front(); - if (message_to_deliver.msg_type == trx_message_type) + if (message_to_deliver.msg_type.value() == trx_message_type) destination_node->delegate->handle_transaction(message_to_deliver.as()); - else if (message_to_deliver.msg_type == block_message_type) + else if (message_to_deliver.msg_type.value() == block_message_type) { std::vector contained_transaction_message_ids; destination_node->delegate->handle_block(message_to_deliver.as(), false, contained_transaction_message_ids); @@ -4909,7 +4913,8 @@ namespace graphene { namespace net { namespace detail { # define INVOKE_AND_COLLECT_STATISTICS(method_name, ...) \ try \ { \ - call_statistics_collector statistics_collector(#method_name, \ + std::shared_ptr statistics_collector = std::make_shared( \ + #method_name, \ &_ ## method_name ## _execution_accumulator, \ &_ ## method_name ## _delay_before_accumulator, \ &_ ## method_name ## _delay_after_accumulator); \ @@ -4919,7 +4924,7 @@ namespace graphene { namespace net { namespace detail { return _node_delegate->method_name(__VA_ARGS__); \ } \ else \ - return _thread->async([&](){ \ + return _thread->async([&, statistics_collector](){ \ call_statistics_collector::actual_execution_measurement_helper helper(statistics_collector); \ return _node_delegate->method_name(__VA_ARGS__); \ }, "invoke " BOOST_STRINGIZE(method_name)).wait(); \ @@ -4941,7 +4946,8 @@ namespace graphene { namespace net { namespace detail { } #else # define INVOKE_AND_COLLECT_STATISTICS(method_name, ...) \ - call_statistics_collector statistics_collector(#method_name, \ + std::shared_ptr statistics_collector = std::make_shared( \ + #method_name, \ &_ ## method_name ## _execution_accumulator, \ &_ ## method_name ## _delay_before_accumulator, \ &_ ## method_name ## _delay_after_accumulator); \ @@ -4951,7 +4957,7 @@ namespace graphene { namespace net { namespace detail { return _node_delegate->method_name(__VA_ARGS__); \ } \ else \ - return _thread->async([&](){ \ + return _thread->async([&, statistics_collector](){ \ call_statistics_collector::actual_execution_measurement_helper helper(statistics_collector); \ return _node_delegate->method_name(__VA_ARGS__); \ }, "invoke " BOOST_STRINGIZE(method_name)).wait() diff --git a/libraries/net/node_impl.hxx b/libraries/net/node_impl.hxx index 6cebda8f8f..7d31d16eea 100644 --- a/libraries/net/node_impl.hxx +++ b/libraries/net/node_impl.hxx @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -84,16 +84,16 @@ private: public: class actual_execution_measurement_helper { - call_statistics_collector &_collector; + std::shared_ptr _collector; public: - actual_execution_measurement_helper(call_statistics_collector& collector) : + actual_execution_measurement_helper(std::shared_ptr collector) : _collector(collector) { - _collector.starting_execution(); + _collector->starting_execution(); } ~actual_execution_measurement_helper() { - _collector.execution_completed(); + _collector->execution_completed(); } }; call_statistics_collector(const char* method_name, @@ -150,7 +150,7 @@ private: uint32_t& remaining_item_count, uint32_t limit = 2000) override; message get_item( const item_id& id ) override; - graphene::chain::chain_id_type get_chain_id() const override; + graphene::protocol::chain_id_type get_chain_id() const override; std::vector get_blockchain_synopsis(const item_hash_t& reference_point, uint32_t number_of_blocks_after_reference_point) override; void sync_status( uint32_t item_type, uint32_t item_count ) override; diff --git a/libraries/net/peer_connection.cpp b/libraries/net/peer_connection.cpp index 23ac403ab0..12a0eccdb4 100644 --- a/libraries/net/peer_connection.cpp +++ b/libraries/net/peer_connection.cpp @@ -25,8 +25,8 @@ #include #include #include -#include +#include #include #include diff --git a/libraries/net/peer_database.cpp b/libraries/net/peer_database.cpp index 2b20364e31..0e4867675d 100644 --- a/libraries/net/peer_database.cpp +++ b/libraries/net/peer_database.cpp @@ -274,3 +274,14 @@ namespace graphene { namespace net { } } } // end namespace graphene::net + +FC_REFLECT_ENUM( graphene::net::potential_peer_last_connection_disposition, + (never_attempted_to_connect) + (last_connection_failed)(last_connection_rejected) + (last_connection_handshaking_failed)(last_connection_succeeded) ) +FC_REFLECT_DERIVED_NO_TYPENAME( graphene::net::potential_peer_record, BOOST_PP_SEQ_NIL, + (endpoint)(last_seen_time)(last_connection_disposition) + (last_connection_attempt_time)(number_of_successful_connection_attempts) + (number_of_failed_connection_attempts)(last_error) ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::net::potential_peer_record) diff --git a/libraries/plugins/account_history/account_history_plugin.cpp b/libraries/plugins/account_history/account_history_plugin.cpp index 4697837faa..c3d0826077 100644 --- a/libraries/plugins/account_history/account_history_plugin.cpp +++ b/libraries/plugins/account_history/account_history_plugin.cpp @@ -130,7 +130,7 @@ void account_history_plugin_impl::update_account_histories( const signed_block& vector other; operation_get_required_authorities( op.op, impacted, impacted, other ); // fee_payer is added here - if( op.op.which() == operation::tag< account_create_operation >::value ) + if( op.op.is_type< account_create_operation >() ) impacted.insert( op.result.get() ); else graphene::chain::operation_get_impacted_accounts( op.op, impacted ); diff --git a/libraries/plugins/account_history/include/graphene/account_history/account_history_plugin.hpp b/libraries/plugins/account_history/include/graphene/account_history/account_history_plugin.hpp index 7bec37ddfe..99492768ce 100644 --- a/libraries/plugins/account_history/include/graphene/account_history/account_history_plugin.hpp +++ b/libraries/plugins/account_history/include/graphene/account_history/account_history_plugin.hpp @@ -81,28 +81,3 @@ class account_history_plugin : public graphene::app::plugin }; } } //graphene::account_history - -/*struct by_id; -struct by_seq; -struct by_op; -typedef boost::multi_index_container< - graphene::chain::account_transaction_history_object, - boost::multi_index::indexed_by< - boost::multi_index::ordered_unique< tag, member< object, object_id_type, &object::id > >, - boost::multi_index::ordered_unique< tag, - composite_key< account_transaction_history_object, - member< account_transaction_history_object, account_id_type, &account_transaction_history_object::account>, - member< account_transaction_history_object, uint32_t, &account_transaction_history_object::sequence> - > - >, - boost::multi_index::ordered_unique< tag, - composite_key< account_transaction_history_object, - member< account_transaction_history_object, account_id_type, &account_transaction_history_object::account>, - member< account_transaction_history_object, operation_history_id_type, &account_transaction_history_object::operation_id> - > - > - > -> account_transaction_history_multi_index_type; - -typedef graphene::account_history::generic_index account_transaction_history_index; -*/ diff --git a/libraries/plugins/debug_witness/CMakeLists.txt b/libraries/plugins/debug_witness/CMakeLists.txt index f0fcb7fb28..c512066981 100644 --- a/libraries/plugins/debug_witness/CMakeLists.txt +++ b/libraries/plugins/debug_witness/CMakeLists.txt @@ -16,3 +16,4 @@ install( TARGETS LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) +INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/debug_witness" ) diff --git a/libraries/plugins/debug_witness/include/graphene/debug_witness/debug_witness.hpp b/libraries/plugins/debug_witness/include/graphene/debug_witness/debug_witness.hpp index 22c71236b5..4b5369211a 100644 --- a/libraries/plugins/debug_witness/include/graphene/debug_witness/debug_witness.hpp +++ b/libraries/plugins/debug_witness/include/graphene/debug_witness/debug_witness.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/plugins/delayed_node/delayed_node_plugin.cpp b/libraries/plugins/delayed_node/delayed_node_plugin.cpp index c56f8bb6b3..01f4e48b31 100644 --- a/libraries/plugins/delayed_node/delayed_node_plugin.cpp +++ b/libraries/plugins/delayed_node/delayed_node_plugin.cpp @@ -23,7 +23,7 @@ */ #include -#include +#include #include #include @@ -63,7 +63,9 @@ void delayed_node_plugin::plugin_set_program_options(bpo::options_description& c void delayed_node_plugin::connect() { - my->client_connection = std::make_shared(*my->client.connect(my->remote_endpoint), GRAPHENE_NET_MAX_NESTED_OBJECTS); + my->client_connection = std::make_shared( + my->client.connect(my->remote_endpoint), + GRAPHENE_NET_MAX_NESTED_OBJECTS ); my->database_api = my->client_connection->get_remote_api(0); my->client_connection_closed = my->client_connection->closed.connect([this] { connection_failed(); diff --git a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp index c2cfcb9129..d6ee6d719a 100644 --- a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp +++ b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp @@ -93,6 +93,10 @@ class elasticsearch_plugin_impl elasticsearch_plugin_impl::~elasticsearch_plugin_impl() { + if (curl) { + curl_easy_cleanup(curl); + curl = nullptr; + } return; } @@ -152,7 +156,7 @@ bool elasticsearch_plugin_impl::update_account_histories( const signed_block& b vector other; operation_get_required_authorities( op.op, impacted, impacted, other ); // fee_payer is added here - if( op.op.which() == operation::tag< account_create_operation >::value ) + if( op.op.is_type< account_create_operation >() ) impacted.insert( op.result.get() ); else graphene::chain::operation_get_impacted_accounts( op.op, impacted ); diff --git a/libraries/plugins/es_objects/es_objects.cpp b/libraries/plugins/es_objects/es_objects.cpp index 21ae19094e..c88237164e 100644 --- a/libraries/plugins/es_objects/es_objects.cpp +++ b/libraries/plugins/es_objects/es_objects.cpp @@ -46,8 +46,9 @@ class es_objects_plugin_impl { curl = curl_easy_init(); } virtual ~es_objects_plugin_impl(); - bool index_database( const vector& ids, std::string action); - void remove_from_database( object_id_type id, std::string index); + bool index_database(const vector& ids, std::string action); + bool genesis(); + void remove_from_database(object_id_type id, std::string index); es_objects_plugin& _self; std::string _es_objects_elasticsearch_url = "http://localhost:9200/"; @@ -76,7 +77,55 @@ class es_objects_plugin_impl void prepareTemplate(T blockchain_object, string index_name); }; -bool es_objects_plugin_impl::index_database( const vector& ids, std::string action) +bool es_objects_plugin_impl::genesis() +{ + + ilog("elasticsearch OBJECTS: inserting data from genesis"); + + graphene::chain::database &db = _self.database(); + + block_number = db.head_block_num(); + block_time = db.head_block_time(); + + if (_es_objects_accounts) { + auto &index_accounts = db.get_index(1, 2); + index_accounts.inspect_all_objects([this, &db](const graphene::db::object &o) { + auto obj = db.find_object(o.id); + auto a = static_cast(obj); + prepareTemplate(*a, "account"); + }); + } + if (_es_objects_assets) { + auto &index_assets = db.get_index(1, 3); + index_assets.inspect_all_objects([this, &db](const graphene::db::object &o) { + auto obj = db.find_object(o.id); + auto a = static_cast(obj); + prepareTemplate(*a, "asset"); + }); + } + if (_es_objects_balances) { + auto &index_balances = db.get_index(2, 5); + index_balances.inspect_all_objects([this, &db](const graphene::db::object &o) { + auto obj = db.find_object(o.id); + auto b = static_cast(obj); + prepareTemplate(*b, "balance"); + }); + } + + graphene::utilities::ES es; + es.curl = curl; + es.bulk_lines = bulk; + es.elasticsearch_url = _es_objects_elasticsearch_url; + es.auth = _es_objects_auth; + if (!graphene::utilities::SendBulk(std::move(es))) + FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error inserting genesis data."); + else + bulk.clear(); + + return true; +} + +bool es_objects_plugin_impl::index_database(const vector& ids, std::string action) { graphene::chain::database &db = _self.database(); @@ -214,6 +263,10 @@ void es_objects_plugin_impl::prepareTemplate(T blockchain_object, string index_n es_objects_plugin_impl::~es_objects_plugin_impl() { + if (curl) { + curl_easy_cleanup(curl); + curl = nullptr; + } return; } @@ -262,13 +315,20 @@ void es_objects_plugin::plugin_set_program_options( void es_objects_plugin::plugin_initialize(const boost::program_options::variables_map& options) { - database().new_objects.connect([&]( const vector& ids, const flat_set& impacted_accounts ) { + database().applied_block.connect([this](const signed_block &b) { + if(b.block_num() == 1) { + if (!my->genesis()) + FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error populating genesis data."); + } + }); + + database().new_objects.connect([this]( const vector& ids, const flat_set& impacted_accounts ) { if(!my->index_database(ids, "create")) { FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error creating object from ES database, we are going to keep trying."); } }); - database().changed_objects.connect([&]( const vector& ids, const flat_set& impacted_accounts ) { + database().changed_objects.connect([this]( const vector& ids, const flat_set& impacted_accounts ) { if(!my->index_database(ids, "update")) { FC_THROW_EXCEPTION(graphene::chain::plugin_exception, "Error updating object from ES database, we are going to keep trying."); diff --git a/libraries/plugins/market_history/market_history_plugin.cpp b/libraries/plugins/market_history/market_history_plugin.cpp index f6948dc59e..9c01ea2149 100644 --- a/libraries/plugins/market_history/market_history_plugin.cpp +++ b/libraries/plugins/market_history/market_history_plugin.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/libraries/plugins/witness/witness.cpp b/libraries/plugins/witness/witness.cpp index af2101e9ea..eda18b1ce8 100644 --- a/libraries/plugins/witness/witness.cpp +++ b/libraries/plugins/witness/witness.cpp @@ -63,13 +63,17 @@ void witness_plugin::plugin_set_program_options( auto default_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(std::string("nathan"))); string witness_id_example = fc::json::to_string(chain::witness_id_type(5)); command_line_options.add_options() - ("enable-stale-production", bpo::bool_switch()->notifier([this](bool e){_production_enabled = e;}), "Enable block production, even if the chain is stale.") - ("required-participation", bpo::bool_switch()->notifier([this](int e){_required_witness_participation = uint32_t(e*GRAPHENE_1_PERCENT);}), "Percent of witnesses (0-99) that must be participating in order to produce blocks") + ("enable-stale-production", bpo::bool_switch()->notifier([this](bool e){_production_enabled = e;}), + "Enable block production, even if the chain is stale.") + ("required-participation", bpo::value()->default_value(33), + "Percent of witnesses (0-100) that must be participating in order to produce blocks") ("witness-id,w", bpo::value>()->composing()->multitoken(), - ("ID of witness controlled by this node (e.g. " + witness_id_example + ", quotes are required, may specify multiple times)").c_str()) + ("ID of witness controlled by this node (e.g. " + witness_id_example + + ", quotes are required, may specify multiple times)").c_str()) ("private-key", bpo::value>()->composing()->multitoken()-> - DEFAULT_VALUE_VECTOR(std::make_pair(chain::public_key_type(default_priv_key.get_public_key()), graphene::utilities::key_to_wif(default_priv_key))), - "Tuple of [PublicKey, WIF private key] (may specify multiple times)") + DEFAULT_VALUE_VECTOR(std::make_pair(chain::public_key_type(default_priv_key.get_public_key()), + graphene::utilities::key_to_wif(default_priv_key))), + "Tuple of [PublicKey, WIF private key] (may specify multiple times)") ; config_file_options.add(command_line_options); } @@ -90,7 +94,8 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m const std::vector key_id_to_wif_pair_strings = options["private-key"].as>(); for (const std::string& key_id_to_wif_pair_string : key_id_to_wif_pair_strings) { - auto key_id_to_wif_pair = graphene::app::dejsonify >(key_id_to_wif_pair_string, 5); + auto key_id_to_wif_pair = graphene::app::dejsonify > + (key_id_to_wif_pair_string, 5); ilog("Public Key: ${public}", ("public", key_id_to_wif_pair.first)); fc::optional private_key = graphene::utilities::wif_to_key(key_id_to_wif_pair.second); if (!private_key) @@ -109,6 +114,16 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m _private_keys[key_id_to_wif_pair.first] = *private_key; } } + if(options.count("required-participation")) + { + auto required_participation = options["required-participation"].as(); + FC_ASSERT(required_participation <= 100); + _required_witness_participation = options["required-participation"].as()*GRAPHENE_1_PERCENT; + if(required_participation < 10) + wlog("witness plugin: Warning - Low required participation of ${rp}% found", ("rp", required_participation)); + else if(required_participation > 90) + wlog("witness plugin: Warning - High required participation of ${rp}% found", ("rp", required_participation)); + } ilog("witness plugin: plugin_initialize() end"); } FC_LOG_AND_RETHROW() } @@ -222,7 +237,8 @@ block_production_condition::block_production_condition_enum witness_plugin::bloc ilog("Generated block #${n} with ${x} transaction(s) and timestamp ${t} at time ${c}", (capture)); break; case block_production_condition::not_synced: - ilog("Not producing block because production is disabled until we receive a recent block (see: --enable-stale-production)"); + ilog("Not producing block because production is disabled until we receive a recent block " + "(see: --enable-stale-production)"); break; case block_production_condition::not_my_turn: break; @@ -232,7 +248,8 @@ block_production_condition::block_production_condition_enum witness_plugin::bloc ilog("Not producing block because I don't have the private key for ${scheduled_key}", (capture) ); break; case block_production_condition::low_participation: - elog("Not producing block because node appears to be on a minority fork with only ${pct}% witness participation", (capture) ); + elog("Not producing block because node appears to be on a minority fork with only ${pct}% witness participation", + (capture) ); break; case block_production_condition::lag: elog("Not producing block because node didn't wake up within 2500ms of the slot time."); @@ -252,7 +269,8 @@ block_production_condition::block_production_condition_enum witness_plugin::bloc return result; } -block_production_condition::block_production_condition_enum witness_plugin::maybe_produce_block( fc::limited_mutable_variant_object& capture ) +block_production_condition::block_production_condition_enum witness_plugin::maybe_produce_block( + fc::limited_mutable_variant_object& capture ) { chain::database& db = database(); fc::time_point now_fine = fc::time_point::now(); diff --git a/libraries/protocol/CMakeLists.txt b/libraries/protocol/CMakeLists.txt new file mode 100644 index 0000000000..11a3b66016 --- /dev/null +++ b/libraries/protocol/CMakeLists.txt @@ -0,0 +1,43 @@ +file(GLOB HEADERS "include/graphene/protocol/*.hpp") + +list(APPEND SOURCES account.cpp + assert.cpp + asset_ops.cpp + block.cpp + confidential.cpp + chain_parameters.cpp + fee_schedule.cpp + memo.cpp + proposal.cpp + transfer.cpp + vote.cpp + witness.cpp + address.cpp + asset.cpp + authority.cpp + special_authority.cpp + committee_member.cpp + custom.cpp + market.cpp + operations.cpp + pts_address.cpp + small_ops.cpp + transaction.cpp + types.cpp + withdraw_permission.cpp + worker.cpp + htlc.cpp) + + +add_library( graphene_protocol ${SOURCES} ${HEADERS} ) +target_link_libraries( graphene_protocol fc ) +target_include_directories( graphene_protocol PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +install( TARGETS + graphene_protocol + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) +install( FILES ${HEADERS} DESTINATION "include/graphene/protocol" ) diff --git a/libraries/chain/protocol/account.cpp b/libraries/protocol/account.cpp similarity index 88% rename from libraries/chain/protocol/account.cpp rename to libraries/protocol/account.cpp index 9d281e4caf..f51271405b 100644 --- a/libraries/chain/protocol/account.cpp +++ b/libraries/protocol/account.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { /** * Names must comply with the following grammar (RFC 1035): @@ -275,4 +277,16 @@ void account_transfer_operation::validate()const } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_options ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_whitelist_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_upgrade_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_transfer_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_whitelist_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_update_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_upgrade_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::account_transfer_operation ) diff --git a/libraries/chain/protocol/address.cpp b/libraries/protocol/address.cpp similarity index 85% rename from libraries/chain/protocol/address.cpp rename to libraries/protocol/address.cpp index 19bb4df569..9ab70220ba 100644 --- a/libraries/chain/protocol/address.cpp +++ b/libraries/protocol/address.cpp @@ -21,15 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include -#include +#include +#include #include #include -namespace graphene { - namespace chain { - address::address(){} +#include + +namespace graphene { namespace protocol { address::address( const std::string& base58str ) { @@ -83,7 +82,7 @@ namespace graphene { addr = fc::ripemd160::hash( fc::sha512::hash( pub.data, sizeof( pub ) ) ); } - address::address( const graphene::chain::public_key_type& pub ) + address::address( const graphene::protocol::public_key_type& pub ) { addr = fc::ripemd160::hash( fc::sha512::hash( pub.key_data.data, sizeof( pub.key_data ) ) ); } @@ -97,16 +96,18 @@ namespace graphene { return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( bin_addr.data, sizeof( bin_addr ) ); } -} } // namespace graphene::chain +} } // namespace graphene::protocol namespace fc { - void to_variant( const graphene::chain::address& var, variant& vo, uint32_t max_depth ) + void to_variant( const graphene::protocol::address& var, variant& vo, uint32_t max_depth ) { vo = std::string(var); } - void from_variant( const variant& var, graphene::chain::address& vo, uint32_t max_depth ) + void from_variant( const variant& var, graphene::protocol::address& vo, uint32_t max_depth ) { - vo = graphene::chain::address( var.as_string() ); + vo = graphene::protocol::address( var.as_string() ); } } + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::address ) diff --git a/libraries/chain/protocol/assert.cpp b/libraries/protocol/assert.cpp similarity index 82% rename from libraries/chain/protocol/assert.cpp rename to libraries/protocol/assert.cpp index 2c15a44563..2199b314d8 100644 --- a/libraries/chain/protocol/assert.cpp +++ b/libraries/protocol/assert.cpp @@ -21,9 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include +#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { bool account_name_eq_lit_predicate::validate()const { @@ -62,5 +66,7 @@ share_type assert_operation::calculate_fee(const fee_parameters_type& k)const return k.fee * predicates.size(); } +} } // namespace graphene::protocol -} } // namespace graphene::chain +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::assert_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::assert_operation ) diff --git a/libraries/chain/protocol/asset.cpp b/libraries/protocol/asset.cpp similarity index 97% rename from libraries/chain/protocol/asset.cpp rename to libraries/protocol/asset.cpp index a9c1daf502..77f6dd7c12 100644 --- a/libraries/chain/protocol/asset.cpp +++ b/libraries/protocol/asset.cpp @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include #include #include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { typedef boost::multiprecision::uint128_t uint128_t; typedef boost::multiprecision::int128_t int128_t; @@ -314,4 +316,8 @@ const int64_t scaled_precision_lut[19] = p10< 16 >::v, p10< 17 >::v, p10< 18 >::v }; -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::price ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::price_feed ) diff --git a/libraries/chain/protocol/asset_ops.cpp b/libraries/protocol/asset_ops.cpp similarity index 70% rename from libraries/chain/protocol/asset_ops.cpp rename to libraries/protocol/asset_ops.cpp index c88eb9bd8a..ba1b7f65f8 100644 --- a/libraries/chain/protocol/asset_ops.cpp +++ b/libraries/protocol/asset_ops.cpp @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include + +#include #include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * Valid symbols can contain [A-Z0-9], and '.' @@ -236,6 +238,8 @@ void asset_options::validate()const { FC_ASSERT( whitelist_markets.find(item) == whitelist_markets.end() ); } + if( extensions.value.reward_percent.valid() ) + FC_ASSERT( *extensions.value.reward_percent < GRAPHENE_100_PERCENT ); } void asset_claim_fees_operation::validate()const { @@ -250,4 +254,35 @@ void asset_claim_pool_operation::validate()const { FC_ASSERT( amount_to_claim.asset_id == asset_id_type()); } -} } // namespace graphene::chain +} } // namespace graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_options ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::bitasset_options ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::additional_asset_options ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_global_settle_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_fund_fee_pool_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_pool_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_fees_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_issuer_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_bitasset_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_feed_producers_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_publish_feed_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_issue_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_reserve_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_global_settle_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_cancel_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_fund_fee_pool_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_pool_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_fees_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_issuer_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_bitasset_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_feed_producers_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_publish_feed_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_issue_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::asset_reserve_operation ) diff --git a/libraries/chain/protocol/authority.cpp b/libraries/protocol/authority.cpp similarity index 86% rename from libraries/chain/protocol/authority.cpp rename to libraries/protocol/authority.cpp index 97470d3328..121ad46d9b 100644 --- a/libraries/chain/protocol/authority.cpp +++ b/libraries/protocol/authority.cpp @@ -22,9 +22,11 @@ * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { void add_authority_accounts( flat_set& result, @@ -35,4 +37,6 @@ void add_authority_accounts( result.insert( item.first ); } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::authority ) diff --git a/libraries/chain/protocol/block.cpp b/libraries/protocol/block.cpp similarity index 82% rename from libraries/chain/protocol/block.cpp rename to libraries/protocol/block.cpp index 9fdf4707eb..307b592d4e 100644 --- a/libraries/chain/protocol/block.cpp +++ b/libraries/protocol/block.cpp @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include +#include +#include #include -#include #include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { digest_type block_header::digest()const { return digest_type::hash(*this); @@ -34,15 +35,15 @@ namespace graphene { namespace chain { uint32_t block_header::num_from_id(const block_id_type& id) { - return fc::endian_reverse_u32(id._hash[0]); + return boost::endian::endian_reverse(id._hash[0].value()); } const block_id_type& signed_block_header::id()const { - if( !_block_id._hash[0] ) + if( !_block_id._hash[0].value() ) { auto tmp = fc::sha224::hash( *this ); - tmp._hash[0] = fc::endian_reverse_u32(block_num()); // store the block num in the ID, 160 bits is plenty for the hash + tmp._hash[0] = boost::endian::endian_reverse(block_num()); // store the block num in the ID, 160 bits is plenty for the hash static_assert( sizeof(tmp._hash[0]) == 4, "should be 4 bytes" ); memcpy(_block_id._hash, tmp._hash, std::min(sizeof(_block_id), sizeof(tmp))); } @@ -72,7 +73,7 @@ namespace graphene { namespace chain { if( transactions.size() == 0 ) return empty_checksum; - if( !_calculated_merkle_root._hash[0] ) + if( !_calculated_merkle_root._hash[0].value() ) { vector ids; ids.resize( transactions.size() ); @@ -98,3 +99,7 @@ namespace graphene { namespace chain { return _calculated_merkle_root; } } } + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::block_header) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::signed_block_header) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::signed_block) diff --git a/libraries/protocol/chain_parameters.cpp b/libraries/protocol/chain_parameters.cpp new file mode 100644 index 0000000000..eed40e8416 --- /dev/null +++ b/libraries/protocol/chain_parameters.cpp @@ -0,0 +1,83 @@ +#include +#include + +#include + +namespace graphene { namespace protocol { + chain_parameters::chain_parameters() { + current_fees = std::make_shared(); + } + + // copy constructor + chain_parameters::chain_parameters(const chain_parameters& other) + { + current_fees = std::make_shared(*other.current_fees); + safe_copy(*this, other); + } + + // copy assignment + chain_parameters& chain_parameters::operator=(const chain_parameters& other) + { + if (&other != this) + { + current_fees = std::make_shared(*other.current_fees); + safe_copy(*this, other); + } + return *this; + } + + // copies the easy stuff + void chain_parameters::safe_copy(chain_parameters& to, const chain_parameters& from) + { + to.block_interval = from.block_interval; + to.maintenance_interval = from.maintenance_interval; + to.maintenance_skip_slots = from.maintenance_skip_slots; + to.committee_proposal_review_period = from.committee_proposal_review_period; + to.maximum_transaction_size = from.maximum_transaction_size; + to.maximum_block_size = from.maximum_block_size; + to.maximum_time_until_expiration = from.maximum_time_until_expiration; + to.maximum_proposal_lifetime = from.maximum_proposal_lifetime; + to.maximum_asset_whitelist_authorities = from.maximum_asset_whitelist_authorities; + to.maximum_asset_feed_publishers = from.maximum_asset_feed_publishers; + to.maximum_witness_count = from.maximum_witness_count; + to.maximum_committee_count = from.maximum_committee_count; + to.maximum_authority_membership = from.maximum_authority_membership; + to.reserve_percent_of_fee = from.reserve_percent_of_fee; + to.network_percent_of_fee = from.network_percent_of_fee; + to.lifetime_referrer_percent_of_fee = from.lifetime_referrer_percent_of_fee; + to.cashback_vesting_period_seconds = from.cashback_vesting_period_seconds; + to.cashback_vesting_threshold = from.cashback_vesting_threshold; + to.count_non_member_votes = from.count_non_member_votes; + to.allow_non_member_whitelists = from.allow_non_member_whitelists; + to.witness_pay_per_block = from.witness_pay_per_block; + to.witness_pay_vesting_seconds = from.witness_pay_vesting_seconds; + to.worker_budget_per_day = from.worker_budget_per_day; + to.max_predicate_opcode = from.max_predicate_opcode; + to.fee_liquidation_threshold = from.fee_liquidation_threshold; + to.accounts_per_fee_scale = from.accounts_per_fee_scale; + to.account_fee_scale_bitshifts = from.account_fee_scale_bitshifts; + to.max_authority_depth = from.max_authority_depth; + to.extensions = from.extensions; + } + + // move constructor + chain_parameters::chain_parameters(chain_parameters&& other) + { + current_fees = std::move(other.current_fees); + safe_copy(*this, other); + } + + // move assignment + chain_parameters& chain_parameters::operator=(chain_parameters&& other) + { + if (&other != this) + { + current_fees = std::move(other.current_fees); + safe_copy(*this, other); + } + return *this; + } + +}} + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::chain_parameters ) diff --git a/libraries/protocol/committee_member.cpp b/libraries/protocol/committee_member.cpp new file mode 100644 index 0000000000..d48372c944 --- /dev/null +++ b/libraries/protocol/committee_member.cpp @@ -0,0 +1,57 @@ +/* + * 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 + +namespace graphene { namespace protocol { + +void committee_member_create_operation::validate()const +{ + FC_ASSERT( fee.amount >= 0 ); + FC_ASSERT(url.size() < GRAPHENE_MAX_URL_LENGTH ); +} + +void committee_member_update_operation::validate()const +{ + FC_ASSERT( fee.amount >= 0 ); + if( new_url.valid() ) + FC_ASSERT(new_url->size() < GRAPHENE_MAX_URL_LENGTH ); +} + +void committee_member_update_global_parameters_operation::validate() const +{ + FC_ASSERT( fee.amount >= 0 ); + new_parameters.validate(); +} + +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_global_parameters_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_global_parameters_operation ) diff --git a/libraries/chain/protocol/confidential.cpp b/libraries/protocol/confidential.cpp similarity index 88% rename from libraries/chain/protocol/confidential.cpp rename to libraries/protocol/confidential.cpp index 603befa122..43a8b0587e 100644 --- a/libraries/chain/protocol/confidential.cpp +++ b/libraries/protocol/confidential.cpp @@ -21,15 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include -#include + +#include #include #include -#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { void transfer_to_blind_operation::validate()const { @@ -141,9 +139,6 @@ share_type blind_transfer_operation::calculate_fee( const fee_parameters_type& k return k.fee + outputs.size() * k.price_per_output; } - - - /** * Packs *this then encodes as base58 encoded string. */ @@ -159,6 +154,11 @@ stealth_confirmation::stealth_confirmation( const std::string& base58 ) *this = fc::raw::unpack( fc::from_base58( base58 ) ); } +} } // graphene::protocol - -} } // graphene::chain +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_to_blind_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_from_blind_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::blind_transfer_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_to_blind_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_from_blind_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::blind_transfer_operation ) diff --git a/libraries/chain/protocol/custom.cpp b/libraries/protocol/custom.cpp similarity index 82% rename from libraries/chain/protocol/custom.cpp rename to libraries/protocol/custom.cpp index b69243bee3..22ea61f72b 100644 --- a/libraries/chain/protocol/custom.cpp +++ b/libraries/protocol/custom.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { void custom_operation::validate()const { @@ -35,3 +37,6 @@ share_type custom_operation::calculate_fee(const fee_parameters_type& k)const } } } + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::custom_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::custom_operation ) diff --git a/libraries/chain/protocol/fee_schedule.cpp b/libraries/protocol/fee_schedule.cpp similarity index 84% rename from libraries/chain/protocol/fee_schedule.cpp rename to libraries/protocol/fee_schedule.cpp index c52c229768..336c52a202 100644 --- a/libraries/chain/protocol/fee_schedule.cpp +++ b/libraries/protocol/fee_schedule.cpp @@ -22,23 +22,13 @@ * THE SOFTWARE. */ #include -#include +#include -namespace fc -{ - // these are required on certain platforms in Release mode - template<> - bool smart_ref::operator !()const - { - throw std::logic_error("Not Implemented"); - } - - template class smart_ref; -} +#include #define MAX_FEE_STABILIZATION_ITERATION 4 -namespace graphene { namespace chain { +namespace graphene { namespace protocol { fee_schedule::fee_schedule() { @@ -127,21 +117,23 @@ namespace graphene { namespace chain { this->scale = 0; } + asset fee_schedule::calculate_fee( const operation& op )const + { + uint64_t required_fee = op.visit( calc_fee_visitor( *this, op ) ); + if( scale != GRAPHENE_100_PERCENT ) + { + auto scaled = fc::uint128(required_fee) * scale; + scaled /= GRAPHENE_100_PERCENT; + FC_ASSERT( scaled <= GRAPHENE_MAX_SHARE_SUPPLY, + "Required fee after scaling would exceed maximum possible supply" ); + required_fee = scaled.to_uint64(); + } + return asset( required_fee ); + } + asset fee_schedule::calculate_fee( const operation& op, const price& core_exchange_rate )const { - auto base_value = op.visit( calc_fee_visitor( *this, op ) ); - auto scaled = fc::uint128(base_value) * scale; - scaled /= GRAPHENE_100_PERCENT; - FC_ASSERT( scaled <= GRAPHENE_MAX_SHARE_SUPPLY ); - //idump( (base_value)(scaled)(core_exchange_rate) ); - auto result = asset( scaled.to_uint64(), asset_id_type(0) ) * core_exchange_rate; - //FC_ASSERT( result * core_exchange_rate >= asset( scaled.to_uint64()) ); - - while( result * core_exchange_rate < asset( scaled.to_uint64()) ) - result.amount++; - - FC_ASSERT( result.amount <= GRAPHENE_MAX_SHARE_SUPPLY ); - return result; + return calculate_fee( op ).multiply_and_round_up( core_exchange_rate ); } asset fee_schedule::set_fee( operation& op, const price& core_exchange_rate )const @@ -168,7 +160,7 @@ namespace graphene { namespace chain { void chain_parameters::validate()const { - current_fees->validate(); + get_current_fees().validate(); FC_ASSERT( reserve_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( network_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT ); @@ -191,4 +183,6 @@ namespace graphene { namespace chain { "Committee proposal review period must be less than the maximum proposal lifetime" ); } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::fee_schedule ) diff --git a/libraries/chain/protocol/htlc.cpp b/libraries/protocol/htlc.cpp similarity index 76% rename from libraries/chain/protocol/htlc.cpp rename to libraries/protocol/htlc.cpp index 645feb6dbf..b7fe9ef4a0 100644 --- a/libraries/chain/protocol/htlc.cpp +++ b/libraries/protocol/htlc.cpp @@ -21,11 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include + +#include #define SECONDS_PER_DAY (60 * 60 * 24) -namespace graphene { namespace chain { +namespace graphene { namespace protocol { void htlc_create_operation::validate()const { FC_ASSERT( fee.amount >= 0, "Fee amount should not be negative" ); @@ -65,3 +67,12 @@ namespace graphene { namespace chain { return fee_params.fee + per_day_fee; } } } + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeem_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_extend_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeem_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeemed_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_extend_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_refund_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/README.md b/libraries/protocol/include/graphene/protocol/README.md similarity index 100% rename from libraries/chain/include/graphene/chain/protocol/README.md rename to libraries/protocol/include/graphene/protocol/README.md diff --git a/libraries/chain/include/graphene/chain/protocol/account.hpp b/libraries/protocol/include/graphene/protocol/account.hpp similarity index 80% rename from libraries/chain/include/graphene/chain/protocol/account.hpp rename to libraries/protocol/include/graphene/protocol/account.hpp index f2be53837b..02aba3a3f7 100644 --- a/libraries/chain/include/graphene/chain/protocol/account.hpp +++ b/libraries/protocol/include/graphene/protocol/account.hpp @@ -22,14 +22,15 @@ * THE SOFTWARE. */ #pragma once -#include -#include -#include -#include -#include -#include -namespace graphene { namespace chain { +#include +#include +#include +#include +#include +#include + +namespace graphene { namespace protocol { bool is_valid_name( const string& s ); bool is_cheap_name( const string& n ); @@ -267,35 +268,47 @@ namespace graphene { namespace chain { void validate()const; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT(graphene::chain::account_options, (memo_key)(voting_account)(num_witness)(num_committee)(votes)(extensions)) -FC_REFLECT_ENUM( graphene::chain::account_whitelist_operation::account_listing, +FC_REFLECT(graphene::protocol::account_options, (memo_key)(voting_account)(num_witness)(num_committee)(votes)(extensions)) +FC_REFLECT_ENUM( graphene::protocol::account_whitelist_operation::account_listing, (no_listing)(white_listed)(black_listed)(white_and_black_listed)) -FC_REFLECT(graphene::chain::account_create_operation::ext, (null_ext)(owner_special_authority)(active_special_authority)(buyback_options) ) -FC_REFLECT_TYPENAME(graphene::chain::extension) -FC_REFLECT( graphene::chain::account_create_operation, +FC_REFLECT(graphene::protocol::account_create_operation::ext, (null_ext)(owner_special_authority)(active_special_authority)(buyback_options) ) +FC_REFLECT_TYPENAME(graphene::protocol::extension) +FC_REFLECT( graphene::protocol::account_create_operation, (fee)(registrar) (referrer)(referrer_percent) (name)(owner)(active)(options)(extensions) ) -FC_REFLECT(graphene::chain::account_update_operation::ext, (null_ext)(owner_special_authority)(active_special_authority) ) -FC_REFLECT_TYPENAME(graphene::chain::extension) -FC_REFLECT( graphene::chain::account_update_operation, +FC_REFLECT(graphene::protocol::account_update_operation::ext, (null_ext)(owner_special_authority)(active_special_authority) ) +FC_REFLECT_TYPENAME(graphene::protocol::extension) +FC_REFLECT( graphene::protocol::account_update_operation, (fee)(account)(owner)(active)(new_options)(extensions) ) -FC_REFLECT( graphene::chain::account_upgrade_operation, +FC_REFLECT( graphene::protocol::account_upgrade_operation, (fee)(account_to_upgrade)(upgrade_to_lifetime_member)(extensions) ) -FC_REFLECT( graphene::chain::account_whitelist_operation, (fee)(authorizing_account)(account_to_list)(new_listing)(extensions)) - -FC_REFLECT( graphene::chain::account_create_operation::fee_parameters_type, (basic_fee)(premium_fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::account_whitelist_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::account_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::account_upgrade_operation::fee_parameters_type, (membership_annual_fee)(membership_lifetime_fee) ) -FC_REFLECT( graphene::chain::account_transfer_operation::fee_parameters_type, (fee) ) - -FC_REFLECT( graphene::chain::account_transfer_operation, (fee)(account_id)(new_owner)(extensions) ) +FC_REFLECT( graphene::protocol::account_whitelist_operation, (fee)(authorizing_account)(account_to_list)(new_listing)(extensions)) + +FC_REFLECT( graphene::protocol::account_create_operation::fee_parameters_type, (basic_fee)(premium_fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::account_whitelist_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::account_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::account_upgrade_operation::fee_parameters_type, (membership_annual_fee)(membership_lifetime_fee) ) +FC_REFLECT( graphene::protocol::account_transfer_operation::fee_parameters_type, (fee) ) + +FC_REFLECT( graphene::protocol::account_transfer_operation, (fee)(account_id)(new_owner)(extensions) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_options ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_whitelist_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_upgrade_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_transfer_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_whitelist_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_upgrade_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::account_transfer_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/address.hpp b/libraries/protocol/include/graphene/protocol/address.hpp similarity index 68% rename from libraries/chain/include/graphene/chain/protocol/address.hpp rename to libraries/protocol/include/graphene/protocol/address.hpp index b225b42caf..e118128b55 100644 --- a/libraries/chain/include/graphene/chain/protocol/address.hpp +++ b/libraries/protocol/include/graphene/protocol/address.hpp @@ -23,20 +23,13 @@ */ #pragma once -#include -#include +#include -#include #include +#include -namespace fc { namespace ecc { - class public_key; - typedef fc::array public_key_data; -} } // fc::ecc - -namespace graphene { namespace chain { - - struct public_key_type; +namespace graphene { namespace protocol { + struct pts_address; /** * @brief a 160 bit hash of a public key @@ -51,7 +44,7 @@ namespace graphene { namespace chain { class address { public: - address(); ///< constructs empty / null address + address(){} ///< constructs empty / null address explicit address( const std::string& base58str ); ///< converts to binary, validates checksum address( const fc::ecc::public_key& pub ); ///< converts to binary explicit address( const fc::ecc::public_key_data& pub ); ///< converts to binary @@ -62,38 +55,20 @@ namespace graphene { namespace chain { explicit operator std::string()const; ///< converts to base58 + checksum - friend size_t hash_value( const address& v ) { - const void* tmp = static_cast(v.addr._hash+2); - - const size_t* tmp2 = reinterpret_cast(tmp); - return *tmp2; - } fc::ripemd160 addr; }; inline bool operator == ( const address& a, const address& b ) { return a.addr == b.addr; } inline bool operator != ( const address& a, const address& b ) { return a.addr != b.addr; } inline bool operator < ( const address& a, const address& b ) { return a.addr < b.addr; } -} } // namespace graphene::chain +} } // namespace graphene::protocol namespace fc { - void to_variant( const graphene::chain::address& var, fc::variant& vo, uint32_t max_depth = 1 ); - void from_variant( const fc::variant& var, graphene::chain::address& vo, uint32_t max_depth = 1 ); + void to_variant( const graphene::protocol::address& var, fc::variant& vo, uint32_t max_depth = 1 ); + void from_variant( const fc::variant& var, graphene::protocol::address& vo, uint32_t max_depth = 1 ); } -namespace std -{ - template<> - struct hash - { - public: - size_t operator()(const graphene::chain::address &a) const - { - return (uint64_t(a.addr._hash[0])<<32) | uint64_t( a.addr._hash[0] ); - } - }; -} +FC_REFLECT( graphene::protocol::address, (addr) ) -#include -FC_REFLECT( graphene::chain::address, (addr) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::address ) diff --git a/libraries/chain/include/graphene/chain/protocol/assert.hpp b/libraries/protocol/include/graphene/protocol/assert.hpp similarity index 80% rename from libraries/chain/include/graphene/chain/protocol/assert.hpp rename to libraries/protocol/include/graphene/protocol/assert.hpp index c9f3b2774a..fead1a7031 100644 --- a/libraries/chain/include/graphene/chain/protocol/assert.hpp +++ b/libraries/protocol/include/graphene/protocol/assert.hpp @@ -22,9 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -namespace graphene { namespace chain { +#include +#include + +namespace graphene { namespace protocol { /** * Used to verify that account_id->name is equal to the given string literal. @@ -103,12 +105,14 @@ namespace graphene { namespace chain { share_type calculate_fee(const fee_parameters_type& k)const; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::assert_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::account_name_eq_lit_predicate, (account_id)(name) ) -FC_REFLECT( graphene::chain::asset_symbol_eq_lit_predicate, (asset_id)(symbol) ) -FC_REFLECT( graphene::chain::block_id_predicate, (id) ) -FC_REFLECT_TYPENAME( graphene::chain::predicate ) -FC_REFLECT( graphene::chain::assert_operation, (fee)(fee_paying_account)(predicates)(required_auths)(extensions) ) +FC_REFLECT( graphene::protocol::assert_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::account_name_eq_lit_predicate, (account_id)(name) ) +FC_REFLECT( graphene::protocol::asset_symbol_eq_lit_predicate, (asset_id)(symbol) ) +FC_REFLECT( graphene::protocol::block_id_predicate, (id) ) +FC_REFLECT_TYPENAME( graphene::protocol::predicate ) +FC_REFLECT( graphene::protocol::assert_operation, (fee)(fee_paying_account)(predicates)(required_auths)(extensions) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::assert_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::assert_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/asset.hpp b/libraries/protocol/include/graphene/protocol/asset.hpp similarity index 94% rename from libraries/chain/include/graphene/chain/protocol/asset.hpp rename to libraries/protocol/include/graphene/protocol/asset.hpp index b354d5ccac..657a17c896 100644 --- a/libraries/chain/include/graphene/chain/protocol/asset.hpp +++ b/libraries/protocol/include/graphene/protocol/asset.hpp @@ -22,10 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { extern const int64_t scaled_precision_lut[]; @@ -221,10 +220,14 @@ namespace graphene { namespace chain { } } -FC_REFLECT( graphene::chain::asset, (amount)(asset_id) ) -FC_REFLECT( graphene::chain::price, (base)(quote) ) +FC_REFLECT( graphene::protocol::asset, (amount)(asset_id) ) +FC_REFLECT( graphene::protocol::price, (base)(quote) ) #define GRAPHENE_PRICE_FEED_FIELDS (settlement_price)(maintenance_collateral_ratio)(maximum_short_squeeze_ratio) \ (core_exchange_rate) -FC_REFLECT( graphene::chain::price_feed, GRAPHENE_PRICE_FEED_FIELDS ) +FC_REFLECT( graphene::protocol::price_feed, GRAPHENE_PRICE_FEED_FIELDS ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::price ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::price_feed ) diff --git a/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp b/libraries/protocol/include/graphene/protocol/asset_ops.hpp similarity index 80% rename from libraries/chain/include/graphene/chain/protocol/asset_ops.hpp rename to libraries/protocol/include/graphene/protocol/asset_ops.hpp index 9c6fca3c9c..6dd4545481 100644 --- a/libraries/chain/include/graphene/chain/protocol/asset_ops.hpp +++ b/libraries/protocol/include/graphene/protocol/asset_ops.hpp @@ -22,10 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { struct additional_asset_options { @@ -511,14 +512,14 @@ namespace graphene { namespace chain { void validate()const; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::asset_claim_fees_operation, (fee)(issuer)(amount_to_claim)(extensions) ) -FC_REFLECT( graphene::chain::asset_claim_fees_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_claim_pool_operation, (fee)(issuer)(asset_id)(amount_to_claim)(extensions) ) -FC_REFLECT( graphene::chain::asset_claim_pool_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_claim_fees_operation, (fee)(issuer)(amount_to_claim)(extensions) ) +FC_REFLECT( graphene::protocol::asset_claim_fees_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_claim_pool_operation, (fee)(issuer)(asset_id)(amount_to_claim)(extensions) ) +FC_REFLECT( graphene::protocol::asset_claim_pool_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_options, +FC_REFLECT( graphene::protocol::asset_options, (max_supply) (market_fee_percent) (max_market_fee) @@ -532,7 +533,7 @@ FC_REFLECT( graphene::chain::asset_options, (description) (extensions) ) -FC_REFLECT( graphene::chain::bitasset_options, +FC_REFLECT( graphene::protocol::bitasset_options, (feed_lifetime_sec) (minimum_feeds) (force_settlement_delay_sec) @@ -542,22 +543,22 @@ FC_REFLECT( graphene::chain::bitasset_options, (extensions) ) -FC_REFLECT( graphene::chain::additional_asset_options, (reward_percent)(whitelist_market_fee_sharing) ) -FC_REFLECT( graphene::chain::asset_create_operation::fee_parameters_type, (symbol3)(symbol4)(long_symbol)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::asset_global_settle_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_settle_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_settle_cancel_operation::fee_parameters_type, ) -FC_REFLECT( graphene::chain::asset_fund_fee_pool_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::asset_update_issuer_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_update_bitasset_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_update_feed_producers_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_publish_feed_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::asset_issue_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::asset_reserve_operation::fee_parameters_type, (fee) ) - - -FC_REFLECT( graphene::chain::asset_create_operation, +FC_REFLECT( graphene::protocol::additional_asset_options, (reward_percent)(whitelist_market_fee_sharing) ) +FC_REFLECT( graphene::protocol::asset_create_operation::fee_parameters_type, (symbol3)(symbol4)(long_symbol)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::asset_global_settle_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_settle_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_settle_cancel_operation::fee_parameters_type, ) +FC_REFLECT( graphene::protocol::asset_fund_fee_pool_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::asset_update_issuer_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_update_bitasset_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_update_feed_producers_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_publish_feed_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::asset_issue_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::asset_reserve_operation::fee_parameters_type, (fee) ) + + +FC_REFLECT( graphene::protocol::asset_create_operation, (fee) (issuer) (symbol) @@ -567,7 +568,7 @@ FC_REFLECT( graphene::chain::asset_create_operation, (is_prediction_market) (extensions) ) -FC_REFLECT( graphene::chain::asset_update_operation, +FC_REFLECT( graphene::protocol::asset_update_operation, (fee) (issuer) (asset_to_update) @@ -575,31 +576,62 @@ FC_REFLECT( graphene::chain::asset_update_operation, (new_options) (extensions) ) -FC_REFLECT( graphene::chain::asset_update_issuer_operation, +FC_REFLECT( graphene::protocol::asset_update_issuer_operation, (fee) (issuer) (asset_to_update) (new_issuer) (extensions) ) -FC_REFLECT( graphene::chain::asset_update_bitasset_operation, +FC_REFLECT( graphene::protocol::asset_update_bitasset_operation, (fee) (issuer) (asset_to_update) (new_options) (extensions) ) -FC_REFLECT( graphene::chain::asset_update_feed_producers_operation, +FC_REFLECT( graphene::protocol::asset_update_feed_producers_operation, (fee)(issuer)(asset_to_update)(new_feed_producers)(extensions) ) -FC_REFLECT( graphene::chain::asset_publish_feed_operation, +FC_REFLECT( graphene::protocol::asset_publish_feed_operation, (fee)(publisher)(asset_id)(feed)(extensions) ) -FC_REFLECT( graphene::chain::asset_settle_operation, (fee)(account)(amount)(extensions) ) -FC_REFLECT( graphene::chain::asset_settle_cancel_operation, (fee)(settlement)(account)(amount)(extensions) ) -FC_REFLECT( graphene::chain::asset_global_settle_operation, (fee)(issuer)(asset_to_settle)(settle_price)(extensions) ) -FC_REFLECT( graphene::chain::asset_issue_operation, +FC_REFLECT( graphene::protocol::asset_settle_operation, (fee)(account)(amount)(extensions) ) +FC_REFLECT( graphene::protocol::asset_settle_cancel_operation, (fee)(settlement)(account)(amount)(extensions) ) +FC_REFLECT( graphene::protocol::asset_global_settle_operation, (fee)(issuer)(asset_to_settle)(settle_price)(extensions) ) +FC_REFLECT( graphene::protocol::asset_issue_operation, (fee)(issuer)(asset_to_issue)(issue_to_account)(memo)(extensions) ) -FC_REFLECT( graphene::chain::asset_reserve_operation, +FC_REFLECT( graphene::protocol::asset_reserve_operation, (fee)(payer)(amount_to_reserve)(extensions) ) -FC_REFLECT( graphene::chain::asset_fund_fee_pool_operation, (fee)(from_account)(asset_id)(amount)(extensions) ); +FC_REFLECT( graphene::protocol::asset_fund_fee_pool_operation, (fee)(from_account)(asset_id)(amount)(extensions) ); + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_options ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::bitasset_options ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::additional_asset_options ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_global_settle_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_fund_fee_pool_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_pool_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_fees_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_issuer_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_bitasset_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_feed_producers_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_publish_feed_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_issue_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_reserve_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_global_settle_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_settle_cancel_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_fund_fee_pool_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_pool_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_claim_fees_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_issuer_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_bitasset_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_update_feed_producers_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_publish_feed_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_issue_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::asset_reserve_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/authority.hpp b/libraries/protocol/include/graphene/protocol/authority.hpp similarity index 91% rename from libraries/chain/include/graphene/chain/protocol/authority.hpp rename to libraries/protocol/include/graphene/protocol/authority.hpp index 145c24b5c5..ba309ef9e8 100644 --- a/libraries/chain/include/graphene/chain/protocol/authority.hpp +++ b/libraries/protocol/include/graphene/protocol/authority.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @class authority @@ -129,7 +130,9 @@ void add_authority_accounts( const authority& a ); -} } // namespace graphene::chain +} } // namespace graphene::protocol -FC_REFLECT( graphene::chain::authority, (weight_threshold)(account_auths)(key_auths)(address_auths) ) -FC_REFLECT_ENUM( graphene::chain::authority::classification, (owner)(active)(key) ) +FC_REFLECT( graphene::protocol::authority, (weight_threshold)(account_auths)(key_auths)(address_auths) ) +FC_REFLECT_ENUM( graphene::protocol::authority::classification, (owner)(active)(key) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::authority ) diff --git a/libraries/chain/include/graphene/chain/protocol/balance.hpp b/libraries/protocol/include/graphene/protocol/balance.hpp similarity index 82% rename from libraries/chain/include/graphene/chain/protocol/balance.hpp rename to libraries/protocol/include/graphene/protocol/balance.hpp index f60087a71e..9cc1d6f388 100644 --- a/libraries/chain/include/graphene/chain/protocol/balance.hpp +++ b/libraries/protocol/include/graphene/protocol/balance.hpp @@ -22,12 +22,14 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** - * @brief Claim a balance in a @ref balanc_object + * @brief Claim a balance in a @ref balance_object * * This operation is used to claim the balance in a given @ref balance_object. If the balance object contains a * vesting balance, @ref total_claimed must not exceed @ref balance_object::available at the time of evaluation. If @@ -52,8 +54,10 @@ namespace graphene { namespace chain { } }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::balance_claim_operation::fee_parameters_type, ) -FC_REFLECT( graphene::chain::balance_claim_operation, +FC_REFLECT( graphene::protocol::balance_claim_operation::fee_parameters_type, ) +FC_REFLECT( graphene::protocol::balance_claim_operation, (fee)(deposit_to_account)(balance_to_claim)(balance_owner_key)(total_claimed) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::balance_claim_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/base.hpp b/libraries/protocol/include/graphene/protocol/base.hpp similarity index 93% rename from libraries/chain/include/graphene/chain/protocol/base.hpp rename to libraries/protocol/include/graphene/protocol/base.hpp index 73209a1861..fbdf39fb06 100644 --- a/libraries/chain/include/graphene/chain/protocol/base.hpp +++ b/libraries/protocol/include/graphene/protocol/base.hpp @@ -23,13 +23,14 @@ */ #pragma once -#include -#include -#include +#include +#include #include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { + struct asset; + struct authority; /** * @defgroup operations Operations @@ -120,8 +121,8 @@ namespace graphene { namespace chain { ///@} -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT_TYPENAME( graphene::chain::operation_result ) -FC_REFLECT_TYPENAME( graphene::chain::future_extensions ) -FC_REFLECT( graphene::chain::void_result, ) +FC_REFLECT_TYPENAME( graphene::protocol::operation_result ) +FC_REFLECT_TYPENAME( graphene::protocol::future_extensions ) +FC_REFLECT( graphene::protocol::void_result, ) diff --git a/libraries/chain/include/graphene/chain/protocol/block.hpp b/libraries/protocol/include/graphene/protocol/block.hpp similarity index 78% rename from libraries/chain/include/graphene/chain/protocol/block.hpp rename to libraries/protocol/include/graphene/protocol/block.hpp index aa8c46052f..499d970998 100644 --- a/libraries/chain/include/graphene/chain/protocol/block.hpp +++ b/libraries/protocol/include/graphene/protocol/block.hpp @@ -22,9 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { class block_header { @@ -65,8 +65,12 @@ namespace graphene { namespace chain { mutable checksum_type _calculated_merkle_root; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::block_header, (previous)(timestamp)(witness)(transaction_merkle_root)(extensions) ) -FC_REFLECT_DERIVED( graphene::chain::signed_block_header, (graphene::chain::block_header), (witness_signature) ) -FC_REFLECT_DERIVED( graphene::chain::signed_block, (graphene::chain::signed_block_header), (transactions) ) +FC_REFLECT( graphene::protocol::block_header, (previous)(timestamp)(witness)(transaction_merkle_root)(extensions) ) +FC_REFLECT_DERIVED( graphene::protocol::signed_block_header, (graphene::protocol::block_header), (witness_signature) ) +FC_REFLECT_DERIVED( graphene::protocol::signed_block, (graphene::protocol::signed_block_header), (transactions) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::block_header) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::signed_block_header) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::signed_block) diff --git a/libraries/chain/include/graphene/chain/protocol/buyback.hpp b/libraries/protocol/include/graphene/protocol/buyback.hpp similarity index 85% rename from libraries/chain/include/graphene/chain/protocol/buyback.hpp rename to libraries/protocol/include/graphene/protocol/buyback.hpp index 6adad52d1f..77960bd17a 100644 --- a/libraries/chain/include/graphene/chain/protocol/buyback.hpp +++ b/libraries/protocol/include/graphene/protocol/buyback.hpp @@ -23,9 +23,9 @@ */ #pragma once -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { struct buyback_account_options { @@ -49,4 +49,6 @@ struct buyback_account_options } } -FC_REFLECT( graphene::chain::buyback_account_options, (asset_to_buy)(asset_to_buy_issuer)(markets) ); +FC_REFLECT( graphene::protocol::buyback_account_options, (asset_to_buy)(asset_to_buy_issuer)(markets) ); + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::buyback_account_options ) diff --git a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp b/libraries/protocol/include/graphene/protocol/chain_parameters.hpp similarity index 85% rename from libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp rename to libraries/protocol/include/graphene/protocol/chain_parameters.hpp index dba8281305..3ccf499b58 100644 --- a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp +++ b/libraries/protocol/include/graphene/protocol/chain_parameters.hpp @@ -22,13 +22,12 @@ * THE SOFTWARE. */ #pragma once -#include -#include -#include -namespace graphene { namespace chain { struct fee_schedule; } } +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { + struct fee_schedule; struct htlc_options { @@ -38,8 +37,11 @@ namespace graphene { namespace chain { struct chain_parameters { - /** using a smart ref breaks the circular dependency created between operations and the fee schedule */ - smart_ref current_fees; ///< current schedule of fees + /** using a shared_ptr breaks the circular dependency created between operations and the fee schedule */ + std::shared_ptr current_fees; ///< current schedule of fees + const fee_schedule& get_current_fees() const { FC_ASSERT(current_fees); return *current_fees; } + fee_schedule& get_mutable_fees() { FC_ASSERT(current_fees); return const_cast(*current_fees); } + uint8_t block_interval = GRAPHENE_DEFAULT_BLOCK_INTERVAL; ///< interval in seconds between blocks uint32_t maintenance_interval = GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL; ///< interval in sections between blockchain maintenance events uint8_t maintenance_skip_slots = GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS; ///< number of block_intervals to skip at maintenance time @@ -78,21 +80,29 @@ namespace graphene { namespace chain { /** defined in fee_schedule.cpp */ void validate()const; + + chain_parameters(); + chain_parameters(const chain_parameters& other); + chain_parameters(chain_parameters&& other); + chain_parameters& operator=(const chain_parameters& other); + chain_parameters& operator=(chain_parameters&& other); + private: + static void safe_copy(chain_parameters& to, const chain_parameters& from); }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::htlc_options, - (max_timeout_secs) - (max_preimage_size) +FC_REFLECT( graphene::protocol::htlc_options, + (max_timeout_secs) + (max_preimage_size) ) -FC_REFLECT( graphene::chain::chain_parameters::ext, +FC_REFLECT( graphene::protocol::chain_parameters::ext, (updatable_htlc_options) ) -FC_REFLECT( graphene::chain::chain_parameters, +FC_REFLECT( graphene::protocol::chain_parameters, (current_fees) (block_interval) (maintenance_interval) @@ -123,3 +133,5 @@ FC_REFLECT( graphene::chain::chain_parameters, (max_authority_depth) (extensions) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::chain_parameters ) diff --git a/libraries/chain/include/graphene/chain/protocol/committee_member.hpp b/libraries/protocol/include/graphene/protocol/committee_member.hpp similarity index 74% rename from libraries/chain/include/graphene/chain/protocol/committee_member.hpp rename to libraries/protocol/include/graphene/protocol/committee_member.hpp index 7718836723..f941a8ff10 100644 --- a/libraries/chain/include/graphene/chain/protocol/committee_member.hpp +++ b/libraries/protocol/include/graphene/protocol/committee_member.hpp @@ -22,10 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief Create a committee_member object, as a bid to hold a committee_member seat on the network. @@ -93,14 +94,21 @@ namespace graphene { namespace chain { /// TODO: committee_member_resign_operation : public base_operation -} } // graphene::chain -FC_REFLECT( graphene::chain::committee_member_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::committee_member_update_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::committee_member_update_global_parameters_operation::fee_parameters_type, (fee) ) +} } // graphene::protocol +FC_REFLECT( graphene::protocol::committee_member_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::committee_member_update_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::committee_member_update_global_parameters_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::committee_member_create_operation, +FC_REFLECT( graphene::protocol::committee_member_create_operation, (fee)(committee_member_account)(url) ) -FC_REFLECT( graphene::chain::committee_member_update_operation, +FC_REFLECT( graphene::protocol::committee_member_update_operation, (fee)(committee_member)(committee_member_account)(new_url) ) -FC_REFLECT( graphene::chain::committee_member_update_global_parameters_operation, (fee)(new_parameters) ); +FC_REFLECT( graphene::protocol::committee_member_update_global_parameters_operation, (fee)(new_parameters) ); + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_global_parameters_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::committee_member_update_global_parameters_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/confidential.hpp b/libraries/protocol/include/graphene/protocol/confidential.hpp similarity index 86% rename from libraries/chain/include/graphene/chain/protocol/confidential.hpp rename to libraries/protocol/include/graphene/protocol/confidential.hpp index 763006ae68..b47ecf3ca1 100644 --- a/libraries/chain/include/graphene/chain/protocol/confidential.hpp +++ b/libraries/protocol/include/graphene/protocol/confidential.hpp @@ -23,9 +23,11 @@ */ #pragma once -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { using fc::ecc::blind_factor_type; @@ -258,26 +260,33 @@ struct blind_transfer_operation : public base_operation ///@} endgroup stealth -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::stealth_confirmation, +FC_REFLECT( graphene::protocol::stealth_confirmation, (one_time_key)(to)(encrypted_memo) ) -FC_REFLECT( graphene::chain::stealth_confirmation::memo_data, +FC_REFLECT( graphene::protocol::stealth_confirmation::memo_data, (from)(amount)(blinding_factor)(commitment)(check) ); -FC_REFLECT( graphene::chain::blind_memo, +FC_REFLECT( graphene::protocol::blind_memo, (from)(amount)(message)(check) ) -FC_REFLECT( graphene::chain::blind_input, +FC_REFLECT( graphene::protocol::blind_input, (commitment)(owner) ) -FC_REFLECT( graphene::chain::blind_output, +FC_REFLECT( graphene::protocol::blind_output, (commitment)(range_proof)(owner)(stealth_memo) ) -FC_REFLECT( graphene::chain::transfer_to_blind_operation, +FC_REFLECT( graphene::protocol::transfer_to_blind_operation, (fee)(amount)(from)(blinding_factor)(outputs) ) -FC_REFLECT( graphene::chain::transfer_from_blind_operation, +FC_REFLECT( graphene::protocol::transfer_from_blind_operation, (fee)(amount)(to)(blinding_factor)(inputs) ) -FC_REFLECT( graphene::chain::blind_transfer_operation, +FC_REFLECT( graphene::protocol::blind_transfer_operation, (fee)(inputs)(outputs) ) -FC_REFLECT( graphene::chain::transfer_to_blind_operation::fee_parameters_type, (fee)(price_per_output) ) -FC_REFLECT( graphene::chain::transfer_from_blind_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::blind_transfer_operation::fee_parameters_type, (fee)(price_per_output) ) +FC_REFLECT( graphene::protocol::transfer_to_blind_operation::fee_parameters_type, (fee)(price_per_output) ) +FC_REFLECT( graphene::protocol::transfer_from_blind_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::blind_transfer_operation::fee_parameters_type, (fee)(price_per_output) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_to_blind_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_from_blind_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::blind_transfer_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_to_blind_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_from_blind_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::blind_transfer_operation ) diff --git a/libraries/protocol/include/graphene/protocol/config.hpp b/libraries/protocol/include/graphene/protocol/config.hpp new file mode 100644 index 0000000000..8ea4bcc56b --- /dev/null +++ b/libraries/protocol/include/graphene/protocol/config.hpp @@ -0,0 +1,140 @@ +/* + * 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. + */ +#pragma once + +#define GRAPHENE_SYMBOL "BTS" +#define GRAPHENE_ADDRESS_PREFIX "BTS" + +#define GRAPHENE_BLOCKCHAIN_PRECISION uint64_t( 100000 ) +#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS 5 + +#define GRAPHENE_MIN_ACCOUNT_NAME_LENGTH 1 +#define GRAPHENE_MAX_ACCOUNT_NAME_LENGTH 63 + +#define GRAPHENE_MIN_ASSET_SYMBOL_LENGTH 3 +#define GRAPHENE_MAX_ASSET_SYMBOL_LENGTH 16 + +#define GRAPHENE_MAX_SHARE_SUPPLY int64_t(1000000000000000ll) + +#define GRAPHENE_MAX_WORKER_NAME_LENGTH 63 +#define GRAPHENE_MAX_URL_LENGTH 127 + +#define GRAPHENE_MAX_SIG_CHECK_DEPTH 2 + +#define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT) + +/** + * every second, the fraction of burned core asset which cycles is + * GRAPHENE_CORE_ASSET_CYCLE_RATE / (1 << GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS) + */ +#define GRAPHENE_CORE_ASSET_CYCLE_RATE 17 +#define GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS 32 + +/** + * Don't allow the committee_members to publish a limit that would + * make the network unable to operate. + */ +#define GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT 1024 +#define GRAPHENE_MIN_BLOCK_INTERVAL 1 /* seconds */ +#define GRAPHENE_MAX_BLOCK_INTERVAL 30 /* seconds */ + +#define GRAPHENE_DEFAULT_BLOCK_INTERVAL 5 /* seconds */ +#define GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE 2048 +#define GRAPHENE_DEFAULT_MAX_BLOCK_SIZE (2*1000*1000) /* < 2 MiB (less than MAX_MESSAGE_SIZE in graphene/net/config.hpp) */ +#define GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION (60*60*24) // seconds, aka: 1 day +#define GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (60*60*24) // seconds, aka: 1 day +#define GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS 3 // number of slots to skip for maintenance interval + +#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_DELAY (60*60*24) ///< 1 day +#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_OFFSET 0 ///< 1% +#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_MAX_VOLUME (20* GRAPHENE_1_PERCENT) ///< 20% +#define GRAPHENE_DEFAULT_PRICE_FEED_LIFETIME (60*60*24) ///< 1 day +#define GRAPHENE_DEFAULT_MAX_AUTHORITY_MEMBERSHIP 10 +#define GRAPHENE_DEFAULT_MAX_ASSET_WHITELIST_AUTHORITIES 10 +#define GRAPHENE_DEFAULT_MAX_ASSET_FEED_PUBLISHERS 10 + +#define GRAPHENE_DEFAULT_MIN_WITNESS_COUNT (11) +#define GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT (11) +#define GRAPHENE_DEFAULT_MAX_WITNESSES (1001) // SHOULD BE ODD +#define GRAPHENE_DEFAULT_MAX_COMMITTEE (1001) // SHOULD BE ODD +#define GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC (60*60*24*7*4) // Four weeks +#define GRAPHENE_DEFAULT_COMMITTEE_PROPOSAL_REVIEW_PERIOD_SEC (60*60*24*7*2) // Two weeks +#define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT) +#define GRAPHENE_DEFAULT_LIFETIME_REFERRER_PERCENT_OF_FEE (30*GRAPHENE_1_PERCENT) +#define GRAPHENE_DEFAULT_CASHBACK_VESTING_PERIOD_SEC (60*60*24*365) ///< 1 year +#define GRAPHENE_DEFAULT_CASHBACK_VESTING_THRESHOLD (GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(100)) +#define GRAPHENE_DEFAULT_BURN_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT) +#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1 +#define GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD GRAPHENE_BLOCKCHAIN_PRECISION * 100; +#define GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE 1000 +#define GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS 4 +#define GRAPHENE_DEFAULT_MAX_BUYBACK_MARKETS 4 + +#define GRAPHENE_DEFAULT_WITNESS_PAY_PER_BLOCK (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t( 10) ) +#define GRAPHENE_DEFAULT_WITNESS_PAY_VESTING_SECONDS (60*60*24) +#define GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(500) * 1000 ) +#define GRAPHENE_DEFAULT_MINIMUM_FEEDS 7 + +#define GRAPHENE_MIN_BLOCK_SIZE_LIMIT (GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT*5) // 5 transactions per block + +/** percentage fields are fixed point with a denominator of 10,000 */ +#define GRAPHENE_100_PERCENT 10000 +#define GRAPHENE_1_PERCENT (GRAPHENE_100_PERCENT/100) +/** NOTE: making this a power of 2 (say 2^15) would greatly accelerate fee calcs */ + +#define GRAPHENE_MAX_MARKET_FEE_PERCENT GRAPHENE_100_PERCENT +/** + * These ratios are fixed point numbers with a denominator of GRAPHENE_COLLATERAL_RATIO_DENOM, the + * minimum maitenance collateral is therefore 1.001x and the default + * maintenance ratio is 1.75x + */ +///@{ +#define GRAPHENE_COLLATERAL_RATIO_DENOM 1000 +#define GRAPHENE_MIN_COLLATERAL_RATIO 1001 ///< lower than this could result in divide by 0 +#define GRAPHENE_MAX_COLLATERAL_RATIO 32000 ///< higher than this is unnecessary and may exceed int16 storage +#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO 1750 ///< Call when collateral only pays off 175% the debt +#define GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO 1500 ///< Stop calling when collateral only pays off 150% of the debt +///@} + +/** + * Reserved Account IDs with special meaning + */ +///@{ +/// Represents the current committee members, two-week review period +#define GRAPHENE_COMMITTEE_ACCOUNT (graphene::protocol::account_id_type(0)) +/// Represents the current witnesses +#define GRAPHENE_WITNESS_ACCOUNT (graphene::protocol::account_id_type(1)) +/// Represents the current committee members +#define GRAPHENE_RELAXED_COMMITTEE_ACCOUNT (graphene::protocol::account_id_type(2)) +/// Represents the canonical account with NO authority (nobody can access funds in null account) +#define GRAPHENE_NULL_ACCOUNT (graphene::protocol::account_id_type(3)) +/// Represents the canonical account with WILDCARD authority (anybody can access funds in temp account) +#define GRAPHENE_TEMP_ACCOUNT (graphene::protocol::account_id_type(4)) +/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy) +#define GRAPHENE_PROXY_TO_SELF_ACCOUNT (graphene::protocol::account_id_type(5)) +/// Sentinel value used in the scheduler. +#define GRAPHENE_NULL_WITNESS (graphene::protocol::witness_id_type(0)) +///@} + +#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743)) diff --git a/libraries/chain/include/graphene/chain/protocol/custom.hpp b/libraries/protocol/include/graphene/protocol/custom.hpp similarity index 79% rename from libraries/chain/include/graphene/chain/protocol/custom.hpp rename to libraries/protocol/include/graphene/protocol/custom.hpp index e5701a4b2a..8be5ab1e60 100644 --- a/libraries/chain/include/graphene/chain/protocol/custom.hpp +++ b/libraries/protocol/include/graphene/protocol/custom.hpp @@ -23,9 +23,10 @@ */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief provides a generic way to add higher level protocols on top of witness consensus @@ -52,7 +53,10 @@ namespace graphene { namespace chain { share_type calculate_fee(const fee_parameters_type& k)const; }; -} } // namespace graphene::chain +} } // namespace graphene::protocol -FC_REFLECT( graphene::chain::custom_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::custom_operation, (fee)(payer)(required_auths)(id)(data) ) +FC_REFLECT( graphene::protocol::custom_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::custom_operation, (fee)(payer)(required_auths)(id)(data) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::custom_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::custom_operation ) diff --git a/libraries/protocol/include/graphene/protocol/exceptions.hpp b/libraries/protocol/include/graphene/protocol/exceptions.hpp new file mode 100644 index 0000000000..f062dd7d18 --- /dev/null +++ b/libraries/protocol/include/graphene/protocol/exceptions.hpp @@ -0,0 +1,48 @@ +/* + * 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. + */ +#pragma once + +#include + +#define GRAPHENE_ASSERT( expr, exc_type, FORMAT, ... ) \ + FC_MULTILINE_MACRO_BEGIN \ + if( !(expr) ) \ + FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \ + FC_MULTILINE_MACRO_END + +namespace graphene { namespace protocol { + + FC_DECLARE_EXCEPTION( protocol_exception, 4000000 ) + + FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, protocol_exception, 4010000 ) + + FC_DECLARE_DERIVED_EXCEPTION( tx_missing_active_auth, transaction_exception, 4010001 ) + FC_DECLARE_DERIVED_EXCEPTION( tx_missing_owner_auth, transaction_exception, 4010002 ) + FC_DECLARE_DERIVED_EXCEPTION( tx_missing_other_auth, transaction_exception, 4010003 ) + FC_DECLARE_DERIVED_EXCEPTION( tx_irrelevant_sig, transaction_exception, 4010004 ) + FC_DECLARE_DERIVED_EXCEPTION( tx_duplicate_sig, transaction_exception, 4010005 ) + FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_approval, transaction_exception, 4010006 ) + FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, transaction_exception, 4010007 ) + +} } // graphene::protocol diff --git a/libraries/chain/include/graphene/chain/protocol/ext.hpp b/libraries/protocol/include/graphene/protocol/ext.hpp similarity index 84% rename from libraries/chain/include/graphene/chain/protocol/ext.hpp rename to libraries/protocol/include/graphene/protocol/ext.hpp index f868fa0b23..5dccf9fe9b 100644 --- a/libraries/chain/include/graphene/chain/protocol/ext.hpp +++ b/libraries/protocol/include/graphene/protocol/ext.hpp @@ -24,9 +24,11 @@ #pragma once #include +#include #include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { using fc::unsigned_int; @@ -128,7 +130,7 @@ struct graphene_extension_unpack_visitor const uint32_t max_depth; }; -} } // graphene::chain +} } // graphene::protocol namespace fc { @@ -161,9 +163,9 @@ struct graphene_extension_from_variant_visitor }; template< typename T > -void from_variant( const fc::variant& var, graphene::chain::extension& value, uint32_t max_depth ) +void from_variant( const fc::variant& var, graphene::protocol::extension& value, uint32_t max_depth ) { - value = graphene::chain::extension(); + value = graphene::protocol::extension(); if( var.is_null() ) return; if( var.is_array() ) @@ -194,7 +196,7 @@ struct graphene_extension_to_variant_visitor }; template< typename T > -void to_variant( const graphene::chain::extension& value, fc::variant& var, uint32_t max_depth ) +void to_variant( const graphene::protocol::extension& value, fc::variant& var, uint32_t max_depth ) { graphene_extension_to_variant_visitor vtor( value.value, max_depth ); fc::reflector::visit( vtor ); @@ -204,36 +206,36 @@ void to_variant( const graphene::chain::extension& value, fc::variant& var, u namespace raw { template< typename Stream, typename T > -void pack( Stream& stream, const graphene::chain::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) +void pack( Stream& stream, const graphene::protocol::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { FC_ASSERT( _max_depth > 0 ); --_max_depth; - graphene::chain::graphene_extension_pack_count_visitor count_vtor( value.value ); + graphene::protocol::graphene_extension_pack_count_visitor count_vtor( value.value ); fc::reflector::visit( count_vtor ); fc::raw::pack( stream, unsigned_int( count_vtor.count ), _max_depth ); - graphene::chain::graphene_extension_pack_read_visitor read_vtor( stream, value.value, _max_depth ); + graphene::protocol::graphene_extension_pack_read_visitor read_vtor( stream, value.value, _max_depth ); fc::reflector::visit( read_vtor ); } template< typename Stream, typename T > -void unpack( Stream& s, graphene::chain::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) +void unpack( Stream& s, graphene::protocol::extension& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { FC_ASSERT( _max_depth > 0 ); --_max_depth; - value = graphene::chain::extension(); - graphene::chain::graphene_extension_unpack_visitor vtor( s, value.value, _max_depth ); + value = graphene::protocol::extension(); + graphene::protocol::graphene_extension_unpack_visitor vtor( s, value.value, _max_depth ); fc::reflector::visit( vtor ); FC_ASSERT( vtor.count_left == 0 ); // unrecognized extension throws here } } // fc::raw -template struct get_typename< graphene::chain::extension > +template struct get_typename< graphene::protocol::extension > { static const char* name() { - static std::string n = std::string("graphene::chain::extension<") + static std::string n = std::string("graphene::protocol::extension<") + fc::get_typename::name() + std::string(">"); return n.c_str(); } diff --git a/libraries/chain/include/graphene/chain/protocol/fba.hpp b/libraries/protocol/include/graphene/protocol/fba.hpp similarity index 74% rename from libraries/chain/include/graphene/chain/protocol/fba.hpp rename to libraries/protocol/include/graphene/protocol/fba.hpp index 7460ca8df6..0c58c2eb53 100644 --- a/libraries/chain/include/graphene/chain/protocol/fba.hpp +++ b/libraries/protocol/include/graphene/protocol/fba.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { struct fba_distribute_operation : public base_operation { @@ -32,7 +33,8 @@ struct fba_distribute_operation : public base_operation asset fee; // always zero account_id_type account_id; - fba_accumulator_id_type fba_id; + // We use object_id_type because this is an implementaton object, and therefore is not known to the protocol library + object_id_type fba_id; share_type amount; account_id_type fee_payer()const { return account_id; } @@ -42,6 +44,8 @@ struct fba_distribute_operation : public base_operation } } -FC_REFLECT( graphene::chain::fba_distribute_operation::fee_parameters_type, ) +FC_REFLECT( graphene::protocol::fba_distribute_operation::fee_parameters_type, ) -FC_REFLECT( graphene::chain::fba_distribute_operation, (fee)(account_id)(fba_id)(amount) ) +FC_REFLECT( graphene::protocol::fba_distribute_operation, (fee)(account_id)(fba_id)(amount) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::fba_distribute_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp b/libraries/protocol/include/graphene/protocol/fee_schedule.hpp similarity index 90% rename from libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp rename to libraries/protocol/include/graphene/protocol/fee_schedule.hpp index 54d702c84e..590ae840d5 100644 --- a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp +++ b/libraries/protocol/include/graphene/protocol/fee_schedule.hpp @@ -22,10 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { template struct transform_to_fee_parameters; template @@ -159,9 +158,18 @@ namespace graphene { namespace chain { /** * Finds the appropriate fee parameter struct for the operation - * and then calculates the appropriate fee. + * and then calculates the appropriate fee in CORE asset. + */ + asset calculate_fee( const operation& op )const; + /** + * Finds the appropriate fee parameter struct for the operation + * and then calculates the appropriate fee in an asset specified + * implicitly by core_exchange_rate. + */ + asset calculate_fee( const operation& op, const price& core_exchange_rate )const; + /** + * Updates the operation with appropriate fee and returns the fee. */ - asset calculate_fee( const operation& op, const price& core_exchange_rate = price::unit_price() )const; asset set_fee( operation& op, const price& core_exchange_rate = price::unit_price() )const; void zero_all_fees(); @@ -193,11 +201,15 @@ namespace graphene { namespace chain { */ flat_set parameters; uint32_t scale = GRAPHENE_100_PERCENT; ///< fee * scale / GRAPHENE_100_PERCENT + private: + static void set_fee_parameters(fee_schedule& sched); }; typedef fee_schedule fee_schedule_type; -} } // graphene::chain +} } // graphene::protocol + +FC_REFLECT_TYPENAME( graphene::protocol::fee_parameters ) +FC_REFLECT( graphene::protocol::fee_schedule, (parameters)(scale) ) -FC_REFLECT_TYPENAME( graphene::chain::fee_parameters ) -FC_REFLECT( graphene::chain::fee_schedule, (parameters)(scale) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::fee_schedule ) diff --git a/libraries/chain/include/graphene/chain/protocol/htlc.hpp b/libraries/protocol/include/graphene/protocol/htlc.hpp similarity index 75% rename from libraries/chain/include/graphene/chain/protocol/htlc.hpp rename to libraries/protocol/include/graphene/protocol/htlc.hpp index 5e9ab847a8..ac1732cd9d 100644 --- a/libraries/chain/include/graphene/chain/protocol/htlc.hpp +++ b/libraries/protocol/include/graphene/protocol/htlc.hpp @@ -23,18 +23,12 @@ */ #pragma once -#include -#include -#include #include -#include -#include -#include +#include +#include #include // std::max -namespace graphene { - namespace chain { - +namespace graphene { namespace protocol { typedef fc::ripemd160 htlc_algo_ripemd160; typedef fc::sha1 htlc_algo_sha1; typedef fc::sha256 htlc_algo_sha256; @@ -126,8 +120,8 @@ namespace graphene { struct fee_parameters_type {}; htlc_redeemed_operation() {} - htlc_redeemed_operation( htlc_id_type htlc_id, account_id_type from, account_id_type to, asset amount) : - htlc_id(htlc_id), from(from), to(to), amount(amount) {} + htlc_redeemed_operation( htlc_id_type htlc_id, account_id_type from, account_id_type to, account_id_type redeemer, asset amount ) : + htlc_id(htlc_id), from(from), to(to), redeemer(redeemer), amount(amount) {} account_id_type fee_payer()const { return to; } void validate()const { FC_ASSERT( !"virtual operation" ); } @@ -135,7 +129,7 @@ namespace graphene { share_type calculate_fee(const fee_parameters_type& k)const { return 0; } htlc_id_type htlc_id; - account_id_type from, to; + account_id_type from, to, redeemer; asset amount; asset fee; }; @@ -195,17 +189,26 @@ namespace graphene { } } -FC_REFLECT_TYPENAME( graphene::chain::htlc_hash ) +FC_REFLECT_TYPENAME( graphene::protocol::htlc_hash ) -FC_REFLECT( graphene::chain::htlc_create_operation::fee_parameters_type, (fee) (fee_per_day) ) -FC_REFLECT( graphene::chain::htlc_redeem_operation::fee_parameters_type, (fee) (fee_per_kb) ) -FC_REFLECT( graphene::chain::htlc_redeemed_operation::fee_parameters_type, ) // VIRTUAL -FC_REFLECT( graphene::chain::htlc_extend_operation::fee_parameters_type, (fee) (fee_per_day)) -FC_REFLECT( graphene::chain::htlc_refund_operation::fee_parameters_type, ) // VIRTUAL +FC_REFLECT( graphene::protocol::htlc_create_operation::fee_parameters_type, (fee) (fee_per_day) ) +FC_REFLECT( graphene::protocol::htlc_redeem_operation::fee_parameters_type, (fee) (fee_per_kb) ) +FC_REFLECT( graphene::protocol::htlc_redeemed_operation::fee_parameters_type, ) // VIRTUAL +FC_REFLECT( graphene::protocol::htlc_extend_operation::fee_parameters_type, (fee) (fee_per_day)) +FC_REFLECT( graphene::protocol::htlc_refund_operation::fee_parameters_type, ) // VIRTUAL -FC_REFLECT( graphene::chain::htlc_create_operation, +FC_REFLECT( graphene::protocol::htlc_create_operation, (fee)(from)(to)(amount)(preimage_hash)(preimage_size)(claim_period_seconds)(extensions)) -FC_REFLECT( graphene::chain::htlc_redeem_operation, (fee)(htlc_id)(redeemer)(preimage)(extensions)) -FC_REFLECT( graphene::chain::htlc_redeemed_operation, (fee)(htlc_id)(from)(to)(amount) ) -FC_REFLECT( graphene::chain::htlc_extend_operation, (fee)(htlc_id)(update_issuer)(seconds_to_add)(extensions)) -FC_REFLECT( graphene::chain::htlc_refund_operation, (fee)(htlc_id)(to)) +FC_REFLECT( graphene::protocol::htlc_redeem_operation, (fee)(htlc_id)(redeemer)(preimage)(extensions)) +FC_REFLECT( graphene::protocol::htlc_redeemed_operation, (fee)(htlc_id)(from)(to)(redeemer)(amount) ) +FC_REFLECT( graphene::protocol::htlc_extend_operation, (fee)(htlc_id)(update_issuer)(seconds_to_add)(extensions)) +FC_REFLECT( graphene::protocol::htlc_refund_operation, (fee)(htlc_id)(to)) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeem_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_extend_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeem_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_redeemed_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_extend_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::htlc_refund_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/market.hpp b/libraries/protocol/include/graphene/protocol/market.hpp similarity index 77% rename from libraries/chain/include/graphene/chain/protocol/market.hpp rename to libraries/protocol/include/graphene/protocol/market.hpp index 55438d7cc5..b29d8b4fa3 100644 --- a/libraries/chain/include/graphene/chain/protocol/market.hpp +++ b/libraries/protocol/include/graphene/protocol/market.hpp @@ -22,10 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @class limit_order_create_operation @@ -73,7 +73,6 @@ namespace graphene { namespace chain { price get_price()const { return amount_to_sell / min_to_receive; } }; - /** * @ingroup operations * Used to cancel an existing limit order. Both fee_pay_account and the @@ -216,22 +215,32 @@ namespace graphene { namespace chain { /// This is a virtual operation; there is no fee share_type calculate_fee(const fee_parameters_type& k)const { return 0; } }; -} } // graphene::chain - -FC_REFLECT( graphene::chain::limit_order_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::limit_order_cancel_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::call_order_update_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::bid_collateral_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::fill_order_operation::fee_parameters_type, ) // VIRTUAL -FC_REFLECT( graphene::chain::execute_bid_operation::fee_parameters_type, ) // VIRTUAL - -FC_REFLECT( graphene::chain::call_order_update_operation::options_type, (target_collateral_ratio) ) - -FC_REFLECT_TYPENAME( graphene::chain::call_order_update_operation::extensions_type ) - -FC_REFLECT( graphene::chain::limit_order_create_operation,(fee)(seller)(amount_to_sell)(min_to_receive)(expiration)(fill_or_kill)(extensions)) -FC_REFLECT( graphene::chain::limit_order_cancel_operation,(fee)(fee_paying_account)(order)(extensions) ) -FC_REFLECT( graphene::chain::call_order_update_operation, (fee)(funding_account)(delta_collateral)(delta_debt)(extensions) ) -FC_REFLECT( graphene::chain::fill_order_operation, (fee)(order_id)(account_id)(pays)(receives)(fill_price)(is_maker) ) -FC_REFLECT( graphene::chain::bid_collateral_operation, (fee)(bidder)(additional_collateral)(debt_covered)(extensions) ) -FC_REFLECT( graphene::chain::execute_bid_operation, (fee)(bidder)(debt)(collateral) ) +} } // graphene::protocol + +FC_REFLECT( graphene::protocol::limit_order_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::limit_order_cancel_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::call_order_update_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::bid_collateral_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::fill_order_operation::fee_parameters_type, ) // VIRTUAL +FC_REFLECT( graphene::protocol::execute_bid_operation::fee_parameters_type, ) // VIRTUAL + +FC_REFLECT( graphene::protocol::call_order_update_operation::options_type, (target_collateral_ratio) ) + +FC_REFLECT( graphene::protocol::limit_order_create_operation,(fee)(seller)(amount_to_sell)(min_to_receive)(expiration)(fill_or_kill)(extensions)) +FC_REFLECT( graphene::protocol::limit_order_cancel_operation,(fee)(fee_paying_account)(order)(extensions) ) +FC_REFLECT( graphene::protocol::call_order_update_operation, (fee)(funding_account)(delta_collateral)(delta_debt)(extensions) ) +FC_REFLECT( graphene::protocol::fill_order_operation, (fee)(order_id)(account_id)(pays)(receives)(fill_price)(is_maker) ) +FC_REFLECT( graphene::protocol::bid_collateral_operation, (fee)(bidder)(additional_collateral)(debt_covered)(extensions) ) +FC_REFLECT( graphene::protocol::execute_bid_operation, (fee)(bidder)(debt)(collateral) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation::options_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_cancel_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::bid_collateral_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_cancel_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::bid_collateral_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::fill_order_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::execute_bid_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/memo.hpp b/libraries/protocol/include/graphene/protocol/memo.hpp similarity index 89% rename from libraries/chain/include/graphene/chain/protocol/memo.hpp rename to libraries/protocol/include/graphene/protocol/memo.hpp index b126d3a7d5..8762fbeb85 100644 --- a/libraries/chain/include/graphene/chain/protocol/memo.hpp +++ b/libraries/protocol/include/graphene/protocol/memo.hpp @@ -22,9 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief defines the keys used to derive the shared secret @@ -85,7 +85,10 @@ namespace graphene { namespace chain { static memo_message deserialize(const string& serial); }; -} } // namespace graphene::chain +} } // namespace graphene::protocol -FC_REFLECT( graphene::chain::memo_message, (checksum)(text) ) -FC_REFLECT( graphene::chain::memo_data, (from)(to)(nonce)(message) ) +FC_REFLECT( graphene::protocol::memo_message, (checksum)(text) ) +FC_REFLECT( graphene::protocol::memo_data, (from)(to)(nonce)(message) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::memo_message ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::memo_data ) diff --git a/libraries/db/include/graphene/db/object_id.hpp b/libraries/protocol/include/graphene/protocol/object_id.hpp similarity index 80% rename from libraries/db/include/graphene/db/object_id.hpp rename to libraries/protocol/include/graphene/protocol/object_id.hpp index acada38d14..4175a8ea75 100644 --- a/libraries/db/include/graphene/db/object_id.hpp +++ b/libraries/protocol/include/graphene/protocol/object_id.hpp @@ -91,14 +91,26 @@ namespace graphene { namespace db { class object; class object_database; - template + /// This template is used to downcast a generic object type to a specific xyz_object type. + template + struct object_downcast { using type = object; }; + // This macro specializes the above template for a specific xyz_object type +#define MAP_OBJECT_ID_TO_TYPE(OBJECT) \ + namespace graphene { namespace db { \ + template<> \ + struct object_downcast> { using type = OBJECT; }; \ + } } + template + using object_downcast_t = typename object_downcast::type; + + template struct object_id { - typedef T type; static const uint8_t space_id = SpaceID; static const uint8_t type_id = TypeID; - object_id(){} + object_id() = default; object_id( unsigned_int i ):instance(i){} explicit object_id( uint64_t i ):instance(i) { @@ -115,14 +127,18 @@ namespace graphene { namespace db { explicit operator uint64_t()const { return object_id_type( *this ).number; } template - const T& operator()(const DB& db)const { return db.get(*this); } + auto operator()(const DB& db)const -> const decltype(db.get(*this))& { return db.get(*this); } friend bool operator == ( const object_id& a, const object_id& b ) { return a.instance == b.instance; } friend bool operator != ( const object_id& a, const object_id& b ) { return a.instance != b.instance; } friend bool operator == ( const object_id_type& a, const object_id& b ) { return a == object_id_type(b); } friend bool operator != ( const object_id_type& a, const object_id& b ) { return a != object_id_type(b); } - friend bool operator == ( const object_id& b, const object_id_type& a ) { return a == object_id_type(b); } - friend bool operator != ( const object_id& b, const object_id_type& a ) { return a != object_id_type(b); } + friend bool operator == ( const object_id& a, const object_id_type& b ) { return object_id_type(a) == b; } + friend bool operator != ( const object_id& a, const object_id_type& b ) { return object_id_type(a) != b; } + friend bool operator == ( const object_id& a, const fc::unsigned_int& b ) { return a.instance == b; } + friend bool operator != ( const object_id& a, const fc::unsigned_int& b ) { return a.instance != b; } + friend bool operator == ( const fc::unsigned_int& a, const object_id& b ) { return a == b.instance; } + friend bool operator != ( const fc::unsigned_int& a, const object_id& b ) { return a != b.instance; } friend bool operator < ( const object_id& a, const object_id& b ) { return a.instance.value < b.instance.value; } friend bool operator > ( const object_id& a, const object_id& b ) { return a.instance.value > b.instance.value; } @@ -138,8 +154,8 @@ FC_REFLECT( graphene::db::object_id_type, (number) ) // REFLECT object_id manually because it has 2 template params namespace fc { -template -struct get_typename> +template +struct get_typename> { static const char* name() { return typeid(get_typename).name(); @@ -148,10 +164,10 @@ struct get_typename> } }; -template -struct reflector > +template +struct reflector > { - typedef graphene::db::object_id type; + typedef graphene::db::object_id type; typedef fc::true_type is_defined; typedef fc::false_type is_enum; enum member_count_enum { @@ -188,13 +204,13 @@ struct reflector > FC_ASSERT( type_id <= 0xff ); vo.number |= (space_id << 56) | (type_id << 48); } FC_CAPTURE_AND_RETHROW( (var) ) } - template - void to_variant( const graphene::db::object_id& var, fc::variant& vo, uint32_t max_depth = 1 ) + template + void to_variant( const graphene::db::object_id& var, fc::variant& vo, uint32_t max_depth = 1 ) { vo = fc::to_string(SpaceID) + "." + fc::to_string(TypeID) + "." + fc::to_string(var.instance.value); } - template - void from_variant( const fc::variant& var, graphene::db::object_id& vo, uint32_t max_depth = 1 ) + template + void from_variant( const fc::variant& var, graphene::db::object_id& vo, uint32_t max_depth = 1 ) { try { const auto& s = var.get_string(); auto first_dot = s.find('.'); diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/protocol/include/graphene/protocol/operations.hpp similarity index 82% rename from libraries/chain/include/graphene/chain/protocol/operations.hpp rename to libraries/protocol/include/graphene/protocol/operations.hpp index 9b5ffabb37..3a603ebf64 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/protocol/include/graphene/protocol/operations.hpp @@ -22,25 +22,25 @@ * THE SOFTWARE. */ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @ingroup operations @@ -129,7 +129,9 @@ namespace graphene { namespace chain { operation op; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT_TYPENAME( graphene::chain::operation ) -FC_REFLECT( graphene::chain::op_wrapper, (op) ) +FC_REFLECT_TYPENAME( graphene::protocol::operation ) +FC_REFLECT( graphene::protocol::op_wrapper, (op) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::op_wrapper ) diff --git a/libraries/chain/include/graphene/chain/protocol/proposal.hpp b/libraries/protocol/include/graphene/protocol/proposal.hpp similarity index 87% rename from libraries/chain/include/graphene/chain/protocol/proposal.hpp rename to libraries/protocol/include/graphene/protocol/proposal.hpp index 3383b6cfd6..9f862fe46c 100644 --- a/libraries/chain/include/graphene/chain/protocol/proposal.hpp +++ b/libraries/protocol/include/graphene/protocol/proposal.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @defgroup proposed_transactions The Graphene Transaction Proposal Protocol * @ingroup operations @@ -167,15 +168,22 @@ namespace graphene { namespace chain { }; ///@} -}} // graphene::chain +}} // graphene::protocol -FC_REFLECT( graphene::chain::proposal_create_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::proposal_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::proposal_delete_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::proposal_create_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::proposal_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::proposal_delete_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::proposal_create_operation, (fee)(fee_paying_account)(expiration_time) +FC_REFLECT( graphene::protocol::proposal_create_operation, (fee)(fee_paying_account)(expiration_time) (proposed_ops)(review_period_seconds)(extensions) ) -FC_REFLECT( graphene::chain::proposal_update_operation, (fee)(fee_paying_account)(proposal) +FC_REFLECT( graphene::protocol::proposal_update_operation, (fee)(fee_paying_account)(proposal) (active_approvals_to_add)(active_approvals_to_remove)(owner_approvals_to_add)(owner_approvals_to_remove) (key_approvals_to_add)(key_approvals_to_remove)(extensions) ) -FC_REFLECT( graphene::chain::proposal_delete_operation, (fee)(fee_paying_account)(using_owner_authority)(proposal)(extensions) ) +FC_REFLECT( graphene::protocol::proposal_delete_operation, (fee)(fee_paying_account)(using_owner_authority)(proposal)(extensions) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_delete_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::proposal_delete_operation ) diff --git a/libraries/chain/include/graphene/chain/pts_address.hpp b/libraries/protocol/include/graphene/protocol/pts_address.hpp similarity index 70% rename from libraries/chain/include/graphene/chain/pts_address.hpp rename to libraries/protocol/include/graphene/protocol/pts_address.hpp index 636e2f114e..981440cd16 100644 --- a/libraries/chain/include/graphene/chain/pts_address.hpp +++ b/libraries/protocol/include/graphene/protocol/pts_address.hpp @@ -24,11 +24,13 @@ #pragma once #include +#include +#include #include namespace fc { namespace ecc { class public_key; } } -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * Implements address stringification and validation from PTS @@ -51,15 +53,15 @@ namespace graphene { namespace chain { inline bool operator != ( const pts_address& a, const pts_address& b ) { return a.addr != b.addr; } inline bool operator < ( const pts_address& a, const pts_address& b ) { return a.addr < b.addr; } -} } // namespace graphene::chain +} } // namespace graphene::protocol namespace std { template<> - struct hash + struct hash { public: - size_t operator()(const graphene::chain::pts_address &a) const + size_t operator()(const graphene::protocol::pts_address &a) const { size_t s; memcpy( (char*)&s, &a.addr.data[sizeof(a)-sizeof(s)], sizeof(s) ); @@ -69,10 +71,18 @@ namespace std } #include -FC_REFLECT( graphene::chain::pts_address, (addr) ) +FC_REFLECT( graphene::protocol::pts_address, (addr) ) namespace fc { - void to_variant( const graphene::chain::pts_address& var, fc::variant& vo, uint32_t max_depth = 1 ); - void from_variant( const fc::variant& var, graphene::chain::pts_address& vo, uint32_t max_depth = 1 ); -} + void to_variant( const graphene::protocol::pts_address& var, fc::variant& vo, uint32_t max_depth = 1 ); + void from_variant( const fc::variant& var, graphene::protocol::pts_address& vo, uint32_t max_depth = 1 ); + +namespace raw { + extern template void pack( datastream& s, const graphene::protocol::pts_address& tx, + uint32_t _max_depth ); + extern template void pack( datastream& s, const graphene::protocol::pts_address& tx, + uint32_t _max_depth ); + extern template void unpack( datastream& s, graphene::protocol::pts_address& tx, + uint32_t _max_depth ); +} } // fc::raw diff --git a/libraries/chain/include/graphene/chain/protocol/special_authority.hpp b/libraries/protocol/include/graphene/protocol/special_authority.hpp similarity index 78% rename from libraries/chain/include/graphene/chain/protocol/special_authority.hpp rename to libraries/protocol/include/graphene/protocol/special_authority.hpp index 3ee6f15fd2..393fae1078 100644 --- a/libraries/chain/include/graphene/chain/protocol/special_authority.hpp +++ b/libraries/protocol/include/graphene/protocol/special_authority.hpp @@ -23,10 +23,9 @@ */ #pragma once -#include -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { struct no_special_authority {}; @@ -43,8 +42,10 @@ typedef static_variant< void validate_special_authority( const special_authority& auth ); -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::no_special_authority, ) -FC_REFLECT( graphene::chain::top_holders_special_authority, (asset)(num_top_holders) ) -FC_REFLECT_TYPENAME( graphene::chain::special_authority ) +FC_REFLECT( graphene::protocol::no_special_authority, ) +FC_REFLECT( graphene::protocol::top_holders_special_authority, (asset)(num_top_holders) ) +FC_REFLECT_TYPENAME( graphene::protocol::special_authority ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::top_holders_special_authority ) diff --git a/libraries/chain/include/graphene/chain/protocol/transaction.hpp b/libraries/protocol/include/graphene/protocol/transaction.hpp similarity index 92% rename from libraries/chain/include/graphene/chain/protocol/transaction.hpp rename to libraries/protocol/include/graphene/protocol/transaction.hpp index 3d1e81c461..17b7874d41 100644 --- a/libraries/chain/include/graphene/chain/protocol/transaction.hpp +++ b/libraries/protocol/include/graphene/protocol/transaction.hpp @@ -22,12 +22,9 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include -#include - -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @defgroup transactions Transactions @@ -65,6 +62,7 @@ namespace graphene { namespace chain { class transaction { public: + virtual ~transaction() = default; /** * Least significant 16 bits from the reference block number. If @ref relative_expiration is zero, this field * must be zero as well. @@ -131,6 +129,7 @@ namespace graphene { namespace chain { public: signed_transaction( const transaction& trx = transaction() ) : transaction(trx){} + virtual ~signed_transaction() = default; /** signs and appends to signatures */ const signature_type& sign( const private_key_type& key, const chain_id_type& chain_id ); @@ -223,6 +222,7 @@ namespace graphene { namespace chain { precomputable_transaction() {} precomputable_transaction( const signed_transaction& tx ) : signed_transaction(tx) {}; precomputable_transaction( signed_transaction&& tx ) : signed_transaction( std::move(tx) ) {}; + virtual ~precomputable_transaction() = default; virtual const transaction_id_type& id()const override; virtual void validate()const override; @@ -275,6 +275,7 @@ namespace graphene { namespace chain { { processed_transaction( const signed_transaction& trx = signed_transaction() ) : precomputable_transaction(trx){} + virtual ~processed_transaction() = default; vector operation_results; @@ -283,10 +284,15 @@ namespace graphene { namespace chain { /// @} transactions group -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::transaction, (ref_block_num)(ref_block_prefix)(expiration)(operations)(extensions) ) +FC_REFLECT( graphene::protocol::transaction, (ref_block_num)(ref_block_prefix)(expiration)(operations)(extensions) ) // Note: not reflecting signees field for backward compatibility; in addition, it should not be in p2p messages -FC_REFLECT_DERIVED( graphene::chain::signed_transaction, (graphene::chain::transaction), (signatures) ) -FC_REFLECT_DERIVED( graphene::chain::precomputable_transaction, (graphene::chain::signed_transaction), ) -FC_REFLECT_DERIVED( graphene::chain::processed_transaction, (graphene::chain::precomputable_transaction), (operation_results) ) +FC_REFLECT_DERIVED( graphene::protocol::signed_transaction, (graphene::protocol::transaction), (signatures) ) +FC_REFLECT_DERIVED( graphene::protocol::precomputable_transaction, (graphene::protocol::signed_transaction), ) +FC_REFLECT_DERIVED( graphene::protocol::processed_transaction, (graphene::protocol::precomputable_transaction), (operation_results) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transaction) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::signed_transaction) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::precomputable_transaction) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::processed_transaction) diff --git a/libraries/chain/include/graphene/chain/protocol/transfer.hpp b/libraries/protocol/include/graphene/protocol/transfer.hpp similarity index 78% rename from libraries/chain/include/graphene/chain/protocol/transfer.hpp rename to libraries/protocol/include/graphene/protocol/transfer.hpp index f4417bb747..2125ed4eb6 100644 --- a/libraries/chain/include/graphene/chain/protocol/transfer.hpp +++ b/libraries/protocol/include/graphene/protocol/transfer.hpp @@ -22,10 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @ingroup operations @@ -98,10 +99,15 @@ namespace graphene { namespace chain { share_type calculate_fee(const fee_parameters_type& k)const; }; -}} // graphene::chain +}} // graphene::protocol -FC_REFLECT( graphene::chain::transfer_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::override_transfer_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::transfer_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::override_transfer_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::override_transfer_operation, (fee)(issuer)(from)(to)(amount)(memo)(extensions) ) -FC_REFLECT( graphene::chain::transfer_operation, (fee)(from)(to)(amount)(memo)(extensions) ) +FC_REFLECT( graphene::protocol::override_transfer_operation, (fee)(issuer)(from)(to)(amount)(memo)(extensions) ) +FC_REFLECT( graphene::protocol::transfer_operation, (fee)(from)(to)(amount)(memo)(extensions) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::override_transfer_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::override_transfer_operation ) diff --git a/libraries/protocol/include/graphene/protocol/types.hpp b/libraries/protocol/include/graphene/protocol/types.hpp new file mode 100644 index 0000000000..16c589133f --- /dev/null +++ b/libraries/protocol/include/graphene/protocol/types.hpp @@ -0,0 +1,283 @@ +/* + * 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. + */ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define GRAPHENE_EXTERNAL_SERIALIZATION(ext, type) \ +namespace fc { \ + ext template void from_variant( const variant& v, type& vo, uint32_t max_depth ); \ + ext template void to_variant( const type& v, variant& vo, uint32_t max_depth ); \ +namespace raw { \ + ext template void pack< datastream, type >( datastream& s, const type& tx, uint32_t _max_depth ); \ + ext template void pack< sha256::encoder, type >( sha256::encoder& s, const type& tx, uint32_t _max_depth ); \ + ext template void pack< datastream, type >( datastream& s, const type& tx, uint32_t _max_depth ); \ + ext template void unpack< datastream, type >( datastream& s, type& tx, uint32_t _max_depth ); \ +} } // fc::raw +#define GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION(type) GRAPHENE_EXTERNAL_SERIALIZATION(extern, type) +#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type) GRAPHENE_EXTERNAL_SERIALIZATION(/*not extern*/, type) + +#define FC_REFLECT_DERIVED_NO_TYPENAME( TYPE, INHERITS, MEMBERS ) \ +namespace fc { \ +template<> struct reflector {\ + typedef TYPE type; \ + typedef fc::true_type is_defined; \ + typedef fc::false_type is_enum; \ + enum member_count_enum { \ + local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\ + total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\ + }; \ + FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \ +}; \ +} // fc + +#define GRAPHENE_NAME_TO_OBJECT_TYPE(x, prefix, name) BOOST_PP_CAT(prefix, BOOST_PP_CAT(name, _object_type)) +#define GRAPHENE_NAME_TO_ID_TYPE(x, y, name) BOOST_PP_CAT(name, _id_type) +#define GRAPHENE_DECLARE_ID(x, space_prefix_seq, name) \ + using BOOST_PP_CAT(name, _id_type) = object_id; +#define GRAPHENE_REFLECT_ID(x, id_namespace, name) FC_REFLECT_TYPENAME(graphene::id_namespace::name) + +#define GRAPHENE_DEFINE_IDS(id_namespace, object_space, object_type_prefix, names_seq) \ + namespace graphene { namespace id_namespace { \ + \ + enum BOOST_PP_CAT(object_type_prefix, object_type) { \ + BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(GRAPHENE_NAME_TO_OBJECT_TYPE, object_type_prefix, names_seq)) \ + }; \ + \ + BOOST_PP_SEQ_FOR_EACH(GRAPHENE_DECLARE_ID, (object_space, object_type_prefix), names_seq) \ + \ + } } \ + \ + FC_REFLECT_ENUM(graphene::id_namespace::BOOST_PP_CAT(object_type_prefix, object_type), \ + BOOST_PP_SEQ_TRANSFORM(GRAPHENE_NAME_TO_OBJECT_TYPE, object_type_prefix, names_seq)) \ + BOOST_PP_SEQ_FOR_EACH(GRAPHENE_REFLECT_ID, id_namespace, BOOST_PP_SEQ_TRANSFORM(GRAPHENE_NAME_TO_ID_TYPE, , names_seq)) + +namespace graphene { namespace protocol { +using namespace graphene::db; + +using std::map; +using std::vector; +using std::unordered_map; +using std::string; +using std::deque; +using std::shared_ptr; +using std::weak_ptr; +using std::unique_ptr; +using std::set; +using std::pair; +using std::enable_shared_from_this; +using std::tie; +using std::make_pair; + +using fc::variant_object; +using fc::variant; +using fc::enum_type; +using fc::optional; +using fc::unsigned_int; +using fc::time_point_sec; +using fc::time_point; +using fc::safe; +using fc::flat_map; +using fc::flat_set; +using fc::static_variant; +using fc::ecc::range_proof_type; +using fc::ecc::range_proof_info; +using fc::ecc::commitment_type; +struct void_t{}; + +using private_key_type = fc::ecc::private_key; +using chain_id_type = fc::sha256; +using ratio_type = boost::rational; + +enum asset_issuer_permission_flags { + charge_market_fee = 0x01, /**< an issuer-specified percentage of all market trades in this asset is paid to the issuer */ + white_list = 0x02, /**< accounts must be whitelisted in order to hold this asset */ + override_authority = 0x04, /**< issuer may transfer asset back to himself */ + transfer_restricted = 0x08, /**< require the issuer to be one party to every transfer */ + disable_force_settle = 0x10, /**< disable force settling */ + global_settle = 0x20, /**< allow the bitasset issuer to force a global settling -- this may be set in permissions, but not flags */ + disable_confidential = 0x40, /**< allow the asset to be used with confidential transactions */ + witness_fed_asset = 0x80, /**< allow the asset to be fed by witnesses */ + committee_fed_asset = 0x100 /**< allow the asset to be fed by the committee */ +}; +const static uint32_t ASSET_ISSUER_PERMISSION_MASK = + charge_market_fee + | white_list + | override_authority + | transfer_restricted + | disable_force_settle + | global_settle + | disable_confidential + | witness_fed_asset + | committee_fed_asset; +const static uint32_t UIA_ASSET_ISSUER_PERMISSION_MASK = + charge_market_fee + | white_list + | override_authority + | transfer_restricted + | disable_confidential; + +enum reserved_spaces { + relative_protocol_ids = 0, + protocol_ids = 1, + implementation_ids = 2 +}; + +inline bool is_relative(object_id_type o) { return o.space() == 0; } + +using block_id_type = fc::ripemd160; +using checksum_type = fc::ripemd160; +using transaction_id_type = fc::ripemd160; +using digest_type = fc::sha256; +using signature_type = fc::ecc::compact_signature; +using share_type = safe; +using weight_type = uint16_t; + +struct public_key_type { + struct binary_key { + binary_key() = default; + uint32_t check = 0; + fc::ecc::public_key_data data; + }; + fc::ecc::public_key_data key_data; + public_key_type(); + public_key_type(const fc::ecc::public_key_data& data); + public_key_type(const fc::ecc::public_key& pubkey); + explicit public_key_type(const std::string& base58str); + operator fc::ecc::public_key_data() const; + operator fc::ecc::public_key() const; + explicit operator std::string() const; + friend bool operator == (const public_key_type& p1, const fc::ecc::public_key& p2); + friend bool operator == (const public_key_type& p1, const public_key_type& p2); + friend bool operator != (const public_key_type& p1, const public_key_type& p2); +}; + +class pubkey_comparator { +public: + inline bool operator()(const public_key_type& a, const public_key_type& b) const { + return a.key_data < b.key_data; + } +}; + +struct fee_schedule; +} } // graphene::protocol + +namespace fc { +void to_variant(const graphene::protocol::public_key_type& var, fc::variant& vo, uint32_t max_depth = 2); +void from_variant(const fc::variant& var, graphene::protocol::public_key_type& vo, uint32_t max_depth = 2); + + +template<> +struct get_typename> { static const char* name() { + return "shared_ptr"; +} }; +template<> +struct get_typename> { static const char* name() { + return "shared_ptr"; +} }; +void from_variant( const fc::variant& var, std::shared_ptr& vo, + uint32_t max_depth = 2 ); + +} // fc::raw + +GRAPHENE_DEFINE_IDS(protocol, protocol_ids, /*protocol objects are not prefixed*/, + (null) + (base) + (account) + (asset) + (force_settlement) + (committee_member) + (witness) + (limit_order) + (call_order) + (custom) + (proposal) + (operation_history) + (withdraw_permission) + (vesting_balance) + (worker) + (balance) + (htlc)) + +FC_REFLECT(graphene::protocol::public_key_type, (key_data)) +FC_REFLECT(graphene::protocol::public_key_type::binary_key, (data)(check)) + +FC_REFLECT_TYPENAME(graphene::protocol::share_type) +FC_REFLECT(graphene::protocol::void_t,) + +FC_REFLECT_ENUM(graphene::protocol::asset_issuer_permission_flags, + (charge_market_fee) + (white_list) + (transfer_restricted) + (override_authority) + (disable_force_settle) + (global_settle) + (disable_confidential) + (witness_fed_asset) + (committee_fed_asset)) + +namespace fc { namespace raw { + extern template void pack( datastream& s, const graphene::protocol::public_key_type& tx, + uint32_t _max_depth ); + extern template void pack( datastream& s, const graphene::protocol::public_key_type& tx, + uint32_t _max_depth ); + extern template void unpack( datastream& s, graphene::protocol::public_key_type& tx, + uint32_t _max_depth ); +} } // fc::raw diff --git a/libraries/chain/include/graphene/chain/protocol/vesting.hpp b/libraries/protocol/include/graphene/protocol/vesting.hpp similarity index 75% rename from libraries/chain/include/graphene/chain/protocol/vesting.hpp rename to libraries/protocol/include/graphene/protocol/vesting.hpp index b5d03585de..a733506d1d 100644 --- a/libraries/chain/include/graphene/chain/protocol/vesting.hpp +++ b/libraries/protocol/include/graphene/protocol/vesting.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { struct linear_vesting_policy_initializer { @@ -111,18 +112,24 @@ namespace graphene { namespace chain { { FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( amount.amount > 0 ); + FC_ASSERT( owner != GRAPHENE_TEMP_ACCOUNT ); } }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::vesting_balance_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::vesting_balance_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::vesting_balance_withdraw_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::vesting_balance_create_operation, (fee)(creator)(owner)(amount)(policy) ) -FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation, (fee)(vesting_balance)(owner)(amount) ) +FC_REFLECT( graphene::protocol::vesting_balance_create_operation, (fee)(creator)(owner)(amount)(policy) ) +FC_REFLECT( graphene::protocol::vesting_balance_withdraw_operation, (fee)(vesting_balance)(owner)(amount) ) -FC_REFLECT(graphene::chain::linear_vesting_policy_initializer, (begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds) ) -FC_REFLECT(graphene::chain::cdd_vesting_policy_initializer, (start_claim)(vesting_seconds) ) -FC_REFLECT_EMPTY( graphene::chain::instant_vesting_policy_initializer ) -FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer ) +FC_REFLECT(graphene::protocol::linear_vesting_policy_initializer, (begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds) ) +FC_REFLECT(graphene::protocol::cdd_vesting_policy_initializer, (start_claim)(vesting_seconds) ) +FC_REFLECT_EMPTY( graphene::protocol::instant_vesting_policy_initializer ) +FC_REFLECT_TYPENAME( graphene::protocol::vesting_policy_initializer ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_withdraw_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_withdraw_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/vote.hpp b/libraries/protocol/include/graphene/protocol/vote.hpp similarity index 85% rename from libraries/chain/include/graphene/chain/protocol/vote.hpp rename to libraries/protocol/include/graphene/protocol/vote.hpp index ec2ebd1640..b9f5c1be44 100644 --- a/libraries/chain/include/graphene/chain/protocol/vote.hpp +++ b/libraries/protocol/include/graphene/protocol/vote.hpp @@ -24,14 +24,9 @@ #pragma once -#include -#include -#include +#include -#include -#include - -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief An ID for some votable object @@ -130,23 +125,21 @@ struct vote_id_type } }; -class global_property_object; - -vote_id_type get_next_vote_id( global_property_object& gpo, vote_id_type::vote_type type ); - -} } // graphene::chain +} } // graphene::protocol namespace fc { class variant; -void to_variant( const graphene::chain::vote_id_type& var, fc::variant& vo, uint32_t max_depth = 1 ); -void from_variant( const fc::variant& var, graphene::chain::vote_id_type& vo, uint32_t max_depth = 1 ); +void to_variant( const graphene::protocol::vote_id_type& var, fc::variant& vo, uint32_t max_depth = 1 ); +void from_variant( const fc::variant& var, graphene::protocol::vote_id_type& vo, uint32_t max_depth = 1 ); } // fc -FC_REFLECT_TYPENAME( fc::flat_set ) +FC_REFLECT_TYPENAME( fc::flat_set ) + +FC_REFLECT_ENUM( graphene::protocol::vote_id_type::vote_type, (witness)(committee)(worker)(VOTE_TYPE_COUNT) ) +FC_REFLECT( graphene::protocol::vote_id_type, (content) ) -FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(VOTE_TYPE_COUNT) ) -FC_REFLECT( graphene::chain::vote_id_type, (content) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::vote_id_type ) diff --git a/libraries/chain/include/graphene/chain/protocol/withdraw_permission.hpp b/libraries/protocol/include/graphene/protocol/withdraw_permission.hpp similarity index 80% rename from libraries/chain/include/graphene/chain/protocol/withdraw_permission.hpp rename to libraries/protocol/include/graphene/protocol/withdraw_permission.hpp index 7bc905acc7..1712490844 100644 --- a/libraries/chain/include/graphene/chain/protocol/withdraw_permission.hpp +++ b/libraries/protocol/include/graphene/protocol/withdraw_permission.hpp @@ -22,10 +22,11 @@ * THE SOFTWARE. */ #pragma once -#include -#include +#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief Create a new withdrawal permission @@ -165,17 +166,26 @@ namespace graphene { namespace chain { void validate()const; }; -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::withdraw_permission_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::withdraw_permission_update_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::withdraw_permission_claim_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::withdraw_permission_delete_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::withdraw_permission_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::withdraw_permission_update_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::withdraw_permission_claim_operation::fee_parameters_type, (fee)(price_per_kbyte) ) +FC_REFLECT( graphene::protocol::withdraw_permission_delete_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::withdraw_permission_create_operation, (fee)(withdraw_from_account)(authorized_account) +FC_REFLECT( graphene::protocol::withdraw_permission_create_operation, (fee)(withdraw_from_account)(authorized_account) (withdrawal_limit)(withdrawal_period_sec)(periods_until_expiration)(period_start_time) ) -FC_REFLECT( graphene::chain::withdraw_permission_update_operation, (fee)(withdraw_from_account)(authorized_account) +FC_REFLECT( graphene::protocol::withdraw_permission_update_operation, (fee)(withdraw_from_account)(authorized_account) (permission_to_update)(withdrawal_limit)(withdrawal_period_sec)(period_start_time)(periods_until_expiration) ) -FC_REFLECT( graphene::chain::withdraw_permission_claim_operation, (fee)(withdraw_permission)(withdraw_from_account)(withdraw_to_account)(amount_to_withdraw)(memo) ); -FC_REFLECT( graphene::chain::withdraw_permission_delete_operation, (fee)(withdraw_from_account)(authorized_account) +FC_REFLECT( graphene::protocol::withdraw_permission_claim_operation, (fee)(withdraw_permission)(withdraw_from_account)(withdraw_to_account)(amount_to_withdraw)(memo) ); +FC_REFLECT( graphene::protocol::withdraw_permission_delete_operation, (fee)(withdraw_from_account)(authorized_account) (withdrawal_permission) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_claim_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_delete_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_update_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_claim_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_delete_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/witness.hpp b/libraries/protocol/include/graphene/protocol/witness.hpp similarity index 75% rename from libraries/chain/include/graphene/chain/protocol/witness.hpp rename to libraries/protocol/include/graphene/protocol/witness.hpp index 5eb75f9be3..89efe54f70 100644 --- a/libraries/chain/include/graphene/chain/protocol/witness.hpp +++ b/libraries/protocol/include/graphene/protocol/witness.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @brief Create a witness object, as a bid to hold a witness position on the network. @@ -74,10 +75,15 @@ namespace graphene { namespace chain { /// TODO: witness_resign_operation : public base_operation -} } // graphene::chain +} } // graphene::protocol -FC_REFLECT( graphene::chain::witness_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::witness_create_operation, (fee)(witness_account)(url)(block_signing_key) ) +FC_REFLECT( graphene::protocol::witness_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::witness_create_operation, (fee)(witness_account)(url)(block_signing_key) ) -FC_REFLECT( graphene::chain::witness_update_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::witness_update_operation, (fee)(witness)(witness_account)(new_url)(new_signing_key) ) +FC_REFLECT( graphene::protocol::witness_update_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::witness_update_operation, (fee)(witness)(witness_account)(new_url)(new_signing_key) ) + +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::witness_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::witness_update_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::witness_create_operation ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::witness_update_operation ) diff --git a/libraries/chain/include/graphene/chain/protocol/worker.hpp b/libraries/protocol/include/graphene/protocol/worker.hpp similarity index 84% rename from libraries/chain/include/graphene/chain/protocol/worker.hpp rename to libraries/protocol/include/graphene/protocol/worker.hpp index 9e6eef3592..6eabf9258b 100644 --- a/libraries/chain/include/graphene/chain/protocol/worker.hpp +++ b/libraries/protocol/include/graphene/protocol/worker.hpp @@ -22,9 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include +#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { /** * @defgroup workers The Blockchain Worker System @@ -95,12 +96,14 @@ namespace graphene { namespace chain { } } -FC_REFLECT( graphene::chain::vesting_balance_worker_initializer, (pay_vesting_period_days) ) -FC_REFLECT( graphene::chain::burn_worker_initializer, ) -FC_REFLECT( graphene::chain::refund_worker_initializer, ) -FC_REFLECT_TYPENAME( graphene::chain::worker_initializer ) +FC_REFLECT( graphene::protocol::vesting_balance_worker_initializer, (pay_vesting_period_days) ) +FC_REFLECT( graphene::protocol::burn_worker_initializer, ) +FC_REFLECT( graphene::protocol::refund_worker_initializer, ) +FC_REFLECT_TYPENAME( graphene::protocol::worker_initializer ) -FC_REFLECT( graphene::chain::worker_create_operation::fee_parameters_type, (fee) ) -FC_REFLECT( graphene::chain::worker_create_operation, +FC_REFLECT( graphene::protocol::worker_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::protocol::worker_create_operation, (fee)(owner)(work_begin_date)(work_end_date)(daily_pay)(name)(url)(initializer) ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::worker_create_operation::fee_parameters_type ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::protocol::worker_create_operation ) diff --git a/libraries/chain/protocol/market.cpp b/libraries/protocol/market.cpp similarity index 62% rename from libraries/chain/protocol/market.cpp rename to libraries/protocol/market.cpp index fd12fa4e7d..8e8fc721e2 100644 --- a/libraries/chain/protocol/market.cpp +++ b/libraries/protocol/market.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { void limit_order_create_operation::validate()const { @@ -54,4 +56,16 @@ void bid_collateral_operation::validate()const FC_ASSERT( debt_covered.amount == 0 || (debt_covered.amount > 0 && additional_collateral.amount > 0) ); } FC_CAPTURE_AND_RETHROW((*this)) } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation::options_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_cancel_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::bid_collateral_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::limit_order_cancel_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::call_order_update_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::bid_collateral_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::fill_order_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::execute_bid_operation ) diff --git a/libraries/chain/protocol/memo.cpp b/libraries/protocol/memo.cpp similarity index 83% rename from libraries/chain/protocol/memo.cpp rename to libraries/protocol/memo.cpp index e04b5e4302..f68585c548 100644 --- a/libraries/chain/protocol/memo.cpp +++ b/libraries/protocol/memo.cpp @@ -21,10 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include +#include #include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::public_key& pub, const string& msg, uint64_t custom_nonce) @@ -35,7 +37,7 @@ void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::pub to = pub; if( custom_nonce == 0 ) { - uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0]; + uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0].value(); entropy <<= 32; entropy &= 0xff00000000000000; nonce = (fc::time_point::now().time_since_epoch().count() & 0x00ffffffffffffff) | entropy; @@ -43,7 +45,7 @@ void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::pub nonce = custom_nonce; auto secret = priv.get_shared_secret(pub); auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str()); - string text = memo_message(digest_type::hash(msg)._hash[0], msg).serialize(); + string text = memo_message(digest_type::hash(msg)._hash[0].value(), msg).serialize(); message = fc::aes_encrypt( nonce_plus_secret, vector(text.begin(), text.end()) ); } else @@ -62,7 +64,7 @@ string memo_data::get_message(const fc::ecc::private_key& priv, auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str()); auto plain_text = fc::aes_decrypt( nonce_plus_secret, message ); auto result = memo_message::deserialize(string(plain_text.begin(), plain_text.end())); - FC_ASSERT( result.checksum == uint32_t(digest_type::hash(result.text)._hash[0]) ); + FC_ASSERT( result.checksum == (uint32_t)digest_type::hash(result.text)._hash[0].value() ); return result.text; } else @@ -74,7 +76,7 @@ string memo_data::get_message(const fc::ecc::private_key& priv, string memo_message::serialize() const { auto serial_checksum = string(sizeof(checksum), ' '); - (uint32_t&)(*serial_checksum.data()) = checksum; + (uint32_t&)(*serial_checksum.data()) = boost::endian::native_to_little(checksum); return serial_checksum + text; } @@ -82,9 +84,12 @@ memo_message memo_message::deserialize(const string& serial) { memo_message result; FC_ASSERT( serial.size() >= sizeof(result.checksum) ); - result.checksum = ((uint32_t&)(*serial.data())); + result.checksum = boost::endian::little_to_native((uint32_t&)(*serial.data())); result.text = serial.substr(sizeof(result.checksum)); return result; } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::memo_message ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::memo_data ) diff --git a/libraries/chain/protocol/operations.cpp b/libraries/protocol/operations.cpp similarity index 91% rename from libraries/chain/protocol/operations.cpp rename to libraries/protocol/operations.cpp index 48a65f6fed..8045ed3261 100644 --- a/libraries/chain/protocol/operations.cpp +++ b/libraries/protocol/operations.cpp @@ -21,9 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { uint64_t base_operation::calculate_data_fee( uint64_t bytes, uint64_t price_per_kbyte ) { @@ -90,4 +93,6 @@ void operation_get_required_authorities( const operation& op, op.visit( operation_get_required_auth( active, owner, other ) ); } -} } // namespace graphene::chain +} } // namespace graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::op_wrapper ) diff --git a/libraries/chain/protocol/proposal.cpp b/libraries/protocol/proposal.cpp similarity index 83% rename from libraries/chain/protocol/proposal.cpp rename to libraries/protocol/proposal.cpp index 7d072e4a90..22d66d44f1 100644 --- a/libraries/chain/protocol/proposal.cpp +++ b/libraries/protocol/proposal.cpp @@ -21,10 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include +#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { proposal_create_operation proposal_create_operation::committee_proposal(const chain_parameters& global_params, fc::time_point_sec head_block_time ) { @@ -104,4 +106,11 @@ void proposal_update_operation::get_required_owner_authorities( flat_set -#include +#include #include #include #include +#include #include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { pts_address::pts_address() { @@ -42,10 +42,7 @@ namespace graphene { namespace chain { if( v.size() ) memcpy( addr.data, v.data(), std::min( v.size(), sizeof(addr) ) ); - if( !is_valid() ) - { - FC_THROW_EXCEPTION( invalid_pts_address, "invalid pts_address ${a}", ("a", base58str) ); - } + FC_ASSERT(is_valid(), "invalid pts_address ${a}", ("a", base58str)); } pts_address::pts_address( const fc::ecc::public_key& pub, bool compressed, uint8_t version ) @@ -89,12 +86,20 @@ namespace graphene { namespace chain { namespace fc { - void to_variant( const graphene::chain::pts_address& var, variant& vo, uint32_t max_depth ) + void to_variant( const graphene::protocol::pts_address& var, variant& vo, uint32_t max_depth ) { vo = std::string(var); } - void from_variant( const variant& var, graphene::chain::pts_address& vo, uint32_t max_depth ) + void from_variant( const variant& var, graphene::protocol::pts_address& vo, uint32_t max_depth ) { - vo = graphene::chain::pts_address( var.as_string() ); + vo = graphene::protocol::pts_address( var.as_string() ); } -} + +namespace raw { + template void pack( datastream& s, const graphene::protocol::pts_address& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template void pack( datastream& s, const graphene::protocol::pts_address& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template void unpack( datastream& s, graphene::protocol::pts_address& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); +} } // fc::raw diff --git a/libraries/protocol/small_ops.cpp b/libraries/protocol/small_ops.cpp new file mode 100644 index 0000000000..f8bcf06338 --- /dev/null +++ b/libraries/protocol/small_ops.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019 BitShares Blockchain Foundation, 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 +#include + +#include + +namespace graphene { namespace protocol { + +FC_IMPLEMENT_EXCEPTION( protocol_exception, 4000000, "protocol exception" ) + +FC_IMPLEMENT_DERIVED_EXCEPTION( transaction_exception, protocol_exception, 4010000, + "transaction validation exception" ) + +FC_IMPLEMENT_DERIVED_EXCEPTION( tx_missing_active_auth, transaction_exception, 4010001, + "missing required active authority" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( tx_missing_owner_auth, transaction_exception, 4010002, + "missing required owner authority" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( tx_missing_other_auth, transaction_exception, 4010003, + "missing required other authority" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( tx_irrelevant_sig, transaction_exception, 4010004, + "irrelevant signature included" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( tx_duplicate_sig, transaction_exception, 4010005, + "duplicate signature included" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( invalid_committee_approval, transaction_exception, 4010006, + "committee account cannot directly approve transaction" ) +FC_IMPLEMENT_DERIVED_EXCEPTION( insufficient_fee, transaction_exception, 4010007, "insufficient fee" ) + +} } // graphene::protocol + + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::balance_claim_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::buyback_account_options ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::fba_distribute_operation ) + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_withdraw_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::vesting_balance_withdraw_operation ) diff --git a/libraries/chain/protocol/committee_member.cpp b/libraries/protocol/special_authority.cpp similarity index 65% rename from libraries/chain/protocol/committee_member.cpp rename to libraries/protocol/special_authority.cpp index 4c8c5d2591..fee2546b59 100644 --- a/libraries/chain/protocol/committee_member.cpp +++ b/libraries/protocol/special_authority.cpp @@ -21,27 +21,31 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -namespace graphene { namespace chain { +#include -void committee_member_create_operation::validate()const -{ - FC_ASSERT( fee.amount >= 0 ); - FC_ASSERT(url.size() < GRAPHENE_MAX_URL_LENGTH ); -} +#include -void committee_member_update_operation::validate()const +namespace graphene { namespace protocol { + +struct special_authority_validate_visitor { - FC_ASSERT( fee.amount >= 0 ); - if( new_url.valid() ) - FC_ASSERT(new_url->size() < GRAPHENE_MAX_URL_LENGTH ); -} + typedef void result_type; -void committee_member_update_global_parameters_operation::validate() const + void operator()( const no_special_authority& a ) {} + + void operator()( const top_holders_special_authority& a ) + { + FC_ASSERT( a.num_top_holders > 0 ); + } +}; + +void validate_special_authority( const special_authority& a ) { - FC_ASSERT( fee.amount >= 0 ); - new_parameters.validate(); + special_authority_validate_visitor vtor; + a.visit( vtor ); } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::top_holders_special_authority ) diff --git a/libraries/chain/protocol/transaction.cpp b/libraries/protocol/transaction.cpp similarity index 91% rename from libraries/chain/protocol/transaction.cpp rename to libraries/protocol/transaction.cpp index 6b4d7f3235..42b1d8ee0f 100644 --- a/libraries/chain/protocol/transaction.cpp +++ b/libraries/protocol/transaction.cpp @@ -21,14 +21,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include -#include + +#include +#include +#include +#include +#include + #include -#include -#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { digest_type processed_transaction::merkle_digest()const { @@ -71,14 +73,14 @@ const transaction_id_type& transaction::id() const return _tx_id_buffer; } -const signature_type& graphene::chain::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id) +const signature_type& graphene::protocol::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id) { digest_type h = sig_digest( chain_id ); signatures.push_back(key.sign_compact(h)); return signatures.back(); } -signature_type graphene::chain::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id)const +signature_type graphene::protocol::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id)const { digest_type::encoder enc; fc::raw::pack( enc, chain_id ); @@ -93,8 +95,8 @@ void transaction::set_expiration( fc::time_point_sec expiration_time ) void transaction::set_reference_block( const block_id_type& reference_block ) { - ref_block_num = fc::endian_reverse_u32(reference_block._hash[0]); - ref_block_prefix = reference_block._hash[1]; + ref_block_num = boost::endian::endian_reverse(reference_block._hash[0].value()); + ref_block_prefix = reference_block._hash[1].value(); } void transaction::get_required_authorities( flat_set& active, @@ -385,7 +387,8 @@ set signed_transaction::minimize_required_signatures( result.erase( k ); try { - graphene::chain::verify_authority( operations, result, get_active, get_owner, allow_non_immediate_owner, max_recursion ); + graphene::protocol::verify_authority( operations, result, get_active, get_owner, + allow_non_immediate_owner, max_recursion ); continue; // element stays erased if verify_authority is ok } catch( const tx_missing_owner_auth& e ) {} @@ -398,7 +401,7 @@ set signed_transaction::minimize_required_signatures( const transaction_id_type& precomputable_transaction::id()const { - if( !_tx_id_buffer._hash[0] ) + if( !_tx_id_buffer._hash[0].value() ) transaction::id(); return _tx_id_buffer; } @@ -433,12 +436,13 @@ void signed_transaction::verify_authority( bool allow_non_immediate_owner, uint32_t max_recursion )const { try { - graphene::chain::verify_authority( operations, - get_signature_keys( chain_id ), - get_active, - get_owner, - allow_non_immediate_owner, - max_recursion ); + graphene::protocol::verify_authority( operations, get_signature_keys( chain_id ), get_active, get_owner, + allow_non_immediate_owner, max_recursion ); } FC_CAPTURE_AND_RETHROW( (*this) ) } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transaction) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::signed_transaction) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::precomputable_transaction) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::processed_transaction) diff --git a/libraries/chain/protocol/transfer.cpp b/libraries/protocol/transfer.cpp similarity index 79% rename from libraries/chain/protocol/transfer.cpp rename to libraries/protocol/transfer.cpp index 3dfe4eb727..bc244d317f 100644 --- a/libraries/chain/protocol/transfer.cpp +++ b/libraries/protocol/transfer.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { share_type transfer_operation::calculate_fee( const fee_parameters_type& schedule )const { @@ -60,4 +62,9 @@ void override_transfer_operation::validate()const FC_ASSERT( issuer != from ); } -} } // graphene::chain +} } // graphene::protocol + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::override_transfer_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::transfer_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::override_transfer_operation ) diff --git a/libraries/protocol/types.cpp b/libraries/protocol/types.cpp new file mode 100644 index 0000000000..641e4fe328 --- /dev/null +++ b/libraries/protocol/types.cpp @@ -0,0 +1,122 @@ +/* + * 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 +#include +#include + +namespace graphene { namespace protocol { + + public_key_type::public_key_type():key_data(){}; + + public_key_type::public_key_type( const fc::ecc::public_key_data& data ) + :key_data( data ) {}; + + public_key_type::public_key_type( const fc::ecc::public_key& pubkey ) + :key_data( pubkey ) {}; + + public_key_type::public_key_type( const std::string& base58str ) + { + // TODO: Refactor syntactic checks into static is_valid() + // to make public_key_type API more similar to address API + std::string prefix( GRAPHENE_ADDRESS_PREFIX ); + const size_t prefix_len = prefix.size(); + FC_ASSERT( base58str.size() > prefix_len ); + FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); + auto bin = fc::from_base58( base58str.substr( prefix_len ) ); + auto bin_key = fc::raw::unpack(bin); + key_data = bin_key.data; + FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0].value() == bin_key.check ); + }; + + public_key_type::operator fc::ecc::public_key_data() const + { + return key_data; + }; + + public_key_type::operator fc::ecc::public_key() const + { + return fc::ecc::public_key( key_data ); + }; + + public_key_type::operator std::string() const + { + binary_key k; + k.data = key_data; + k.check = fc::ripemd160::hash( k.data.data, k.data.size() )._hash[0].value(); + auto data = fc::raw::pack( k ); + return GRAPHENE_ADDRESS_PREFIX + fc::to_base58( data.data(), data.size() ); + } + + bool operator == ( const public_key_type& p1, const fc::ecc::public_key& p2) + { + return p1.key_data == p2.serialize(); + } + + bool operator == ( const public_key_type& p1, const public_key_type& p2) + { + return p1.key_data == p2.key_data; + } + + bool operator != ( const public_key_type& p1, const public_key_type& p2) + { + return p1.key_data != p2.key_data; + } + +} } // graphene::protocol + +namespace fc +{ + using namespace std; + void to_variant( const graphene::protocol::public_key_type& var, fc::variant& vo, uint32_t max_depth ) + { + vo = std::string( var ); + } + + void from_variant( const fc::variant& var, graphene::protocol::public_key_type& vo, uint32_t max_depth ) + { + vo = graphene::protocol::public_key_type( var.as_string() ); + } + + void from_variant( const fc::variant& var, std::shared_ptr& vo, + uint32_t max_depth ) { + // If it's null, just make a new one + if (!vo) vo = std::make_shared(); + // Convert the non-const shared_ptr to a non-const fee_schedule& so we can write it + // Don't decrement max_depth since we're not actually deserializing at this step + from_variant(var, const_cast(*vo), max_depth); + } + +namespace raw { + template void pack( datastream& s, const graphene::protocol::public_key_type& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template void pack( datastream& s, const graphene::protocol::public_key_type& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); + template void unpack( datastream& s, graphene::protocol::public_key_type& tx, + uint32_t _max_depth=FC_PACK_MAX_DEPTH ); +} } // fc::raw diff --git a/libraries/chain/protocol/witness.cpp b/libraries/protocol/vote.cpp similarity index 73% rename from libraries/chain/protocol/witness.cpp rename to libraries/protocol/vote.cpp index 82fa462af1..16bd163337 100644 --- a/libraries/chain/protocol/witness.cpp +++ b/libraries/protocol/vote.cpp @@ -21,21 +21,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -namespace graphene { namespace chain { +#include -void witness_create_operation::validate() const +namespace fc { - FC_ASSERT(fee.amount >= 0); - FC_ASSERT(url.size() < GRAPHENE_MAX_URL_LENGTH ); + +void to_variant( const graphene::protocol::vote_id_type& var, variant& vo, uint32_t max_depth ) +{ + vo = string(var); } -void witness_update_operation::validate() const +void from_variant( const variant& var, graphene::protocol::vote_id_type& vo, uint32_t max_depth ) { - FC_ASSERT(fee.amount >= 0); - if( new_url.valid() ) - FC_ASSERT(new_url->size() < GRAPHENE_MAX_URL_LENGTH ); + vo = graphene::protocol::vote_id_type(var.as_string()); } -} } // graphene::chain +} // fc + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::vote_id_type ) diff --git a/libraries/chain/protocol/withdraw_permission.cpp b/libraries/protocol/withdraw_permission.cpp similarity index 70% rename from libraries/chain/protocol/withdraw_permission.cpp rename to libraries/protocol/withdraw_permission.cpp index 33b40c8561..d715eece4d 100644 --- a/libraries/chain/protocol/withdraw_permission.cpp +++ b/libraries/protocol/withdraw_permission.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { void withdraw_permission_update_operation::validate()const { @@ -65,6 +67,13 @@ void withdraw_permission_delete_operation::validate() const FC_ASSERT( withdraw_from_account != authorized_account ); } +} } // graphene::protocol -} } // graphene::chain - +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_claim_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_delete_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_update_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_claim_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::withdraw_permission_delete_operation ) diff --git a/libraries/chain/protocol/vote.cpp b/libraries/protocol/witness.cpp similarity index 58% rename from libraries/chain/protocol/vote.cpp rename to libraries/protocol/witness.cpp index f78f2b4f11..5085156fe7 100644 --- a/libraries/chain/protocol/vote.cpp +++ b/libraries/protocol/witness.cpp @@ -21,31 +21,28 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include -#include -#include -#include +#include -namespace graphene { namespace chain { +namespace graphene { namespace protocol { -vote_id_type get_next_vote_id( global_property_object& gpo, vote_id_type::vote_type type ) +void witness_create_operation::validate() const { - return vote_id_type( type, gpo.next_available_vote_id++ ); + FC_ASSERT(fee.amount >= 0); + FC_ASSERT(url.size() < GRAPHENE_MAX_URL_LENGTH ); } -} } // graphene::chain - -namespace fc -{ - -void to_variant( const graphene::chain::vote_id_type& var, variant& vo, uint32_t max_depth ) +void witness_update_operation::validate() const { - vo = string(var); + FC_ASSERT(fee.amount >= 0); + if( new_url.valid() ) + FC_ASSERT(new_url->size() < GRAPHENE_MAX_URL_LENGTH ); } -void from_variant( const variant& var, graphene::chain::vote_id_type& vo, uint32_t max_depth ) -{ - vo = graphene::chain::vote_id_type(var.as_string()); -} +} } // graphene::protocol -} // fc +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::witness_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::witness_update_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::witness_create_operation ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::witness_update_operation ) diff --git a/libraries/chain/protocol/worker.cpp b/libraries/protocol/worker.cpp similarity index 82% rename from libraries/chain/protocol/worker.cpp rename to libraries/protocol/worker.cpp index eb133da077..9b6a5d475c 100644 --- a/libraries/chain/protocol/worker.cpp +++ b/libraries/protocol/worker.cpp @@ -21,9 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include +#include -namespace graphene { namespace chain { +#include + +namespace graphene { namespace protocol { void worker_create_operation::validate() const { @@ -36,3 +38,6 @@ void worker_create_operation::validate() const } } } + +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::worker_create_operation::fee_parameters_type ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::protocol::worker_create_operation ) diff --git a/libraries/wallet/include/graphene/wallet/reflect_util.hpp b/libraries/wallet/include/graphene/wallet/reflect_util.hpp index 7a9e6e0812..c037f20722 100644 --- a/libraries/wallet/include/graphene/wallet/reflect_util.hpp +++ b/libraries/wallet/include/graphene/wallet/reflect_util.hpp @@ -39,9 +39,9 @@ namespace impl { std::string clean_name( const std::string& name ) { - const static std::string prefix = "graphene::chain::"; + const static std::string prefix = "graphene::protocol::"; const static std::string suffix = "_operation"; - // graphene::chain::.*_operation + // graphene::protocol::.*_operation if( (name.size() >= prefix.size() + suffix.size()) && (name.substr( 0, prefix.size() ) == prefix) && (name.substr( name.size()-suffix.size(), suffix.size() ) == suffix ) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 8ec275c60f..1fc432ce1c 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -31,7 +31,8 @@ using namespace graphene::app; using namespace graphene::chain; using namespace graphene::utilities; -using namespace std; +using std::string; +using std::vector; namespace fc { @@ -1618,6 +1619,23 @@ class wallet_api */ signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false); + /** Get transaction signers. + * + * Returns information about who signed the transaction, specifically, + * the corresponding public keys of the private keys used to sign the transaction. + * @param tx the signed transaction + * @return the set of public_keys + */ + flat_set get_transaction_signers(const signed_transaction &tx) const; + + /** Get key references. + * + * Returns accounts related to given public keys. + * @param keys public keys to search for related accounts + * @return the set of related accounts + */ + vector> get_key_references(const vector &keys) const; + /** Returns an uninitialized object representing a given blockchain operation. * * This returns a default-initialized object of the given type; it can be used @@ -1685,6 +1703,20 @@ class wallet_api order_book get_order_book( const string& base, const string& quote, unsigned limit = 50); + /** Signs a transaction. + * + * Given a fully-formed transaction with or without signatures, signs + * the transaction with the owned keys and optionally broadcasts the + * transaction. + * + * @param tx the unsigned transaction + * @param broadcast true if you wish to broadcast the transaction + * + * @return the signed transaction + */ + signed_transaction add_transaction_signature( signed_transaction tx, + bool broadcast = false ); + void dbg_make_uia(string creator, string symbol); void dbg_make_mia(string creator, string symbol); void dbg_push_blocks( std::string src_filename, uint32_t count ); @@ -1717,6 +1749,8 @@ class wallet_api } } +extern template class fc::api; + FC_REFLECT( graphene::wallet::key_label, (label)(key) ) FC_REFLECT( graphene::wallet::blind_balance, (amount)(from)(to)(one_time_key)(blinding_factor)(commitment)(used) ) FC_REFLECT( graphene::wallet::blind_confirmation::output, (label)(pub_key)(decrypted_memo)(confirmation)(auth)(confirmation_receipt) ) @@ -1879,6 +1913,9 @@ FC_API( graphene::wallet::wallet_api, (save_wallet_file) (serialize_transaction) (sign_transaction) + (add_transaction_signature) + (get_transaction_signers) + (get_key_references) (get_prototype_operation) (propose_parameter_change) (propose_fee_change) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 462a5b91c5..2f964bb811 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -65,8 +64,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -76,6 +75,8 @@ #include #include +#include + #ifndef WIN32 # include # include @@ -83,7 +84,7 @@ // explicit instantiation for later use namespace fc { - template class api; + template class api; } #define BRAIN_KEY_WORD_COUNT 16 @@ -94,6 +95,16 @@ namespace fc { namespace graphene { namespace wallet { +using std::ostream; +using std::stringstream; +using std::to_string; +using std::setprecision; +using std::fixed; +using std::ios; +using std::setiosflags; +using std::setw; +using std::endl; + namespace detail { struct operation_result_printer @@ -160,7 +171,7 @@ optional maybe_id( const string& name_or_id ) string address_to_shorthash( const address& addr ) { - uint32_t x = addr.addr._hash[0]; + uint32_t x = addr.addr._hash[0].value(); static const char hd[] = "0123456789abcdef"; string result; @@ -293,9 +304,10 @@ class wallet_api_impl private: void claim_registered_account(const account_object& account) { + bool import_keys = false; auto it = _wallet.pending_account_registrations.find( account.name ); FC_ASSERT( it != _wallet.pending_account_registrations.end() ); - for (const std::string& wif_key : it->second) + for (const std::string& wif_key : it->second) { if( !import_key( account.name, wif_key ) ) { // somebody else beat our pending registration, there is @@ -308,8 +320,15 @@ class wallet_api_impl // possibility of migrating to a fork where the // name is available, the user can always // manually re-register) + } else { + import_keys = true; } + } _wallet.pending_account_registrations.erase( it ); + + if( import_keys ) { + save_wallet_file(); + } } // after a witness registration succeeds, this saves the private key in the wallet permanently @@ -344,7 +363,8 @@ class wallet_api_impl if( !_wallet.pending_account_registrations.empty() ) { // make a vector of the account names pending registration - std::vector pending_account_names = boost::copy_range >(boost::adaptors::keys(_wallet.pending_account_registrations)); + std::vector pending_account_names = + boost::copy_range >(boost::adaptors::keys(_wallet.pending_account_registrations)); // look those up on the blockchain std::vector> @@ -359,10 +379,12 @@ class wallet_api_impl if (!_wallet.pending_witness_registrations.empty()) { // make a vector of the owner accounts for witnesses pending registration - std::vector pending_witness_names = boost::copy_range >(boost::adaptors::keys(_wallet.pending_witness_registrations)); + std::vector pending_witness_names = + boost::copy_range >(boost::adaptors::keys(_wallet.pending_witness_registrations)); // look up the owners on the blockchain - std::vector> owner_account_objects = _remote_db->lookup_account_names(pending_witness_names); + std::vector> owner_account_objects = + _remote_db->lookup_account_names(pending_witness_names); // if any of them have registered witnesses, claim them for( const fc::optional& optional_account : owner_account_objects ) @@ -415,13 +437,27 @@ class wallet_api_impl graphene::chain::transaction_id_type transaction_id; }; struct timestamp_index{}; - typedef boost::multi_index_container, - std::hash >, - boost::multi_index::ordered_non_unique, - boost::multi_index::member > > > recently_generated_transaction_set_type; + typedef boost::multi_index_container< + recently_generated_transaction_record, + boost::multi_index::indexed_by< + boost::multi_index::hashed_unique< + boost::multi_index::member< + recently_generated_transaction_record, + graphene::chain::transaction_id_type, + &recently_generated_transaction_record::transaction_id + >, + std::hash + >, + boost::multi_index::ordered_non_unique< + boost::multi_index::tag, + boost::multi_index::member< + recently_generated_transaction_record, + fc::time_point_sec, + &recently_generated_transaction_record::generation_time + > + > + > + > recently_generated_transaction_set_type; recently_generated_transaction_set_type _recently_generated_transactions; public: @@ -524,11 +560,11 @@ class wallet_api_impl return _checksum == fc::sha512(); } - template - T get_object(object_id id)const + template + graphene::db::object_downcast_t get_object(ID id)const { auto ob = _remote_db->get_objects({id}).front(); - return ob.template as( GRAPHENE_MAX_NESTED_OBJECTS ); + return ob.template as>( GRAPHENE_MAX_NESTED_OBJECTS ); } void set_operation_fees( signed_transaction& tx, const fee_schedule& s ) @@ -548,11 +584,15 @@ class wallet_api_impl result["head_block_age"] = fc::get_approximate_relative_time_string(dynamic_props.time, time_point_sec(time_point::now()), " old"); - result["next_maintenance_time"] = fc::get_approximate_relative_time_string(dynamic_props.next_maintenance_time); + result["next_maintenance_time"] = + fc::get_approximate_relative_time_string(dynamic_props.next_maintenance_time); result["chain_id"] = chain_props.chain_id; - result["participation"] = (100*dynamic_props.recent_slots_filled.popcount()) / 128.0; + stringstream participation; + participation << fixed << std::setprecision(2) << (100*dynamic_props.recent_slots_filled.popcount()) / 128.0; + result["participation"] = participation.str(); result["active_witnesses"] = fc::variant(global_props.active_witnesses, GRAPHENE_MAX_NESTED_OBJECTS); - result["active_committee_members"] = fc::variant(global_props.active_committee_members, GRAPHENE_MAX_NESTED_OBJECTS); + result["active_committee_members"] = + fc::variant(global_props.active_committee_members, GRAPHENE_MAX_NESTED_OBJECTS); return result; } @@ -568,9 +608,11 @@ class wallet_api_impl //result["blockchain_description"] = BTS_BLOCKCHAIN_DESCRIPTION; result["client_version"] = client_version; result["graphene_revision"] = graphene::utilities::git_revision_sha; - result["graphene_revision_age"] = fc::get_approximate_relative_time_string( fc::time_point_sec( graphene::utilities::git_revision_unix_timestamp ) ); + result["graphene_revision_age"] = fc::get_approximate_relative_time_string( fc::time_point_sec( + graphene::utilities::git_revision_unix_timestamp ) ); result["fc_revision"] = fc::git_revision_sha; - result["fc_revision_age"] = fc::get_approximate_relative_time_string( fc::time_point_sec( fc::git_revision_unix_timestamp ) ); + result["fc_revision_age"] = fc::get_approximate_relative_time_string( fc::time_point_sec( + fc::git_revision_unix_timestamp ) ); result["compile_date"] = "compiled on " __DATE__ " at " __TIME__; result["boost_version"] = boost::replace_all_copy(std::string(BOOST_LIB_VERSION), "_", "."); result["openssl_version"] = OPENSSL_VERSION_TEXT; @@ -742,8 +784,10 @@ class wallet_api_impl flat_set all_keys_for_account; std::vector active_keys = account.active.get_keys(); std::vector owner_keys = account.owner.get_keys(); - std::copy(active_keys.begin(), active_keys.end(), std::inserter(all_keys_for_account, all_keys_for_account.end())); - std::copy(owner_keys.begin(), owner_keys.end(), std::inserter(all_keys_for_account, all_keys_for_account.end())); + std::copy(active_keys.begin(), active_keys.end(), + std::inserter(all_keys_for_account, all_keys_for_account.end())); + std::copy(owner_keys.begin(), owner_keys.end(), + std::inserter(all_keys_for_account, all_keys_for_account.end())); all_keys_for_account.insert(account.options.memo_key); _keys[wif_pub_key] = wif_key; @@ -802,7 +846,8 @@ class wallet_api_impl account_object& old_acct = old_accounts[i]; if( !acct.valid() ) { - elog( "Could not find account ${id} : \"${name}\" does not exist on the chain!", ("id", old_acct.id)("name", old_acct.name) ); + elog( "Could not find account ${id} : \"${name}\" does not exist on the chain!", + ("id", old_acct.id)("name", old_acct.name) ); i++; continue; } @@ -821,12 +866,80 @@ class wallet_api_impl return true; } - void quit() - { - ilog( "Quitting Cli Wallet ..." ); - - throw fc::canceled_exception(); - } + /** + * Get the required public keys to sign the transaction which had been + * owned by us + * + * NOTE, if `erase_existing_sigs` set to true, the original trasaction's + * signatures will be erased + * + * @param tx The transaction to be signed + * @param erase_existing_sigs + * The transaction could have been partially signed already, + * if set to false, the corresponding public key of existing + * signatures won't be returned. + * If set to true, the existing signatures will be erased and + * all required keys returned. + */ + set get_owned_required_keys( signed_transaction &tx, + bool erase_existing_sigs = true) + { + set pks = _remote_db->get_potential_signatures( tx ); + flat_set owned_keys; + owned_keys.reserve( pks.size() ); + std::copy_if( pks.begin(), pks.end(), + std::inserter( owned_keys, owned_keys.end() ), + [this]( const public_key_type &pk ) { + return _keys.find( pk ) != _keys.end(); + } ); + + if ( erase_existing_sigs ) + tx.signatures.clear(); + + return _remote_db->get_required_signatures( tx, owned_keys ); + } + + signed_transaction add_transaction_signature( signed_transaction tx, + bool broadcast ) + { + set approving_key_set = get_owned_required_keys(tx, false); + + if ( ( ( tx.ref_block_num == 0 && tx.ref_block_prefix == 0 ) || + tx.expiration == fc::time_point_sec() ) && + tx.signatures.empty() ) + { + auto dyn_props = get_dynamic_global_properties(); + auto parameters = get_global_properties().parameters; + fc::time_point_sec now = dyn_props.time; + tx.set_reference_block( dyn_props.head_block_id ); + tx.set_expiration( now + parameters.maximum_time_until_expiration ); + } + for ( const public_key_type &key : approving_key_set ) + tx.sign( get_private_key( key ), _chain_id ); + + if ( broadcast ) + { + try + { + _remote_net_broadcast->broadcast_transaction( tx ); + } + catch ( const fc::exception &e ) + { + elog( "Caught exception while broadcasting tx ${id}: ${e}", + ( "id", tx.id().str() )( "e", e.to_detail_string() ) ); + FC_THROW( "Caught exception while broadcasting tx" ); + } + } + + return tx; + } + + void quit() + { + ilog( "Quitting Cli Wallet ..." ); + + throw fc::canceled_exception(); + } void save_wallet_file(string wallet_filename = "") { @@ -872,8 +985,8 @@ class wallet_api_impl fc::rename( tmp_wallet_filename, wallet_filename ); wlog( "renamed successfully tmp wallet file ${fn}", ("fn", tmp_wallet_filename) ); - } - else + } + else { FC_THROW("tmp wallet file cannot be validated ${fn}", ("fn", tmp_wallet_filename) ); } @@ -926,15 +1039,15 @@ class wallet_api_impl if( fee_asset_obj.get_id() != asset_id_type() ) { for( auto& op : _builder_transactions[handle].operations ) - total_fee += gprops.current_fees->set_fee( op, fee_asset_obj.options.core_exchange_rate ); + total_fee += gprops.get_current_fees().set_fee( op, fee_asset_obj.options.core_exchange_rate ); FC_ASSERT((total_fee * fee_asset_obj.options.core_exchange_rate).amount <= - get_object(fee_asset_obj.dynamic_asset_data_id).fee_pool, + get_object(fee_asset_obj.dynamic_asset_data_id).fee_pool, "Cannot pay fees in ${asset}, as this asset's fee pool is insufficiently funded.", ("asset", fee_asset_obj.symbol)); } else { for( auto& op : _builder_transactions[handle].operations ) - total_fee += gprops.current_fees->set_fee( op ); + total_fee += gprops.get_current_fees().set_fee( op ); } return total_fee; @@ -948,7 +1061,8 @@ class wallet_api_impl { FC_ASSERT(_builder_transactions.count(transaction_handle)); - return _builder_transactions[transaction_handle] = sign_transaction(_builder_transactions[transaction_handle], broadcast); + return _builder_transactions[transaction_handle] = + sign_transaction(_builder_transactions[transaction_handle], broadcast); } pair broadcast_transaction(signed_transaction tx) @@ -957,7 +1071,8 @@ class wallet_api_impl _remote_net_broadcast->broadcast_transaction(tx); } catch (const fc::exception& e) { - elog("Caught exception while broadcasting tx ${id}: ${e}", ("id", tx.id().str())("e", e.to_detail_string())); + elog("Caught exception while broadcasting tx ${id}: ${e}", + ("id", tx.id().str())("e", e.to_detail_string())); throw; } return std::make_pair(tx.id(),tx); @@ -977,7 +1092,7 @@ class wallet_api_impl if( review_period_seconds ) op.review_period_seconds = review_period_seconds; trx.operations = {op}; - _remote_db->get_global_properties().parameters.current_fees->set_fee( trx.operations.front() ); + _remote_db->get_global_properties().parameters.get_current_fees().set_fee( trx.operations.front() ); return trx = sign_transaction(trx, broadcast); } @@ -998,7 +1113,7 @@ class wallet_api_impl if( review_period_seconds ) op.review_period_seconds = review_period_seconds; trx.operations = {op}; - _remote_db->get_global_properties().parameters.current_fees->set_fee( trx.operations.front() ); + _remote_db->get_global_properties().parameters.get_current_fees().set_fee( trx.operations.front() ); return trx = sign_transaction(trx, broadcast); } @@ -1008,7 +1123,6 @@ class wallet_api_impl _builder_transactions.erase(handle); } - signed_transaction register_account(string name, public_key_type owner, public_key_type active, @@ -1045,38 +1159,13 @@ class wallet_api_impl account_create_op.options.memo_key = active; signed_transaction tx; - tx.operations.push_back( account_create_op ); - - auto current_fees = _remote_db->get_global_properties().parameters.current_fees; - set_operation_fees( tx, current_fees ); - - vector paying_keys = registrar_account_object.active.get_keys(); - - auto dyn_props = get_dynamic_global_properties(); - tx.set_reference_block( dyn_props.head_block_id ); - tx.set_expiration( dyn_props.time + fc::seconds(30) ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); - for( public_key_type& key : paying_keys ) - { - auto it = _keys.find(key); - if( it != _keys.end() ) - { - fc::optional< fc::ecc::private_key > privkey = wif_to_key( it->second ); - if( !privkey.valid() ) - { - FC_ASSERT( false, "Malformed private key in _keys" ); - } - tx.sign( *privkey, _chain_id ); - } - } - - if( broadcast ) - _remote_net_broadcast->broadcast_transaction( tx ); - return tx; - } FC_CAPTURE_AND_RETHROW( (name)(owner)(active)(registrar_account)(referrer_account)(referrer_percent)(broadcast) ) } - + return sign_transaction(tx, broadcast); + } FC_CAPTURE_AND_RETHROW( (name)(owner)(active)(registrar_account) + (referrer_account)(referrer_percent)(broadcast) ) } signed_transaction upgrade_account(string name, bool broadcast) { try { @@ -1089,13 +1178,12 @@ class wallet_api_impl op.account_to_upgrade = account_obj.get_id(); op.upgrade_to_lifetime_member = true; tx.operations = {op}; - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (name) ) } - // This function generates derived keys starting with index 0 and keeps incrementing // the index until it finds a key that isn't registered in the block chain. To be // safer, it continues checking for a few more keys to make sure there wasn't a short gap @@ -1172,38 +1260,17 @@ class wallet_api_impl // account_create_op.fee = account_create_op.calculate_fee(db.current_fee_schedule()); signed_transaction tx; - tx.operations.push_back( account_create_op ); - - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); - - vector paying_keys = registrar_account_object.active.get_keys(); - - auto dyn_props = get_dynamic_global_properties(); - tx.set_reference_block( dyn_props.head_block_id ); - tx.set_expiration( dyn_props.time + fc::seconds(30) ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); - for( public_key_type& key : paying_keys ) - { - auto it = _keys.find(key); - if( it != _keys.end() ) - { - fc::optional< fc::ecc::private_key > privkey = wif_to_key( it->second ); - FC_ASSERT( privkey.valid(), "Malformed private key in _keys" ); - tx.sign( *privkey, _chain_id ); - } - } - // we do not insert owner_privkey here because // it is intended to only be used for key recovery _wallet.pending_account_registrations[account_name].push_back(key_to_wif( active_privkey )); _wallet.pending_account_registrations[account_name].push_back(key_to_wif( memo_privkey )); if( save_wallet ) save_wallet_file(); - if( broadcast ) - _remote_net_broadcast->broadcast_transaction( tx ); - return tx; + return sign_transaction(tx, broadcast); } FC_CAPTURE_AND_RETHROW( (account_name)(registrar_account)(referrer_account)(broadcast) ) } signed_transaction create_account_with_brain_key(string brain_key, @@ -1217,7 +1284,8 @@ class wallet_api_impl string normalized_brain_key = normalize_brain_key( brain_key ); // TODO: scan blockchain for accounts that exist with same brain key fc::ecc::private_key owner_privkey = derive_private_key( normalized_brain_key, 0 ); - return create_account_with_private_key(owner_privkey, account_name, registrar_account, referrer_account, broadcast, save_wallet); + return create_account_with_private_key(owner_privkey, account_name, registrar_account, + referrer_account, broadcast, save_wallet); } FC_CAPTURE_AND_RETHROW( (account_name)(registrar_account)(referrer_account) ) } @@ -1240,7 +1308,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( create_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1253,14 +1321,11 @@ class wallet_api_impl { try { optional asset_to_update = find_asset(symbol); if (!asset_to_update) - FC_THROW("No asset with that symbol exists!"); + FC_THROW("No asset with that symbol exists!"); optional new_issuer_account_id; if (new_issuer) { - FC_ASSERT( _remote_db->get_dynamic_global_properties().time < HARDFORK_CORE_199_TIME, - "The use of 'new_issuer' is no longer supported. Please use `update_asset_issuer' instead!"); - account_object new_issuer_account = get_account(*new_issuer); - new_issuer_account_id = new_issuer_account.id; + FC_THROW( "The use of 'new_issuer' is no longer supported. Please use `update_asset_issuer' instead!" ); } asset_update_operation update_op; @@ -1271,7 +1336,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1294,7 +1359,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( update_issuer ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1315,7 +1380,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1339,7 +1404,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1361,7 +1426,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( publish_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1385,7 +1450,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( fund_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1407,7 +1472,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( claim_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1430,7 +1495,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( reserve_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1451,7 +1516,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( settle_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1472,7 +1537,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( settle_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1486,7 +1551,10 @@ class wallet_api_impl optional debt_asset = find_asset(debt_symbol); if (!debt_asset) FC_THROW("No asset with that symbol exists!"); - const asset_object& collateral = get_asset(get_object(*debt_asset->bitasset_data_id).options.short_backing_asset); + + FC_ASSERT(debt_asset->bitasset_data_id.valid(), "Not a bitasset, bidding not possible."); + const asset_object& collateral = + get_asset(get_object(*debt_asset->bitasset_data_id).options.short_backing_asset); bid_collateral_operation op; op.bidder = get_account_id(bidder_name); @@ -1495,7 +1563,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1513,7 +1581,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( whitelist_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1526,20 +1594,12 @@ class wallet_api_impl committee_member_create_operation committee_member_create_op; committee_member_create_op.committee_member_account = get_account_id(owner_account); committee_member_create_op.url = url; - - /* - * Compatibility issue - * Current Date: 2018-09-28 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to name in remote call after next hardfork - */ - auto account = get_account(owner_account); - auto always_id = account_id_to_string(account.id); - if (_remote_db->get_committee_member_by_account(always_id)) + if (_remote_db->get_committee_member_by_account(owner_account)) FC_THROW("Account ${owner_account} is already a committee_member", ("owner_account", owner_account)); signed_transaction tx; tx.operations.push_back( committee_member_create_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1584,12 +1644,14 @@ class wallet_api_impl { try { - fc::optional committee_member_id = maybe_id(owner_account); + fc::optional committee_member_id = + maybe_id(owner_account); if (committee_member_id) { std::vector ids_to_get; ids_to_get.push_back(*committee_member_id); - std::vector> committee_member_objects = _remote_db->get_committee_members(ids_to_get); + std::vector> committee_member_objects = + _remote_db->get_committee_members(ids_to_get); if (committee_member_objects.front()) return *committee_member_objects.front(); FC_THROW("No committee_member is registered for id ${id}", ("id", owner_account)); @@ -1599,7 +1661,8 @@ class wallet_api_impl // then maybe it's the owner account try { - fc::optional committee_member = _remote_db->get_committee_member_by_account(owner_account); + fc::optional committee_member = + _remote_db->get_committee_member_by_account(owner_account); if (committee_member) return *committee_member; else @@ -1621,7 +1684,8 @@ class wallet_api_impl account_object witness_account = get_account(owner_account); fc::ecc::private_key active_private_key = get_private_key_for_account(witness_account); int witness_key_index = find_first_unused_derived_key_index(active_private_key); - fc::ecc::private_key witness_private_key = derive_private_key(key_to_wif(active_private_key), witness_key_index); + fc::ecc::private_key witness_private_key = + derive_private_key(key_to_wif(active_private_key), witness_key_index); graphene::chain::public_key_type witness_public_key = witness_private_key.get_public_key(); witness_create_operation witness_create_op; @@ -1634,7 +1698,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( witness_create_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); _wallet.pending_witness_registrations[owner_account] = key_to_wif(witness_private_key); @@ -1660,7 +1724,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( witness_update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1711,7 +1775,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1775,7 +1839,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1798,7 +1862,7 @@ class wallet_api_impl string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size, const uint32_t claim_period_seconds, bool broadcast = false ) { - try + try { FC_ASSERT( !self.is_locked() ); fc::optional asset_obj = get_asset(asset_symbol); @@ -1814,17 +1878,17 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(create_op); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); } FC_CAPTURE_AND_RETHROW( (source)(destination)(amount)(asset_symbol)(hash_algorithm) - (preimage_hash)(preimage_size)(claim_period_seconds)(broadcast) ) + (preimage_hash)(preimage_size)(claim_period_seconds)(broadcast) ) } signed_transaction htlc_redeem( string htlc_id, string issuer, const std::vector& preimage, bool broadcast ) { - try + try { FC_ASSERT( !self.is_locked() ); fc::optional htlc_obj = get_htlc(htlc_id); @@ -1839,16 +1903,16 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(update_op); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); - } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(preimage)(broadcast) ) + } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(preimage)(broadcast) ) } signed_transaction htlc_extend ( string htlc_id, string issuer, const uint32_t seconds_to_add, bool broadcast) { - try + try { FC_ASSERT( !self.is_locked() ); fc::optional htlc_obj = get_htlc(htlc_id); @@ -1863,11 +1927,11 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(update_op); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); - } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(seconds_to_add)(broadcast) ) + } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(seconds_to_add)(broadcast) ) } vector< vesting_balance_object_with_info > get_vesting_balances( string account_name ) @@ -1878,18 +1942,11 @@ class wallet_api_impl if( vbid ) { - result.emplace_back( get_object(*vbid), now ); + result.emplace_back( get_object(*vbid), now ); return result; } - /* - * Compatibility issue - * Current Date: 2018-09-28 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to name in remote call after next hardfork - */ - auto account = get_account(account_name); - auto always_id = account_id_to_string(account.id); - - vector< vesting_balance_object > vbos = _remote_db->get_vesting_balances( always_id ); + + vector< vesting_balance_object > vbos = _remote_db->get_vesting_balances( account_name ); if( vbos.size() == 0 ) return result; @@ -1915,7 +1972,7 @@ class wallet_api_impl vbid = wit.pay_vb; } - vesting_balance_object vbo = get_object< vesting_balance_object >( *vbid ); + vesting_balance_object vbo = get_object( *vbid ); vesting_balance_withdraw_operation vesting_balance_withdraw_op; vesting_balance_withdraw_op.vesting_balance = *vbid; @@ -1924,7 +1981,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( vesting_balance_withdraw_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1937,28 +1994,24 @@ class wallet_api_impl bool broadcast /* = false */) { try { account_object voting_account_object = get_account(voting_account); - - /* - * Compatibility issue - * Current Date: 2018-09-28 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to name in remote call after next hardfork - */ - auto account = get_account(committee_member); - auto always_id = account_id_to_string(account.id); - fc::optional committee_member_obj = _remote_db->get_committee_member_by_account(always_id); + fc::optional committee_member_obj = + _remote_db->get_committee_member_by_account(committee_member); if (!committee_member_obj) - FC_THROW("Account ${committee_member} is not registered as a committee_member", ("committee_member", committee_member)); + FC_THROW("Account ${committee_member} is not registered as a committee_member", + ("committee_member", committee_member)); if (approve) { auto insert_result = voting_account_object.options.votes.insert(committee_member_obj->vote_id); if (!insert_result.second) - FC_THROW("Account ${account} was already voting for committee_member ${committee_member}", ("account", voting_account)("committee_member", committee_member)); + FC_THROW("Account ${account} was already voting for committee_member ${committee_member}", + ("account", voting_account)("committee_member", committee_member)); } else { unsigned votes_removed = voting_account_object.options.votes.erase(committee_member_obj->vote_id); if (!votes_removed) - FC_THROW("Account ${account} is already not voting for committee_member ${committee_member}", ("account", voting_account)("committee_member", committee_member)); + FC_THROW("Account ${account} is already not voting for committee_member ${committee_member}", + ("account", voting_account)("committee_member", committee_member)); } account_update_operation account_update_op; account_update_op.account = voting_account_object.id; @@ -1966,7 +2019,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( account_update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -1979,27 +2032,22 @@ class wallet_api_impl { try { account_object voting_account_object = get_account(voting_account); - /* - * Compatibility issue - * Current Date: 2018-09-28 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to name in remote call after next hardfork - */ - auto account = get_account(witness); - auto always_id = account_id_to_string(account.id); - fc::optional witness_obj = _remote_db->get_witness_by_account(always_id); + fc::optional witness_obj = _remote_db->get_witness_by_account(witness); if (!witness_obj) FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness)); if (approve) { auto insert_result = voting_account_object.options.votes.insert(witness_obj->vote_id); if (!insert_result.second) - FC_THROW("Account ${account} was already voting for witness ${witness}", ("account", voting_account)("witness", witness)); + FC_THROW("Account ${account} was already voting for witness ${witness}", + ("account", voting_account)("witness", witness)); } else { unsigned votes_removed = voting_account_object.options.votes.erase(witness_obj->vote_id); if (!votes_removed) - FC_THROW("Account ${account} is already not voting for witness ${witness}", ("account", voting_account)("witness", witness)); + FC_THROW("Account ${account} is already not voting for witness ${witness}", + ("account", voting_account)("witness", witness)); } account_update_operation account_update_op; account_update_op.account = voting_account_object.id; @@ -2007,7 +2055,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( account_update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -2022,7 +2070,8 @@ class wallet_api_impl { account_id_type new_voting_account_id = get_account_id(*voting_account); if (account_object_to_modify.options.voting_account == new_voting_account_id) - FC_THROW("Voting proxy for ${account} is already set to ${voter}", ("account", account_to_modify)("voter", *voting_account)); + FC_THROW("Voting proxy for ${account} is already set to ${voter}", + ("account", account_to_modify)("voter", *voting_account)); account_object_to_modify.options.voting_account = new_voting_account_id; } else @@ -2038,7 +2087,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( account_update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -2053,8 +2102,10 @@ class wallet_api_impl if (account_object_to_modify.options.num_witness == desired_number_of_witnesses && account_object_to_modify.options.num_committee == desired_number_of_committee_members) - FC_THROW("Account ${account} is already voting for ${witnesses} witnesses and ${committee_members} committee_members", - ("account", account_to_modify)("witnesses", desired_number_of_witnesses)("committee_members",desired_number_of_witnesses)); + FC_THROW("Account ${account} is already voting for ${witnesses} witnesses" + " and ${committee_members} committee_members", + ("account", account_to_modify)("witnesses", desired_number_of_witnesses) + ("committee_members",desired_number_of_witnesses)); account_object_to_modify.options.num_witness = desired_number_of_witnesses; account_object_to_modify.options.num_committee = desired_number_of_committee_members; @@ -2064,21 +2115,17 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back( account_update_op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); - } FC_CAPTURE_AND_RETHROW( (account_to_modify)(desired_number_of_witnesses)(desired_number_of_committee_members)(broadcast) ) } + } FC_CAPTURE_AND_RETHROW( (account_to_modify)(desired_number_of_witnesses) + (desired_number_of_committee_members)(broadcast) ) } signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false) { - set pks = _remote_db->get_potential_signatures( tx ); - flat_set owned_keys; - owned_keys.reserve( pks.size() ); - std::copy_if( pks.begin(), pks.end(), std::inserter(owned_keys, owned_keys.end()), - [this](const public_key_type& pk){ return _keys.find(pk) != _keys.end(); } ); - tx.clear_signatures(); - set approving_key_set = _remote_db->get_required_signatures( tx, owned_keys ); + + set approving_key_set = get_owned_required_keys(tx); auto dyn_props = get_dynamic_global_properties(); tx.set_reference_block( dyn_props.head_block_id ); @@ -2088,7 +2135,8 @@ class wallet_api_impl // when there are multiple transactions in the same block. choose a time period that should be at // least one block long, even in the worst case. 2 minutes ought to be plenty. fc::time_point_sec oldest_transaction_ids_to_track(dyn_props.time - fc::minutes(2)); - auto oldest_transaction_record_iter = _recently_generated_transactions.get().lower_bound(oldest_transaction_ids_to_track); + auto oldest_transaction_record_iter = + _recently_generated_transactions.get().lower_bound(oldest_transaction_ids_to_track); auto begin_iter = _recently_generated_transactions.get().begin(); _recently_generated_transactions.get().erase(begin_iter, oldest_transaction_record_iter); @@ -2125,7 +2173,8 @@ class wallet_api_impl } catch (const fc::exception& e) { - elog("Caught exception while broadcasting tx ${id}: ${e}", ("id", tx.id().str())("e", e.to_detail_string()) ); + elog("Caught exception while broadcasting tx ${id}: ${e}", + ("id", tx.id().str())("e", e.to_detail_string()) ); throw; } } @@ -2133,6 +2182,16 @@ class wallet_api_impl return tx; } + flat_set get_transaction_signers(const signed_transaction &tx) const + { + return tx.get_signature_keys(_chain_id); + } + + vector> get_key_references(const vector &keys) const + { + return _remote_db->get_key_references(keys); + } + memo_data sign_memo(string from, string to, string memo) { FC_ASSERT( !self.is_locked() ); @@ -2166,7 +2225,9 @@ class wallet_api_impl const memo_data *memo = &md; try { - FC_ASSERT(_keys.count(memo->to) || _keys.count(memo->from), "Memo is encrypted to a key ${to} or ${from} not in this wallet.", ("to", memo->to)("from",memo->from)); + FC_ASSERT( _keys.count(memo->to) || _keys.count(memo->from), + "Memo is encrypted to a key ${to} or ${from} not in this wallet.", + ("to", memo->to)("from",memo->from) ); if( _keys.count(memo->to) ) { auto my_key = wif_to_key(_keys.at(memo->to)); FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted."); @@ -2204,7 +2265,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(op); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction( tx, broadcast ); @@ -2225,7 +2286,7 @@ class wallet_api_impl signed_transaction trx; trx.operations = {op}; - set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees()); trx.validate(); return sign_transaction(trx, broadcast); @@ -2249,23 +2310,22 @@ class wallet_api_impl signed_transaction trx; trx.operations = {op}; - set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees()); trx.validate(); return sign_transaction(trx, broadcast); } - signed_transaction cancel_order(object_id_type order_id, bool broadcast = false) + signed_transaction cancel_order(limit_order_id_type order_id, bool broadcast = false) { try { FC_ASSERT(!is_locked()); - FC_ASSERT(order_id.space() == protocol_ids, "Invalid order ID ${id}", ("id", order_id)); signed_transaction trx; limit_order_cancel_operation op; - op.fee_paying_account = get_object(order_id).seller; + op.fee_paying_account = get_object(order_id).seller; op.order = order_id; trx.operations = {op}; - set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees()); trx.validate(); return sign_transaction(trx, broadcast); @@ -2300,7 +2360,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(xfer_op); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); @@ -2330,7 +2390,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(issue_op); - set_operation_fees(tx,_remote_db->get_global_properties().parameters.current_fees); + set_operation_fees(tx,_remote_db->get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); @@ -2445,7 +2505,8 @@ class wallet_api_impl for( const auto& out : r.outputs ) { asset_object a = get_asset( out.decrypted_memo.amount.asset_id ); - ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n"; + ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label + << "\n\t receipt: " << out.confirmation_receipt << "\n\n"; } return ss.str(); }; @@ -2458,7 +2519,8 @@ class wallet_api_impl for( const auto& out : r.outputs ) { asset_object a = get_asset( out.decrypted_memo.amount.asset_id ); - ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n"; + ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label + << "\n\t receipt: " << out.confirmation_receipt << "\n\n"; } return ss.str(); }; @@ -2467,7 +2529,8 @@ class wallet_api_impl auto r = result.as( GRAPHENE_MAX_NESTED_OBJECTS ); std::stringstream ss; asset_object as = get_asset( r.amount.asset_id ); - ss << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n"; + ss << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " + << r.to_label << " " << r.memo <<"\n"; return ss.str(); }; m["blind_history"] = [this](variant result, const fc::variants& a) @@ -2481,7 +2544,8 @@ class wallet_api_impl { asset_object as = get_asset( r.amount.asset_id ); ss << fc::get_approximate_relative_time_string( r.date ) - << " " << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n"; + << " " << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label + << " " << r.memo <<"\n"; } return ss.str(); }; @@ -2600,11 +2664,11 @@ class wallet_api_impl prop_op.fee_paying_account = get_account(proposing_account).id; prop_op.proposed_ops.emplace_back( update_op ); - current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); + current_params.get_current_fees().set_fee( prop_op.proposed_ops.back().op ); signed_transaction tx; tx.operations.push_back(prop_op); - set_operation_fees(tx, current_params.current_fees); + set_operation_fees(tx, current_params.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); @@ -2617,7 +2681,7 @@ class wallet_api_impl bool broadcast = false) { const chain_parameters& current_params = get_global_properties().parameters; - const fee_schedule_type& current_fees = *(current_params.current_fees); + const fee_schedule_type& current_fees = current_params.get_current_fees(); flat_map< int, fee_parameters > fee_map; fee_map.reserve( current_fees.parameters.size() ); @@ -2670,7 +2734,7 @@ class wallet_api_impl new_fees.scale = scale; chain_parameters new_params = current_params; - new_params.current_fees = new_fees; + new_params.get_mutable_fees() = new_fees; committee_member_update_global_parameters_operation update_op; update_op.new_parameters = new_params; @@ -2682,11 +2746,11 @@ class wallet_api_impl prop_op.fee_paying_account = get_account(proposing_account).id; prop_op.proposed_ops.emplace_back( update_op ); - current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); + current_params.get_current_fees().set_fee( prop_op.proposed_ops.back().op ); signed_transaction tx; tx.operations.push_back(prop_op); - set_operation_fees(tx, current_params.current_fees); + set_operation_fees(tx, current_params.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); @@ -2720,7 +2784,7 @@ class wallet_api_impl signed_transaction tx; tx.operations.push_back(update_op); - set_operation_fees(tx, get_global_properties().parameters.current_fees); + set_operation_fees(tx, get_global_properties().parameters.get_current_fees()); tx.validate(); return sign_transaction(tx, broadcast); } @@ -2850,7 +2914,9 @@ class wallet_api_impl { std::ostringstream brain_key; brain_key << "brain key for account " << prefix << i; - signed_transaction trx = create_account_with_brain_key(brain_key.str(), prefix + fc::to_string(i), master.name, master.name, /* broadcast = */ true, /* save wallet = */ false); + signed_transaction trx = create_account_with_brain_key( + brain_key.str(), prefix + fc::to_string(i), master.name, master.name, + /* broadcast = */ true, /* save wallet = */ false); } fc::time_point end = fc::time_point::now(); ilog("Created ${n} accounts in ${time} milliseconds", @@ -2922,8 +2988,6 @@ std::string operation_printer::fee(const asset& a)const { template std::string operation_printer::operator()(const T& op)const { - //balance_accumulator acc; - //op.get_balance_delta( acc, result ); auto a = wallet.get_asset( op.fee.asset_id ); auto payer = wallet.get_account( op.fee_payer() ); @@ -2931,7 +2995,6 @@ std::string operation_printer::operator()(const T& op)const if( op_name.find_last_of(':') != string::npos ) op_name.erase(0, op_name.find_last_of(':')+1); out << op_name <<" "; - // out << "balance delta: " << fc::json::to_string(acc.balance) <<" "; out << payer.name << " fee: " << a.amount_to_pretty_string( op.fee ); operation_result_printer rprinter(wallet); std::string str_result = result.visit(rprinter); @@ -2947,7 +3010,7 @@ std::string operation_printer::operator()(const transfer_from_blind_operation& o auto receiver = wallet.get_account( op.to ); out << receiver.name - << " received " << a.amount_to_pretty_string( op.amount ) << " from blinded balance"; + << " received " << a.amount_to_pretty_string( op.amount ) << " from blinded balance"; return ""; } std::string operation_printer::operator()(const transfer_to_blind_operation& op)const @@ -2957,8 +3020,9 @@ std::string operation_printer::operator()(const transfer_to_blind_operation& op) auto sender = wallet.get_account( op.from ); out << sender.name - << " sent " << a.amount_to_pretty_string( op.amount ) << " to " << op.outputs.size() << " blinded balance" << (op.outputs.size()>1?"s":"") - << " fee: " << fa.amount_to_pretty_string( op.fee ); + << " sent " << a.amount_to_pretty_string( op.amount ) << " to " << op.outputs.size() + << " blinded balance" << (op.outputs.size()>1?"s":"") + << " fee: " << fa.amount_to_pretty_string( op.fee ); return ""; } string operation_printer::operator()(const transfer_operation& op) const @@ -2973,7 +3037,9 @@ string operation_printer::operator()(const transfer_operation& op) const out << " -- Unlock wallet to see memo."; } else { try { - FC_ASSERT(wallet._keys.count(op.memo->to) || wallet._keys.count(op.memo->from), "Memo is encrypted to a key ${to} or ${from} not in this wallet.", ("to", op.memo->to)("from",op.memo->from)); + FC_ASSERT( wallet._keys.count(op.memo->to) || wallet._keys.count(op.memo->from), + "Memo is encrypted to a key ${to} or ${from} not in this wallet.", + ("to", op.memo->to)("from",op.memo->from) ); if( wallet._keys.count(op.memo->to) ) { auto my_key = wif_to_key(wallet._keys.at(op.memo->to)); FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted."); @@ -3019,9 +3085,9 @@ std::string operation_printer::operator()(const asset_create_operation& op) cons std::string operation_printer::operator()(const htlc_redeem_operation& op) const { - out << "Redeem HTLC with database id " - << std::to_string(op.htlc_id.space_id) - << "." << std::to_string(op.htlc_id.type_id) + out << "Redeem HTLC with database id " + << std::to_string(op.htlc_id.space_id) + << "." << std::to_string(op.htlc_id.type_id) << "." << std::to_string((uint64_t)op.htlc_id.instance) << " with preimage \""; for (unsigned char c : op.preimage) @@ -3161,15 +3227,7 @@ map wallet_api::list_accounts(const string& lowerbound, vector wallet_api::list_account_balances(const string& id) { - /* - * Compatibility issue - * Current Date: 2018-09-13 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to id in remote call after next hardfork - */ - auto account = get_account(id); - auto always_id = my->account_id_to_string(account.id); - - return my->_remote_db->get_account_balances(always_id, flat_set()); + return my->_remote_db->get_account_balances(id, flat_set()); } vector wallet_api::list_assets(const string& lowerbound, uint32_t limit)const @@ -3183,7 +3241,7 @@ uint64_t wallet_api::get_asset_count()const } signed_transaction wallet_api::htlc_create( string source, string destination, string amount, string asset_symbol, - string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size, + string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size, const uint32_t claim_period_seconds, bool broadcast) { return my->htlc_create(source, destination, amount, asset_symbol, hash_algorithm, preimage_hash, preimage_size, @@ -3210,18 +3268,18 @@ fc::optional wallet_api::get_htlc(std::string htlc_id) const public: typedef fc::mutable_variant_object result_type; - result_type operator()(const fc::ripemd160& obj)const + result_type operator()(const fc::ripemd160& obj)const { return convert("RIPEMD160", obj.str()); } - result_type operator()(const fc::sha1& obj)const + result_type operator()(const fc::sha1& obj)const { return convert("SHA1", obj.str()); } - result_type operator()(const fc::sha256& obj)const + result_type operator()(const fc::sha256& obj)const { return convert("SHA256", obj.str()); } private: result_type convert(const std::string& type, const std::string& hash)const { - fc::mutable_variant_object ret_val; - ret_val["hash_algo"] = type; - ret_val["preimage_hash"] = hash; + fc::mutable_variant_object ret_val; + ret_val["hash_algo"] = type; + ret_val["preimage_hash"] = hash; return ret_val; } }; @@ -3259,14 +3317,6 @@ vector wallet_api::get_account_history(string name, int limit) { vector result; - /* - * Compatibility issue - * Current Date: 2018-09-14 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next 2 lines and change always_id to name in remote call after next hardfork - */ - auto account = get_account(name); - auto always_id = my->account_id_to_string(account.id); - while( limit > 0 ) { bool skip_first_row = false; @@ -3277,7 +3327,8 @@ vector wallet_api::get_account_history(string name, int limit) if( start == operation_history_id_type() ) // no more data break; start = start + (-1); - if( start == operation_history_id_type() ) // will return most recent history if directly call remote API with this + if( start == operation_history_id_type() ) // will return most recent history if + // directly call remote API with this { start = start + 1; skip_first_row = true; @@ -3287,7 +3338,7 @@ vector wallet_api::get_account_history(string name, int limit) int page_limit = skip_first_row ? std::min( 100, limit + 1 ) : std::min( 100, limit ); vector current = my->_remote_hist->get_account_history( - always_id, + name, operation_history_id_type(), page_limit, start ); @@ -3330,13 +3381,6 @@ vector wallet_api::get_relative_account_history( const account_object& account = my->get_account(account_id); const account_statistics_object& stats = my->get_object(account.statistics); - /* - * Compatibility issue - * Current Date: 2018-09-14 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next line and change always_id to name in remote call after next hardfork - */ - auto always_id = my->account_id_to_string(account_id); - if(start == 0) start = stats.total_ops; else @@ -3345,7 +3389,7 @@ vector wallet_api::get_relative_account_history( while( limit > 0 ) { vector current = my->_remote_hist->get_relative_account_history( - always_id, + name, stop, std::min(100, limit), start); @@ -3375,13 +3419,6 @@ account_history_operation_detail wallet_api::get_account_history_by_operations( const auto& account = my->get_account(account_id); const auto& stats = my->get_object(account.statistics); - /* - * Compatibility issue - * Current Date: 2018-09-14 More info: https://github.com/bitshares/bitshares-core/issues/1307 - * Todo: remove the next line and change always_id to name in remote call after next hardfork - */ - auto always_id = my->account_id_to_string(account_id); - // sequence of account_transaction_history_object start with 1 start = start == 0 ? 1 : start; @@ -3392,7 +3429,7 @@ account_history_operation_detail wallet_api::get_account_history_by_operations( while (limit > 0 && start <= stats.total_ops) { uint32_t min_limit = std::min (100, limit); - auto current = my->_remote_hist->get_account_history_by_operations(always_id, operation_types, start, min_limit); + auto current = my->_remote_hist->get_account_history_by_operations(name, operation_types, start, min_limit); for (auto& obj : current.operation_history_objs) { std::stringstream ss; auto memo = obj.op.visit(detail::operation_printer(ss, *my, obj)); @@ -3465,7 +3502,9 @@ brain_key_info wallet_api::suggest_brain_key()const return graphene::wallet::utility::suggest_brain_key(); } -vector wallet_api::derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys) const +vector wallet_api::derive_owner_keys_from_brain_key( + string brain_key, + int number_of_desired_keys) const { return graphene::wallet::utility::derive_owner_keys_from_brain_key(brain_key, number_of_desired_keys); } @@ -3497,12 +3536,17 @@ transaction_handle_type wallet_api::begin_builder_transaction() return my->begin_builder_transaction(); } -void wallet_api::add_operation_to_builder_transaction(transaction_handle_type transaction_handle, const operation& op) +void wallet_api::add_operation_to_builder_transaction( + transaction_handle_type transaction_handle, + const operation& op) { my->add_operation_to_builder_transaction(transaction_handle, op); } -void wallet_api::replace_operation_in_builder_transaction(transaction_handle_type handle, unsigned operation_index, const operation& new_op) +void wallet_api::replace_operation_in_builder_transaction( + transaction_handle_type handle, + unsigned operation_index, + const operation& new_op) { my->replace_operation_in_builder_transaction(handle, operation_index, new_op); } @@ -3528,10 +3572,10 @@ pair wallet_api::broadcast_transaction(s } signed_transaction wallet_api::propose_builder_transaction( - transaction_handle_type handle, - time_point_sec expiration, - uint32_t review_period_seconds, - bool broadcast) + transaction_handle_type handle, + time_point_sec expiration, + uint32_t review_period_seconds, + bool broadcast) { return my->propose_builder_transaction(handle, expiration, review_period_seconds, broadcast); } @@ -3567,7 +3611,7 @@ asset_bitasset_data_object wallet_api::get_bitasset_data(string asset_name_or_id { auto asset = get_asset(asset_name_or_id); FC_ASSERT(asset.is_market_issued() && asset.bitasset_data_id); - return my->get_object(*asset.bitasset_data_id); + return my->get_object(*asset.bitasset_data_id); } account_id_type wallet_api::get_account_id(string account_name_or_id) const @@ -3660,16 +3704,22 @@ map wallet_api::import_accounts( string filename, string password ++import_failures; } } - ilog( "successfully imported ${n} keys for account ${name}", ("n", import_successes)("name", item.account_name) ); + ilog( "successfully imported ${n} keys for account ${name}", + ("n", import_successes)("name", item.account_name) ); if( import_failures > 0 ) - elog( "failed to import ${n} keys for account ${name}", ("n", import_failures)("name", item.account_name) ); + elog( "failed to import ${n} keys for account ${name}", + ("n", import_failures)("name", item.account_name) ); } } return result; } -bool wallet_api::import_account_keys( string filename, string password, string src_account_name, string dest_account_name ) +bool wallet_api::import_account_keys( + string filename, + string password, + string src_account_name, + string dest_account_name ) { FC_ASSERT( !is_locked() ); FC_ASSERT( fc::exists( filename ) ); @@ -3744,7 +3794,8 @@ signed_transaction wallet_api::register_account(string name, uint32_t referrer_percent, bool broadcast) { - return my->register_account( name, owner_pubkey, active_pubkey, registrar_account, referrer_account, referrer_percent, broadcast ); + return my->register_account( name, owner_pubkey, active_pubkey, + registrar_account, referrer_account, referrer_percent, broadcast ); } signed_transaction wallet_api::create_account_with_brain_key(string brain_key, string account_name, string registrar_account, string referrer_account, @@ -3988,6 +4039,16 @@ signed_transaction wallet_api::sign_transaction(signed_transaction tx, bool broa return my->sign_transaction( tx, broadcast); } FC_CAPTURE_AND_RETHROW( (tx) ) } +flat_set wallet_api::get_transaction_signers(const signed_transaction &tx) const +{ try { + return my->get_transaction_signers(tx); +} FC_CAPTURE_AND_RETHROW( (tx) ) } + +vector> wallet_api::get_key_references(const vector &keys) const +{ try { + return my->get_key_references(keys); +} FC_CAPTURE_AND_RETHROW( (keys) ) } + operation wallet_api::get_prototype_operation(string operation_name) { return my->get_prototype_operation( operation_name ); @@ -4081,6 +4142,12 @@ dynamic_global_property_object wallet_api::get_dynamic_global_properties() const return my->get_dynamic_global_properties(); } +signed_transaction wallet_api::add_transaction_signature( signed_transaction tx, + bool broadcast ) +{ + return my->add_transaction_signature( tx, broadcast ); +} + string wallet_api::help()const { std::vector method_names = my->method_documentation.get_method_names(); @@ -4120,18 +4187,25 @@ string wallet_api::gethelp(const string& method)const else if( method == "create_account_with_brain_key" ) { ss << "usage: create_account_with_brain_key BRAIN_KEY ACCOUNT_NAME REGISTRAR REFERRER BROADCAST\n\n"; - ss << "example: create_account_with_brain_key \"my really long brain key\" \"newaccount\" \"1.3.11\" \"1.3.11\" true\n"; - ss << "example: create_account_with_brain_key \"my really long brain key\" \"newaccount\" \"someaccount\" \"otheraccount\" true\n"; + ss << "example: create_account_with_brain_key " + << "\"my really long brain key\" \"newaccount\" \"1.3.11\" \"1.3.11\" true\n"; + ss << "example: create_account_with_brain_key " + << "\"my really long brain key\" \"newaccount\" \"someaccount\" \"otheraccount\" true\n"; ss << "\n"; - ss << "This method should be used if you would like the wallet to generate new keys derived from the brain key.\n"; - ss << "The BRAIN_KEY will be used as the owner key, and the active key will be derived from the BRAIN_KEY. Use\n"; - ss << "register_account if you already know the keys you know the public keys that you would like to register.\n"; + ss << "This method should be used if you would like the wallet to generate new keys derived from the " + << "brain key.\n"; + ss << "The BRAIN_KEY will be used as the owner key, and the active key will be derived from the BRAIN_KEY. " + << "Use\n"; + ss << "register_account if you already know the keys you know the public keys that you would like to " + << "register.\n"; } else if( method == "register_account" ) { - ss << "usage: register_account ACCOUNT_NAME OWNER_PUBLIC_KEY ACTIVE_PUBLIC_KEY REGISTRAR REFERRER REFERRER_PERCENT BROADCAST\n\n"; - ss << "example: register_account \"newaccount\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"1.3.11\" \"1.3.11\" 50 true\n"; + ss << "usage: register_account ACCOUNT_NAME OWNER_PUBLIC_KEY ACTIVE_PUBLIC_KEY REGISTRAR " + << "REFERRER REFERRER_PERCENT BROADCAST\n\n"; + ss << "example: register_account \"newaccount\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" " + << "\"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"1.3.11\" \"1.3.11\" 50 true\n"; ss << "\n"; ss << "Use this method to register an account for which you do not know the private keys."; } @@ -4164,7 +4238,7 @@ bool wallet_api::load_wallet_file( string wallet_filename ) void wallet_api::quit() { - my->quit(); + my->quit(); } void wallet_api::save_wallet_file( string wallet_filename ) @@ -4223,14 +4297,20 @@ void wallet_api::set_password( string password ) lock(); } -vector< signed_transaction > wallet_api::import_balance( string name_or_id, const vector& wif_keys, bool broadcast ) +vector< signed_transaction > wallet_api::import_balance( + string name_or_id, + const vector& wif_keys, + bool broadcast ) { return my->import_balance( name_or_id, wif_keys, broadcast ); } namespace detail { -vector< signed_transaction > wallet_api_impl::import_balance( string name_or_id, const vector& wif_keys, bool broadcast ) +vector< signed_transaction > wallet_api_impl::import_balance( + string name_or_id, + const vector& wif_keys, + bool broadcast ) { try { FC_ASSERT(!is_locked()); const dynamic_global_property_object& dpo = _remote_db->get_dynamic_global_properties(); @@ -4325,7 +4405,7 @@ vector< signed_transaction > wallet_api_impl::import_balance( string name_or_id, tx.operations.reserve( ctx.ops.size() ); for( const balance_claim_operation& op : ctx.ops ) tx.operations.emplace_back( op ); - set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees ); + set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() ); tx.validate(); signed_transaction signed_tx = sign_transaction( tx, false ); for( const address& addr : ctx.addrs ) @@ -4380,7 +4460,8 @@ signed_transaction wallet_api::borrow_asset_ext( string seller_name, string amou bool broadcast) { FC_ASSERT(!is_locked()); - return my->borrow_asset_ext(seller_name, amount_to_sell, asset_symbol, amount_of_collateral, extensions, broadcast); + return my->borrow_asset_ext(seller_name, amount_to_sell, asset_symbol, + amount_of_collateral, extensions, broadcast); } signed_transaction wallet_api::cancel_order(object_id_type order_id, bool broadcast) @@ -4519,12 +4600,12 @@ blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_ke transfer_from_blind_operation from_blind; - auto fees = my->_remote_db->get_global_properties().parameters.current_fees; + auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees(); fc::optional asset_obj = get_asset(symbol); FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol)); auto amount = asset_obj->amount_from_string(amount_in); - from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); + from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); auto blind_in = asset_obj->amount_to_string( from_blind.fee + amount ); @@ -4539,7 +4620,7 @@ blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_ke from_blind.amount = amount; from_blind.blinding_factor = conf.outputs.back().decrypted_memo.blinding_factor; from_blind.inputs.push_back( {conf.outputs.back().decrypted_memo.commitment, authority() } ); - from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); + from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); idump( (from_blind) ); conf.trx.operations.push_back(from_blind); @@ -4562,7 +4643,9 @@ blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_ke conf_output.confirmation.encrypted_memo = change_output.confirmation.encrypted_memo; conf_output.confirmation_receipt = conf_output.confirmation; //try { - receive_blind_transfer( conf_output.confirmation_receipt, from_blind_account_key_or_label, "@"+to_account.name ); + receive_blind_transfer( conf_output.confirmation_receipt, + from_blind_account_key_or_label, + "@"+to_account.name ); //} catch ( ... ){} } @@ -4597,7 +4680,7 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, blind_transfer_operation blind_tr; blind_tr.outputs.resize(2); - auto fees = my->_remote_db->get_global_properties().parameters.current_fees; + auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees(); auto amount = asset_obj->amount_from_string(amount_in); @@ -4607,7 +4690,7 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, //auto from_priv_key = my->get_private_key( from_key ); - blind_tr.fee = fees->calculate_fee( blind_tr, asset_obj->options.core_exchange_rate ); + blind_tr.fee = fees.calculate_fee( blind_tr, asset_obj->options.core_exchange_rate ); vector used; @@ -4638,7 +4721,9 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } ); } - FC_ASSERT( total_amount >= amount+blind_tr.fee, "Insufficient Balance", ("available",total_amount)("amount",amount)("fee",blind_tr.fee) ); + FC_ASSERT( total_amount >= amount+blind_tr.fee, + "Insufficient Balance", + ("available",total_amount)("amount",amount)("fee",blind_tr.fee) ); auto one_time_key = fc::ecc::private_key::generate(); auto secret = one_time_key.get_shared_secret( to_key ); @@ -4697,10 +4782,11 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, conf_output.decrypted_memo.amount = change; conf_output.decrypted_memo.blinding_factor = change_blind_factor; conf_output.decrypted_memo.commitment = change_out.commitment; - conf_output.decrypted_memo.check = from_secret._hash[0]; + conf_output.decrypted_memo.check = from_secret._hash[0].value(); conf_output.confirmation.one_time_key = one_time_key.get_public_key(); conf_output.confirmation.to = from_key; - conf_output.confirmation.encrypted_memo = fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) ); + conf_output.confirmation.encrypted_memo = + fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) ); conf_output.auth = change_out.owner; conf_output.confirmation_receipt = conf_output.confirmation; @@ -4715,7 +4801,7 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, conf_output.decrypted_memo.amount = amount; conf_output.decrypted_memo.blinding_factor = blind_factor; conf_output.decrypted_memo.commitment = to_out.commitment; - conf_output.decrypted_memo.check = secret._hash[0]; + conf_output.decrypted_memo.check = secret._hash[0].value(); conf_output.confirmation.one_time_key = one_time_key.get_public_key(); conf_output.confirmation.to = to_key; conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) ); @@ -4803,10 +4889,11 @@ blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name conf_output.decrypted_memo.amount = amount; conf_output.decrypted_memo.blinding_factor = blind_factor; conf_output.decrypted_memo.commitment = out.commitment; - conf_output.decrypted_memo.check = secret._hash[0]; + conf_output.decrypted_memo.check = secret._hash[0].value(); conf_output.confirmation.one_time_key = one_time_key.get_public_key(); conf_output.confirmation.to = to_key; - conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) ); + conf_output.confirmation.encrypted_memo = + fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) ); conf_output.confirmation_receipt = conf_output.confirmation; confirm.outputs.push_back( conf_output ); @@ -4821,7 +4908,7 @@ blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } ); confirm.trx.operations.push_back( bop ); - my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.current_fees); + my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.get_current_fees()); confirm.trx.validate(); confirm.trx = sign_transaction(confirm.trx, broadcast); @@ -4829,7 +4916,9 @@ blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name { for( const auto& out : confirm.outputs ) { - try { receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name ); } catch ( ... ){} + try { + receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name ); + } catch ( ... ){} } } @@ -4926,7 +5015,8 @@ vector wallet_api::blind_history( string key_or_account ) if( r.from_key == pub_key || r.to_key == pub_key ) result.push_back( r ); } - std::sort( result.begin(), result.end(), [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } ); + std::sort( result.begin(), result.end(), + [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } ); return result; } @@ -4945,7 +5035,9 @@ signed_block_with_info::signed_block_with_info( const signed_block& block ) transaction_ids.push_back( tx.id() ); } -vesting_balance_object_with_info::vesting_balance_object_with_info( const vesting_balance_object& vbo, fc::time_point_sec now ) +vesting_balance_object_with_info::vesting_balance_object_with_info( + const vesting_balance_object& vbo, + fc::time_point_sec now ) : vesting_balance_object( vbo ) { allowed_withdraw = get_allowed_withdraw( now ); diff --git a/programs/build_helpers/member_enumerator.cpp b/programs/build_helpers/member_enumerator.cpp index 9eda6e3ab5..cce25a5f4a 100644 --- a/programs/build_helpers/member_enumerator.cpp +++ b/programs/build_helpers/member_enumerator.cpp @@ -18,8 +18,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -#include -#include +#include +#include #include #include #include diff --git a/programs/build_helpers/set_sonar_branch b/programs/build_helpers/set_sonar_branch new file mode 100755 index 0000000000..aed0d722d5 --- /dev/null +++ b/programs/build_helpers/set_sonar_branch @@ -0,0 +1,82 @@ +#!/bin/sh + +# Relevant variables set by travis: +# TRAVIS_BRANCH: +# * for push builds, or builds not triggered by a pull request, this is the +# name of the branch. +# * for builds triggered by a pull request this is the name of the branch +# targeted by the pull request. +# * for builds triggered by a tag, this is the same as the name of the tag +# (see TRAVIS_TAG). +# TRAVIS_PULL_REQUEST: The pull request number if the current job is a pull +# request, “false” if it’s not a pull request. +# TRAVIS_TAG: If the current build is for a git tag, this variable is set to +# the tag’s name. + +if [ "$#" != 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +clear_branch () { + sed -i '/sonar\.branch/d' "$1" +} + +TARGET= +FETCH= + +if [ -n "$TRAVIS_PULL_REQUEST" -a "$TRAVIS_PULL_REQUEST" != false ]; then + # PRs work per default + echo "Detected PR '$TRAVIS_PULL_REQUEST'" + clear_branch "$1" + FETCH="$TRAVIS_BRANCH" +elif [ -n "$TRAVIS_TAG" ]; then + # Tag build is either master or testnet + echo "Detected tag '$TRAVIS_TAG'" + clear_branch "$1" + case "$TRAVIS_TAG" in + *test*) TARGET=testnet; FETCH=testnet; ;; + *) FETCH=master; ;; + esac +else + case "$TRAVIS_BRANCH" in + master|develop|testnet|next_hardfork) + # Long-lived branches stand for themselves + echo "Detected long-lived branch '$TRAVIS_BRANCH'" + clear_branch "$1" + FETCH="$TRAVIS_BRANCH" + ;; + *test*release*) + # Testnet release branch will be merged into testnet + echo "Detected testnet release branch '$TRAVIS_BRANCH'" + clear_branch "$1" + TARGET=testnet + FETCH=testnet + ;; + *release*) + # Release branch will be merged into default (master) + echo "Detected release branch '$TRAVIS_BRANCH'" + clear_branch "$1" + FETCH=master + ;; + *) + # All other branches should have sonar.branch.target in their + # sonar.properties, leave it unchanged + echo "Detected normal branch '$TRAVIS_BRANCH'" + FETCH="$( grep 'sonar\.branch\.target' "$1" | sed 's=^.*[:=] *==' )" + esac +fi + +echo "Branch target '$TARGET', fetch target '$FETCH'" + +if [ -n "$TARGET" ]; then + echo "sonar.branch.target=$TARGET" >>"$1" +fi +#if [ -n "$FETCH" ]; then + # Unfortunately this leads to sonar failing. Apparently it needs a full + # clone, not a shallow one. Since our repo is somewhat large and this is + # only required for blame annotations, disabled for now. + #git fetch --depth=50 origin "$FETCH:$FETCH" +#fi + +exit 0 diff --git a/programs/cli_wallet/main.cpp b/programs/cli_wallet/main.cpp index 2a949417ae..630256615a 100644 --- a/programs/cli_wallet/main.cpp +++ b/programs/cli_wallet/main.cpp @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -67,6 +66,63 @@ using namespace graphene::wallet; using namespace std; namespace bpo = boost::program_options; +fc::log_level string_to_level(string level) +{ + fc::log_level result; + if(level == "info") + result = fc::log_level::info; + else if(level == "debug") + result = fc::log_level::debug; + else if(level == "warn") + result = fc::log_level::warn; + else if(level == "error") + result = fc::log_level::error; + else if(level == "all") + result = fc::log_level::all; + else + FC_THROW("Log level not allowed. Allowed levels are info, debug, warn, error and all."); + + return result; +} + +void setup_logging(string console_level, bool file_logger, string file_level, string file_name) +{ + fc::logging_config cfg; + + // console logger + fc::console_appender::config console_appender_config; + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::debug, + fc::console_appender::color::green)); + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::warn, + fc::console_appender::color::brown)); + console_appender_config.level_colors.emplace_back( + fc::console_appender::level_color(fc::log_level::error, + fc::console_appender::color::red)); + cfg.appenders.push_back(fc::appender_config( "default", "console", fc::variant(console_appender_config, 20))); + cfg.loggers = { fc::logger_config("default"), fc::logger_config( "rpc") }; + cfg.loggers.front().level = string_to_level(console_level); + cfg.loggers.front().appenders = {"default"}; + + // file logger + if(file_logger) { + fc::path data_dir; + fc::path log_dir = data_dir / "cli_wallet_logs"; + fc::file_appender::config ac; + ac.filename = log_dir / file_name; + ac.flush = true; + ac.rotate = true; + ac.rotation_interval = fc::hours( 1 ); + ac.rotation_limit = fc::days( 1 ); + cfg.appenders.push_back(fc::appender_config( "rpc", "file", fc::variant(ac, 5))); + cfg.loggers.back().level = string_to_level(file_level); + cfg.loggers.back().appenders = {"rpc"}; + fc::configure_logging( cfg ); + ilog ("Logging RPC to file: " + (ac.filename).preferred_string()); + } +} + int main( int argc, char** argv ) { try { @@ -77,17 +133,26 @@ int main( int argc, char** argv ) ("server-rpc-endpoint,s", bpo::value()->implicit_value("ws://127.0.0.1:8090"), "Server websocket RPC endpoint") ("server-rpc-user,u", bpo::value(), "Server Username") ("server-rpc-password,p", bpo::value(), "Server Password") - ("rpc-endpoint,r", bpo::value()->implicit_value("127.0.0.1:8091"), "Endpoint for wallet websocket RPC to listen on") - ("rpc-tls-endpoint,t", bpo::value()->implicit_value("127.0.0.1:8092"), "Endpoint for wallet websocket TLS RPC to listen on") - ("rpc-tls-certificate,c", bpo::value()->implicit_value("server.pem"), "PEM certificate for wallet websocket TLS RPC") - ("rpc-http-endpoint,H", bpo::value()->implicit_value("127.0.0.1:8093"), "Endpoint for wallet HTTP RPC to listen on") + ("rpc-endpoint,r", bpo::value()->implicit_value("127.0.0.1:8091"), + "Endpoint for wallet websocket RPC to listen on (DEPRECATED, use rpc-http-endpoint instead)") + ("rpc-tls-endpoint,t", bpo::value()->implicit_value("127.0.0.1:8092"), + "Endpoint for wallet websocket TLS RPC to listen on") + ("rpc-tls-certificate,c", bpo::value()->implicit_value("server.pem"), + "PEM certificate for wallet websocket TLS RPC") + ("rpc-http-endpoint,H", bpo::value()->implicit_value("127.0.0.1:8093"), + "Endpoint for wallet HTTP and websocket RPC to listen on") ("daemon,d", "Run the wallet in daemon mode" ) ("wallet-file,w", bpo::value()->implicit_value("wallet.json"), "wallet to load") ("chain-id", bpo::value(), "chain ID to connect to") ("suggest-brain-key", "Suggest a safe brain key to use for creating your account") + ("logs-rpc-console-level", bpo::value()->default_value("info"), + "Level of console logging. Allowed levels: info, debug, warn, error, all") + ("logs-rpc-file", bpo::value()->default_value(false), "Turn on/off file logging") + ("logs-rpc-file-level", bpo::value()->default_value("debug"), + "Level of file logging. Allowed levels: info, debug, warn, error, all") + ("logs-rpc-file-name", bpo::value()->default_value("rpc.log"), "File name for file rpc logs") ("version,v", "Display version information"); - bpo::variables_map options; bpo::store( bpo::parse_command_line(argc, argv, opts), options ); @@ -115,28 +180,10 @@ int main( int argc, char** argv ) return 0; } - fc::path data_dir; - fc::logging_config cfg; - fc::path log_dir = data_dir / "logs"; - - fc::file_appender::config ac; - ac.filename = log_dir / "rpc" / "rpc.log"; - ac.flush = true; - ac.rotate = true; - ac.rotation_interval = fc::hours( 1 ); - ac.rotation_limit = fc::days( 1 ); - - std::cout << "Logging RPC to file: " << (data_dir / ac.filename).preferred_string() << "\n"; - - cfg.appenders.push_back(fc::appender_config( "default", "console", fc::variant(fc::console_appender::config(), 20))); - cfg.appenders.push_back(fc::appender_config( "rpc", "file", fc::variant(ac, 5))); - - cfg.loggers = { fc::logger_config("default"), fc::logger_config( "rpc") }; - cfg.loggers.front().level = fc::log_level::info; - cfg.loggers.front().appenders = {"default"}; - cfg.loggers.back().level = fc::log_level::debug; - cfg.loggers.back().appenders = {"rpc"}; + setup_logging(options.at("logs-rpc-console-level").as(),options.at("logs-rpc-file").as(), + options.at("logs-rpc-file-level").as(), options.at("logs-rpc-file-name").as()); + // key generation fc::ecc::private_key committee_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key"))); idump( (key_to_wif( committee_private_key ) ) ); @@ -193,7 +240,7 @@ int main( int argc, char** argv ) fc::http::websocket_client client; idump((wdata.ws_server)); auto con = client.connect( wdata.ws_server ); - auto apic = std::make_shared(*con, GRAPHENE_MAX_NESTED_OBJECTS); + auto apic = std::make_shared(con, GRAPHENE_MAX_NESTED_OBJECTS); auto remote_api = apic->get_remote_api< login_api >(1); edump((wdata.ws_user)(wdata.ws_password) ); @@ -205,36 +252,16 @@ int main( int argc, char** argv ) fc::api wapi(wapiptr); - auto wallet_cli = std::make_shared( GRAPHENE_MAX_NESTED_OBJECTS ); - for( auto& name_formatter : wapiptr->get_result_formatters() ) - wallet_cli->format_result( name_formatter.first, name_formatter.second ); - - boost::signals2::scoped_connection closed_connection(con->closed.connect([wallet_cli]{ - cerr << "Server has disconnected us.\n"; - wallet_cli->stop(); - })); - (void)(closed_connection); - - if( wapiptr->is_new() ) - { - std::cout << "Please use the set_password method to initialize a new wallet before continuing\n"; - wallet_cli->set_prompt( "new >>> " ); - } else - wallet_cli->set_prompt( "locked >>> " ); - - boost::signals2::scoped_connection locked_connection(wapiptr->lock_changed.connect([&](bool locked) { - wallet_cli->set_prompt( locked ? "locked >>> " : "unlocked >>> " ); - })); - - auto _websocket_server = std::make_shared(); + std::shared_ptr _websocket_server; if( options.count("rpc-endpoint") ) { + _websocket_server = std::make_shared(); _websocket_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){ - auto wsc = std::make_shared(*c, GRAPHENE_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); c->set_session_data( wsc ); }); - ilog( "Listening for incoming RPC requests on ${p}", ("p", options.at("rpc-endpoint").as() )); + ilog( "Listening for incoming HTTP and WS RPC requests on ${p}", ("p", options.at("rpc-endpoint").as() )); _websocket_server->listen( fc::ip::endpoint::from_string(options.at("rpc-endpoint").as()) ); _websocket_server->start_accept(); } @@ -243,76 +270,127 @@ int main( int argc, char** argv ) if( options.count( "rpc-tls-certificate" ) ) cert_pem = options.at("rpc-tls-certificate").as(); - auto _websocket_tls_server = std::make_shared(cert_pem); + std::shared_ptr _websocket_tls_server; if( options.count("rpc-tls-endpoint") ) { + _websocket_tls_server = std::make_shared(cert_pem); _websocket_tls_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){ - auto wsc = std::make_shared(*c, GRAPHENE_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); c->set_session_data( wsc ); }); - ilog( "Listening for incoming TLS RPC requests on ${p}", ("p", options.at("rpc-tls-endpoint").as() )); + ilog( "Listening for incoming HTTPS and WSS RPC requests on ${p}", + ("p", options.at("rpc-tls-endpoint").as()) ); _websocket_tls_server->listen( fc::ip::endpoint::from_string(options.at("rpc-tls-endpoint").as()) ); _websocket_tls_server->start_accept(); } - auto _http_server = std::make_shared(); + std::shared_ptr _http_ws_server; if( options.count("rpc-http-endpoint" ) ) { - ilog( "Listening for incoming HTTP RPC requests on ${p}", ("p", options.at("rpc-http-endpoint").as() ) ); - _http_server->listen( fc::ip::endpoint::from_string( options.at( "rpc-http-endpoint" ).as() ) ); - // - // due to implementation, on_request() must come AFTER listen() - // - _http_server->on_request( - [&wapi]( const fc::http::request& req, const fc::http::server::response& resp ) - { - std::shared_ptr< fc::rpc::http_api_connection > conn = - std::make_shared< fc::rpc::http_api_connection >( GRAPHENE_MAX_NESTED_OBJECTS ); - conn->register_api( wapi ); - conn->on_request( req, resp ); - } ); + _http_ws_server = std::make_shared(); + ilog( "Listening for incoming HTTP and WS RPC requests on ${p}", + ("p", options.at("rpc-http-endpoint").as()) ); + _http_ws_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){ + auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); + wsc->register_api(wapi); + c->set_session_data( wsc ); + }); + _http_ws_server->listen( fc::ip::endpoint::from_string(options.at("rpc-http-endpoint").as()) ); + _http_ws_server->start_accept(); } if( !options.count( "daemon" ) ) { - wallet_cli->register_api( wapi ); - wallet_cli->start(); + auto wallet_cli = std::make_shared( GRAPHENE_MAX_NESTED_OBJECTS ); + + wallet_cli->set_regex_secret("\\s*(unlock|set_password)\\s*"); - fc::set_signal_handler([](int signal) { - ilog( "Captured SIGINT not in daemon mode" ); - fclose(stdin); - }, SIGINT); + for( auto& name_formatter : wapiptr->get_result_formatters() ) + wallet_cli->format_result( name_formatter.first, name_formatter.second ); - fc::set_signal_handler([](int signal) { - ilog( "Captured SIGTERM not in daemon mode" ); - fclose(stdin); - }, SIGTERM); + if( wapiptr->is_new() ) + { + std::cout << "Please use the set_password method to initialize a new wallet before continuing\n"; + wallet_cli->set_prompt( "new >>> " ); + } + else + wallet_cli->set_prompt( "locked >>> " ); + + boost::signals2::scoped_connection locked_connection( wapiptr->lock_changed.connect( + [wallet_cli](bool locked) { + wallet_cli->set_prompt( locked ? "locked >>> " : "unlocked >>> " ); + })); + + auto sig_set = fc::set_signal_handler( [wallet_cli](int signal) { + ilog( "Captured SIGINT not in daemon mode, exiting" ); + fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler + wallet_cli->cancel(); + }, SIGINT ); + + fc::set_signal_handler( [wallet_cli,sig_set](int signal) { + ilog( "Captured SIGTERM not in daemon mode, exiting" ); + sig_set->cancel(); + fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler + wallet_cli->cancel(); + }, SIGTERM ); +#ifdef SIGQUIT + fc::set_signal_handler( [wallet_cli,sig_set](int signal) { + ilog( "Captured SIGQUIT not in daemon mode, exiting" ); + sig_set->cancel(); + fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler + wallet_cli->cancel(); + }, SIGQUIT ); +#endif + boost::signals2::scoped_connection closed_connection( con->closed.connect( [wallet_cli,sig_set] { + elog( "Server has disconnected us." ); + sig_set->cancel(); + fc::set_signal_handler( [](int sig) {}, SIGINT ); // reinstall an empty SIGINT handler + wallet_cli->cancel(); + })); + wallet_cli->register_api( wapi ); + wallet_cli->start(); wallet_cli->wait(); + + locked_connection.disconnect(); + closed_connection.disconnect(); } else { - fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); - fc::set_signal_handler([&exit_promise](int signal) { - exit_promise->set_value(signal); - }, SIGINT); + fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); + + fc::set_signal_handler( [&exit_promise](int signal) { + ilog( "Captured SIGINT in daemon mode, exiting" ); + exit_promise->set_value(signal); + }, SIGINT ); + + fc::set_signal_handler( [&exit_promise](int signal) { + ilog( "Captured SIGTERM in daemon mode, exiting" ); + exit_promise->set_value(signal); + }, SIGTERM ); +#ifdef SIGQUIT + fc::set_signal_handler( [&exit_promise](int signal) { + ilog( "Captured SIGQUIT in daemon mode, exiting" ); + exit_promise->set_value(signal); + }, SIGQUIT ); +#endif + boost::signals2::scoped_connection closed_connection( con->closed.connect( [&exit_promise] { + elog( "Server has disconnected us." ); + exit_promise->set_value(0); + })); - fc::set_signal_handler([&exit_promise](int signal) { - exit_promise->set_value(signal); - }, SIGTERM); + ilog( "Entering Daemon Mode, ^C to exit" ); + exit_promise->wait(); - ilog( "Entering Daemon Mode, ^C to exit" ); - exit_promise->wait(); + closed_connection.disconnect(); } wapi->save_wallet_file(wallet_file.generic_string()); - locked_connection.disconnect(); - closed_connection.disconnect(); } catch ( const fc::exception& e ) { - std::cout << e.to_detail_string() << "\n"; + std::cerr << e.to_detail_string() << "\n"; return -1; } return 0; diff --git a/programs/genesis_util/convert_address.cpp b/programs/genesis_util/convert_address.cpp index 7f73acdb1c..f8224cc8e8 100644 --- a/programs/genesis_util/convert_address.cpp +++ b/programs/genesis_util/convert_address.cpp @@ -26,13 +26,13 @@ * Convert BTC / PTS addresses to a Graphene address. */ -#include -#include +#include +#include #include #include -using namespace graphene::chain; +using namespace graphene::protocol; int main(int argc, char** argv) { diff --git a/programs/genesis_util/genesis_update.cpp b/programs/genesis_util/genesis_update.cpp index 7e251de8a7..d35547bfde 100644 --- a/programs/genesis_util/genesis_update.cpp +++ b/programs/genesis_util/genesis_update.cpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/programs/genesis_util/get_dev_key.cpp b/programs/genesis_util/get_dev_key.cpp index ea7cdf9f0e..4fc6a42f2c 100644 --- a/programs/genesis_util/get_dev_key.cpp +++ b/programs/genesis_util/get_dev_key.cpp @@ -28,8 +28,8 @@ #include #include -#include -#include +#include +#include #include #ifndef WIN32 @@ -73,10 +73,10 @@ int main( int argc, char** argv ) auto show_key = [&comma]( const fc::ecc::private_key& priv_key ) { fc::limited_mutable_variant_object mvo(5); - graphene::chain::public_key_type pub_key = priv_key.get_public_key(); + graphene::protocol::public_key_type pub_key = priv_key.get_public_key(); mvo( "private_key", graphene::utilities::key_to_wif( priv_key ) ) ( "public_key", std::string( pub_key ) ) - ( "address", graphene::chain::address( pub_key ) ) + ( "address", graphene::protocol::address( pub_key ) ) ; if( comma ) std::cout << ",\n"; diff --git a/programs/js_operation_serializer/main.cpp b/programs/js_operation_serializer/main.cpp index 097c8616f8..94e5057d7c 100644 --- a/programs/js_operation_serializer/main.cpp +++ b/programs/js_operation_serializer/main.cpp @@ -21,8 +21,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include +#include +#include #include #include @@ -107,29 +107,30 @@ struct js_name> { static std::string name(){ return "fixed_array "+ fc::to_string(N) + ", " + remove_namespace(fc::get_typename::name()); }; }; -template struct js_name> { static std::string name(){ return "bytes "+ fc::to_string(N); }; }; -template struct js_name> { static std::string name(){ return "bytes "+ fc::to_string(N); }; }; -template struct js_name< fc::optional > { static std::string name(){ return "optional " + js_name::name(); } }; -template struct js_name< fc::smart_ref > { static std::string name(){ return js_name::name(); } }; +template struct js_name> { static std::string name(){ return "bytes("+ fc::to_string(N) + ")"; }; }; +template struct js_name> { static std::string name(){ return "bytes("+ fc::to_string(N) + ")"; }; }; +template struct js_name< fc::optional > { static std::string name(){ return "optional(" + js_name::name() + ")"; } }; template<> struct js_name< object_id_type > { static std::string name(){ return "object_id_type"; } }; -template struct js_name< fc::flat_set > { static std::string name(){ return "set " + js_name::name(); } }; -template struct js_name< std::vector > { static std::string name(){ return "array " + js_name::name(); } }; +template struct js_name< fc::flat_set > { static std::string name(){ return "set(" + js_name::name() + ")"; } }; +template struct js_name< std::vector > { static std::string name(){ return "array(" + js_name::name() + ")"; } }; template struct js_name< fc::safe > { static std::string name(){ return js_name::name(); } }; template<> struct js_name< std::vector > { static std::string name(){ return "bytes()"; } }; -template<> struct js_name { static std::string name(){ return "bytes 20"; } }; -template<> struct js_name { static std::string name(){ return "bytes 28"; } }; -template<> struct js_name { static std::string name(){ return "bytes 32"; } }; +template<> struct js_name { static std::string name(){ return "bytes(20)"; } }; +template<> struct js_name { static std::string name(){ return "bytes(20)"; } }; +template<> struct js_name { static std::string name(){ return "bytes(28)"; } }; +template<> struct js_name { static std::string name(){ return "bytes(32)"; } }; template<> struct js_name { static std::string name(){ return "varuint64"; } }; template<> struct js_name< vote_id_type > { static std::string name(){ return "vote_id"; } }; template<> struct js_name< time_point_sec > { static std::string name(){ return "time_point_sec"; } }; -template -struct js_name > +template +struct js_name > { static std::string name(){ - return "protocol_id_type \"" + remove_namespace(fc::get_typename::name()) + "\""; + return "protocol_id_type(\"" + + remove_namespace(fc::get_typename>>::name()) + "\")"; }; }; @@ -137,10 +138,10 @@ struct js_name > template struct js_name< std::set > { static std::string name(){ return "set " + js_name::name(); } }; template -struct js_name< std::map > { static std::string name(){ return "map (" + js_name::name() + "), (" + js_name::name() +")"; } }; +struct js_name< std::map > { static std::string name(){ return "map(" + js_name::name() + ", " + js_name::name() +")"; } }; template -struct js_name< fc::flat_map > { static std::string name(){ return "map (" + js_name::name() + "), (" + js_name::name() +")"; } }; +struct js_name< fc::flat_map > { static std::string name(){ return "map(" + js_name::name() + ", " + js_name::name() +")"; } }; template struct js_sv_name; @@ -149,7 +150,7 @@ template struct js_sv_name { static std::string name(){ return "\n " + js_name::name(); } }; template -struct js_sv_name { static std::string name(){ return "\n " + js_name::name() +" " + js_sv_name::name(); } }; +struct js_sv_name { static std::string name(){ return "\n " + js_name::name() +"," + js_sv_name::name(); } }; template struct js_name< fc::static_variant > @@ -157,7 +158,7 @@ struct js_name< fc::static_variant > static std::string name( std::string n = ""){ static const std::string name = n; if( name == "" ) - return "static_variant [" + js_sv_name::name() + "\n]"; + return "static_variant([" + js_sv_name::name() + "\n]);"; else return name; } }; @@ -167,7 +168,7 @@ struct js_name< fc::static_variant<> > static std::string name( std::string n = ""){ static const std::string name = n; if( name == "" ) - return "static_variant []"; + return "static_variant([]);"; else return name; } }; @@ -209,7 +210,7 @@ class serialize_member_visitor template void operator()( const char* name )const { - std::cout << " " << name <<": " << js_name::name() <<"\n"; + std::cout << " " << name <<": " << js_name::name() <<",\n"; } }; @@ -237,14 +238,6 @@ struct serializer,false> static void generate() {} }; -template -struct serializer,false> -{ - static void init() { - serializer::init(); } - static void generate() {} -}; - template<> struct serializer,false> { @@ -280,8 +273,8 @@ struct serializer,false> static void generate(){} }; -template -struct serializer< graphene::db::object_id ,true> +template +struct serializer< graphene::db::object_id ,true> { static void init() {} static void generate() {} @@ -308,7 +301,7 @@ struct serializer< fc::static_variant, false > static void generate() { - std::cout << js_name>::name() << " = static_variant [" + js_sv_name::name() + "\n]\n\n"; + std::cout << "var " << js_name>::name() << " = static_variant([" + js_sv_name::name() + "\n]);\n\n"; } }; template<> @@ -327,7 +320,7 @@ struct serializer< fc::static_variant<>, false > static void generate() { - std::cout << js_name>::name() << " = static_variant []\n\n"; + std::cout << js_name>::name() << " = static_variant([]);\n\n"; } }; @@ -360,13 +353,11 @@ struct serializer { auto name = remove_namespace( js_name::name() ); if( name == "int64" ) return; - std::cout << "" << name - << " = new Serializer( \n" - << " \"" + name + "\"\n"; - + std::cout << "export const " << name + << " = new Serializer(" + << "\"" + name + "\", {\n"; fc::reflector::visit( serialize_member_visitor() ); - - std::cout <<")\n\n"; + std::cout <<"});\n\n"; } }; diff --git a/programs/network_mapper/network_mapper.cpp b/programs/network_mapper/network_mapper.cpp index 2ecc724d8c..b00439467a 100644 --- a/programs/network_mapper/network_mapper.cpp +++ b/programs/network_mapper/network_mapper.cpp @@ -74,8 +74,9 @@ class peer_probe : public graphene::net::peer_connection_delegate { graphene::net::message_hash_type message_hash = received_message.id(); dlog( "handling message ${type} ${hash} size ${size} from peer ${endpoint}", - ( "type", graphene::net::core_message_type_enum(received_message.msg_type ) )("hash", message_hash )("size", received_message.size )("endpoint", originating_peer->get_remote_endpoint() ) ); - switch ( received_message.msg_type ) + ( "type", graphene::net::core_message_type_enum(received_message.msg_type.value() ) )("hash", message_hash ) + ("size", received_message.size )("endpoint", originating_peer->get_remote_endpoint() ) ); + switch ( received_message.msg_type.value() ) { case graphene::net::core_message_type_enum::hello_message_type: on_hello_message( originating_peer, received_message.as() ); diff --git a/programs/size_checker/main.cpp b/programs/size_checker/main.cpp index 72d7d85f85..f4fb956341 100644 --- a/programs/size_checker/main.cpp +++ b/programs/size_checker/main.cpp @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -35,7 +35,7 @@ #include #include -using namespace graphene::chain; +using namespace graphene::protocol; vector< fc::variant_object > g_op_types; @@ -68,7 +68,7 @@ int main( int argc, char** argv ) { try { - graphene::chain::operation op; + graphene::protocol::operation op; vector witnesses; witnesses.resize(50); diff --git a/sonar-project.properties b/sonar-project.properties index a4487be06e..fcf8c487b4 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -12,3 +12,6 @@ sonar.sources=libraries,programs sonar.cfamily.build-wrapper-output=bw-output sonar.cfamily.gcov.reportsPath=. sonar.cfamily.threads=2 + +# should be changed in hardfork branch and removed in release branches +sonar.branch.target=develop diff --git a/tests/benchmarks/main.cpp b/tests/benchmarks/main.cpp index 706318d62e..479fb3371d 100644 --- a/tests/benchmarks/main.cpp +++ b/tests/benchmarks/main.cpp @@ -23,3 +23,4 @@ */ #define BOOST_TEST_MODULE "C++ Benchmarks for Graphene Blockchain Database" #include + diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index b091f298fc..ccff75736a 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -38,6 +38,8 @@ #include #include +#include + #ifdef _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 @@ -78,6 +80,9 @@ int sockQuit(void) #include "../common/genesis_file_util.hpp" +using std::exception; +using std::cerr; + #define INVOKE(test) ((struct test*)this)->test_method(); ////// @@ -126,7 +131,7 @@ std::shared_ptr start_application(fc::temp_directory #endif server_port_number = get_available_port(); cfg.emplace( - "rpc-endpoint", + "rpc-endpoint", boost::program_options::variable_value(string("127.0.0.1:" + std::to_string(server_port_number)), false) ); cfg.emplace("genesis-json", boost::program_options::variable_value(create_genesis_file(app_dir), false)); @@ -201,8 +206,8 @@ class client_connection // constructor ///////// client_connection( - std::shared_ptr app, - const fc::temp_directory& data_dir, + std::shared_ptr app, + const fc::temp_directory& data_dir, const int server_port_number ) { @@ -212,7 +217,8 @@ class client_connection wallet_data.ws_password = ""; websocket_connection = websocket_client.connect( wallet_data.ws_server ); - api_connection = std::make_shared(*websocket_connection, GRAPHENE_MAX_NESTED_OBJECTS); + api_connection = std::make_shared( websocket_connection, + GRAPHENE_MAX_NESTED_OBJECTS ); remote_login_api = api_connection->get_remote_api< graphene::app::login_api >(1); BOOST_CHECK(remote_login_api->login( wallet_data.ws_user, wallet_data.ws_password ) ); @@ -233,6 +239,11 @@ class client_connection })); (void)(closed_connection); } + ~client_connection() + { + // wait for everything to finish up + fc::usleep(fc::milliseconds(500)); + } public: fc::http::websocket_client websocket_client; graphene::wallet::wallet_data wallet_data; @@ -251,16 +262,26 @@ class client_connection struct cli_fixture { + class dummy + { + public: + ~dummy() + { + // wait for everything to finish up + fc::usleep(fc::milliseconds(500)); + } + }; + dummy dmy; int server_port_number; fc::temp_directory app_dir; std::shared_ptr app1; client_connection con; std::vector nathan_keys; - cli_fixture() : + cli_fixture() : server_port_number(0), app_dir( graphene::utilities::temp_directory_path() ), - app1( start_application(app_dir, server_port_number) ), + app1( start_application(app_dir, server_port_number) ), con( app1, app_dir, server_port_number ), nathan_keys( {"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"} ) { @@ -269,7 +290,7 @@ struct cli_fixture using namespace graphene::chain; using namespace graphene::app; - try + try { BOOST_TEST_MESSAGE("Setting wallet password"); con.wallet_api_ptr->set_password("supersecret"); @@ -291,7 +312,7 @@ struct cli_fixture // wait for everything to finish up fc::usleep(fc::seconds(1)); - + app1->shutdown(); #ifdef _WIN32 sockQuit(); @@ -341,10 +362,10 @@ BOOST_FIXTURE_TEST_CASE( upgrade_nathan_account, cli_fixture ) nathan_acct_after_upgrade = con.wallet_api_ptr->get_account("nathan"); // verify that the upgrade was successful - BOOST_CHECK_PREDICATE( - std::not_equal_to(), + BOOST_CHECK_PREDICATE( + std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch()) - (nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) + (nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); } catch( fc::exception& e ) { @@ -431,6 +452,132 @@ BOOST_FIXTURE_TEST_CASE( cli_vote_for_2_witnesses, cli_fixture ) } } +BOOST_FIXTURE_TEST_CASE( cli_get_signed_transaction_signers, cli_fixture ) +{ + try + { + INVOKE(upgrade_nathan_account); + + // register account and transfer funds + const auto test_bki = con.wallet_api_ptr->suggest_brain_key(); + con.wallet_api_ptr->register_account( + "test", test_bki.pub_key, test_bki.pub_key, "nathan", "nathan", 0, true + ); + con.wallet_api_ptr->transfer("nathan", "test", "1000", "1.3.0", "", true); + + // import key and save wallet + BOOST_CHECK(con.wallet_api_ptr->import_key("test", test_bki.wif_priv_key)); + con.wallet_api_ptr->save_wallet_file(con.wallet_filename); + + // create transaction and check expected result + auto signed_trx = con.wallet_api_ptr->transfer("test", "nathan", "10", "1.3.0", "", true); + + const auto &test_acc = con.wallet_api_ptr->get_account("test"); + flat_set expected_signers = {test_bki.pub_key}; + vector > expected_key_refs{{test_acc.id, test_acc.id}}; + + auto signers = con.wallet_api_ptr->get_transaction_signers(signed_trx); + BOOST_CHECK(signers == expected_signers); + + auto key_refs = con.wallet_api_ptr->get_key_references({expected_signers.begin(), expected_signers.end()}); + BOOST_CHECK(key_refs == expected_key_refs); + + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_FIXTURE_TEST_CASE( cli_get_available_transaction_signers, cli_fixture ) +{ + try + { + INVOKE(upgrade_nathan_account); + + // register account + const auto test_bki = con.wallet_api_ptr->suggest_brain_key(); + con.wallet_api_ptr->register_account( + "test", test_bki.pub_key, test_bki.pub_key, "nathan", "nathan", 0, true + ); + const auto &test_acc = con.wallet_api_ptr->get_account("test"); + + // create and sign transaction + signed_transaction trx; + trx.operations = {transfer_operation()}; + + // sign with test key + const auto test_privkey = wif_to_key( test_bki.wif_priv_key ); + BOOST_REQUIRE( test_privkey ); + trx.sign( *test_privkey, con.wallet_data.chain_id ); + + // sign with other keys + const auto privkey_1 = fc::ecc::private_key::generate(); + trx.sign( privkey_1, con.wallet_data.chain_id ); + + const auto privkey_2 = fc::ecc::private_key::generate(); + trx.sign( privkey_2, con.wallet_data.chain_id ); + + // verify expected result + flat_set expected_signers = {test_bki.pub_key, + privkey_1.get_public_key(), + privkey_2.get_public_key()}; + + auto signers = con.wallet_api_ptr->get_transaction_signers(trx); + BOOST_CHECK(signers == expected_signers); + + // blockchain has no references to unknown accounts (privkey_1, privkey_2) + // only test account available + vector > expected_key_refs; + expected_key_refs.push_back(flat_set()); + expected_key_refs.push_back(flat_set()); + expected_key_refs.push_back({test_acc.id}); + + auto key_refs = con.wallet_api_ptr->get_key_references({expected_signers.begin(), expected_signers.end()}); + std::sort(key_refs.begin(), key_refs.end()); + + BOOST_CHECK(key_refs == expected_key_refs); + + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_FIXTURE_TEST_CASE( cli_cant_get_signers_from_modified_transaction, cli_fixture ) +{ + try + { + INVOKE(upgrade_nathan_account); + + // register account + const auto test_bki = con.wallet_api_ptr->suggest_brain_key(); + con.wallet_api_ptr->register_account( + "test", test_bki.pub_key, test_bki.pub_key, "nathan", "nathan", 0, true + ); + + // create and sign transaction + signed_transaction trx; + trx.operations = {transfer_operation()}; + + // sign with test key + const auto test_privkey = wif_to_key( test_bki.wif_priv_key ); + BOOST_REQUIRE( test_privkey ); + trx.sign( *test_privkey, con.wallet_data.chain_id ); + + // modify transaction (MITM-attack) + trx.operations.clear(); + + // verify if transaction has no valid signature of test account + flat_set expected_signers_of_valid_transaction = {test_bki.pub_key}; + auto signers = con.wallet_api_ptr->get_transaction_signers(trx); + BOOST_CHECK(signers != expected_signers_of_valid_transaction); + + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } +} + /////////////////// // Start a server and connect using the same calls as the CLI // Set a voting proxy and be assured that it sticks @@ -474,7 +621,7 @@ BOOST_FIXTURE_TEST_CASE( cli_confidential_tx_test, cli_fixture ) unsigned int head_block = 0; auto & W = *con.wallet_api_ptr; // Wallet alias - + BOOST_TEST_MESSAGE("Creating blind accounts"); graphene::wallet::brain_key_info bki_nathan = W.suggest_brain_key(); graphene::wallet::brain_key_info bki_alice = W.suggest_brain_key(); @@ -582,6 +729,177 @@ BOOST_FIXTURE_TEST_CASE( account_history_pagination, cli_fixture ) } } + +/////////////////////// +// Create a multi-sig account and verify that only when all signatures are +// signed, the transaction could be broadcast +/////////////////////// +BOOST_AUTO_TEST_CASE( cli_multisig_transaction ) +{ + using namespace graphene::chain; + using namespace graphene::app; + std::shared_ptr app1; + try { + fc::temp_directory app_dir( graphene::utilities::temp_directory_path() ); + + int server_port_number = 0; + app1 = start_application(app_dir, server_port_number); + + // connect to the server + client_connection con(app1, app_dir, server_port_number); + + BOOST_TEST_MESSAGE("Setting wallet password"); + con.wallet_api_ptr->set_password("supersecret"); + con.wallet_api_ptr->unlock("supersecret"); + + // import Nathan account + BOOST_TEST_MESSAGE("Importing nathan key"); + std::vector nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"}; + BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"); + BOOST_CHECK(con.wallet_api_ptr->import_key("nathan", nathan_keys[0])); + + BOOST_TEST_MESSAGE("Importing nathan's balance"); + std::vector import_txs = con.wallet_api_ptr->import_balance("nathan", nathan_keys, true); + account_object nathan_acct_before_upgrade = con.wallet_api_ptr->get_account("nathan"); + + // upgrade nathan + BOOST_TEST_MESSAGE("Upgrading Nathan to LTM"); + signed_transaction upgrade_tx = con.wallet_api_ptr->upgrade_account("nathan", true); + account_object nathan_acct_after_upgrade = con.wallet_api_ptr->get_account("nathan"); + + // verify that the upgrade was successful + BOOST_CHECK_PREDICATE( std::not_equal_to(), (nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) ); + BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member()); + + // create a new multisig account + graphene::wallet::brain_key_info bki1 = con.wallet_api_ptr->suggest_brain_key(); + graphene::wallet::brain_key_info bki2 = con.wallet_api_ptr->suggest_brain_key(); + graphene::wallet::brain_key_info bki3 = con.wallet_api_ptr->suggest_brain_key(); + graphene::wallet::brain_key_info bki4 = con.wallet_api_ptr->suggest_brain_key(); + BOOST_CHECK(!bki1.brain_priv_key.empty()); + BOOST_CHECK(!bki2.brain_priv_key.empty()); + BOOST_CHECK(!bki3.brain_priv_key.empty()); + BOOST_CHECK(!bki4.brain_priv_key.empty()); + + signed_transaction create_multisig_acct_tx; + account_create_operation account_create_op; + + account_create_op.referrer = nathan_acct_after_upgrade.id; + account_create_op.referrer_percent = nathan_acct_after_upgrade.referrer_rewards_percentage; + account_create_op.registrar = nathan_acct_after_upgrade.id; + account_create_op.name = "cifer.test"; + account_create_op.owner = authority(1, bki1.pub_key, 1); + account_create_op.active = authority(2, bki2.pub_key, 1, bki3.pub_key, 1); + account_create_op.options.memo_key = bki4.pub_key; + account_create_op.fee = asset(1000000); // should be enough for creating account + + create_multisig_acct_tx.operations.push_back(account_create_op); + con.wallet_api_ptr->sign_transaction(create_multisig_acct_tx, true); + + // attempt to give cifer.test some bitsahres + BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to cifer.test"); + signed_transaction transfer_tx1 = con.wallet_api_ptr->transfer("nathan", "cifer.test", "10000", "1.3.0", "Here are some BTS for your new account", true); + + // transfer bts from cifer.test to nathan + BOOST_TEST_MESSAGE("Transferring bitshares from cifer.test to nathan"); + auto dyn_props = app1->chain_database()->get_dynamic_global_properties(); + account_object cifer_test = con.wallet_api_ptr->get_account("cifer.test"); + + // construct a transfer transaction + signed_transaction transfer_tx2; + transfer_operation xfer_op; + xfer_op.from = cifer_test.id; + xfer_op.to = nathan_acct_after_upgrade.id; + xfer_op.amount = asset(100000000); + xfer_op.fee = asset(3000000); // should be enough for transfer + transfer_tx2.operations.push_back(xfer_op); + + // case1: sign a transaction without TaPoS and expiration fields + // expect: return a transaction with TaPoS and expiration filled + transfer_tx2 = + con.wallet_api_ptr->add_transaction_signature( transfer_tx2, false ); + BOOST_CHECK( ( transfer_tx2.ref_block_num != 0 && + transfer_tx2.ref_block_prefix != 0 ) || + ( transfer_tx2.expiration != fc::time_point_sec() ) ); + + // case2: broadcast without signature + // expect: exception with missing active authority + BOOST_CHECK_THROW(con.wallet_api_ptr->broadcast_transaction(transfer_tx2), fc::exception); + + // case3: + // import one of the private keys for this new account in the wallet file, + // sign and broadcast with partial signatures + // + // expect: exception with missing active authority + BOOST_CHECK(con.wallet_api_ptr->import_key("cifer.test", bki2.wif_priv_key)); + BOOST_CHECK_THROW(con.wallet_api_ptr->add_transaction_signature(transfer_tx2, true), fc::exception); + + // case4: sign again as signature exists + // expect: num of signatures not increase + transfer_tx2 = con.wallet_api_ptr->add_transaction_signature(transfer_tx2, false); + BOOST_CHECK_EQUAL(transfer_tx2.signatures.size(), 1); + + // case5: + // import another private key, sign and broadcast without full signatures + // + // expect: transaction broadcast successfully + BOOST_CHECK(con.wallet_api_ptr->import_key("cifer.test", bki3.wif_priv_key)); + con.wallet_api_ptr->add_transaction_signature(transfer_tx2, true); + auto balances = con.wallet_api_ptr->list_account_balances( "cifer.test" ); + for (auto b : balances) { + if (b.asset_id == asset_id_type()) { + BOOST_ASSERT(b == asset(900000000 - 3000000)); + } + } + + // wait for everything to finish up + fc::usleep(fc::seconds(1)); + } catch( fc::exception& e ) { + edump((e.to_detail_string())); + throw; + } + app1->shutdown(); +} + +graphene::wallet::plain_keys decrypt_keys( const std::string& password, const vector& cipher_keys ) +{ + auto pw = fc::sha512::hash( password.c_str(), password.size() ); + vector decrypted = fc::aes_decrypt( pw, cipher_keys ); + return fc::raw::unpack( decrypted ); +} + +BOOST_AUTO_TEST_CASE( saving_keys_wallet_test ) { + cli_fixture cli; + + cli.con.wallet_api_ptr->import_balance( "nathan", cli.nathan_keys, true ); + cli.con.wallet_api_ptr->upgrade_account( "nathan", true ); + std::string brain_key( "FICTIVE WEARY MINIBUS LENS HAWKIE MAIDISH MINTY GLYPH GYTE KNOT COCKSHY LENTIGO PROPS BIFORM KHUTBAH BRAZIL" ); + cli.con.wallet_api_ptr->create_account_with_brain_key( brain_key, "account1", "nathan", "nathan", true ); + + BOOST_CHECK_NO_THROW( cli.con.wallet_api_ptr->transfer( "nathan", "account1", "9000", "1.3.0", "", true ) ); + + std::string path( cli.app_dir.path().generic_string() + "/wallet.json" ); + graphene::wallet::wallet_data wallet = fc::json::from_file( path ).as( 2 * GRAPHENE_MAX_NESTED_OBJECTS ); + BOOST_CHECK( wallet.extra_keys.size() == 1 ); // nathan + BOOST_CHECK( wallet.pending_account_registrations.size() == 1 ); // account1 + BOOST_CHECK( wallet.pending_account_registrations["account1"].size() == 2 ); // account1 active key + account1 memo key + + graphene::wallet::plain_keys pk = decrypt_keys( "supersecret", wallet.cipher_keys ); + BOOST_CHECK( pk.keys.size() == 1 ); // nathan key + + BOOST_CHECK( generate_block( cli.app1 ) ); + fc::usleep( fc::seconds(1) ); + + wallet = fc::json::from_file( path ).as( 2 * GRAPHENE_MAX_NESTED_OBJECTS ); + BOOST_CHECK( wallet.extra_keys.size() == 2 ); // nathan + account1 + BOOST_CHECK( wallet.pending_account_registrations.empty() ); + BOOST_CHECK_NO_THROW( cli.con.wallet_api_ptr->transfer( "account1", "nathan", "1000", "1.3.0", "", true ) ); + + pk = decrypt_keys( "supersecret", wallet.cipher_keys ); + BOOST_CHECK( pk.keys.size() == 3 ); // nathan key + account1 active key + account1 memo key +} + + /////////////////////// // Start a server and connect using the same calls as the CLI // Create an HTLC diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index f6063e8beb..0760f68bc2 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -101,7 +101,7 @@ database_fixture::database_fixture(const fc::time_point_sec &initial_timestamp) genesis_state.initial_committee_candidates.push_back({name}); genesis_state.initial_witness_candidates.push_back({name, init_account_priv_key.get_public_key()}); } - genesis_state.initial_parameters.current_fees->zero_all_fees(); + genesis_state.initial_parameters.get_mutable_fees().zero_all_fees(); genesis_state_type::initial_asset_type init_mpa1; init_mpa1.symbol = "INITMPA"; @@ -125,6 +125,74 @@ database_fixture::database_fixture(const fc::time_point_sec &initial_timestamp) { options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)75, false))); } + if (current_test_name == "api_limit_get_account_history_operations") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-account-history-operations", boost::program_options::variable_value((uint64_t)300, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_account_history") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_grouped_limit_orders") + { + options.insert(std::make_pair("api-limit-get-grouped-limit-orders", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("grouped_orders"), false))); + } + if(current_test_name =="api_limit_get_relative_account_history") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-relative-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_account_history_by_operations") + { + options.insert(std::make_pair("api-limit-get-account-history-by-operations", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("api-limit-get-relative-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_asset_holders") + { + options.insert(std::make_pair("api-limit-get-asset-holders", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_key_references") + { + options.insert(std::make_pair("api-limit-get-key-references", boost::program_options::variable_value((uint64_t)200, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_limit_orders") + { + options.insert(std::make_pair("api-limit-get-limit-orders", boost::program_options::variable_value( + (uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value( + string("account_history"), false))); + } + if(current_test_name =="api_limit_get_call_orders") + { + options.insert(std::make_pair("api-limit-get-call-orders", boost::program_options::variable_value( + (uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value( + string("account_history"), false))); + } + if(current_test_name =="api_limit_get_settle_orders") + { + options.insert(std::make_pair("api-limit-get-settle-orders", boost::program_options::variable_value( + (uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value( + string("account_history"), false))); + } + if(current_test_name =="api_limit_get_order_book") + { + options.insert(std::make_pair("api-limit-get-order-book", boost::program_options::variable_value( + (uint64_t)80, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value( + string("account_history"), false))); + } + // add account tracking for ahplugin for special test case with track-account enabled if( !options.count("track-account") && current_test_name == "track_account") { std::vector track_account; @@ -166,6 +234,16 @@ database_fixture::database_fixture(const fc::time_point_sec &initial_timestamp) ahplugin->plugin_set_app(&app); ahplugin->plugin_initialize(options); ahplugin->plugin_startup(); + if (current_test_name == "api_limit_get_account_history_operations" || current_test_name == "api_limit_get_account_history" + || current_test_name == "api_limit_get_grouped_limit_orders" || current_test_name == "api_limit_get_relative_account_history" + || current_test_name == "api_limit_get_account_history_by_operations" || current_test_name =="api_limit_get_asset_holders" + || current_test_name =="api_limit_get_key_references" || current_test_name =="api_limit_get_limit_orders" + || current_test_name =="api_limit_get_call_orders" || current_test_name =="api_limit_get_settle_orders" + || current_test_name =="api_limit_get_order_book") + { + app.initialize(graphene::utilities::temp_directory_path(), options); + app.set_api_limit(); + } } if(current_test_name == "elasticsearch_objects" || current_test_name == "elasticsearch_suite") { @@ -595,7 +673,7 @@ void database_fixture::change_fees( ) { const chain_parameters& current_chain_params = db.get_global_properties().parameters; - const fee_schedule& current_fees = *(current_chain_params.current_fees); + const fee_schedule& current_fees = current_chain_params.get_current_fees(); flat_map< int, fee_parameters > fee_map; fee_map.reserve( current_fees.parameters.size() ); @@ -612,7 +690,7 @@ void database_fixture::change_fees( new_fees.scale = new_scale; chain_parameters new_chain_params = current_chain_params; - new_chain_params.current_fees = new_fees; + new_chain_params.get_mutable_fees() = new_fees; db.modify(db.get_global_properties(), [&](global_property_object& p) { p.parameters = new_chain_params; @@ -940,7 +1018,7 @@ const call_order_object* database_fixture::borrow( const account_object& who, as { try { set_expiration( db, trx ); trx.operations.clear(); - call_order_update_operation update; + call_order_update_operation update = {}; update.funding_account = who.id; update.delta_collateral = collateral; update.delta_debt = what; @@ -965,7 +1043,7 @@ void database_fixture::cover(const account_object& who, asset what, asset collat { try { set_expiration( db, trx ); trx.operations.clear(); - call_order_update_operation update; + call_order_update_operation update = {}; update.funding_account = who.id; update.delta_collateral = -collateral; update.delta_debt = -what; @@ -1014,7 +1092,7 @@ void database_fixture::enable_fees() { db.modify(global_property_id_type()(db), [](global_property_object& gpo) { - gpo.parameters.current_fees = fee_schedule::get_default(); + gpo.parameters.get_mutable_fees() = fee_schedule::get_default(); }); } @@ -1030,7 +1108,7 @@ void database_fixture::upgrade_to_lifetime_member( const account_object& account account_upgrade_operation op; op.account_to_upgrade = account.get_id(); op.upgrade_to_lifetime_member = true; - op.fee = db.get_global_properties().parameters.current_fees->calculate_fee(op); + op.fee = db.get_global_properties().parameters.get_current_fees().calculate_fee(op); trx.operations = {op}; PUSH_TX(db, trx, ~0); FC_ASSERT( op.account_to_upgrade(db).is_lifetime_member() ); @@ -1050,7 +1128,7 @@ void database_fixture::upgrade_to_annual_member(const account_object& account) try { account_upgrade_operation op; op.account_to_upgrade = account.get_id(); - op.fee = db.get_global_properties().parameters.current_fees->calculate_fee(op); + op.fee = db.get_global_properties().parameters.get_current_fees().calculate_fee(op); trx.operations = {op}; PUSH_TX(db, trx, ~0); FC_ASSERT( op.account_to_upgrade(db).is_member(db.head_block_time()) ); diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index e10f679de4..bf764f45f6 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -23,12 +23,16 @@ */ #pragma once -#include -#include -#include #include +#include +#include + +#include +#include #include +#include +#include #include #include diff --git a/tests/generate_empty_blocks/main.cpp b/tests/generate_empty_blocks/main.cpp index 721747eef2..7b4f3077fa 100644 --- a/tests/generate_empty_blocks/main.cpp +++ b/tests/generate_empty_blocks/main.cpp @@ -131,14 +131,14 @@ int main( int argc, char** argv ) signed_block b = db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot), nathan_priv_key, database::skip_nothing); FC_ASSERT( db.head_block_id() == b.id() ); fc::sha256 h = b.digest(); - uint64_t rand = h._hash[0]; + uint64_t rand = h._hash[0].value(); slot = 1; while(true) { if( (rand % 100) < miss_rate ) { slot++; - rand = (rand/100) ^ h._hash[slot&3]; + rand = (rand/100) ^ h._hash[slot&3].value(); missed++; } else diff --git a/tests/tests/app_util_tests.cpp b/tests/tests/app_util_tests.cpp index b85c9a3e8d..7034673443 100644 --- a/tests/tests/app_util_tests.cpp +++ b/tests/tests/app_util_tests.cpp @@ -24,10 +24,10 @@ #include -#include - #include "../common/database_fixture.hpp" +#include + using namespace graphene::chain; using namespace graphene::chain::test; using namespace graphene::app; diff --git a/tests/tests/asset_api_tests.cpp b/tests/tests/asset_api_tests.cpp index ff3eeb9785..7536b3529a 100644 --- a/tests/tests/asset_api_tests.cpp +++ b/tests/tests/asset_api_tests.cpp @@ -60,5 +60,25 @@ BOOST_AUTO_TEST_CASE( asset_holders ) BOOST_CHECK(holders[2].name == "alice"); BOOST_CHECK(holders[3].name == "dan"); } +BOOST_AUTO_TEST_CASE( api_limit_get_asset_holders ) +{ + graphene::app::asset_api asset_api(app); + + // create an asset and some accounts + create_bitasset("USD", account_id_type()); + auto dan = create_account("dan"); + auto bob = create_account("bob"); + auto alice = create_account("alice"); + + // send them some bts + transfer(account_id_type()(db), dan, asset(100)); + transfer(account_id_type()(db), alice, asset(200)); + transfer(account_id_type()(db), bob, asset(300)); + + // make call + GRAPHENE_CHECK_THROW(asset_api.get_asset_holders(std::string( static_cast(asset_id_type())), 0, 260), fc::exception); + vector holders = asset_api.get_asset_holders(std::string( static_cast(asset_id_type())), 0, 210); + BOOST_REQUIRE_EQUAL( holders.size(), 4u ); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/authority_tests.cpp b/tests/tests/authority_tests.cpp index ce9f1cadc5..4ffa93460e 100644 --- a/tests/tests/authority_tests.cpp +++ b/tests/tests/authority_tests.cpp @@ -1858,6 +1858,44 @@ BOOST_FIXTURE_TEST_CASE( parent_owner_test, database_fixture ) } } +BOOST_FIXTURE_TEST_CASE( owner_delegation_test, database_fixture ) +{ try { + ACTORS( (alice)(bob) ); + + fc::ecc::private_key bob_active_key = fc::ecc::private_key::regenerate(fc::digest("bob_active")); + fc::ecc::private_key bob_owner_key = fc::ecc::private_key::regenerate(fc::digest("bob_owner")); + + trx.clear(); + + // Make sure Bob has different keys + account_update_operation auo; + auo.account = bob_id; + auo.active = authority( 1, public_key_type(bob_active_key.get_public_key()), 1 ); + auo.owner = authority( 1, public_key_type(bob_owner_key.get_public_key()), 1 ); + trx.operations.push_back( auo ); + sign( trx, bob_private_key ); + PUSH_TX( db, trx ); + trx.clear(); + + // Delegate Alice's owner auth to herself and active auth to Bob + auo.account = alice_id; + auo.active = authority( 1, bob_id, 1 ); + auo.owner = authority( 1, alice_id, 1 ); + trx.operations.push_back( auo ); + sign( trx, alice_private_key ); + PUSH_TX( db, trx ); + trx.clear(); + + // Now Bob has full control over Alice's account + auo.account = alice_id; + auo.active.reset(); + auo.owner = authority( 1, bob_id, 1 ); + trx.operations.push_back( auo ); + sign( trx, bob_active_key ); + PUSH_TX( db, trx ); + trx.clear(); +} FC_LOG_AND_RETHROW() } + /// This test case reproduces https://github.com/bitshares/bitshares-core/issues/944 /// and https://github.com/bitshares/bitshares-core/issues/580 BOOST_FIXTURE_TEST_CASE( missing_owner_auth_test, database_fixture ) diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 2c7eec7d05..9b336eb2d5 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -62,7 +62,7 @@ genesis_state_type make_genesis() { genesis_state.initial_committee_candidates.push_back({name}); genesis_state.initial_witness_candidates.push_back({name, init_account_priv_key.get_public_key()}); } - genesis_state.initial_parameters.current_fees->zero_all_fees(); + genesis_state.initial_parameters.get_mutable_fees().zero_all_fees(); return genesis_state; } diff --git a/tests/tests/call_order_tests.cpp b/tests/tests/call_order_tests.cpp index 2095de0ac1..4f700cda87 100644 --- a/tests/tests/call_order_tests.cpp +++ b/tests/tests/call_order_tests.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include "../common/database_fixture.hpp" diff --git a/tests/tests/database_api_tests.cpp b/tests/tests/database_api_tests.cpp index 2db747d0ce..a8ba90c63e 100644 --- a/tests/tests/database_api_tests.cpp +++ b/tests/tests/database_api_tests.cpp @@ -751,30 +751,75 @@ BOOST_AUTO_TEST_CASE( get_required_signatures_partially_signed_or_not ) } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE( set_subscribe_callback_disable_notify_all_test ) +BOOST_AUTO_TEST_CASE( subscription_key_collision_test ) +{ + object_id_type uia_object_id = create_user_issued_asset( "UIATEST" ).get_id(); + + uint32_t objects_changed = 0; + auto callback = [&]( const variant& v ) + { + ++objects_changed; + }; + + graphene::app::database_api db_api(db); + db_api.set_subscribe_callback( callback, false ); + + // subscribe to an account which has same instance ID as UIATEST + vector collision_ids; + collision_ids.push_back( string( object_id_type( account_id_type( uia_object_id ) ) ) ); + db_api.get_accounts( collision_ids ); + + generate_block(); + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + + BOOST_CHECK_EQUAL( objects_changed, 0 ); // did not subscribe to UIATEST, so no notification + + vector asset_names; + asset_names.push_back( "UIATEST" ); + db_api.get_assets( asset_names ); + + generate_block(); + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + + BOOST_CHECK_EQUAL( objects_changed, 0 ); // UIATEST did not change in this block, so no notification +} + +BOOST_AUTO_TEST_CASE( subscription_notification_test ) { try { - ACTORS( (alice) ); + ACTORS( (alice)(bob) ); - uint32_t objects_changed1 = 0; - uint32_t objects_changed2 = 0; - uint32_t objects_changed3 = 0; - auto callback1 = [&]( const variant& v ) - { - ++objects_changed1; - }; - auto callback2 = [&]( const variant& v ) - { - ++objects_changed2; - }; - auto callback3 = [&]( const variant& v ) + create_user_issued_asset( "UIATEST" ); + +#define SUB_NOTIF_TEST_NUM_CALLBACKS_PLUS_ONE 8 + +#define SUB_NOTIF_TEST_INIT_CALLBACKS(z, i, data) \ + uint32_t objects_changed ## i = 0; \ + auto callback ## i = [&]( const variant& v ) \ + { \ + idump((i)(v)); \ + ++objects_changed ## i; \ + }; \ + uint32_t expected_objects_changed ## i = 0; + +#define SUB_NOTIF_TEST_CHECK(z, i, data) \ + if( expected_objects_changed ## i > 0 ) { \ + BOOST_CHECK_LE( expected_objects_changed ## i, objects_changed ## i ); \ + } else { \ + BOOST_CHECK_EQUAL( expected_objects_changed ## i, objects_changed ## i ); \ + } \ + expected_objects_changed ## i = 0; \ + objects_changed ## i = 0; + + BOOST_PP_REPEAT_FROM_TO( 1, SUB_NOTIF_TEST_NUM_CALLBACKS_PLUS_ONE, SUB_NOTIF_TEST_INIT_CALLBACKS, unused ); + + auto check_results = [&]() { - ++objects_changed3; + BOOST_PP_REPEAT_FROM_TO( 1, SUB_NOTIF_TEST_NUM_CALLBACKS_PLUS_ONE, SUB_NOTIF_TEST_CHECK, unused ); }; - uint32_t expected_objects_changed1 = 0; - uint32_t expected_objects_changed2 = 0; - uint32_t expected_objects_changed3 = 0; +#undef SUB_NOTIF_TEST_CHECK +#undef SUB_NOTIF_TEST_INIT_CALLBACKS graphene::app::database_api db_api1(db); @@ -787,30 +832,149 @@ BOOST_AUTO_TEST_CASE( set_subscribe_callback_disable_notify_all_test ) opt.enable_subscribe_to_all = true; graphene::app::database_api db_api2( db, &opt ); - db_api2.set_subscribe_callback( callback2, true ); + db_api2.set_subscribe_callback( callback2, true ); // subscribing to all should succeed + +#define SUB_NOTIF_TEST_INIT_APIS(z, i, data) \ + graphene::app::database_api db_api ## i( db, &opt ); \ + db_api ## i.set_subscribe_callback( callback ## i, false ); + + BOOST_PP_REPEAT_FROM_TO( 3, SUB_NOTIF_TEST_NUM_CALLBACKS_PLUS_ONE, SUB_NOTIF_TEST_INIT_APIS, unused ); + +#undef SUB_NOTIF_TEST_INIT_APIS +#undef SUB_NOTIF_TEST_NUM_CALLBACKS_PLUS_ONE + + vector account_ids; + account_ids.push_back( alice_id ); + db_api1.get_objects( account_ids ); // db_api1 subscribe to Alice + + vector account_names; + account_names.push_back( "alice" ); + db_api4.get_accounts( account_names ); // db_api4 subscribe to Alice - graphene::app::database_api db_api3( db, &opt ); - db_api3.set_subscribe_callback( callback3, false ); + db_api5.lookup_accounts( "ali", 1 ); // db_api5 subscribe to Alice - vector ids; - ids.push_back( alice_id ); + db_api6.lookup_accounts( "alice", 3 ); // db_api6 does not subscribe to Alice - db_api1.get_objects( ids ); // db_api1 subscribe to Alice - db_api2.get_objects( ids ); // db_api2 subscribe to Alice + vector asset_names; + asset_names.push_back( "UIATEST" ); + db_api7.get_assets( asset_names ); // db_api7 subscribe to UIA generate_block(); - ++expected_objects_changed2; // subscribed to all, notify block changes + ++expected_objects_changed1; // db_api1 subscribed to Alice, notify Alice account creation + ++expected_objects_changed2; // db_api2 subscribed to all, notify new objects + // db_api3 didn't subscribe to anything, nothing would be notified + ++expected_objects_changed4; // db_api4 subscribed to Alice, notify Alice account creation + ++expected_objects_changed5; // db_api5 subscribed to Alice, notify Alice account creation + // db_api6 didn't subscribe to anything, nothing would be notified + ++expected_objects_changed7; // db_api7 subscribed to UIA, notify asset creation + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); transfer( account_id_type(), alice_id, asset(1) ); generate_block(); - ++expected_objects_changed1; // subscribed to Alice, notify Alice balance change - ++expected_objects_changed2; // subscribed to all, notify block changes + // db_api1 didn't subscribe to Alice with get_full_accounts but only subscribed to the account object, + // nothing would be notified + ++expected_objects_changed2; // db_api2 subscribed to all, notify new balance object and etc + // db_api3 didn't subscribe to anything, nothing would be notified + // db_api4 only subscribed to the account object of Alice, nothing notified + // db_api5 only subscribed to the account object of Alice, nothing notified + // db_api6 didn't subscribe to anything, nothing would be notified + // db_api7: no change on UIA, nothing would be notified fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); + + vector obj_ids; + obj_ids.push_back( db.get_dynamic_global_properties().id ); + db_api3.get_objects( obj_ids ); // db_api3 subscribe to dynamic global properties + + db_api4.get_full_accounts( account_names, true ); // db_api4 subscribe to Alice with get_full_accounts + db_api5.get_full_accounts( account_names, false ); // db_api5 doesn't subscribe - BOOST_CHECK_EQUAL( expected_objects_changed1, objects_changed1 ); - BOOST_CHECK_EQUAL( expected_objects_changed2, objects_changed2 ); - BOOST_CHECK_EQUAL( expected_objects_changed3, objects_changed3 ); + transfer( account_id_type(), alice_id, asset(1) ); + generate_block(); + // db_api1 didn't subscribe to Alice with get_full_accounts but only subscribed to the account object, + // nothing would be notified + ++expected_objects_changed2; // db_api2 subscribed to all, notify new history records and etc + ++expected_objects_changed3; // db_api3 subscribed to dynamic global properties, would be notified + ++expected_objects_changed4; // db_api4 subscribed to full account data of Alice, would be notified + // db_api5 only subscribed to the account object of Alice, nothing notified + // db_api6 didn't subscribe to anything, nothing would be notified + // db_api7: no change on UIA, nothing would be notified + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); + + db_api6.set_auto_subscription( false ); + db_api6.get_objects( obj_ids ); // db_api6 doesn't auto-subscribe to dynamic global properties + + generate_block(); + // db_api1 only subscribed to the account object of Alice, nothing notified + // db_api2 subscribed to all, but no object is created or removed in this block, so nothing notified + ++expected_objects_changed3; // db_api3 subscribed to dynamic global properties, would be notified + // db_api4 subscribed to full account data of Alice, nothing would be notified + // db_api5 only subscribed to the account object of Alice, nothing notified + // db_api6 didn't subscribe to anything, nothing would be notified + // db_api7: no change on UIA, nothing would be notified + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); + + account_names.clear(); + account_names.push_back( "bob" ); + db_api5.set_auto_subscription( false ); + db_api5.get_full_accounts( account_names, true ); // db_api5 subscribe to full account data of Bob + + db_api6.get_full_accounts( account_names, false ); // db_api6 doesn't subscribe + + transfer( account_id_type(), bob_id, asset(1) ); + + generate_block(); + // db_api1 only subscribed to the account object of Alice, nothing notified + ++expected_objects_changed2; // db_api2 subscribed to all, notify new history records and etc + ++expected_objects_changed3; // db_api3 subscribed to dynamic global properties, would be notified + // db_api4 subscribed to full account data of Alice, nothing would be notified + ++expected_objects_changed5; // db_api5 subscribed to full account data of Bob, would be notified + // db_api6 didn't subscribe to anything, nothing would be notified + // db_api7: no change on UIA, nothing would be notified + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); + + db_api6.set_auto_subscription( true ); + db_api6.get_objects( obj_ids ); // db_api6 auto-subscribe to dynamic global properties + + generate_block(); + // db_api1 only subscribed to the account object of Alice, nothing notified + // db_api2 subscribed to all, but no object is created or removed in this block, so nothing notified + ++expected_objects_changed3; // db_api3 subscribed to dynamic global properties, would be notified + // db_api4 subscribed to full account data of Alice, nothing would be notified + // db_api5 subscribed to full account data of Bob, nothing notified + ++expected_objects_changed6; // db_api6 subscribed to dynamic global properties, would be notified + // db_api7: no change on UIA, nothing would be notified + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); + + db_api5.set_subscribe_callback( callback5, false ); // reset subscription + + db_api6.cancel_all_subscriptions(); + db_api6.get_objects( obj_ids ); // db_api6 doesn't auto-subscribe to dynamic global properties + + transfer( alice_id, bob_id, asset(1) ); + + generate_block(); + // db_api1 only subscribed to the account object of Alice, nothing notified + ++expected_objects_changed2; // db_api2 subscribed to all, notify new history records and etc + ++expected_objects_changed3; // db_api3 subscribed to dynamic global properties, would be notified + ++expected_objects_changed4; // db_api4 subscribed to full account data of Alice, would be notified + // db_api5 subscribed to anything, nothing notified + // db_api6 subscribed to anything, nothing notified + // db_api7: no change on UIA, nothing would be notified + + fc::usleep(fc::milliseconds(200)); // sleep a while to execute callback in another thread + check_results(); } FC_LOG_AND_RETHROW() } @@ -981,10 +1145,10 @@ BOOST_AUTO_TEST_CASE( get_transaction_hex ) } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE(verify_account_authority) +BOOST_AUTO_TEST_CASE(verify_account_authority) { try { - + ACTORS( (nathan) ); graphene::app::database_api db_api(db); @@ -1014,7 +1178,7 @@ BOOST_AUTO_TEST_CASE( any_two_of_three ) try { account_update_operation op; op.account = nathan.id; - op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, + op.active = authority(2, public_key_type(nathan_key1.get_public_key()), 1, public_key_type(nathan_key2.get_public_key()), 1, public_key_type(nathan_key3.get_public_key()), 1); op.owner = *op.active; trx.operations.push_back(op); @@ -1090,5 +1254,292 @@ BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) throw; } } +BOOST_AUTO_TEST_CASE( api_limit_get_key_references ){ + try{ + const int num_keys = 210; + const int num_keys1 = 2; + vector< private_key_type > numbered_private_keys; + vector< public_key_type > numbered_key_id; + numbered_private_keys.reserve( num_keys ); + graphene::app::database_api db_api( db, &( app.get_options() )); + for( int i=0; i > final_result=db_api.get_key_references(numbered_key_id); + BOOST_REQUIRE_EQUAL( final_result.size(), 2u ); + numbered_private_keys.reserve( num_keys ); + for( int i=num_keys1; iapp.get_options())); + + const account_object& alice = create_account("alice"); + const account_object& bob = create_account("bob"); + const account_object& carl = create_account("carl"); + const account_object& dan = create_account("dan"); + const account_object& fred = create_account("fred"); + const account_object& henry = create_account("henry"); + const account_object& kevin = create_account("kevin"); + const account_object& laura = create_account("laura"); + const account_object& lucy = create_account("lucy"); + const account_object& martin = create_account("martin"); + const account_object& patty = create_account("patty"); + + vector accounts; + accounts.push_back(alice.name); + accounts.push_back(bob.name); + accounts.push_back(carl.name); + accounts.push_back(dan.name); + accounts.push_back(fred.name); + accounts.push_back(henry.name); + accounts.push_back(kevin.name); + accounts.push_back(laura.name); + accounts.push_back(lucy.name); + accounts.push_back(martin.name); + accounts.push_back(patty.name); + + GRAPHENE_CHECK_THROW(db_api.get_full_accounts(accounts, false), fc::exception); + + accounts.erase(accounts.begin()); + auto full_accounts = db_api.get_full_accounts(accounts, false); + BOOST_CHECK(full_accounts.size() == 10); + + // not an account + accounts.erase(accounts.begin()); + accounts.push_back("nosuchaccount"); + + // non existing accounts will be ignored in the results + full_accounts = db_api.get_full_accounts(accounts, false); + BOOST_CHECK(full_accounts.size() == 9); + + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( get_assets_by_issuer ) { + try { + graphene::app::database_api db_api(db, &(this->app.get_options())); + + create_bitasset("CNY"); + create_bitasset("EUR"); + create_bitasset("USD"); + generate_block(); + + auto assets = db_api.get_assets_by_issuer("witness-account", asset_id_type(), 10); + + BOOST_CHECK(assets.size() == 3); + BOOST_CHECK(assets[0].symbol == "CNY"); + BOOST_CHECK(assets[1].symbol == "EUR"); + BOOST_CHECK(assets[2].symbol == "USD"); + + assets = db_api.get_assets_by_issuer("witness-account", asset_id_type(200), 100); + BOOST_CHECK(assets.size() == 0); + + GRAPHENE_CHECK_THROW(db_api.get_assets_by_issuer("nosuchaccount", asset_id_type(), 100), fc::exception); + + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( get_call_orders_by_account ) { + + try { + ACTORS((caller)(feedproducer)); + + graphene::app::database_api db_api(db, &(this->app.get_options())); + + const auto &usd = create_bitasset("USD", feedproducer_id); + const auto &cny = create_bitasset("CNY", feedproducer_id); + const auto &core = asset_id_type()(db); + + int64_t init_balance(1000000); + transfer(committee_account, caller_id, asset(init_balance)); + + update_feed_producers(usd, {feedproducer.id}); + update_feed_producers(cny, {feedproducer.id}); + + price_feed current_feed; + current_feed.maintenance_collateral_ratio = 1750; + current_feed.maximum_short_squeeze_ratio = 1100; + current_feed.settlement_price = usd.amount(1) / core.amount(5); + publish_feed(usd, feedproducer, current_feed); + + current_feed.maintenance_collateral_ratio = 1750; + current_feed.maximum_short_squeeze_ratio = 1100; + current_feed.settlement_price = cny.amount(1) / core.amount(5); + publish_feed(cny, feedproducer, current_feed); + + auto call1 = borrow(caller, usd.amount(1000), asset(15000)); + auto call2 = borrow(caller, cny.amount(1000), asset(15000)); + + auto calls = db_api.get_call_orders_by_account("caller", asset_id_type(), 100); + + BOOST_CHECK(calls.size() == 2); + BOOST_CHECK(calls[0].id == call1->id); + BOOST_CHECK(calls[1].id == call2->id); + + GRAPHENE_CHECK_THROW(db_api.get_call_orders_by_account("nosuchaccount", asset_id_type(), 100), fc::exception); + + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( get_settle_orders_by_account ) { + try { + ACTORS((creator)(settler)(caller)(feedproducer)); + + graphene::app::database_api db_api(db, &(this->app.get_options())); + + const auto &usd = create_bitasset("USD", creator_id); + const auto &core = asset_id_type()(db); + asset_id_type usd_id = usd.id; + + int64_t init_balance(1000000); + transfer(committee_account, settler_id, asset(init_balance)); + transfer(committee_account, caller_id, asset(init_balance)); + + update_feed_producers(usd, {feedproducer.id}); + + price_feed current_feed; + current_feed.maintenance_collateral_ratio = 1750; + current_feed.maximum_short_squeeze_ratio = 1100; + current_feed.settlement_price = usd.amount(1) / core.amount(5); + publish_feed(usd, feedproducer, current_feed); + + borrow(caller, usd.amount(1000), asset(15000)); + generate_block(); + + transfer(caller.id, settler.id, asset(200, usd_id)); + + auto result = force_settle( settler, usd_id(db).amount(4)); + generate_block(); + + auto settlements = db_api.get_settle_orders_by_account("settler", force_settlement_id_type(), 100); + + BOOST_CHECK(settlements.size() == 1); + BOOST_CHECK(settlements[0].id == result.get()); + + GRAPHENE_CHECK_THROW(db_api.get_settle_orders_by_account("nosuchaccount", force_settlement_id_type(), 100), fc::exception); + + } catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( api_limit_get_limit_orders ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + asset_id_type bit_jmj_id = create_bitasset("JMJBIT").id; + generate_block(); + fc::usleep(fc::milliseconds(100)); + GRAPHENE_CHECK_THROW(db_api.get_limit_orders(std::string(static_cast(asset_id_type())), + std::string(static_cast(bit_jmj_id)), 370), fc::exception); + vector limit_orders =db_api.get_limit_orders(std::string( + static_cast(asset_id_type())), + std::string(static_cast(bit_jmj_id)), 340); + BOOST_REQUIRE_EQUAL( limit_orders.size(), 0u); + + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_call_orders ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + //account_id_type() do 3 ops + auto nathan_private_key = generate_private_key("nathan"); + account_id_type nathan_id = create_account("nathan", nathan_private_key.get_public_key()).id; + transfer(account_id_type(), nathan_id, asset(100)); + asset_id_type bitusd_id = create_bitasset( + "USDBIT", nathan_id, 100, disable_force_settle).id; + generate_block(); + fc::usleep(fc::milliseconds(100)); + BOOST_CHECK( bitusd_id(db).is_market_issued() ); + GRAPHENE_CHECK_THROW(db_api.get_call_orders(std::string(static_cast(bitusd_id)), + 370), fc::exception); + vector< call_order_object> call_order =db_api.get_call_orders(std::string( + static_cast(bitusd_id)), 340); + BOOST_REQUIRE_EQUAL( call_order.size(), 0u); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_settle_orders ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + //account_id_type() do 3 ops + auto nathan_private_key = generate_private_key("nathan"); + account_id_type nathan_id = create_account("nathan", nathan_private_key.get_public_key()).id; + transfer(account_id_type(), nathan_id, asset(100)); + asset_id_type bitusd_id = create_bitasset( + "USDBIT", nathan_id, 100, disable_force_settle).id; + generate_block(); + fc::usleep(fc::milliseconds(100)); + GRAPHENE_CHECK_THROW(db_api.get_settle_orders( + std::string(static_cast(bitusd_id)), 370), fc::exception); + vector result =db_api.get_settle_orders( + std::string(static_cast(bitusd_id)), 340); + BOOST_REQUIRE_EQUAL( result.size(), 0u); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_order_book ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + auto nathan_private_key = generate_private_key("nathan"); + auto dan_private_key = generate_private_key("dan"); + account_id_type nathan_id = create_account("nathan", nathan_private_key.get_public_key()).id; + account_id_type dan_id = create_account("dan", dan_private_key.get_public_key()).id; + transfer(account_id_type(), nathan_id, asset(100)); + transfer(account_id_type(), dan_id, asset(100)); + asset_id_type bitusd_id = create_bitasset( + "USDBIT", nathan_id, 100, disable_force_settle).id; + asset_id_type bitdan_id = create_bitasset( + "DANBIT", dan_id, 100, disable_force_settle).id; + generate_block(); + fc::usleep(fc::milliseconds(100)); + GRAPHENE_CHECK_THROW(db_api.get_order_book(std::string(static_cast(bitusd_id)), + std::string(static_cast(bitdan_id)),89), fc::exception); + graphene::app::order_book result =db_api.get_order_book(std::string( + static_cast(bitusd_id)), std::string(static_cast(bitdan_id)),78); + BOOST_REQUIRE_EQUAL( result.bids.size(), 0u); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/database_tests.cpp b/tests/tests/database_tests.cpp index 748fab041d..3978bd3da7 100644 --- a/tests/tests/database_tests.cpp +++ b/tests/tests/database_tests.cpp @@ -27,6 +27,7 @@ #include #include +#include #include @@ -222,4 +223,91 @@ BOOST_AUTO_TEST_CASE( direct_index_test ) // but the secondary has not updated its representation } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( required_approval_index_test ) // see https://github.com/bitshares/bitshares-core/issues/1719 +{ try { + ACTORS( (alice)(bob)(charlie)(agnetha)(benny)(carlos) ); + + database db1; + db1.initialize_indexes(); + const auto& proposals = db1.get_index_type< primary_index< proposal_index > >(); + const auto& required_approvals = proposals.get_secondary_index< required_approval_index >()._account_to_proposals; + + // Create a proposal + const auto& prop = db1.create( [this,alice_id,agnetha_id]( object& o ) { + proposal_object& prop = static_cast(o); + prop.proposer = committee_account; + prop.required_active_approvals.insert( alice_id ); + prop.required_owner_approvals.insert( agnetha_id ); + }); + + BOOST_CHECK_EQUAL( 2u, required_approvals.size() ); + BOOST_REQUIRE( required_approvals.find( alice_id ) != required_approvals.end() ); + BOOST_REQUIRE( required_approvals.find( agnetha_id ) != required_approvals.end() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(alice_id)->second.size() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(agnetha_id)->second.size() ); + + // add approvals + db1.modify( prop, [bob_id,benny_id]( object& o ) { + proposal_object& prop = static_cast(o); + prop.available_active_approvals.insert( bob_id ); + prop.available_owner_approvals.insert( benny_id ); + }); + + BOOST_CHECK_EQUAL( 4u, required_approvals.size() ); + BOOST_REQUIRE( required_approvals.find( bob_id ) != required_approvals.end() ); + BOOST_REQUIRE( required_approvals.find( benny_id ) != required_approvals.end() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(bob_id)->second.size() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(benny_id)->second.size() ); + + // remove approvals + add others + db1.modify( prop, [bob_id,charlie_id,benny_id,carlos_id]( object& o ) { + proposal_object& prop = static_cast(o); + prop.available_active_approvals.insert( charlie_id ); + prop.available_owner_approvals.insert( carlos_id ); + prop.available_active_approvals.erase( bob_id ); + prop.available_owner_approvals.erase( benny_id ); + }); + + BOOST_CHECK_EQUAL( 4u, required_approvals.size() ); + BOOST_REQUIRE( required_approvals.find( charlie_id ) != required_approvals.end() ); + BOOST_REQUIRE( required_approvals.find( carlos_id ) != required_approvals.end() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(charlie_id)->second.size() ); + BOOST_CHECK_EQUAL( 1u, required_approvals.find(carlos_id)->second.size() ); + + // simulate save/restore + std::vector serialized = fc::raw::pack( prop ); + database db2; + db2.initialize_indexes(); + const auto& reloaded_proposals = db2.get_index_type< primary_index< proposal_index > >(); + const auto& reloaded_approvals = reloaded_proposals.get_secondary_index() + ._account_to_proposals; + const_cast< primary_index< proposal_index >& >( reloaded_proposals ).load( serialized ); + const auto& prop2 = *reloaded_proposals.indices().begin(); + + BOOST_CHECK_EQUAL( 4u, reloaded_approvals.size() ); + BOOST_REQUIRE( reloaded_approvals.find( charlie_id ) != reloaded_approvals.end() ); + BOOST_REQUIRE( reloaded_approvals.find( carlos_id ) != reloaded_approvals.end() ); + BOOST_CHECK_EQUAL( 1u, reloaded_approvals.find(charlie_id)->second.size() ); + BOOST_CHECK_EQUAL( 1u, reloaded_approvals.find(carlos_id)->second.size() ); + + db2.modify( prop2, []( object& o ) { + proposal_object& prop = static_cast(o); + prop.available_active_approvals.clear(); + prop.available_owner_approvals.clear(); + }); + + BOOST_CHECK_EQUAL( 2u, reloaded_approvals.size() ); + BOOST_REQUIRE( reloaded_approvals.find( alice_id ) != reloaded_approvals.end() ); + BOOST_REQUIRE( reloaded_approvals.find( agnetha_id ) != reloaded_approvals.end() ); + + db2.remove( prop2 ); + + BOOST_CHECK_EQUAL( 0u, reloaded_approvals.size() ); + + db1.remove( prop ); + + BOOST_CHECK_EQUAL( 0u, required_approvals.size() ); + +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/fee_tests.cpp b/tests/tests/fee_tests.cpp index 1ffa980c01..04bc758eed 100644 --- a/tests/tests/fee_tests.cpp +++ b/tests/tests/fee_tests.cpp @@ -22,8 +22,6 @@ * THE SOFTWARE. */ -#include - #include #include @@ -38,6 +36,8 @@ #include "../common/database_fixture.hpp" +#include + using namespace graphene::chain; using namespace graphene::chain::test; @@ -173,17 +173,6 @@ BOOST_AUTO_TEST_CASE(asset_claim_fees_test) } - if( db.head_block_time() <= HARDFORK_413_TIME ) - { - // can't claim before hardfork - GRAPHENE_REQUIRE_THROW( claim_fees( izzy_id, _izzy(1) ), fc::exception ); - generate_blocks( HARDFORK_413_TIME ); - while( db.head_block_time() <= HARDFORK_413_TIME ) - { - generate_block(); - } - } - { const asset_object& izzycoin = izzycoin_id(db); const asset_object& jillcoin = jillcoin_id(db); @@ -268,7 +257,7 @@ BOOST_AUTO_TEST_CASE(asset_claim_pool_test) claim_op.asset_id = asset_to_claim; claim_op.amount_to_claim = amount_to_fund; - const auto& curfees = *db.get_global_properties().parameters.current_fees; + const auto& curfees = db.get_global_properties().parameters.get_current_fees(); const auto& proposal_create_fees = curfees.get(); proposal_create_operation prop; prop.fee_paying_account = alice_id; @@ -285,18 +274,9 @@ BOOST_AUTO_TEST_CASE(asset_claim_pool_test) }; - const asset_object& core_asset = asset_id_type()(db); - // deposit 100 BTS to the fee pool of ALICEUSD asset fund_fee_pool( alice_id(db), aliceusd_id(db), _core(100).amount ); - // Unable to claim pool before the hardfork - GRAPHENE_REQUIRE_THROW( claim_pool( alice_id, aliceusd_id, _core(1), core_asset), fc::exception ); - GRAPHENE_REQUIRE_THROW( claim_pool_proposal( alice_id, aliceusd_id, _core(1), core_asset), fc::exception ); - - // Fast forward to hard fork date - generate_blocks( HARDFORK_CORE_188_TIME ); - // New reference for core_asset after having produced blocks const asset_object& core_asset_hf = asset_id_type()(db); @@ -462,7 +442,7 @@ BOOST_AUTO_TEST_CASE( cashback_test ) upgrade_to_lifetime_member(rog_id); BOOST_TEST_MESSAGE("Enable fees"); - const auto& fees = db.get_global_properties().parameters.current_fees; + const auto& fees = db.get_global_properties().parameters.get_current_fees(); #define CustomRegisterActor(actor_name, registrar_name, referrer_name, referrer_rate) \ { \ @@ -474,7 +454,7 @@ BOOST_AUTO_TEST_CASE( cashback_test ) op.options.memo_key = actor_name ## _private_key.get_public_key(); \ op.active = authority(1, public_key_type(actor_name ## _private_key.get_public_key()), 1); \ op.owner = op.active; \ - op.fee = fees->calculate_fee(op); \ + op.fee = fees.calculate_fee(op); \ trx.operations = {op}; \ sign( trx, registrar_name ## _private_key ); \ actor_name ## _id = PUSH_TX( db, trx ).operation_results.front().get(); \ @@ -500,10 +480,10 @@ BOOST_AUTO_TEST_CASE( cashback_test ) CustomAuditActor( pleb ); \ } - int64_t reg_fee = fees->get< account_create_operation >().premium_fee; - int64_t xfer_fee = fees->get< transfer_operation >().fee; - int64_t upg_an_fee = fees->get< account_upgrade_operation >().membership_annual_fee; - int64_t upg_lt_fee = fees->get< account_upgrade_operation >().membership_lifetime_fee; + int64_t reg_fee = fees.get< account_create_operation >().premium_fee; + int64_t xfer_fee = fees.get< transfer_operation >().fee; + int64_t upg_an_fee = fees.get< account_upgrade_operation >().membership_annual_fee; + int64_t upg_lt_fee = fees.get< account_upgrade_operation >().membership_lifetime_fee; // all percentages here are cut from whole pie! uint64_t network_pct = 20 * P1; uint64_t lt_pct = 375 * P100 / 1000; @@ -709,29 +689,29 @@ BOOST_AUTO_TEST_CASE( account_create_fee_scaling ) auto accounts_per_scale = db.get_global_properties().parameters.accounts_per_fee_scale; db.modify(global_property_id_type()(db), [](global_property_object& gpo) { - gpo.parameters.current_fees = fee_schedule::get_default(); - gpo.parameters.current_fees->get().basic_fee = 1; + gpo.parameters.get_mutable_fees() = fee_schedule::get_default(); + gpo.parameters.get_mutable_fees().get().basic_fee = 1; }); for( int i = db.get_dynamic_global_properties().accounts_registered_this_interval; i < accounts_per_scale; ++i ) { - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 1u); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.get_current_fees().get().basic_fee, 1u); create_account("shill" + fc::to_string(i)); } for( int i = 0; i < accounts_per_scale; ++i ) { - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 16u); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.get_current_fees().get().basic_fee, 16u); create_account("moreshills" + fc::to_string(i)); } for( int i = 0; i < accounts_per_scale; ++i ) { - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 256u); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.get_current_fees().get().basic_fee, 256u); create_account("moarshills" + fc::to_string(i)); } - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 4096u); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.get_current_fees().get().basic_fee, 4096u); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().basic_fee, 1u); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.get_current_fees().get().basic_fee, 1u); } FC_LOG_AND_RETHROW() } BOOST_AUTO_TEST_CASE( fee_refund_test ) @@ -3443,11 +3423,9 @@ BOOST_AUTO_TEST_CASE( stealth_fba_test ) ACTORS( (alice)(bob)(chloe)(dan)(izzy)(philbin)(tom) ); upgrade_to_lifetime_member(philbin_id); - generate_blocks( HARDFORK_538_TIME ); generate_blocks( HARDFORK_555_TIME ); generate_blocks( HARDFORK_563_TIME ); generate_blocks( HARDFORK_572_TIME ); - generate_blocks( HARDFORK_599_TIME ); // Philbin (registrar who registers Rex) @@ -3694,7 +3672,8 @@ BOOST_AUTO_TEST_CASE( issue_429_test ) // make sure the database requires our fee to be nonzero enable_fees(); - auto fees_to_pay = db.get_global_properties().parameters.current_fees->get(); + const auto& fees = db.get_global_properties().parameters.get_current_fees(); + auto fees_to_pay = fees.get(); { signed_transaction tx; @@ -3766,7 +3745,7 @@ BOOST_AUTO_TEST_CASE( issue_433_test ) // make sure the database requires our fee to be nonzero enable_fees(); - const auto& fees = *db.get_global_properties().parameters.current_fees; + const auto& fees = db.get_global_properties().parameters.get_current_fees(); const auto asset_create_fees = fees.get(); fund_fee_pool( alice, myusd, 5*asset_create_fees.long_symbol ); @@ -3807,7 +3786,7 @@ BOOST_AUTO_TEST_CASE( issue_433_indirect_test ) // make sure the database requires our fee to be nonzero enable_fees(); - const auto& fees = *db.get_global_properties().parameters.current_fees; + const auto& fees = db.get_global_properties().parameters.get_current_fees(); const auto asset_create_fees = fees.get(); fund_fee_pool( alice, myusd, 5*asset_create_fees.long_symbol ); diff --git a/tests/tests/grouped_orders_api_tests.cpp b/tests/tests/grouped_orders_api_tests.cpp new file mode 100644 index 0000000000..e08c7d5d0e --- /dev/null +++ b/tests/tests/grouped_orders_api_tests.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 manikey123, 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 "../common/database_fixture.hpp" + +using namespace graphene::chain; +using namespace graphene::chain::test; +using namespace graphene::app; + +BOOST_FIXTURE_TEST_SUITE(grouped_orders_api_tests, database_fixture) +BOOST_AUTO_TEST_CASE(api_limit_get_grouped_limit_orders) { + try + { + app.enable_plugin("grouped_orders"); + graphene::app::orders_api orders_api(app); + optional< api_access_info > acc; + optional start; + + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + asset_id_type bit_jmj_id = create_bitasset("JMJBIT").id; + generate_block(); + fc::usleep(fc::milliseconds(100)); + GRAPHENE_CHECK_THROW(orders_api.get_grouped_limit_orders(std::string( static_cast(asset_id_type())), std::string( static_cast(asset_id_type())),10, start,260), fc::exception); + vector< limit_order_group > orders =orders_api.get_grouped_limit_orders(std::string( static_cast(asset_id_type())), std::string( static_cast(bit_jmj_id)), 10,start,240); + BOOST_REQUIRE_EQUAL( orders.size(), 0u); + }catch (fc::exception &e) + { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index b5b8ef8199..53e426ca6c 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -596,12 +596,173 @@ BOOST_AUTO_TEST_CASE(get_account_history_operations) { BOOST_CHECK_EQUAL(histories.size(), 75u); if (histories.size() > 0) BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); - + } catch (fc::exception &e) { edump((e.to_detail_string())); throw; } } +//new test case for increasing the limit based on the config file +BOOST_AUTO_TEST_CASE(api_limit_get_account_history_operations) { + try { + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("CNY", account_id_type()); + create_account("sam"); + create_account("alice"); + + generate_block(); + fc::usleep(fc::milliseconds(100)); + + int asset_create_op_id = operation::tag::value; + int account_create_op_id = operation::tag::value; + + //account_id_type() did 1 asset_create op + vector histories = hist_api.get_account_history_operations( + "committee-account", asset_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 0u); + BOOST_CHECK_EQUAL(histories[0].op.which(), asset_create_op_id); + + //account_id_type() did 2 account_create ops + histories = hist_api.get_account_history_operations( + "committee-account", account_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 2u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // No asset_create op larger than id1 + histories = hist_api.get_account_history_operations( + "committee-account", asset_create_op_id, operation_history_id_type(), operation_history_id_type(1), 200); + BOOST_CHECK_EQUAL(histories.size(), 0u); + + // Limit 1 returns 1 result + histories = hist_api.get_account_history_operations( + "committee-account", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 1); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // alice has 1 op + histories = hist_api.get_account_history_operations( + "alice", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // create a bunch of accounts + for(int i = 0; i < 126; ++i) + { + std::string acct_name = "mytempacct" + std::to_string(i); + create_account(acct_name); + } + generate_block(); + + // history is set to limit transactions to 125 (see database_fixture.hpp) + // so asking for more should only return 125 (and not throw exception, + // see https://github.com/bitshares/bitshares-core/issues/1490 + GRAPHENE_CHECK_THROW(hist_api.get_account_history_operations("commitee-account", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 301), fc::exception); + histories = hist_api.get_account_history_operations("committee-account", account_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_REQUIRE_EQUAL( histories.size(), 125u ); + } + catch (fc::exception &e) + { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE(api_limit_get_account_history) { + try{ + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + + generate_block(); + fc::usleep(fc::milliseconds(100)); + + int asset_create_op_id = operation::tag::value; + int account_create_op_id = operation::tag::value; + //account_id_type() did 3 ops and includes id0 + vector histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 210, operation_history_id_type()); + + BOOST_CHECK_EQUAL(histories.size(), 3u); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0u); + BOOST_CHECK_EQUAL(histories[2].op.which(), asset_create_op_id); + + // 1 account_create op larger than id1 + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(1), 210, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK(histories[0].id.instance() != 0u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + + // Limit 2 returns 2 result + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 2, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 2u); + BOOST_CHECK(histories[1].id.instance() != 0u); + BOOST_CHECK_EQUAL(histories[1].op.which(), account_create_op_id); + // bob has 1 op + histories = hist_api.get_account_history("bob", operation_history_id_type(), 210, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // create a bunch of accounts + for(int i = 0; i < 126; ++i) + { + std::string acct_name = "mytempacct" + std::to_string(i); + create_account(acct_name); + } + generate_block(); + + GRAPHENE_CHECK_THROW(hist_api.get_account_history("1.2.0", operation_history_id_type(), 260, operation_history_id_type()), fc::exception); + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 210, operation_history_id_type()); + BOOST_REQUIRE_EQUAL( histories.size(), 125u ); + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE(api_limit_get_relative_account_history) { + try{ + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + + generate_block(); + fc::usleep(fc::milliseconds(100)); + + GRAPHENE_CHECK_THROW(hist_api.get_relative_account_history("1.2.0", 126, 260, 0), fc::exception); + vector histories = hist_api.get_relative_account_history("1.2.0", 126, 210, 0); + BOOST_REQUIRE_EQUAL( histories.size(), 0u ); + + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE(api_limit_get_account_history_by_operations) { + try { + graphene::app::history_api hist_api(app); + vector operation_types; + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + generate_block(); + fc::usleep(fc::milliseconds(100)); + GRAPHENE_CHECK_THROW(hist_api.get_account_history_by_operations("1.2.0", operation_types, 0, 260), fc::exception); + history_operation_detail histories = hist_api.get_account_history_by_operations("1.2.0", operation_types, 0, 210); + BOOST_REQUIRE_EQUAL( histories.total_count, 3u ); + } + catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/htlc_tests.cpp b/tests/tests/htlc_tests.cpp index 826cc7e1a2..b75aeed456 100644 --- a/tests/tests/htlc_tests.cpp +++ b/tests/tests/htlc_tests.cpp @@ -38,7 +38,7 @@ #include -#include +#include #include #include @@ -58,7 +58,7 @@ BOOST_FIXTURE_TEST_SUITE( htlc_tests, database_fixture ) void generate_random_preimage(uint16_t key_size, std::vector& vec) { - std::independent_bits_engine rbe; + std::independent_bits_engine rbe; std::generate(begin(vec), end(vec), std::ref(rbe)); return; } @@ -107,18 +107,18 @@ void set_committee_parameters(database_fixture* db_fixture) const chain_parameters& existing_params = db_fixture->db.get_global_properties().parameters; const fee_schedule_type& existing_fee_schedule = *(existing_params.current_fees); // create a new fee_shedule - fee_schedule_type new_fee_schedule; - new_fee_schedule.scale = GRAPHENE_100_PERCENT; + std::shared_ptr new_fee_schedule = std::make_shared(); + new_fee_schedule->scale = GRAPHENE_100_PERCENT; // replace the old with the new flat_map params_map = get_htlc_fee_parameters(); for(auto param : existing_fee_schedule.parameters) { auto itr = params_map.find(param.which()); if (itr == params_map.end()) - new_fee_schedule.parameters.insert(param); + new_fee_schedule->parameters.insert(param); else { - new_fee_schedule.parameters.insert( (*itr).second); + new_fee_schedule->parameters.insert( (*itr).second); } } // htlc parameters @@ -210,10 +210,60 @@ try { auto obj = db_api.get_objects( {alice_htlc_id }).front(); graphene::chain::htlc_object htlc = obj.template as(GRAPHENE_MAX_NESTED_OBJECTS); + // someone else attempts to extend it (bob says he's alice, but he's not) + { + graphene::chain::htlc_extend_operation bad_extend; + bad_extend.htlc_id = alice_htlc_id; + bad_extend.seconds_to_add = 10; + bad_extend.fee = db.get_global_properties().parameters.current_fees->calculate_fee(bad_extend); + bad_extend.update_issuer = alice_id; + trx.operations.push_back(bad_extend); + sign(trx, bob_private_key); + GRAPHENE_CHECK_THROW( PUSH_TX(db, trx, database::skip_nothing ), fc::exception ); + trx.clear(); + } + // someone else attempts to extend it (bob wants to extend Alice's contract) + { + graphene::chain::htlc_extend_operation bad_extend; + bad_extend.htlc_id = alice_htlc_id; + bad_extend.seconds_to_add = 10; + bad_extend.fee = db.get_global_properties().parameters.current_fees->calculate_fee(bad_extend); + bad_extend.update_issuer = bob_id; + trx.operations.push_back(bad_extend); + sign(trx, bob_private_key); + GRAPHENE_CHECK_THROW( PUSH_TX(db, trx, ~0 ), fc::exception ); + trx.clear(); + } + // attempt to extend it with too much time + { + graphene::chain::htlc_extend_operation big_extend; + big_extend.htlc_id = alice_htlc_id; + big_extend.seconds_to_add = db.get_global_properties().parameters.extensions.value.updatable_htlc_options->max_timeout_secs + 10; + big_extend.fee = db.get_global_properties().parameters.current_fees->calculate_fee(big_extend); + big_extend.update_issuer = alice_id; + trx.operations.push_back(big_extend); + sign(trx, alice_private_key); + GRAPHENE_CHECK_THROW( PUSH_TX(db, trx, ~0), fc::exception ); + trx.clear(); + } + + // attempt to extend properly + { + graphene::chain::htlc_extend_operation extend; + extend.htlc_id = alice_htlc_id; + extend.seconds_to_add = 10; + extend.fee = db.get_global_properties().parameters.current_fees->calculate_fee(extend); + extend.update_issuer = alice_id; + trx.operations.push_back(extend); + sign(trx, alice_private_key); + PUSH_TX(db, trx, ~0); + trx.clear(); + } + // let it expire (wait for timeout) generate_blocks( db.head_block_time() + fc::seconds(120) ); // verify funds return (minus the fees) - BOOST_CHECK_EQUAL( get_balance(alice_id, graphene::chain::asset_id_type()), 96 * GRAPHENE_BLOCKCHAIN_PRECISION ); + BOOST_CHECK_EQUAL( get_balance(alice_id, graphene::chain::asset_id_type()), 92 * GRAPHENE_BLOCKCHAIN_PRECISION ); // verify Bob cannot execute the contract after the fact } FC_LOG_AND_RETHROW() } @@ -221,12 +271,13 @@ try { BOOST_AUTO_TEST_CASE( htlc_fulfilled ) { try { - ACTORS((alice)(bob)); + ACTORS((alice)(bob)(joker)); int64_t init_balance(100 * GRAPHENE_BLOCKCHAIN_PRECISION); transfer( committee_account, alice_id, graphene::chain::asset(init_balance) ); transfer( committee_account, bob_id, graphene::chain::asset(init_balance) ); + transfer( committee_account, joker_id, graphene::chain::asset(init_balance) ); advance_past_hardfork(this); @@ -279,23 +330,32 @@ try { // make sure Alice's money is still on hold, and account for extra fee BOOST_CHECK_EQUAL( get_balance( alice_id, graphene::chain::asset_id_type()), 72 * GRAPHENE_BLOCKCHAIN_PRECISION ); - // send a redeem operation to claim the funds + // grab number of history objects to make sure everyone gets notified + size_t alice_num_history = get_operation_history(alice_id).size(); + size_t bob_num_history = get_operation_history(bob_id).size(); + size_t joker_num_history = get_operation_history(joker_id).size(); + + // joker sends a redeem operation to claim the funds for bob { graphene::chain::htlc_redeem_operation update_operation; - update_operation.redeemer = bob_id; + update_operation.redeemer = joker_id; update_operation.htlc_id = alice_htlc_id; update_operation.preimage = pre_image; update_operation.fee = db.current_fee_schedule().calculate_fee( update_operation ); trx.operations.push_back( update_operation ); - sign(trx, bob_private_key); + sign(trx, joker_private_key); PUSH_TX( db, trx, ~0 ); generate_block(); trx.clear(); } - // verify funds end up in Bob's account (100 + 20 - 4(fee) ) - BOOST_CHECK_EQUAL( get_balance(bob_id, graphene::chain::asset_id_type()), 116 * GRAPHENE_BLOCKCHAIN_PRECISION ); + // verify funds end up in Bob's account (100 + 20 ) + BOOST_CHECK_EQUAL( get_balance(bob_id, graphene::chain::asset_id_type()), 120 * GRAPHENE_BLOCKCHAIN_PRECISION ); // verify funds remain out of Alice's acount ( 100 - 20 - 4 ) BOOST_CHECK_EQUAL( get_balance(alice_id, graphene::chain::asset_id_type()), 72 * GRAPHENE_BLOCKCHAIN_PRECISION ); + // verify all three get notified + BOOST_CHECK_EQUAL( get_operation_history(alice_id).size(), alice_num_history + 1); + BOOST_CHECK_EQUAL( get_operation_history(bob_id).size(), bob_num_history + 1); + BOOST_CHECK_EQUAL( get_operation_history(joker_id).size(), joker_num_history + 1); } FC_LOG_AND_RETHROW() } @@ -390,18 +450,18 @@ BOOST_AUTO_TEST_CASE( htlc_hardfork_test ) const chain_parameters& existing_params = db.get_global_properties().parameters; const fee_schedule_type& existing_fee_schedule = *(existing_params.current_fees); // create a new fee_shedule - fee_schedule_type new_fee_schedule; - new_fee_schedule.scale = existing_fee_schedule.scale; + std::shared_ptr new_fee_schedule = std::make_shared(); + new_fee_schedule->scale = existing_fee_schedule.scale; // replace the old with the new flat_map params_map = get_htlc_fee_parameters(); for(auto param : existing_fee_schedule.parameters) { auto itr = params_map.find(param.which()); if (itr == params_map.end()) - new_fee_schedule.parameters.insert(param); + new_fee_schedule->parameters.insert(param); else { - new_fee_schedule.parameters.insert( (*itr).second); + new_fee_schedule->parameters.insert( (*itr).second); } } proposal_create_operation cop = proposal_create_operation::committee_proposal( @@ -428,18 +488,18 @@ BOOST_AUTO_TEST_CASE( htlc_hardfork_test ) const chain_parameters& existing_params = db.get_global_properties().parameters; const fee_schedule_type& existing_fee_schedule = *(existing_params.current_fees); // create a new fee_shedule - fee_schedule_type new_fee_schedule; - new_fee_schedule.scale = existing_fee_schedule.scale; + std::shared_ptr new_fee_schedule = std::make_shared(); + new_fee_schedule->scale = existing_fee_schedule.scale; // replace the old with the new flat_map params_map = get_htlc_fee_parameters(); for(auto param : existing_fee_schedule.parameters) { auto itr = params_map.find(param.which()); if (itr == params_map.end()) - new_fee_schedule.parameters.insert(param); + new_fee_schedule->parameters.insert(param); else { - new_fee_schedule.parameters.insert( (*itr).second); + new_fee_schedule->parameters.insert( (*itr).second); } } proposal_create_operation cop = proposal_create_operation::committee_proposal(db.get_global_properties().parameters, db.head_block_time()); @@ -485,8 +545,12 @@ BOOST_AUTO_TEST_CASE( htlc_hardfork_test ) generate_block(); // get the maintenance skip slots out of the way BOOST_TEST_MESSAGE( "Verify that the change has been implemented" ); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.extensions.value.updatable_htlc_options->max_preimage_size, 2048u); - BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees->get().fee, 2 * GRAPHENE_BLOCKCHAIN_PRECISION); + const graphene::chain::fee_schedule& current_fee_schedule = *(db.get_global_properties().parameters.current_fees); + const htlc_create_operation::fee_parameters_type& htlc_fee + = current_fee_schedule.get(); + BOOST_CHECK_EQUAL(htlc_fee.fee, 2 * GRAPHENE_BLOCKCHAIN_PRECISION); } FC_LOG_AND_RETHROW() } @@ -768,4 +832,158 @@ try { } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(htlc_database_api) { +try { + + ACTORS((alice)(bob)(carl)(dan)); + + int64_t init_balance(100 * GRAPHENE_BLOCKCHAIN_PRECISION); + + transfer( committee_account, alice_id, graphene::chain::asset(init_balance) ); + + generate_blocks(HARDFORK_CORE_1468_TIME); + set_expiration( db, trx ); + + set_committee_parameters(this); + + uint16_t preimage_size = 256; + std::vector pre_image(256); + std::independent_bits_engine rbe; + std::generate(begin(pre_image), end(pre_image), std::ref(rbe)); + graphene::chain::htlc_id_type alice_htlc_id_bob; + graphene::chain::htlc_id_type alice_htlc_id_carl; + graphene::chain::htlc_id_type alice_htlc_id_dan; + + generate_block(); + set_expiration( db, trx ); + trx.clear(); + // alice puts a htlc contract to bob + { + graphene::chain::htlc_create_operation create_operation; + BOOST_TEST_MESSAGE("Alice, who has 100 coins, is transferring 3 coins to Bob"); + create_operation.amount = graphene::chain::asset( 3 * GRAPHENE_BLOCKCHAIN_PRECISION ); + create_operation.to = bob_id; + create_operation.claim_period_seconds = 60; + create_operation.preimage_hash = hash_it( pre_image ); + create_operation.preimage_size = preimage_size; + create_operation.from = alice_id; + create_operation.fee = db.get_global_properties().parameters.current_fees->calculate_fee(create_operation); + trx.operations.push_back(create_operation); + sign(trx, alice_private_key); + PUSH_TX(db, trx, ~0); + trx.clear(); + set_expiration( db, trx ); + graphene::chain::signed_block blk = generate_block(); + processed_transaction alice_trx = blk.transactions[0]; + alice_htlc_id_bob = alice_trx.operation_results[0].get(); + generate_block(); + set_expiration( db, trx ); + } + + trx.clear(); + // alice puts a htlc contract to carl + { + graphene::chain::htlc_create_operation create_operation; + BOOST_TEST_MESSAGE("Alice, who has 100 coins, is transferring 3 coins to Carl"); + create_operation.amount = graphene::chain::asset( 3 * GRAPHENE_BLOCKCHAIN_PRECISION ); + create_operation.to = carl_id; + create_operation.claim_period_seconds = 60; + create_operation.preimage_hash = hash_it( pre_image ); + create_operation.preimage_size = preimage_size; + create_operation.from = alice_id; + create_operation.fee = db.get_global_properties().parameters.current_fees->calculate_fee(create_operation); + trx.operations.push_back(create_operation); + sign(trx, alice_private_key); + PUSH_TX(db, trx, ~0); + trx.clear(); + set_expiration( db, trx ); + graphene::chain::signed_block blk = generate_block(); + processed_transaction alice_trx = blk.transactions[0]; + alice_htlc_id_carl = alice_trx.operation_results[0].get(); + generate_block(); + set_expiration( db, trx ); + } + + trx.clear(); + // alice puts a htlc contract to dan + { + graphene::chain::htlc_create_operation create_operation; + BOOST_TEST_MESSAGE("Alice, who has 100 coins, is transferring 3 coins to Dan"); + create_operation.amount = graphene::chain::asset( 3 * GRAPHENE_BLOCKCHAIN_PRECISION ); + create_operation.to = dan_id; + create_operation.claim_period_seconds = 60; + create_operation.preimage_hash = hash_it( pre_image ); + create_operation.preimage_size = preimage_size; + create_operation.from = alice_id; + create_operation.fee = db.get_global_properties().parameters.current_fees->calculate_fee(create_operation); + trx.operations.push_back(create_operation); + sign(trx, alice_private_key); + PUSH_TX(db, trx, ~0); + trx.clear(); + set_expiration( db, trx ); + graphene::chain::signed_block blk = generate_block(); + processed_transaction alice_trx = blk.transactions[0]; + alice_htlc_id_dan = alice_trx.operation_results[0].get(); + generate_block(); + set_expiration( db, trx ); + } + + graphene::app::database_api db_api(db, &(this->app.get_options()) ) ; + + auto htlc = db_api.get_htlc(alice_htlc_id_bob); + BOOST_CHECK_EQUAL( htlc->id.instance(), 0); + BOOST_CHECK_EQUAL( htlc->transfer.from.instance.value, 16 ); + BOOST_CHECK_EQUAL( htlc->transfer.to.instance.value, 17 ); + + htlc = db_api.get_htlc(alice_htlc_id_carl); + BOOST_CHECK_EQUAL( htlc->id.instance(), 1); + BOOST_CHECK_EQUAL( htlc->transfer.from.instance.value, 16 ); + BOOST_CHECK_EQUAL( htlc->transfer.to.instance.value, 18 ); + + htlc = db_api.get_htlc(alice_htlc_id_dan); + BOOST_CHECK_EQUAL( htlc->id.instance(), 2); + BOOST_CHECK_EQUAL( htlc->transfer.from.instance.value, 16 ); + BOOST_CHECK_EQUAL( htlc->transfer.to.instance.value, 19 ); + + auto htlcs_alice = db_api.get_htlc_by_from(alice.name, graphene::chain::htlc_id_type(0), 100); + BOOST_CHECK_EQUAL( htlcs_alice.size(), 3 ); + BOOST_CHECK_EQUAL( htlcs_alice[0].id.instance(), 0 ); + BOOST_CHECK_EQUAL( htlcs_alice[1].id.instance(), 1 ); + BOOST_CHECK_EQUAL( htlcs_alice[2].id.instance(), 2 ); + + htlcs_alice = db_api.get_htlc_by_from(alice.name, graphene::chain::htlc_id_type(1), 1); + BOOST_CHECK_EQUAL( htlcs_alice.size(), 1 ); + BOOST_CHECK_EQUAL( htlcs_alice[0].id.instance(), 1 ); + + htlcs_alice = db_api.get_htlc_by_from(alice.name, graphene::chain::htlc_id_type(1), 2); + BOOST_CHECK_EQUAL( htlcs_alice.size(), 2 ); + BOOST_CHECK_EQUAL( htlcs_alice[0].id.instance(), 1 ); + BOOST_CHECK_EQUAL( htlcs_alice[1].id.instance(), 2 ); + + auto htlcs_bob = db_api.get_htlc_by_to(bob.name, graphene::chain::htlc_id_type(0), 100); + BOOST_CHECK_EQUAL( htlcs_bob.size(), 1 ); + BOOST_CHECK_EQUAL( htlcs_bob[0].id.instance(), 0 ); + + auto htlcs_carl = db_api.get_htlc_by_to(carl.name, graphene::chain::htlc_id_type(0), 100); + BOOST_CHECK_EQUAL( htlcs_carl.size(), 1 ); + BOOST_CHECK_EQUAL( htlcs_carl[0].id.instance(), 1 ); + + auto htlcs_dan = db_api.get_htlc_by_to(dan.name, graphene::chain::htlc_id_type(0), 100); + BOOST_CHECK_EQUAL( htlcs_dan.size(), 1 ); + BOOST_CHECK_EQUAL( htlcs_dan[0].id.instance(), 2 ); + + auto full = db_api.get_full_accounts({alice.name}, false); + BOOST_CHECK_EQUAL( full[alice.name].htlcs_from.size(), 3 ); + + full = db_api.get_full_accounts({bob.name}, false); + BOOST_CHECK_EQUAL( full[bob.name].htlcs_to.size(), 1 ); + +} catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + + + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/market_fee_sharing_tests.cpp b/tests/tests/market_fee_sharing_tests.cpp index c8df1f56ac..2ba95b2c5b 100644 --- a/tests/tests/market_fee_sharing_tests.cpp +++ b/tests/tests/market_fee_sharing_tests.cpp @@ -105,9 +105,7 @@ struct reward_database_fixture : database_fixture void create_vesting_balance_object(const account_id_type& account_id, vesting_balance_type balance_type ) { - auto block_time = db.head_block_time(); - - db.create([&account_id, &block_time, balance_type] (vesting_balance_object &vbo) { + db.create([&account_id, balance_type] (vesting_balance_object &vbo) { vbo.owner = account_id; vbo.balance_type = balance_type; }); @@ -149,7 +147,7 @@ BOOST_AUTO_TEST_CASE(create_asset_with_additional_options_after_hf) generate_blocks_past_hf1268(); - uint16_t reward_percent = 100; + uint16_t reward_percent = GRAPHENE_100_PERCENT + 1; // 100.01% flat_set whitelist = {issuer_id}; price price(asset(1, asset_id_type(1)), asset(1)); uint16_t market_fee_percent = 100; @@ -158,6 +156,28 @@ BOOST_AUTO_TEST_CASE(create_asset_with_additional_options_after_hf) options.value.reward_percent = reward_percent; options.value.whitelist_market_fee_sharing = whitelist; + GRAPHENE_CHECK_THROW(create_user_issued_asset("USD", + issuer, + charge_market_fee, + price, + 2, + market_fee_percent, + options), + fc::assert_exception); + + reward_percent = GRAPHENE_100_PERCENT; // 100% + options.value.reward_percent = reward_percent; + GRAPHENE_CHECK_THROW(create_user_issued_asset("USD", + issuer, + charge_market_fee, + price, + 2, + market_fee_percent, + options), + fc::assert_exception); + + reward_percent = GRAPHENE_100_PERCENT - 1; // 99.99% + options.value.reward_percent = reward_percent; asset_object usd_asset = create_user_issued_asset("USD", issuer, charge_market_fee, @@ -199,8 +219,18 @@ BOOST_AUTO_TEST_CASE(update_additional_options_after_hf) generate_blocks_past_hf1268(); - uint16_t reward_percent = 40; + uint16_t reward_percent = GRAPHENE_100_PERCENT + 1; // 100.01% flat_set whitelist = {issuer_id}; + GRAPHENE_CHECK_THROW( + update_asset(issuer_id, issuer_private_key, usd_asset.get_id(), reward_percent, whitelist), + fc::assert_exception ); + + reward_percent = GRAPHENE_100_PERCENT; // 100% + GRAPHENE_CHECK_THROW( + update_asset(issuer_id, issuer_private_key, usd_asset.get_id(), reward_percent, whitelist), + fc::assert_exception ); + + reward_percent = GRAPHENE_100_PERCENT - 1; // 99.99% update_asset(issuer_id, issuer_private_key, usd_asset.get_id(), reward_percent, whitelist); asset_object updated_asset = usd_asset.get_id()(db); diff --git a/tests/tests/market_rounding_tests.cpp b/tests/tests/market_rounding_tests.cpp index b71e1cd0ff..66698bee45 100644 --- a/tests/tests/market_rounding_tests.cpp +++ b/tests/tests/market_rounding_tests.cpp @@ -26,6 +26,7 @@ #include +#include #include #include "../common/database_fixture.hpp" diff --git a/tests/tests/market_tests.cpp b/tests/tests/market_tests.cpp index c30505f87f..f71c56a1fb 100644 --- a/tests/tests/market_tests.cpp +++ b/tests/tests/market_tests.cpp @@ -26,6 +26,7 @@ #include +#include #include #include "../common/database_fixture.hpp" @@ -291,7 +292,7 @@ BOOST_AUTO_TEST_CASE(hardfork_core_338_test) // settlement price = 1/10, mssp = 1/11 // This sell order above MSSP will not be matched with a call - create_sell_order(seller, bitusd.amount(7), core.amount(78))->id; + BOOST_CHECK( create_sell_order(seller, bitusd.amount(7), core.amount(78)) != nullptr ); BOOST_CHECK_EQUAL( 2993, get_balance(seller, bitusd) ); BOOST_CHECK_EQUAL( 0, get_balance(seller, core) ); diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index c5d7bc2318..ce5255f4e8 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE( more_call_order_update_test ) GRAPHENE_REQUIRE_THROW( borrow( bob, bitusd.amount(10000), core.amount(17500) ), fc::exception ); BOOST_TEST_MESSAGE( "alice borrow using 4x collateral at 1:1 price" ); - borrow( alice, bitusd.amount(100000), core.amount(400000) )->id; + BOOST_CHECK( borrow( alice, bitusd.amount(100000), core.amount(400000) ) != nullptr ); BOOST_REQUIRE_EQUAL( get_balance( alice, bitusd ), 100000 ); BOOST_REQUIRE_EQUAL( get_balance( alice, core ), 10000000 - 400000 ); @@ -476,7 +476,7 @@ BOOST_AUTO_TEST_CASE( more_call_order_update_test_after_hardfork_583 ) GRAPHENE_REQUIRE_THROW( borrow( bob, bitusd.amount(10000), core.amount(17500) ), fc::exception ); BOOST_TEST_MESSAGE( "alice borrow using 4x collateral at 1:1 price" ); - borrow( alice, bitusd.amount(100000), core.amount(400000) )->id; + BOOST_CHECK( borrow( alice, bitusd.amount(100000), core.amount(400000) ) != nullptr ); BOOST_REQUIRE_EQUAL( get_balance( alice, bitusd ), 100000 ); BOOST_REQUIRE_EQUAL( get_balance( alice, core ), 10000000 - 400000 ); @@ -599,9 +599,6 @@ BOOST_AUTO_TEST_CASE( call_order_update_validation_test ) BOOST_AUTO_TEST_CASE( call_order_update_target_cr_hardfork_time_test ) { try { - auto mi = db.get_global_properties().parameters.maintenance_interval; - generate_blocks(HARDFORK_CORE_834_TIME - mi); - set_expiration( db, trx ); ACTORS((sam)(alice)(bob)); @@ -622,15 +619,6 @@ BOOST_AUTO_TEST_CASE( call_order_update_target_cr_hardfork_time_test ) FC_ASSERT( bitusd.bitasset_data(db).current_feed.settlement_price == current_feed.settlement_price ); - BOOST_TEST_MESSAGE( "alice tries to borrow using 4x collateral at 1:1 price with target_cr set, " - "will fail before hard fork time" ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 0 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 1 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 1749 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 1750 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 1751 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( borrow( alice, bitusd.amount(100000), core.amount(400000), 65535 ), fc::assert_exception ); - auto call_update_proposal = [this]( const account_object& proposer, const account_object& updater, const asset& delta_collateral, @@ -643,7 +631,7 @@ BOOST_AUTO_TEST_CASE( call_order_update_target_cr_hardfork_time_test ) op.delta_debt = delta_debt; op.extensions.value.target_collateral_ratio = target_cr; - const auto& curfees = *db.get_global_properties().parameters.current_fees; + const auto& curfees = db.get_global_properties().parameters.get_current_fees(); const auto& proposal_create_fees = curfees.get(); proposal_create_operation prop; prop.fee_paying_account = proposer.id; @@ -658,13 +646,7 @@ BOOST_AUTO_TEST_CASE( call_order_update_target_cr_hardfork_time_test ) PUSH_TX( db, tx, ~0 ); }; - BOOST_TEST_MESSAGE( "bob tries to propose a proposal with target_cr set, " - "will fail before hard fork time" ); - GRAPHENE_REQUIRE_THROW( call_update_proposal( bob, alice, bitusd.amount(10), core.amount(40), 0 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( call_update_proposal( bob, alice, bitusd.amount(10), core.amount(40), 1750 ), fc::assert_exception ); - GRAPHENE_REQUIRE_THROW( call_update_proposal( bob, alice, bitusd.amount(10), core.amount(40), 65535 ), fc::assert_exception ); - - generate_blocks( db.get_dynamic_global_properties().next_maintenance_time ); + generate_blocks(HARDFORK_CORE_834_TIME); set_expiration( db, trx ); BOOST_TEST_MESSAGE( "bob tries to propose a proposal with target_cr set, " @@ -968,7 +950,7 @@ BOOST_AUTO_TEST_CASE( update_account ) account_upgrade_operation op; op.account_to_upgrade = nathan.id; op.upgrade_to_lifetime_member = true; - op.fee = db.get_global_properties().parameters.current_fees->calculate_fee(op); + op.fee = db.get_global_properties().parameters.get_current_fees().calculate_fee(op); trx.operations = {op}; PUSH_TX( db, trx, ~0 ); } @@ -1316,7 +1298,7 @@ BOOST_AUTO_TEST_CASE( update_uia_issuer ) op.new_issuer = new_issuer.id; op.asset_to_update = asset_id; - const auto& curfees = *db.get_global_properties().parameters.current_fees; + const auto& curfees = db.get_global_properties().parameters.get_current_fees(); const auto& proposal_create_fees = curfees.get(); proposal_create_operation prop; prop.fee_paying_account = issuer.id; @@ -1349,16 +1331,9 @@ BOOST_AUTO_TEST_CASE( update_uia_issuer ) const auto& test = create_user_issued_asset("UPDATEISSUER", alice_id(db), 0); const asset_id_type test_id = test.id; - BOOST_TEST_MESSAGE( "can't use this operation before the hardfork" ); - GRAPHENE_REQUIRE_THROW( update_issuer( test_id, alice_id(db), bob_id(db), alice_owner), fc::exception ); - - BOOST_TEST_MESSAGE( "can't use this operation before the hardfork (even if wrapped into a proposal)" ); - GRAPHENE_REQUIRE_THROW( update_issuer_proposal( test_id, alice_id(db), bob_id(db), alice_owner), fc::exception ); - // Fast Forward to Hardfork time generate_blocks( HARDFORK_CORE_199_TIME ); - BOOST_TEST_MESSAGE( "After hardfork time, proposal goes through (but doesn't execute yet)" ); update_issuer_proposal( test_id, alice_id(db), bob_id(db), alice_owner); BOOST_TEST_MESSAGE( "Can't change issuer if not my asset" ); diff --git a/tests/tests/operation_tests2.cpp b/tests/tests/operation_tests2.cpp index a5c7b839c9..3d50c66e56 100644 --- a/tests/tests/operation_tests2.cpp +++ b/tests/tests/operation_tests2.cpp @@ -102,13 +102,9 @@ withdrawal_period_descriptor current_period(const withdraw_permission_object& pe * (a) it checks the creation of withdrawal claims, * (b) it is used as a precursor for tests that evaluate withdrawal claims. * - * NOTE: This test verifies proper withdrawal claim behavior - * as it occurred before (for backward compatibility) - * Issue #23 was addressed. - * That issue is concerned with ensuring that the first claim - * can occur before the first withdrawal period. + * NOTE: This test verifies proper withdrawal claim behavior. */ -BOOST_AUTO_TEST_CASE( withdraw_permission_create_before_hardfork_23 ) +BOOST_AUTO_TEST_CASE( withdraw_permission_create ) { try { auto nathan_private_key = generate_private_key("nathan"); auto dan_private_key = generate_private_key("dan"); @@ -126,52 +122,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create_before_hardfork_23 ) op.withdrawal_limit = asset(5); op.withdrawal_period_sec = fc::hours(1).to_seconds(); op.periods_until_expiration = 5; - op.period_start_time = db.head_block_time() + db.get_global_properties().parameters.block_interval*5; // 5 blocks after current blockchain time - trx.operations.push_back(op); - REQUIRE_OP_VALIDATION_FAILURE(op, withdrawal_limit, asset()); - REQUIRE_OP_VALIDATION_FAILURE(op, periods_until_expiration, 0); - REQUIRE_OP_VALIDATION_FAILURE(op, withdraw_from_account, dan_id); - REQUIRE_OP_VALIDATION_FAILURE(op, withdrawal_period_sec, 0); - REQUIRE_THROW_WITH_VALUE(op, withdrawal_limit, asset(10, asset_id_type(10))); - REQUIRE_THROW_WITH_VALUE(op, authorized_account, account_id_type(1000)); - REQUIRE_THROW_WITH_VALUE(op, period_start_time, fc::time_point_sec(10000)); - REQUIRE_THROW_WITH_VALUE(op, withdrawal_period_sec, 1); - trx.operations.back() = op; - } - sign( trx, nathan_private_key ); - PUSH_TX( db, trx ); - trx.clear(); -} FC_LOG_AND_RETHROW() } - -/** - * This auxiliary test is used for two purposes: - * (a) it checks the creation of withdrawal claims, - * (b) it is used as a precursor for tests that evaluate withdrawal claims. - * - * NOTE: This test verifies proper withdrawal claim behavior - * as it should occur after Issue #23 is addressed. - * That issue is concerned with ensuring that the first claim - * can occur before the first withdrawal period. - */ -BOOST_AUTO_TEST_CASE( withdraw_permission_create_after_hardfork_23 ) -{ try { - auto nathan_private_key = generate_private_key("nathan"); - auto dan_private_key = generate_private_key("dan"); - account_id_type nathan_id = create_account("nathan", nathan_private_key.get_public_key()).id; - account_id_type dan_id = create_account("dan", dan_private_key.get_public_key()).id; - - transfer(account_id_type(), nathan_id, asset(1000)); - generate_block(); - set_expiration( db, trx ); - - { - withdraw_permission_create_operation op; - op.authorized_account = dan_id; - op.withdraw_from_account = nathan_id; - op.withdrawal_limit = asset(5); - op.withdrawal_period_sec = fc::hours(1).to_seconds(); - op.periods_until_expiration = 5; - op.period_start_time = HARDFORK_23_TIME + db.get_global_properties().parameters.block_interval*5; // 5 blocks after fork time + op.period_start_time = db.head_block_time() + db.get_global_properties().parameters.block_interval*5; // 5 blocks after fork time trx.operations.push_back(op); REQUIRE_OP_VALIDATION_FAILURE(op, withdrawal_limit, asset()); REQUIRE_OP_VALIDATION_FAILURE(op, periods_until_expiration, 0); @@ -194,177 +145,11 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create_after_hardfork_23 ) * NOTE: The simulated elapse of blockchain time through the use of * generate_blocks() must be carefully used in order to simulate * this test. - * NOTE: This test verifies proper withdrawal claim behavior - * as it occurred before (for backward compatibility) - * Issue #23 was addressed. - * That issue is concerned with ensuring that the first claim - * can occur before the first withdrawal period. + * NOTE: This test verifies proper withdrawal claim behavior. */ -BOOST_AUTO_TEST_CASE( withdraw_permission_test_before_hardfork_23 ) +BOOST_AUTO_TEST_CASE( withdraw_permission_test ) { try { - INVOKE(withdraw_permission_create_before_hardfork_23); - - auto nathan_private_key = generate_private_key("nathan"); - auto dan_private_key = generate_private_key("dan"); - account_id_type nathan_id = get_account("nathan").id; - account_id_type dan_id = get_account("dan").id; - withdraw_permission_id_type permit; - set_expiration( db, trx ); - - fc::time_point_sec first_start_time; - { - const withdraw_permission_object& permit_object = permit(db); - BOOST_CHECK(permit_object.authorized_account == dan_id); - BOOST_CHECK(permit_object.withdraw_from_account == nathan_id); - BOOST_CHECK(permit_object.period_start_time > db.head_block_time()); - first_start_time = permit_object.period_start_time; - BOOST_CHECK(permit_object.withdrawal_limit == asset(5)); - BOOST_CHECK(permit_object.withdrawal_period_sec == fc::hours(1).to_seconds()); - BOOST_CHECK(permit_object.expiration == first_start_time + permit_object.withdrawal_period_sec*5 ); - } - - generate_blocks(2); // Still before the first period, but BEFORE the real time during which "early" claims are checked - - { - withdraw_permission_claim_operation op; - op.withdraw_permission = permit; - op.withdraw_from_account = nathan_id; - op.withdraw_to_account = dan_id; - op.amount_to_withdraw = asset(1); - set_expiration( db, trx ); - - trx.operations.push_back(op); - sign( trx, dan_private_key ); // Transaction should be signed to be valid - - // This operation/transaction will be pushed early/before the first - // withdrawal period - // However, this will not cause an exception prior to HARDFORK_23_TIME - // because withdrawaing before that the first period was acceptable - // before the fix - PUSH_TX( db, trx ); // <-- Claim #1 - - - //Get to the actual withdrawal period - bool miss_intermediate_blocks = false; // Required to have generate_blocks() elapse flush to the time of interest - generate_blocks(first_start_time, miss_intermediate_blocks); - set_expiration( db, trx ); - - REQUIRE_THROW_WITH_VALUE(op, withdraw_permission, withdraw_permission_id_type(5)); - REQUIRE_THROW_WITH_VALUE(op, withdraw_from_account, dan_id); - REQUIRE_THROW_WITH_VALUE(op, withdraw_from_account, account_id_type()); - REQUIRE_THROW_WITH_VALUE(op, withdraw_to_account, nathan_id); - REQUIRE_THROW_WITH_VALUE(op, withdraw_to_account, account_id_type()); - REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(10)); - REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(6)); - set_expiration( db, trx ); - trx.clear(); - trx.operations.push_back(op); - sign( trx, dan_private_key ); - PUSH_TX( db, trx ); // <-- Claim #2 - - // would be legal on its own, but doesn't work because trx already withdrew - REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(5)); - - // Make sure we can withdraw again this period, as long as we're not exceeding the periodic limit - trx.clear(); - // withdraw 1 - trx.operations = {op}; - // make it different from previous trx so it's non-duplicate - trx.expiration += fc::seconds(1); - sign( trx, dan_private_key ); - PUSH_TX( db, trx ); // <-- Claim #3 - trx.clear(); - } - - // Account for three (3) claims of one (1) unit - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 997); - BOOST_CHECK_EQUAL(get_balance(dan_id, asset_id_type()), 3); - - { - const withdraw_permission_object& permit_object = permit(db); - BOOST_CHECK(permit_object.authorized_account == dan_id); - BOOST_CHECK(permit_object.withdraw_from_account == nathan_id); - BOOST_CHECK(permit_object.period_start_time == first_start_time); - BOOST_CHECK(permit_object.withdrawal_limit == asset(5)); - BOOST_CHECK(permit_object.withdrawal_period_sec == fc::hours(1).to_seconds()); - BOOST_CHECK_EQUAL(permit_object.claimed_this_period.value, 3 ); // <-- Account for three (3) claims of one (1) unit - BOOST_CHECK(permit_object.expiration == first_start_time + 5*permit_object.withdrawal_period_sec); - generate_blocks(first_start_time + permit_object.withdrawal_period_sec); - // lazy update: verify period_start_time isn't updated until new trx occurs - BOOST_CHECK(permit_object.period_start_time == first_start_time); - } - - { - // Leave Nathan with one unit - transfer(nathan_id, dan_id, asset(996)); - - // Attempt a withdrawal claim for units than available - withdraw_permission_claim_operation op; - op.withdraw_permission = permit; - op.withdraw_from_account = nathan_id; - op.withdraw_to_account = dan_id; - op.amount_to_withdraw = asset(5); - trx.operations.push_back(op); - set_expiration( db, trx ); - sign( trx, dan_private_key ); - //Throws because nathan doesn't have the money - GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); - - // Attempt a withdrawal claim for which nathan does have sufficient units - op.amount_to_withdraw = asset(1); - trx.clear(); - trx.operations = {op}; - set_expiration( db, trx ); - sign( trx, dan_private_key ); - PUSH_TX( db, trx ); - } - - BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 0); - BOOST_CHECK_EQUAL(get_balance(dan_id, asset_id_type()), 1000); - trx.clear(); - transfer(dan_id, nathan_id, asset(1000)); - - { - const withdraw_permission_object& permit_object = permit(db); - BOOST_CHECK(permit_object.authorized_account == dan_id); - BOOST_CHECK(permit_object.withdraw_from_account == nathan_id); - BOOST_CHECK(permit_object.period_start_time == first_start_time + permit_object.withdrawal_period_sec); - BOOST_CHECK(permit_object.expiration == first_start_time + 5*permit_object.withdrawal_period_sec); - BOOST_CHECK(permit_object.withdrawal_limit == asset(5)); - BOOST_CHECK(permit_object.withdrawal_period_sec == fc::hours(1).to_seconds()); - generate_blocks(permit_object.expiration); - } - // Ensure the permit object has been garbage collected - BOOST_CHECK(db.find_object(permit) == nullptr); - - { - withdraw_permission_claim_operation op; - op.withdraw_permission = permit; - op.withdraw_from_account = nathan_id; - op.withdraw_to_account = dan_id; - op.amount_to_withdraw = asset(5); - trx.operations.push_back(op); - set_expiration( db, trx ); - sign( trx, dan_private_key ); - //Throws because the permission has expired - GRAPHENE_CHECK_THROW(PUSH_TX( db, trx ), fc::exception); - } - } FC_LOG_AND_RETHROW() } - -/** - * Test the claims of withdrawals both before and during - * authorized withdrawal periods. - * NOTE: The simulated elapse of blockchain time through the use of - * generate_blocks() must be carefully used in order to simulate - * this test. - * NOTE: This test verifies proper withdrawal claim behavior - * as it should occur after Issue #23 is addressed. - * That issue is concerned with ensuring that the first claim - * can occur before the first withdrawal period. - */ -BOOST_AUTO_TEST_CASE( withdraw_permission_test_after_hardfork_23 ) -{ try { - INVOKE(withdraw_permission_create_after_hardfork_23); + INVOKE(withdraw_permission_create); auto nathan_private_key = generate_private_key("nathan"); auto dan_private_key = generate_private_key("dan"); @@ -385,8 +170,6 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test_after_hardfork_23 ) BOOST_CHECK(permit_object.expiration == first_start_time + permit_object.withdrawal_period_sec*5 ); } - generate_blocks(HARDFORK_23_TIME); // Still before the first period, but DURING the real time during which "early" claims are checked - { withdraw_permission_claim_operation op; op.withdraw_permission = permit; @@ -508,7 +291,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test_after_hardfork_23 ) BOOST_AUTO_TEST_CASE( withdraw_permission_nominal_case ) { try { - INVOKE(withdraw_permission_create_before_hardfork_23); + INVOKE(withdraw_permission_create); auto nathan_private_key = generate_private_key("nathan"); auto dan_private_key = generate_private_key("dan"); @@ -568,17 +351,10 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_whitelist_asset_test ) | database::skip_merkle_check ; - generate_blocks( HARDFORK_415_TIME, true, skip ); // get over Graphene 415 asset whitelisting bug generate_block( skip ); for( int i=0; i<2; i++ ) { - if( i == 1 ) - { - generate_blocks( HARDFORK_CORE_942_TIME, true, skip ); - generate_block( skip ); - } - int blocks = 0; set_expiration( db, trx ); @@ -642,10 +418,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_whitelist_asset_test ) op.withdraw_to_account = dan_id; op.amount_to_withdraw = asset(5, uia_id); trx.operations.push_back(op); - if( i == 0 ) // before hard fork, should pass - PUSH_TX( db, trx, ~0 ); - else // after hard fork, should throw - GRAPHENE_CHECK_THROW( PUSH_TX( db, trx, ~0 ), fc::assert_exception ); + GRAPHENE_CHECK_THROW( PUSH_TX( db, trx, ~0 ), fc::assert_exception ); trx.operations.clear(); } @@ -680,9 +453,9 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_whitelist_asset_test ) */ BOOST_AUTO_TEST_CASE( withdraw_permission_incremental_case ) { try { - INVOKE(withdraw_permission_create_after_hardfork_23); - time_point_sec expected_first_period_start_time = HARDFORK_23_TIME + db.get_global_properties().parameters.block_interval*5; // Hard-coded to synchronize with withdraw_permission_create_after_hardfork_23() - uint64_t expected_period_duration_seconds = fc::hours(1).to_seconds(); // Hard-coded to synchronize with withdraw_permission_create_after_hardfork_23() + INVOKE(withdraw_permission_create); + time_point_sec expected_first_period_start_time = db.head_block_time() + db.get_global_properties().parameters.block_interval*5; // Hard-coded to synchronize with withdraw_permission_create() + uint64_t expected_period_duration_seconds = fc::hours(1).to_seconds(); // Hard-coded to synchronize with withdraw_permission_create() auto nathan_private_key = generate_private_key("nathan"); auto dan_private_key = generate_private_key("dan"); @@ -884,7 +657,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_incremental_case ) BOOST_AUTO_TEST_CASE( withdraw_permission_update ) { try { - INVOKE(withdraw_permission_create_before_hardfork_23); + INVOKE(withdraw_permission_create); auto nathan_private_key = generate_private_key("nathan"); account_id_type nathan_id = get_account("nathan").id; @@ -2237,7 +2010,6 @@ BOOST_AUTO_TEST_CASE( top_n_special ) ACTORS( (alice)(bob)(chloe)(dan)(izzy)(stan) ); generate_blocks( HARDFORK_516_TIME ); - generate_blocks( HARDFORK_599_TIME ); try { @@ -2388,9 +2160,7 @@ BOOST_AUTO_TEST_CASE( buyback ) ACTORS( (alice)(bob)(chloe)(dan)(izzy)(philbin) ); upgrade_to_lifetime_member(philbin_id); - generate_blocks( HARDFORK_538_TIME ); generate_blocks( HARDFORK_555_TIME ); - generate_blocks( HARDFORK_599_TIME ); try { diff --git a/tests/tests/serialization_tests.cpp b/tests/tests/serialization_tests.cpp index 59e16f01e3..91085af454 100644 --- a/tests/tests/serialization_tests.cpp +++ b/tests/tests/serialization_tests.cpp @@ -86,42 +86,6 @@ BOOST_AUTO_TEST_CASE( json_tests ) } } -BOOST_AUTO_TEST_CASE( extended_private_key_type_test ) -{ - try - { - fc::ecc::extended_private_key key = fc::ecc::extended_private_key( fc::ecc::private_key::generate(), - fc::sha256(), - 0, 0, 0 ); - extended_private_key_type type = extended_private_key_type( key ); - std::string packed = std::string( type ); - extended_private_key_type unpacked = extended_private_key_type( packed ); - BOOST_CHECK( type == unpacked ); - } catch ( const fc::exception& e ) - { - edump((e.to_detail_string())); - throw; - } -} - -BOOST_AUTO_TEST_CASE( extended_public_key_type_test ) -{ - try - { - fc::ecc::extended_public_key key = fc::ecc::extended_public_key( fc::ecc::private_key::generate().get_public_key(), - fc::sha256(), - 0, 0, 0 ); - extended_public_key_type type = extended_public_key_type( key ); - std::string packed = std::string( type ); - extended_public_key_type unpacked = extended_public_key_type( packed ); - BOOST_CHECK( type == unpacked ); - } catch ( const fc::exception& e ) - { - edump((e.to_detail_string())); - throw; - } -} - BOOST_AUTO_TEST_CASE( extension_serialization_test ) { try diff --git a/tests/tests/settle_tests.cpp b/tests/tests/settle_tests.cpp index 07244cd225..f64719e613 100644 --- a/tests/tests/settle_tests.cpp +++ b/tests/tests/settle_tests.cpp @@ -26,6 +26,7 @@ #include +#include #include #include "../common/database_fixture.hpp" diff --git a/tests/tests/uia_tests.cpp b/tests/tests/uia_tests.cpp index 0efc4c5ef9..e68b55d5dd 100644 --- a/tests/tests/uia_tests.cpp +++ b/tests/tests/uia_tests.cpp @@ -156,14 +156,6 @@ BOOST_AUTO_TEST_CASE( issue_whitelist_uia ) op.issue_to_account = nathan_id; trx.operations.emplace_back(op); set_expiration( db, trx ); - //Fail because nathan is not whitelisted, but only before hardfork time - if( db.head_block_time() <= HARDFORK_415_TIME ) - { - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception); - generate_blocks( HARDFORK_415_TIME ); - generate_block(); - set_expiration( db, trx ); - } PUSH_TX( db, trx, ~0 ); BOOST_CHECK(is_authorized_asset( db, nathan_id(db), uia_id(db) )); @@ -275,17 +267,8 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia ) BOOST_TEST_MESSAGE( "Attempting to transfer from nathan after blacklisting, should fail" ); op.amount = advanced.amount(50); trx.operations.back() = op; - //Fail because nathan is blacklisted - if( db.head_block_time() <= HARDFORK_419_TIME ) - { - // before the hardfork time, it fails because the whitelist check fails - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), transfer_from_account_not_whitelisted ); - } - else - { - // after the hardfork time, it fails because the fees are not in a whitelisted asset - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception ); - } + // it fails because the fees are not in a whitelisted asset + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception ); BOOST_TEST_MESSAGE( "Attempting to burn from nathan after blacklisting, should fail" ); asset_reserve_operation burn; @@ -531,11 +514,7 @@ BOOST_AUTO_TEST_CASE( asset_name_test ) create_user_issued_asset( "ALPHA.ONE", alice_id(db), 0 ); BOOST_CHECK( has_asset("ALPHA") ); BOOST_CHECK( has_asset("ALPHA.ONE") ); - // Sam tries to create asset ending in a number but fails before hf_620 - GRAPHENE_REQUIRE_THROW( create_user_issued_asset( "SP500", sam_id(db), 0 ), fc::assert_exception ); - BOOST_CHECK( !has_asset("SP500") ); - - // create a proposal to create asset ending in a number, this will fail before hf_620 + // create a proposal to create asset ending in a number auto& core = asset_id_type()(db); asset_create_operation op_p; op_p.issuer = alice_id; @@ -543,7 +522,7 @@ BOOST_AUTO_TEST_CASE( asset_name_test ) op_p.common_options.core_exchange_rate = asset( 1 ) / asset( 1, asset_id_type( 1 ) ); op_p.fee = core.amount(0); - const auto& curfees = *db.get_global_properties().parameters.current_fees; + const auto& curfees = db.get_global_properties().parameters.get_current_fees(); const auto& proposal_create_fees = curfees.get(); proposal_create_operation prop; prop.fee_paying_account = alice_id; @@ -556,9 +535,8 @@ BOOST_AUTO_TEST_CASE( asset_name_test ) db.current_fee_schedule().set_fee( tx.operations.back() ); set_expiration( db, tx ); sign( tx, alice_private_key ); - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, tx ), fc::assert_exception); + PUSH_TX( db, tx ); - generate_blocks( HARDFORK_CORE_620_TIME + 1); generate_block(); // Sam can create asset ending in number after hf_620