From 9080800c5b61dbd0f374fe7ce3495e0e8e9cf657 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 7 Sep 2015 17:46:47 -0400 Subject: [PATCH] Updated APIs, fixed crash - update fc to fix crash in websocket message handling - added api to verify transactions without broadcasting them - added api to broadcast a block produced outside the P2P network or witness --- libraries/app/api.cpp | 13 +++++++++ libraries/app/application.cpp | 5 ++++ libraries/app/include/graphene/app/api.hpp | 9 ++++++ libraries/chain/db_block.cpp | 6 ++++ .../chain/include/graphene/chain/database.hpp | 7 +++++ libraries/fc | 2 +- programs/witness_node/main.cpp | 29 +++++++++++-------- 7 files changed, 58 insertions(+), 13 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 5fc139fe..306e678b 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -629,6 +629,12 @@ namespace graphene { namespace app { _app.p2p_node()->broadcast_transaction(trx); } + void network_broadcast_api::broadcast_block( const signed_block& b ) + { + _app.chain_database()->push_block(b); + _app.p2p_node()->broadcast( net::block_message( b )); + } + void network_broadcast_api::broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction& trx) { trx.validate(); @@ -1214,6 +1220,13 @@ namespace graphene { namespace app { wdump((result)); return result; } + /** + * Validates a transaction against the current state without broadcast it on the network. + */ + processed_transaction database_api::validate_transaction( const signed_transaction& trx )const + { + return _db.validate_transaction(trx); + } bool database_api::verify_authority( const signed_transaction& trx )const { diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 70b2899a..c9783d53 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -708,6 +708,11 @@ void application::shutdown_plugins() entry.second->plugin_shutdown(); return; } +void application::shutdown() +{ + if( my->_chain_db ) + my->_chain_db->close(); +} void application::initialize_plugins( const boost::program_options::variables_map& options ) { diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index ed495010..4100a62f 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -347,6 +347,11 @@ namespace graphene { namespace app { */ bool verify_account_authority( const string& name_or_id, const flat_set& signers )const; + /** + * Validates a transaction against the current state without broadcast it on the network. + */ + processed_transaction validate_transaction( const signed_transaction& trx )const; + /** * @return the set of blinded balance objects by commitment ID @@ -462,6 +467,8 @@ namespace graphene { namespace app { */ void broadcast_transaction_with_callback( confirmation_callback cb, const signed_transaction& trx); + void broadcast_block( const signed_block& block ); + /** * @brief Not reflected, thus not accessible to API clients. * @@ -595,6 +602,7 @@ FC_API(graphene::app::database_api, (get_blinded_balances) (get_required_fees) (set_subscribe_callback) + (validate_transaction) ) FC_API(graphene::app::history_api, (get_account_history) @@ -604,6 +612,7 @@ FC_API(graphene::app::history_api, FC_API(graphene::app::network_broadcast_api, (broadcast_transaction) (broadcast_transaction_with_callback) + (broadcast_block) ) FC_API(graphene::app::network_node_api, (add_node) diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index fa93b8ed..0181cfa0 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -213,6 +213,12 @@ processed_transaction database::_push_transaction( const signed_transaction& trx return processed_trx; } +processed_transaction database::validate_transaction( const signed_transaction& trx ) +{ + auto session = _undo_db.start_undo_session(); + return _apply_transaction( trx ); +} + processed_transaction database::push_proposal(const proposal_object& proposal) { transaction_evaluation_state eval_state(this); diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 43056a73..c3fc26c8 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -404,7 +404,13 @@ namespace graphene { namespace chain { asset calculate_market_fee(const asset_object& recv_asset, const asset& trade_amount); asset pay_market_fees( const asset_object& recv_asset, const asset& receives ); + ///@} + /** + * This method validates transactions without adding it to the pending state. + * @return true if the transaction would validate + */ + processed_transaction validate_transaction( const signed_transaction& trx ); /** * @} @@ -429,6 +435,7 @@ namespace graphene { namespace chain { processed_transaction _apply_transaction( const signed_transaction& trx ); operation_result apply_operation( transaction_evaluation_state& eval_state, const operation& op ); + ///Steps involved in applying a new block ///@{ diff --git a/libraries/fc b/libraries/fc index c89a25a5..19e42ac4 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit c89a25a55c333bd202185cebf3f87eeae2b54761 +Subproject commit 19e42ac4c41d0a2bbdc8094c2efeed5e28e0ed75 diff --git a/programs/witness_node/main.cpp b/programs/witness_node/main.cpp index 74126d39..97c7a4a9 100644 --- a/programs/witness_node/main.cpp +++ b/programs/witness_node/main.cpp @@ -53,8 +53,8 @@ void write_default_logging_config_to_stream(std::ostream& out); fc::optional load_logging_config_from_ini_file(const fc::path& config_ini_filename); int main(int argc, char** argv) { + app::application* node = new app::application(); try { - app::application node; bpo::options_description app_options("Graphene Witness Node"); bpo::options_description cfg_options("Graphene Witness Node"); app_options.add_options() @@ -64,14 +64,14 @@ int main(int argc, char** argv) { bpo::variables_map options; - auto witness_plug = node.register_plugin(); - auto history_plug = node.register_plugin(); - auto market_history_plug = node.register_plugin(); + auto witness_plug = node->register_plugin(); + auto history_plug = node->register_plugin(); + auto market_history_plug = node->register_plugin(); try { bpo::options_description cli, cfg; - node.set_program_options(cli, cfg); + node->set_program_options(cli, cfg); app_options.add(cli); cfg_options.add(cfg); bpo::store(bpo::parse_command_line(argc, argv, app_options), options); @@ -151,26 +151,31 @@ int main(int argc, char** argv) { } bpo::notify(options); - node.initialize(data_dir, options); - node.initialize_plugins( options ); + node->initialize(data_dir, options); + node->initialize_plugins( options ); - node.startup(); - node.startup_plugins(); + node->startup(); + node->startup_plugins(); fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); fc::set_signal_handler([&exit_promise](int signal) { + elog( "Caught ^C attempting to exit cleanly" ); exit_promise->set_value(signal); }, SIGINT); - ilog("Started witness node on a chain with ${h} blocks.", ("h", node.chain_database()->head_block_num())); - ilog("Chain ID is ${id}", ("id", node.chain_database()->get_chain_id()) ); + ilog("Started witness node on a chain with ${h} blocks.", ("h", node->chain_database()->head_block_num())); + ilog("Chain ID is ${id}", ("id", node->chain_database()->get_chain_id()) ); int signal = exit_promise->wait(); ilog("Exiting from signal ${n}", ("n", signal)); - node.shutdown_plugins(); + node->shutdown_plugins(); + node->shutdown(); + delete node; return 0; } catch( const fc::exception& e ) { elog("Exiting with error:\n${e}", ("e", e.to_detail_string())); + node->shutdown(); + delete node; return 1; } }