diff --git a/Doxyfile b/Doxyfile index 75931ef9a4..fad32a549a 100644 --- a/Doxyfile +++ b/Doxyfile @@ -32,19 +32,19 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Graphene" +PROJECT_NAME = "Bitshares-Core" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = "2.0.180202" # 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 # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = +PROJECT_BRIEF = "Your share in the Decentralized Exchange" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -758,7 +758,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = doc/main.dox libraries/chain libraries/chain/db libraries/app libraries/wallet +INPUT = README.md doc/main.dox libraries/chain libraries/chain/db libraries/app libraries/wallet # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -894,7 +894,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = "README.md" #--------------------------------------------------------------------------- # Configuration options related to source browsing diff --git a/README.md b/README.md index d3619a14ae..c5317db965 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ BitShares Core bugs can be reported directly to the [issue tracker](https://gith BitShares UI bugs should be reported to the [UI issue tracker](https://github.com/bitshares/bitshares-ui/issues) +Up to date online Doxygen documentation can be found at [Doxygen](https://bitshares.org/doxygen/hierarchy.html) + Using the API ------------- diff --git a/libraries/app/util.cpp b/libraries/app/util.cpp index b3a3b9833a..a7c80b9ebe 100644 --- a/libraries/app/util.cpp +++ b/libraries/app/util.cpp @@ -54,7 +54,7 @@ fc::uint128 to_capped128( const u256& t ) string uint128_amount_to_string( const fc::uint128& amount, const uint8_t precision ) { try { string s = string( amount ); - if( precision == 0 || amount == 0 ) + if( precision == 0 || amount == fc::uint128() ) return s; std::stringstream ss; diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index db82df3270..b571f88748 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -247,7 +247,7 @@ processed_transaction database::_push_transaction( const signed_transaction& trx temp_session.merge(); // notify anyone listening to pending transactions - on_pending_transaction( trx ); + notify_on_pending_transaction( trx ); return processed_trx; } @@ -286,7 +286,7 @@ processed_transaction database::push_proposal(const proposal_object& proposal) { _applied_ops.resize( old_applied_ops_size ); } - elog( "e", ("e",e.to_detail_string() ) ); + elog( "${e}", ("e",e.to_detail_string() ) ); throw; } @@ -538,7 +538,7 @@ void database::_apply_block( const signed_block& next_block ) apply_debug_updates(); // notify observers that the block has been applied - applied_block( next_block ); //emit + notify_applied_block( next_block ); //emit _applied_ops.clear(); notify_changed_objects(); diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 65dbaafec9..4d8a066e7f 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -448,11 +448,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) const auto& assets_by_symbol = get_index_type().indices().get(); const auto get_asset_id = [&assets_by_symbol](const string& symbol) { auto itr = assets_by_symbol.find(symbol); - - // TODO: This is temporary for handling BTS snapshot - if( symbol == "BTS" ) - itr = assets_by_symbol.find(GRAPHENE_SYMBOL); - FC_ASSERT(itr != assets_by_symbol.end(), "Unable to find asset '${sym}'. Did you forget to add a record for it to initial_assets?", ("sym", symbol)); diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 8760feb041..f5f9f6753c 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -353,6 +353,16 @@ static void get_relevant_accounts( const object* obj, flat_set& namespace graphene { namespace chain { +void database::notify_applied_block( const signed_block& block ) +{ + GRAPHENE_TRY_NOTIFY( applied_block, block ) +} + +void database::notify_on_pending_transaction( const signed_transaction& tx ) +{ + GRAPHENE_TRY_NOTIFY( on_pending_transaction, tx ) +} + void database::notify_changed_objects() { try { if( _undo_db.enabled() ) @@ -372,7 +382,7 @@ void database::notify_changed_objects() get_relevant_accounts(obj, new_accounts_impacted); } - new_objects(new_ids, new_accounts_impacted); + GRAPHENE_TRY_NOTIFY( new_objects, new_ids, new_accounts_impacted) } // Changed @@ -386,7 +396,7 @@ void database::notify_changed_objects() get_relevant_accounts(item.second.get(), changed_accounts_impacted); } - changed_objects(changed_ids, changed_accounts_impacted); + GRAPHENE_TRY_NOTIFY( changed_objects, changed_ids, changed_accounts_impacted) } // Removed @@ -403,7 +413,7 @@ void database::notify_changed_objects() get_relevant_accounts(obj, removed_accounts_impacted); } - removed_objects(removed_ids, removed, removed_accounts_impacted); + GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted) } } } FC_CAPTURE_AND_LOG( (0) ) } diff --git a/libraries/chain/include/graphene/chain/asset_object.hpp b/libraries/chain/include/graphene/chain/asset_object.hpp index cec4c988b3..a337152bf6 100644 --- a/libraries/chain/include/graphene/chain/asset_object.hpp +++ b/libraries/chain/include/graphene/chain/asset_object.hpp @@ -217,14 +217,10 @@ namespace graphene { namespace chain { void update_median_feeds(time_point_sec current_time); }; - struct by_feed_expiration; typedef multi_index_container< asset_bitasset_data_object, indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > >, - ordered_non_unique< tag, - const_mem_fun< asset_bitasset_data_object, time_point_sec, &asset_bitasset_data_object::feed_expiration_time > - > + ordered_unique< tag, member< object, object_id_type, &object::id > > > > asset_bitasset_data_object_multi_index_type; typedef generic_index asset_bitasset_data_index; diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index c8246229e4..d8fb726dad 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -412,6 +412,8 @@ namespace graphene { namespace chain { protected: //Mark pop_undo() as protected -- we do not want outside calling pop_undo(); it should call pop_block() instead void pop_undo() { object_database::pop_undo(); } + void notify_applied_block( const signed_block& block ); + void notify_on_pending_transaction( const signed_transaction& tx ); void notify_changed_objects(); private: diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index 2e07ca26f6..ee26402918 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -65,6 +65,21 @@ msg \ ) +#define GRAPHENE_TRY_NOTIFY( signal, ... ) \ + try \ + { \ + signal( __VA_ARGS__ ); \ + } \ + catch( const graphene::chain::plugin_exception& e ) \ + { \ + elog( "Caught plugin exception: ${e}", ("e", e.to_detail_string() ) ); \ + throw; \ + } \ + catch( ... ) \ + { \ + wlog( "Caught unexpected exception in plugin" ); \ + } + namespace graphene { namespace chain { FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) @@ -77,6 +92,7 @@ namespace graphene { namespace chain { 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_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" ) diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp index 7fc15c2070..dddb618a68 100644 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ b/libraries/chain/include/graphene/chain/protocol/types.hpp @@ -259,8 +259,6 @@ namespace graphene { namespace chain { 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); - // TODO: This is temporary for testing - bool is_valid_v1( const std::string& base58str ); }; struct extended_public_key_type diff --git a/libraries/chain/index.cpp b/libraries/chain/index.cpp deleted file mode 100644 index 41a469b21a..0000000000 --- a/libraries/chain/index.cpp +++ /dev/null @@ -1,43 +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 - -namespace graphene { namespace chain { - void base_primary_index::save_undo( const object& obj ) - { _db.save_undo( obj ); } - - void base_primary_index::on_add( const object& obj ) - { - _db.save_undo_add( obj ); - for( auto ob : _observers ) ob->on_add( obj ); - } - - void base_primary_index::on_remove( const object& obj ) - { _db.save_undo_remove( obj ); for( auto ob : _observers ) ob->on_remove( obj ); } - - void base_primary_index::on_modify( const object& obj ) - {for( auto ob : _observers ) ob->on_modify( obj ); } -} } // graphene::chain diff --git a/libraries/chain/market_evaluator.cpp b/libraries/chain/market_evaluator.cpp index a8141e5e10..9badb68f41 100644 --- a/libraries/chain/market_evaluator.cpp +++ b/libraries/chain/market_evaluator.cpp @@ -147,13 +147,6 @@ void_result call_order_update_evaluator::do_evaluate(const call_order_update_ope else if( _bitasset_data->current_feed.settlement_price.is_null() ) FC_THROW_EXCEPTION(insufficient_feeds, "Cannot borrow asset with no price feed."); - if( o.delta_debt.amount < 0 ) - { - FC_ASSERT( d.get_balance(*_paying_account, *_debt_asset) >= o.delta_debt, - "Cannot cover by ${c} when payer only has ${b}", - ("c", o.delta_debt.amount)("b", d.get_balance(*_paying_account, *_debt_asset).amount) ); - } - if( o.delta_collateral.amount > 0 ) { FC_ASSERT( d.get_balance(*_paying_account, _bitasset_data->options.short_backing_asset(d)) >= o.delta_collateral, @@ -176,7 +169,7 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat // Deduct the debt paid from the total supply of the debt asset. d.modify(_debt_asset->dynamic_asset_data_id(d), [&](asset_dynamic_data_object& dynamic_asset) { dynamic_asset.current_supply += o.delta_debt.amount; - assert(dynamic_asset.current_supply >= 0); + FC_ASSERT(dynamic_asset.current_supply >= 0); }); } diff --git a/libraries/chain/protocol/types.cpp b/libraries/chain/protocol/types.cpp index ac5ad8c83a..baa036b688 100644 --- a/libraries/chain/protocol/types.cpp +++ b/libraries/chain/protocol/types.cpp @@ -44,17 +44,6 @@ namespace graphene { namespace chain { // 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 ); - - // TODO: This is temporary for testing - try - { - if( is_valid_v1( base58str ) ) - prefix = std::string( "BTS" ); - } - catch( ... ) - { - } - const size_t prefix_len = prefix.size(); FC_ASSERT( base58str.size() > prefix_len ); FC_ASSERT( base58str.substr( 0, prefix_len ) == prefix , "", ("base58str", base58str) ); @@ -64,20 +53,6 @@ namespace graphene { namespace chain { FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0] == bin_key.check ); }; - // TODO: This is temporary for testing - bool public_key_type::is_valid_v1( const std::string& base58str ) - { - std::string prefix( "BTS" ); - 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::ecc::public_key_data key_data = bin_key.data; - FC_ASSERT( fc::ripemd160::hash( key_data.data, key_data.size() )._hash[0] == bin_key.check ); - return true; - } - public_key_type::operator fc::ecc::public_key_data() const { return key_data; diff --git a/libraries/chain/transaction_object.cpp b/libraries/chain/transaction_object.cpp deleted file mode 100644 index fb4f75dff7..0000000000 --- a/libraries/chain/transaction_object.cpp +++ /dev/null @@ -1,95 +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 - -namespace graphene { namespace chain { - -const object* transaction_index::create(const std::function& constructor, object_id_type) -{ - transaction_object obj; - - obj.id = get_next_available_id(); - constructor(&obj); - - auto result = _index.insert(std::move(obj)); - FC_ASSERT(result.second, "Could not create transaction_object! Most likely a uniqueness constraint is violated."); - return &*result.first; -} - -void transaction_index::modify(const object* obj, - const std::function& m) -{ - assert(obj != nullptr); - FC_ASSERT(obj->id < _index.size()); - - const transaction_object* t = dynamic_cast(obj); - assert(t != nullptr); - - auto itr = _index.find(obj->id.instance()); - assert(itr != _index.end()); - _index.modify(itr, [&m](transaction_object& o) { m(&o); }); -} - -void transaction_index::add(unique_ptr o) -{ - assert(o); - object_id_type id = o->id; - assert(id.space() == transaction_object::space_id); - assert(id.type() == transaction_object::type_id); - assert(id.instance() == size()); - - auto trx = dynamic_cast(o.get()); - assert(trx != nullptr); - o.release(); - - auto result = _index.insert(std::move(*trx)); - FC_ASSERT(result.second, "Could not insert transaction_object! Most likely a uniqueness constraint is violated."); -} - -void transaction_index::remove(object_id_type id) -{ - auto& index = _index.get(); - auto itr = index.find(id.instance()); - if( itr == index.end() ) - return; - - assert(id.space() == transaction_object::space_id); - assert(id.type() == transaction_object::type_id); - - index.erase(itr); -} - -const object*transaction_index::get(object_id_type id) const -{ - if( id.type() != transaction_object::type_id || - id.space() != transaction_object::space_id ) - return nullptr; - - auto itr = _index.find(id.instance()); - if( itr == _index.end() ) - return nullptr; - return &*itr; -} - -} } // graphene::chain diff --git a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp index b63802db20..159c4a1cf9 100644 --- a/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp +++ b/libraries/plugins/elasticsearch/elasticsearch_plugin.cpp @@ -270,7 +270,7 @@ void elasticsearch_plugin_impl::sendBulk(std::string _elasticsearch_node_url, bo //wlog((bulking)); struct curl_slist *headers = NULL; - curl_slist_append(headers, "Content-Type: application/json"); + headers = curl_slist_append(headers, "Content-Type: application/json"); std::string url = _elasticsearch_node_url + "_bulk"; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_POST, true); diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4290d2b172..ec7ad00825 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -507,6 +507,13 @@ class wallet_api * @ingroup Transaction Builder API */ signed_transaction sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast = true); + + /** Broadcast signed transaction + * @param tx signed transaction + * @returns the transaction ID along with the signed transaction. + */ + pair broadcast_transaction(signed_transaction tx); + /** * @ingroup Transaction Builder API */ @@ -660,8 +667,6 @@ class wallet_api bool is_public_key_registered(string public_key) const; /** Converts a signed_transaction in JSON form to its binary representation. - * - * TODO: I don't see a broadcast_transaction() function, do we need one? * * @param tx the transaction to serialize * @returns the binary form of the transaction. It will not be hex encoded, @@ -1628,6 +1633,7 @@ FC_API( graphene::wallet::wallet_api, (set_fees_on_builder_transaction) (preview_builder_transaction) (sign_builder_transaction) + (broadcast_transaction) (propose_builder_transaction) (propose_builder_transaction2) (remove_builder_transaction) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 2f9650c9ed..7c8a6025f3 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -565,8 +565,6 @@ class wallet_api_impl } account_object get_account(account_id_type id) const { - if( _wallet.my_accounts.get().count(id) ) - return *_wallet.my_accounts.get().find(id); auto rec = _remote_db->get_accounts({id}).front(); FC_ASSERT(rec); return *rec; @@ -580,19 +578,6 @@ class wallet_api_impl // It's an ID return get_account(*id); } else { - // It's a name - if( _wallet.my_accounts.get().count(account_name_or_id) ) - { - auto local_account = *_wallet.my_accounts.get().find(account_name_or_id); - auto blockchain_account = _remote_db->lookup_account_names({account_name_or_id}).front(); - FC_ASSERT( blockchain_account ); - if (local_account.id != blockchain_account->id) - elog("my account id ${id} different from blockchain id ${id2}", ("id", local_account.id)("id2", blockchain_account->id)); - if (local_account.name != blockchain_account->name) - elog("my account name ${id} different from blockchain name ${id2}", ("id", local_account.name)("id2", blockchain_account->name)); - - return *_wallet.my_accounts.get().find(account_name_or_id); - } auto rec = _remote_db->lookup_account_names({account_name_or_id}).front(); FC_ASSERT( rec && rec->name == account_name_or_id ); return *rec; @@ -866,6 +851,19 @@ class wallet_api_impl return _builder_transactions[transaction_handle] = sign_transaction(_builder_transactions[transaction_handle], broadcast); } + + pair broadcast_transaction(signed_transaction tx) + { + 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())); + throw; + } + return std::make_pair(tx.id(),tx); + } + signed_transaction propose_builder_transaction( transaction_handle_type handle, time_point_sec expiration = time_point::now() + fc::minutes(1), @@ -3043,6 +3041,11 @@ signed_transaction wallet_api::sign_builder_transaction(transaction_handle_type return my->sign_builder_transaction(transaction_handle, broadcast); } +pair wallet_api::broadcast_transaction(signed_transaction tx) +{ + return my->broadcast_transaction(tx); +} + signed_transaction wallet_api::propose_builder_transaction( transaction_handle_type handle, time_point_sec expiration,