diff --git a/BUILD_UBUNTU.md b/BUILD_UBUNTU.md index ea39c59..5741637 100644 --- a/BUILD_UBUNTU.md +++ b/BUILD_UBUNTU.md @@ -1,11 +1 @@ TODO: add rest of unbuntu instructions here. - -If you want posts to be merged / patched then you will require Qt5 to be installed - -sudo apt-get install qt5-default qttools5-dev-tools - -Or you can disable it via cmake: - -cmake -DENABLE_CONTENT_PATCHING=OFF . - -You may need to set CMAKE_PREFIX_PATH to `Qt/5.5/clang_64/` diff --git a/CMakeLists.txt b/CMakeLists.txt index d7c5767..a4107ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,6 @@ LIST(APPEND BOOST_COMPONENTS thread system filesystem program_options - signals - serialization chrono unit_test_framework context diff --git a/README.md b/README.md index f67c099..0ed5e90 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ each individual to inspect the code to understand the consensus rules. Build Instructions ------------------ These instructions apply on Fedora 24. For other distributions, make sure you have -installed Boost 1.58-1.63 first. You also have instructions to build test net here. +installed Boost 1.60-1.66 first. You also have instructions to build test net here. For building, you need at least 4 GB of memory available. We are testing using Fedora 25, x64 diff --git a/libraries/chain/base_evaluator.cpp b/libraries/chain/base_evaluator.cpp index defa472..18d91aa 100644 --- a/libraries/chain/base_evaluator.cpp +++ b/libraries/chain/base_evaluator.cpp @@ -365,7 +365,7 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ wvdo.auto_vest = o.auto_vest; }); - db().modify( from_account, [&]( account_object& a ) + db().modify( from_account, []( account_object& a ) { a.withdraw_routes++; }); @@ -374,7 +374,7 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ { db().remove( *itr ); - db().modify( from_account, [&]( account_object& a ) + db().modify( from_account, []( account_object& a ) { a.withdraw_routes--; }); @@ -393,7 +393,7 @@ void set_withdraw_vesting_route_evaluator::do_apply( const set_withdraw_vesting_ itr = wd_idx.upper_bound( boost::make_tuple( from_account.id, account_id_type() ) ); uint16_t total_percent = 0; - while( itr->from_account == from_account.id && itr != wd_idx.end() ) + while( itr != wd_idx.end() && itr->from_account == from_account.id ) { total_percent += itr->percent; ++itr; @@ -424,7 +424,7 @@ void account_witness_proxy_evaluator::do_apply( const account_witness_proxy_oper /// check for proxy loops and fail to update the proxy if it would create a loop auto cprox = &new_proxy; while( cprox->proxy.size() != 0 ) { - const auto next_proxy = db().get_account( cprox->proxy ); + const auto& next_proxy = db().get_account( cprox->proxy ); FC_ASSERT( proxy_chain.insert( next_proxy.get_id() ).second, "Attempt to create a proxy loop" ); cprox = &next_proxy; FC_ASSERT( proxy_chain.size() <= MUSE_MAX_PROXY_RECURSION_DEPTH, "Proxy chain is too long" ); diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index c830d60..7063b4a 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -20,8 +20,6 @@ #include #include -#include - #include #include diff --git a/libraries/chain/include/muse/chain/protocol/types.hpp b/libraries/chain/include/muse/chain/protocol/types.hpp index d61aec8..1a75be7 100644 --- a/libraries/chain/include/muse/chain/protocol/types.hpp +++ b/libraries/chain/include/muse/chain/protocol/types.hpp @@ -60,7 +60,6 @@ namespace muse { namespace chain { using fc::enum_type; using fc::optional; using fc::unsigned_int; - using fc::signed_int; using fc::time_point_sec; using fc::time_point; using fc::safe; diff --git a/libraries/db/include/graphene/db/generic_index.hpp b/libraries/db/include/graphene/db/generic_index.hpp index dbc2f4a..e24e265 100644 --- a/libraries/db/include/graphene/db/generic_index.hpp +++ b/libraries/db/include/graphene/db/generic_index.hpp @@ -67,10 +67,25 @@ namespace graphene { namespace db { virtual void modify( const object& obj, const std::function& m )override { - assert( nullptr != dynamic_cast(&obj) ); - auto ok = _indices.modify( _indices.iterator_to( static_cast(obj) ), - [&m]( ObjectType& o ){ m(o); } ); - FC_ASSERT( ok, "Could not modify object, most likely a index constraint was violated" ); + assert(nullptr != dynamic_cast(&obj)); + std::exception_ptr exc; + auto ok = _indices.modify(_indices.iterator_to(static_cast(obj)), + [&m, &exc](ObjectType& o) mutable { + try { + m(o); + } catch (fc::exception e) { + exc = std::current_exception(); + elog("Exception while modifying object: ${e} -- object may be corrupted", + ("e", e)); + } catch (...) { + exc = std::current_exception(); + elog("Unknown exception while modifying object"); + } + } + ); + if (exc) + std::rethrow_exception(exc); + FC_ASSERT(ok, "Could not modify object, most likely an index constraint was violated"); } virtual void remove( const object& obj )override diff --git a/libraries/db/include/graphene/db/object_id.hpp b/libraries/db/include/graphene/db/object_id.hpp index 98c636f..2ed5e74 100644 --- a/libraries/db/include/graphene/db/object_id.hpp +++ b/libraries/db/include/graphene/db/object_id.hpp @@ -34,7 +34,6 @@ namespace graphene { namespace db { using fc::flat_map; using fc::variant; using fc::unsigned_int; - using fc::signed_int; struct object_id_type { diff --git a/libraries/fc b/libraries/fc index 1a27ef3..74d347a 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 1a27ef3ff3da270370b4d9a7214ceb9e4a5f0c29 +Subproject commit 74d347ae7e0d8ae903eaa6e222c732eab8b3d19a diff --git a/libraries/manifest/mf_plugins.cpp b/libraries/manifest/mf_plugins.cpp index fb9e917..223a193 100644 --- a/libraries/manifest/mf_plugins.cpp +++ b/libraries/manifest/mf_plugins.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #define MUSE_DECLARE_PLUGIN_CREATOR( r, data, x ) \ std::shared_ptr< muse::app::abstract_plugin > BOOST_PP_CAT( create_, BOOST_PP_CAT( x, _plugin ) )(); diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index f2d23ad..6197df0 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -822,7 +822,7 @@ namespace graphene { namespace net { namespace detail { _maximum_blocks_per_peer_during_syncing(GRAPHENE_NET_MAX_BLOCKS_PER_PEER_DURING_SYNCING) { _rate_limiter.set_actual_rate_time_constant(fc::seconds(2)); - fc::rand_pseudo_bytes(&_node_id.data[0], (int)_node_id.size()); + fc::rand_bytes(&_node_id.data[0], (int)_node_id.size()); } node_impl::~node_impl() diff --git a/libraries/wallet/CMakeLists.txt b/libraries/wallet/CMakeLists.txt index 533ecce..83d4083 100644 --- a/libraries/wallet/CMakeLists.txt +++ b/libraries/wallet/CMakeLists.txt @@ -11,7 +11,7 @@ if( PERL_FOUND AND DOXYGEN_FOUND AND NOT "${CMAKE_GENERATOR}" STREQUAL "Ninja" ) DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${CMAKE_CURRENT_SOURCE_DIR}/include/muse/wallet/wallet.hpp ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp - COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate_api_documentation.pl ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp.new + COMMAND PERLLIB=${CMAKE_CURRENT_BINARY_DIR} ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate_api_documentation.pl ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp.new COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp.new ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/api_documentation.cpp.new diff --git a/libraries/wallet/include/muse/wallet/wallet.hpp b/libraries/wallet/include/muse/wallet/wallet.hpp index 905a346..027ad15 100644 --- a/libraries/wallet/include/muse/wallet/wallet.hpp +++ b/libraries/wallet/include/muse/wallet/wallet.hpp @@ -6,7 +6,6 @@ #include -#include #include using namespace muse::app; @@ -227,8 +226,12 @@ class wallet_api */ string get_private_key( public_key_type pubkey )const; - /** - * @param role - active | owner | basic | memo + /** Generates public and private key pair using account name + role + password + * as the seed string. Should be compatible with how the UI does it. + * @param account account name to which the password belongs + * @param role active | owner | basic | memo + * @param password the actual password + * @return the key pair (public,private) */ pair get_private_key_from_password( string account, string role, string password )const; @@ -840,10 +843,11 @@ class wallet_api uint64_t get_content_scoring( string content ); /** - * Create a new UIA. + * Create a new UIA with 6 digits precision + * @param issuer Account name used for creating the asset * @param asset_name Unique asset name * @param description Description - * @param max_supply Maximum supply + * @param max_supply Maximum supply (in satoshis!) * @param broadcast Broadcast the transaction? */ annotated_signed_transaction create_asset(string issuer, string asset_name, string description, uint64_t max_supply, bool broadcast); @@ -855,7 +859,7 @@ class wallet_api * @param amount Issued amount * @param broadcast Broadcast the transaction? */ - annotated_signed_transaction issue_asset(string asset_name, string to_account, fc::real128 amount, bool broadcast); + annotated_signed_transaction issue_asset(string asset_name, string to_account, string amount, bool broadcast); /** * Reserve asset from an account @@ -864,7 +868,7 @@ class wallet_api * @param amount Reserved amount * @param broadcast Broadcast the transaction? */ - annotated_signed_transaction reserve_asset(string asset_name, string from_account, fc::real128 amount, bool broadcast); + annotated_signed_transaction reserve_asset(string asset_name, string from_account, string amount, bool broadcast); /** * Update an UIA. @@ -896,8 +900,9 @@ class wallet_api vector lookup_content(const string& start, uint32_t limit ); /** - * Get content list, by namei, filtered by approver - * @param start Starting name + * Get content list, by approver, filtered by approver + * @param start Starting content id + * @param approver Account name that approved the content * @param limit Limit, less than 1000 */ vector lookup_content_by_approver(const string& start, const string& approver, uint32_t limit ); @@ -915,11 +920,10 @@ class wallet_api message_body try_decrypt_message( const message_object& mo ); /** - * Vote on a comment to be paid MUSE + * Vote for content * - * @param voter The account voting - * @param author The author of the comment to be voted on - * @param url The permlink of the comment to be voted on. (author, permlink) is a unique pair + * @param voter The voting account + * @param url The ID of the comment to be voted on * @param weight The weight [-100,100] of the vote * @param broadcast true if you wish to broadcast the transaction */ @@ -1044,7 +1048,6 @@ class wallet_api /** Approve or disapprove a proposal. * - * @param fee_paying_account The account paying the fee for the op. * @param proposal_id The proposal to modify. * @param delta Members contain approvals to create or remove. In JSON you can leave empty members undefined. * @param broadcast true if you wish to broadcast the transaction @@ -1086,7 +1089,7 @@ FC_REFLECT( muse::wallet::wallet_data, (ws_password) ) -FC_REFLECT( muse::wallet::brain_key_info, (brain_priv_key)(wif_priv_key) (pub_key)); +FC_REFLECT( muse::wallet::brain_key_info, (brain_priv_key)(wif_priv_key) (pub_key)) FC_REFLECT_DERIVED( muse::wallet::signed_block_with_info, (muse::chain::signed_block), (block_id)(signing_key)(transaction_ids) ) @@ -1218,4 +1221,4 @@ FC_REFLECT( muse::wallet::approval_delta, (key_approvals_to_add) (key_approvals_to_remove) ) -FC_REFLECT( muse::wallet::memo_data, (from)(to)(nonce)(check)(encrypted) ); +FC_REFLECT( muse::wallet::memo_data, (from)(to)(nonce)(check)(encrypted) ) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 651b77d..ddfc56c 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -26,9 +26,7 @@ #include #include -#include #include -#include #include #include #include @@ -1128,18 +1126,17 @@ class wallet_api_impl }FC_CAPTURE_AND_RETHROW( (asset_name)(description)(max_supply)(new_issuer)(broadcast) ) } - annotated_signed_transaction issue_asset(string asset_name, string to_account, fc::real128 amount, bool broadcast) + annotated_signed_transaction issue_asset(string asset_name, string to_account, string amount, bool broadcast) { auto asset_obj = find_asset(asset_name); - auto to_account_obj = get_account(to_account); if (!asset_obj) FC_THROW("No asset with that symbol exists!"); + get_account(to_account); // verify that it exists auto issuer = get_account_from_id(asset_obj->issuer); asset_issue_operation issue_op; issue_op.issuer = issuer->name; - uint64_t amount_i = (amount*asset::static_precision()).to_uint64(); - issue_op.asset_to_issue = asset(amount_i, asset_obj->id); - issue_op.issue_to_account=to_account; + issue_op.asset_to_issue = asset::from_string( amount + std::string(" ") + std::string(asset_obj->id) ); + issue_op.issue_to_account = to_account; signed_transaction tx; tx.operations.push_back(issue_op); @@ -1148,20 +1145,17 @@ class wallet_api_impl return sign_transaction(tx, broadcast); } - annotated_signed_transaction reserve_asset(string asset_name, string from_account, fc::real128 amount, bool broadcast) + annotated_signed_transaction reserve_asset(string asset_name, string from_account, string amount, bool broadcast) { auto asset_obj = find_asset(asset_name); - auto from_account_obj = get_account(from_account); if (!asset_obj) FC_THROW("No asset with that symbol exists!"); + get_account(from_account); // verify that it exists auto issuer = get_account_from_id(asset_obj->issuer); asset_reserve_operation reserve_op; reserve_op.issuer = issuer->name; - - uint64_t amount_i = (amount*asset::static_precision()).to_uint64(); - - reserve_op.amount_to_reserve = asset(amount_i, asset_obj->id); + reserve_op.amount_to_reserve = asset::from_string( amount + std::string(" ") + std::string(asset_obj->id) ); reserve_op.payer = from_account; signed_transaction tx; @@ -2612,12 +2606,12 @@ annotated_signed_transaction wallet_api::create_asset(string issuer, string asse return my->create_asset(issuer, asset_name, description, max_supply, broadcast); } -annotated_signed_transaction wallet_api::issue_asset(string asset_name, string to_account, fc::real128 amount, bool broadcast) +annotated_signed_transaction wallet_api::issue_asset(string asset_name, string to_account, string amount, bool broadcast) { return my->issue_asset(asset_name, to_account, amount, broadcast); } -annotated_signed_transaction wallet_api::reserve_asset(string asset_name, string from_account, fc::real128 amount, bool broadcast) +annotated_signed_transaction wallet_api::reserve_asset(string asset_name, string from_account, string amount, bool broadcast) { return my->reserve_asset(asset_name, from_account, amount, broadcast); } diff --git a/programs/js_operation_serializer/main.cpp b/programs/js_operation_serializer/main.cpp index 0da797b..9239893 100644 --- a/programs/js_operation_serializer/main.cpp +++ b/programs/js_operation_serializer/main.cpp @@ -112,7 +112,6 @@ template<> struct js_name { static std::string name(){ retu 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 "varuint32"; } }; -template<> struct js_name { static std::string name(){ return "varint32"; } }; template<> struct js_name< time_point_sec > { static std::string name(){ return "time_point_sec"; } }; template diff --git a/tests/tests/api_tests.cpp b/tests/tests/api_tests.cpp index 08d0c25..8ac7b78 100644 --- a/tests/tests/api_tests.cpp +++ b/tests/tests/api_tests.cpp @@ -240,6 +240,8 @@ BOOST_AUTO_TEST_CASE( get_accounts_test ) cup.url = url; cup.side = content_update_operation::side_t::publisher; cup.new_threshold = 60; + cup.new_playing_reward = 0; + cup.new_publishers_share = 0; proposal_create_operation pco; pco.proposed_ops.emplace_back( cup ); diff --git a/tests/tests/authority_tests.cpp b/tests/tests/authority_tests.cpp index adf2458..fc2d673 100644 --- a/tests/tests/authority_tests.cpp +++ b/tests/tests/authority_tests.cpp @@ -1281,6 +1281,7 @@ BOOST_AUTO_TEST_CASE( proposals_with_mixed_authorities ) cup.url = "ipfs://abcdefg1"; cup.side = content_update_operation::side_t::master; cup.new_playing_reward = 500; + cup.new_publishers_share = 0; pc.proposed_ops.emplace_back( cup ); pc.expiration_time = db.head_block_time() + fc::minutes(1); trx.operations.push_back( pc ); diff --git a/tests/tests/database_tests.cpp b/tests/tests/database_tests.cpp index 31a63fb..da442df 100644 --- a/tests/tests/database_tests.cpp +++ b/tests/tests/database_tests.cpp @@ -25,7 +25,7 @@ #include #include - +#include #include #include @@ -62,6 +62,32 @@ BOOST_AUTO_TEST_CASE( undo_test ) } } +/** + * Check that database modify() functors that throw do not get caught by boost, which will remove the object + */ +BOOST_AUTO_TEST_CASE(failed_modify_test) +{ try { + database db; + // Create dummy object + const auto& obj = db.create([](content_object& obj) { + obj.manage_master = authority( 1, "test", 1 ); + }); + content_id_type obj_id = obj.id; + BOOST_CHECK_EQUAL( 1, obj.manage_master.weight_threshold ); + + // Modify dummy object, check that changes stick + db.modify(obj, [](content_object& obj) { + obj.manage_master = authority( 2, "tester", 2 ); + }); + BOOST_CHECK_EQUAL( 2, obj_id(db).manage_master.weight_threshold ); + + // Throw exception when modifying object, check that object still exists after + BOOST_CHECK_THROW(db.modify(obj, [](content_object& obj) { + throw 5; + }), int); + BOOST_CHECK_NE((long)db.find_object(obj_id), (long)nullptr); +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_CASE( merge_test ) { try {