From 7e9a29d6f9a9e05e17a1c9e68723c4375f77c8db Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Wed, 3 Sep 2014 16:36:17 -0400 Subject: [PATCH 1/8] Resolve #741: Add opening and closing price to market history --- libraries/blockchain/chain_database.cpp | 26 +++++++++++-------- .../include/bts/blockchain/config.hpp | 2 +- .../include/bts/blockchain/market_records.hpp | 12 +++++++-- libraries/blockchain/market_engine.cpp | 24 ++++++++++++++--- libraries/cli/cli.cpp | 6 ++++- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/libraries/blockchain/chain_database.cpp b/libraries/blockchain/chain_database.cpp index f375252d2..6c3cfae0c 100644 --- a/libraries/blockchain/chain_database.cpp +++ b/libraries/blockchain/chain_database.cpp @@ -1021,12 +1021,18 @@ namespace bts { namespace blockchain { uint32_t last_block_num = -1; block_id_type last_block_id; my->_block_num_to_id_db.last( last_block_num, last_block_id ); - if( !must_rebuild_index && last_block_num != uint32_t(-1) ) - { - my->_head_block_header = get_block_digest( last_block_id ); - my->_head_block_id = last_block_id; + + try { + if( !must_rebuild_index && last_block_num != uint32_t(-1) ) + { + my->_head_block_header = get_block_digest( last_block_id ); + my->_head_block_id = last_block_id; + } + } catch (...) { + must_rebuild_index = true; } - else + + if( must_rebuild_index || last_block_num == uint32_t(-1) ) { close(); fc::remove_all( data_dir / "index" ); @@ -1040,10 +1046,8 @@ namespace bts { namespace blockchain { if( !reindex_status_callback ) std::cout << "Please be patient, this will take a few minutes...\r\nRe-indexing database..." << std::flush << std::fixed; - else { - std::cout << "Progress: 0" << std::endl; + else reindex_status_callback(0); - } uint32_t blocks_indexed = 0; const float total_blocks = num_to_id.size(); @@ -1062,10 +1066,8 @@ namespace bts { namespace blockchain { if( !reindex_status_callback ) std::cout << "\rRe-indexing database... " "Approximately " << std::setprecision(2) << progress << "% complete." << std::flush; - else { - std::cout << "progress: " << progress << std::endl; + else reindex_status_callback(progress); - } } push_block(block); @@ -2701,6 +2703,8 @@ namespace bts { namespace blockchain { record_itr.key().timestamp, fc::variant(string(record_itr.value().highest_bid.ratio * base->precision / quote->precision)).as_double() / (BTS_BLOCKCHAIN_MAX_SHARES*1000), fc::variant(string(record_itr.value().lowest_ask.ratio * base->precision / quote->precision)).as_double() / (BTS_BLOCKCHAIN_MAX_SHARES*1000), + fc::variant(string(record_itr.value().opening_price.ratio * base->precision / quote->precision)).as_double() / (BTS_BLOCKCHAIN_MAX_SHARES*1000), + fc::variant(string(record_itr.value().closing_price.ratio * base->precision / quote->precision)).as_double() / (BTS_BLOCKCHAIN_MAX_SHARES*1000), record_itr.value().volume, record_itr.value().recent_average_price? to_pretty_price_double(*record_itr.value().recent_average_price) : fc::optional() } ); diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index 0cf880062..cf2fe7dfb 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -13,7 +13,7 @@ * @brief Defines global constants that determine blockchain behavior */ #define BTS_BLOCKCHAIN_VERSION 109 -#define BTS_BLOCKCHAIN_DATABASE_VERSION 133 +#define BTS_BLOCKCHAIN_DATABASE_VERSION 134 /** * The address prepended to string representation of diff --git a/libraries/blockchain/include/bts/blockchain/market_records.hpp b/libraries/blockchain/include/bts/blockchain/market_records.hpp index 165771fb8..d2e9c3340 100644 --- a/libraries/blockchain/include/bts/blockchain/market_records.hpp +++ b/libraries/blockchain/include/bts/blockchain/market_records.hpp @@ -71,16 +71,22 @@ namespace bts { namespace blockchain { { market_history_record(price highest_bid = price(), price lowest_ask = price(), + price opening_price = price(), + price closing_price = price(), share_type volume = 0, fc::optional recent_average_price = fc::optional()) : highest_bid(highest_bid), lowest_ask(lowest_ask), + opening_price(opening_price), + closing_price(closing_price), volume(volume), recent_average_price(recent_average_price) {} price highest_bid; price lowest_ask; + price opening_price; + price closing_price; share_type volume; fc::optional recent_average_price; @@ -99,6 +105,8 @@ namespace bts { namespace blockchain { fc::time_point_sec timestamp; double highest_bid; double lowest_ask; + double opening_price; + double closing_price; share_type volume; fc::optional recent_average_price; @@ -244,9 +252,9 @@ FC_REFLECT_ENUM( bts::blockchain::market_history_key::time_granularity_enum, (ea FC_REFLECT( bts::blockchain::market_status, (quote_id)(base_id)(bid_depth)(ask_depth)(avg_price_1h)(last_error) ) FC_REFLECT_DERIVED( bts::blockchain::api_market_status, (bts::blockchain::market_status), (avg_price_1h) ) FC_REFLECT( bts::blockchain::market_index_key, (order_price)(owner) ) -FC_REFLECT( bts::blockchain::market_history_record, (highest_bid)(lowest_ask)(volume)(recent_average_price) ) +FC_REFLECT( bts::blockchain::market_history_record, (highest_bid)(lowest_ask)(opening_price)(closing_price)(volume)(recent_average_price) ) FC_REFLECT( bts::blockchain::market_history_key, (quote_id)(base_id)(granularity)(timestamp) ) -FC_REFLECT( bts::blockchain::market_history_point, (timestamp)(highest_bid)(lowest_ask)(volume)(recent_average_price) ) +FC_REFLECT( bts::blockchain::market_history_point, (timestamp)(highest_bid)(lowest_ask)(opening_price)(closing_price)(volume)(recent_average_price) ) FC_REFLECT( bts::blockchain::order_record, (balance) ) FC_REFLECT( bts::blockchain::collateral_record, (collateral_balance)(payoff_balance) ) FC_REFLECT( bts::blockchain::market_order, (type)(market_index)(state)(collateral) ) diff --git a/libraries/blockchain/market_engine.cpp b/libraries/blockchain/market_engine.cpp index e9e466b51..252c354a5 100644 --- a/libraries/blockchain/market_engine.cpp +++ b/libraries/blockchain/market_engine.cpp @@ -52,6 +52,8 @@ class market_engine price max_short_bid; price min_cover_ask; + price opening_price; + price closing_price; // while bootstraping we use this metric auto median_price = _db_impl.self->get_median_delegate_price( quote_id ); @@ -114,6 +116,9 @@ class market_engine trading_volume += mtrx.ask_received; else if( mtrx.bid_received.asset_id == 0 ) trading_volume += mtrx.bid_received; + if( opening_price == price() ) + opening_price = mtrx.bid_price; + closing_price = mtrx.bid_price; if( mtrx.ask_type == ask_order ) pay_current_ask( mtrx, *base_asset ); @@ -350,6 +355,9 @@ class market_engine trading_volume += mtrx.ask_received; else if( mtrx.bid_received.asset_id == 0 ) trading_volume += mtrx.bid_received; + if( opening_price == price() ) + opening_price = mtrx.bid_price; + closing_price = mtrx.bid_price; accumulate_fees( mtrx, *quote_asset ); } // while( next bid && next ask ) @@ -407,7 +415,7 @@ class market_engine } _pending_state->store_market_status( *market_stat ); - update_market_history( trading_volume, market_stat, timestamp ); + update_market_history( trading_volume, opening_price, closing_price, market_stat, timestamp ); wlog( "done matching orders" ); _pending_state->apply_changes(); @@ -732,15 +740,23 @@ class market_engine /** - * This method should not effect market execution or validation and + * This method should not affect market execution or validation and * is for historical purposes only. */ - void update_market_history( const asset& trading_volume, const omarket_status& market_stat, const fc::time_point_sec& timestamp ) + void update_market_history( const asset& trading_volume, + const price& opening_price, + const price& closing_price, + const omarket_status& market_stat, + const fc::time_point_sec& timestamp ) { if( trading_volume.amount > 0 && get_next_bid() && get_next_ask() ) { market_history_key key(_quote_id, _base_id, market_history_key::each_block, _db_impl._head_block_header.timestamp); - market_history_record new_record(_current_bid->get_price(), _current_ask->get_price(), trading_volume.amount); + market_history_record new_record(_current_bid->get_price(), + _current_ask->get_price(), + opening_price, + closing_price, + trading_volume.amount); FC_ASSERT( market_stat ); new_record.recent_average_price = market_stat->avg_price_1h; diff --git a/libraries/cli/cli.cpp b/libraries/cli/cli.cpp index 5de9e1f2c..3d81ed33a 100644 --- a/libraries/cli/cli.cpp +++ b/libraries/cli/cli.cpp @@ -1162,15 +1162,19 @@ namespace bts { namespace cli { *_out << std::setw(20) << "TIME" << std::setw(20) << "HIGHEST BID" << std::setw(20) << "LOWEST ASK" + << std::setw(20) << "OPENING PRICE" + << std::setw(20) << "CLOSING PRICE" << std::setw(20) << "TRADING VOLUME" << std::setw(20) << "AVERAGE PRICE" - << "\n" << std::string(100,'-') << "\n"; + << "\n" << std::string(140,'-') << "\n"; for( auto point : points ) { *_out << std::setw(20) << pretty_timestamp(point.timestamp) << std::setw(20) << point.highest_bid << std::setw(20) << point.lowest_ask + << std::setw(20) << point.opening_price + << std::setw(20) << point.closing_price << std::setw(20) << _client->get_chain()->to_pretty_asset(asset(point.volume)); if(point.recent_average_price) *_out << std::setw(20) << *point.recent_average_price; From d424bad3af0a9a566a7e0242614a761b07d91178 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 3 Sep 2014 19:50:22 -0400 Subject: [PATCH 2/8] No more duplicate keys used for wallet transaction scanning --- .../wallet/include/bts/wallet/wallet.hpp | 2 - .../wallet/include/bts/wallet/wallet_db.hpp | 16 +++-- .../include/bts/wallet/wallet_records.hpp | 4 +- libraries/wallet/wallet.cpp | 35 ++++------- libraries/wallet/wallet_db.cpp | 62 +++++++++++-------- libraries/wallet/wallet_records.cpp | 16 ++--- 6 files changed, 67 insertions(+), 68 deletions(-) diff --git a/libraries/wallet/include/bts/wallet/wallet.hpp b/libraries/wallet/include/bts/wallet/wallet.hpp index ad558bc25..8bbc5a55e 100644 --- a/libraries/wallet/include/bts/wallet/wallet.hpp +++ b/libraries/wallet/include/bts/wallet/wallet.hpp @@ -198,8 +198,6 @@ namespace bts { namespace wallet { ///@param delegates_to_retrieve Type is delegate_status_flags. Uses int type to allow ORing multiple flags vector get_my_delegates( int delegates_to_retrieve = any_delegate_status )const; - ///@param delegates_to_retrieve Type is delegate_status_flags. Uses int type to allow ORing multiple flags - vector get_my_delegate_private_keys( int delegates_to_retrieve = any_delegate_status )const; optional get_next_producible_block_timestamp( const vector& delegate_records )const; diff --git a/libraries/wallet/include/bts/wallet/wallet_db.hpp b/libraries/wallet/include/bts/wallet/wallet_db.hpp index 055b035cb..514f86bba 100644 --- a/libraries/wallet/include/bts/wallet/wallet_db.hpp +++ b/libraries/wallet/include/bts/wallet/wallet_db.hpp @@ -11,8 +11,6 @@ namespace bts { namespace wallet { - typedef vector private_keys; - namespace detail { class wallet_db_impl; } class wallet_db @@ -28,11 +26,11 @@ namespace bts { namespace wallet { int32_t new_wallet_record_index(); int32_t new_key_child_index( const address& parent_account_address ); - fc::ecc::private_key get_private_key( const fc::sha512& password, int index ); + private_key_type get_private_key( const fc::sha512& password, int index ); - fc::ecc::private_key new_private_key( const fc::sha512& password, - const address& parent_account_address = address(), - bool store_key = true ); + private_key_type new_private_key( const fc::sha512& password, + const address& parent_account_address = address(), + bool store_key = true ); void set_property( property_enum property_id, const fc::variant& v ); fc::variant get_property( property_enum property_id )const; @@ -42,7 +40,7 @@ namespace bts { namespace wallet { void cache_balance( const bts::blockchain::balance_record& b ); void cache_account( const wallet_account_record& ); void cache_memo( const memo_status& memo, - const fc::ecc::private_key& account_key, + const private_key_type& account_key, const fc::sha512& password ); void cache_order( const bts::blockchain::market_order& ); @@ -57,8 +55,8 @@ namespace bts { namespace wallet { owallet_transaction_record lookup_transaction( const transaction_id_type& record_id )const; - private_keys get_account_private_keys( const fc::sha512& password )const; - string get_account_name( const address& account_address )const; + vector get_account_private_keys( const fc::sha512& password )const; + string get_account_name( const address& account_address )const; owallet_account_record lookup_account( const address& address_of_public_key )const; owallet_account_record lookup_account( const string& account_name )const; diff --git a/libraries/wallet/include/bts/wallet/wallet_records.hpp b/libraries/wallet/include/bts/wallet/wallet_records.hpp index bc59f8f4f..56845a4e0 100644 --- a/libraries/wallet/include/bts/wallet/wallet_records.hpp +++ b/libraries/wallet/include/bts/wallet/wallet_records.hpp @@ -134,8 +134,8 @@ namespace bts { namespace wallet { address get_address()const { return address( public_key ); } bool has_private_key()const; void encrypt_private_key( const fc::sha512& password, - const fc::ecc::private_key& ); - fc::ecc::private_key decrypt_private_key( const fc::sha512& password )const; + const private_key_type& ); + private_key_type decrypt_private_key( const fc::sha512& password )const; }; struct ledger_entry diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 57669621c..7386ff426 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -58,7 +58,7 @@ namespace bts { namespace wallet { struct login_record { - fc::ecc::private_key key; + private_key_type key; fc::time_point_sec insertion_time; }; std::map _login_map; @@ -76,7 +76,7 @@ namespace bts { namespace wallet { void relocker(); public: - fc::ecc::private_key create_one_time_key(); + private_key_type create_one_time_key(); /** * This method is called anytime the blockchain state changes including @@ -107,7 +107,7 @@ namespace bts { namespace wallet { bool scan_withdraw( const withdraw_operation& op, wallet_transaction_record& trx_rec, asset& total_fee ); bool scan_withdraw_pay( const withdraw_pay_operation& op, wallet_transaction_record& trx_rec, asset& total_fee ); - bool scan_deposit( const deposit_operation& op, const private_keys& keys, wallet_transaction_record& trx_rec, asset& total_fee ); + bool scan_deposit( const deposit_operation& op, const vector& keys, wallet_transaction_record& trx_rec, asset& total_fee ); bool scan_register_account( const register_account_operation& op, wallet_transaction_record& trx_rec ); bool scan_update_account( const update_account_operation& op, wallet_transaction_record& trx_rec ); @@ -149,10 +149,10 @@ namespace bts { namespace wallet { try { if( _scanner_thread ) _scanner_thread->quit(); } catch( ... ) {} } - fc::ecc::private_key wallet_impl::create_one_time_key() + private_key_type wallet_impl::create_one_time_key() { if( !_use_deterministic_one_time_keys ) - return fc::ecc::private_key::generate(); + return private_key_type::generate(); return _wallet_db.new_private_key( _wallet_password ); } @@ -528,7 +528,7 @@ namespace bts { namespace wallet { return fc::ripemd160::hash( enc.result() ); } - void wallet_impl::scan_block( uint32_t block_num, const private_keys& keys, const time_point_sec& received_time ) + void wallet_impl::scan_block( uint32_t block_num, const vector& keys, const time_point_sec& received_time ) { const auto block = _blockchain->get_block( block_num ); for( const auto& transaction : block.user_transactions ) @@ -1169,7 +1169,7 @@ namespace bts { namespace wallet { } FC_CAPTURE_AND_RETHROW( (op) ) } // TODO: optimize - bool wallet_impl::scan_deposit( const deposit_operation& op, const private_keys& keys, + bool wallet_impl::scan_deposit( const deposit_operation& op, const vector& keys, wallet_transaction_record& trx_rec, asset& total_fee ) { try { auto amount = asset( op.amount, op.condition.asset_id ); @@ -2505,7 +2505,7 @@ namespace bts { namespace wallet { FC_ASSERT( key.valid() ); FC_ASSERT( key->has_private_key() ); - fc::ecc::private_key one_time_key = fc::ecc::private_key::generate(); + private_key_type one_time_key = private_key_type::generate(); public_key_type one_time_public_key = one_time_key.get_public_key(); my->_login_map[one_time_public_key] = {one_time_key, fc::time_point::now()}; @@ -2530,7 +2530,7 @@ namespace bts { namespace wallet { FC_ASSERT( is_unlocked() ); FC_ASSERT( my->_login_map.find(server_key) != my->_login_map.end(), "Login session has expired. Generate a new login URL and try again." ); - fc::ecc::private_key private_key = my->_login_map[server_key].key; + private_key_type private_key = my->_login_map[server_key].key; my->_login_map.erase(server_key); auto secret = private_key.get_shared_secret( fc::ecc::public_key_data(client_key) ); auto user_account_key = fc::ecc::public_key(client_signature, fc::sha256::hash(secret.data(), sizeof(secret))); @@ -2804,15 +2804,6 @@ namespace bts { namespace wallet { return delegate_records; } - vector wallet::get_my_delegate_private_keys(int delegates_to_retrieve )const - { - vector private_keys; - const auto& delegate_records = get_my_delegates( delegates_to_retrieve ); - for( const auto& delegate_record : delegate_records ) - private_keys.push_back( get_private_key( address( delegate_record.active_key() ) ) ); - return private_keys; - } - optional wallet::get_next_producible_block_timestamp( const vector& delegate_records )const { try { if( !is_open() || is_locked() ) return optional(); @@ -3045,7 +3036,7 @@ namespace bts { namespace wallet { while( recoveries < number_of_accounts && attempts++ < max_number_of_attempts ) { - fc::ecc::private_key new_priv_key = my->_wallet_db.new_private_key( my->_wallet_password, address(), false ); + private_key_type new_priv_key = my->_wallet_db.new_private_key( my->_wallet_password, address(), false ); fc::ecc::public_key new_pub_key = new_priv_key.get_public_key(); auto recovered_account = my->_blockchain->get_account_record(new_pub_key); @@ -3103,7 +3094,7 @@ namespace bts { namespace wallet { const auto withdraw_condition = deposit_op.condition.as(); FC_ASSERT( withdraw_condition.memo.valid() ); - fc::ecc::private_key private_key; + private_key_type private_key; try { /* We had to have stored the one-time key */ @@ -3158,12 +3149,12 @@ namespace bts { namespace wallet { my->_wallet_db.store_transaction( transaction_record ); /* Wipe memory */ - private_key = fc::ecc::private_key(); + private_key = private_key_type(); } catch( ... ) { /* Wipe memory */ - private_key = fc::ecc::private_key(); + private_key = private_key_type(); throw; } diff --git a/libraries/wallet/wallet_db.cpp b/libraries/wallet/wallet_db.cpp index 8da0b9320..584310997 100644 --- a/libraries/wallet/wallet_db.cpp +++ b/libraries/wallet/wallet_db.cpp @@ -270,8 +270,8 @@ namespace bts { namespace wallet { return next_child_index; } - fc::ecc::private_key wallet_db::get_private_key( const fc::sha512& password, - int index ) + private_key_type wallet_db::get_private_key( const fc::sha512& password, + int index ) { FC_ASSERT( wallet_master_key.valid() ); @@ -281,9 +281,9 @@ namespace bts { namespace wallet { return new_priv_key; } - fc::ecc::private_key wallet_db::new_private_key( const fc::sha512& password, - const address& parent_account_address, - bool store_key ) + private_key_type wallet_db::new_private_key( const fc::sha512& password, + const address& parent_account_address, + bool store_key ) { FC_ASSERT( wallet_master_key.valid() ); @@ -492,7 +492,7 @@ namespace bts { namespace wallet { } FC_RETHROW_EXCEPTIONS( warn, "", ("address",a) ) } void wallet_db::cache_memo( const memo_status& memo, - const fc::ecc::private_key& account_key, + const private_key_type& account_key, const fc::sha512& password ) { key_data data; @@ -504,33 +504,45 @@ namespace bts { namespace wallet { store_key( data ); } - private_keys wallet_db::get_account_private_keys( const fc::sha512& password )const + vector wallet_db::get_account_private_keys( const fc::sha512& password )const { try { - private_keys keys; - keys.reserve( accounts.size() * 2 ); + vector public_keys; + vector private_keys; - auto insert_key = [&keys,&password]( const owallet_key_record& key_rec ) + public_keys.reserve( accounts.size() ); + private_keys.reserve( accounts.size() ); + + const auto insert_key = [&]( const owallet_key_record& key_record ) { - if( key_rec.valid() && key_rec->has_private_key() ) - { - try { - keys.push_back( key_rec->decrypt_private_key( password ) ); - } catch ( const fc::exception& e ) - { - elog( "error decrypting private key: ${e}", ("e", e.to_detail_string() ) ); - } - } + if( !key_record.valid() || !key_record->has_private_key() ) + return; + + if( std::find( public_keys.begin(), public_keys.end(), key_record->public_key ) != public_keys.end() ) + return; + + private_key_type key; + try + { + key = key_record->decrypt_private_key( password ); + } + catch( const fc::exception& e ) + { + elog( "error decrypting private key: ${e}", ("e",e.to_detail_string()) ); + return; + } + + private_keys.push_back( key ); + public_keys.push_back( key_record->public_key ); }; - for( const auto& item : accounts ) + for( const auto& account_item : accounts ) { - insert_key(lookup_key(item.second.account_address)); - for( const auto& active_key : item.second.active_key_history ) - insert_key(lookup_key(active_key.second)); + insert_key( lookup_key( account_item.second.account_address ) ); + for( const auto& key_item : account_item.second.active_key_history ) + insert_key( lookup_key( key_item.second ) ); } - keys.shrink_to_fit(); - return keys; + return private_keys; } FC_RETHROW_EXCEPTIONS( warn, "" ) } owallet_balance_record wallet_db::lookup_balance( const balance_id_type& balance_id )const diff --git a/libraries/wallet/wallet_records.cpp b/libraries/wallet/wallet_records.cpp index 5319403dc..82d656aa6 100644 --- a/libraries/wallet/wallet_records.cpp +++ b/libraries/wallet/wallet_records.cpp @@ -16,7 +16,7 @@ namespace bts { namespace wallet { return checksum == fc::sha512::hash(password); } - void master_key::encrypt_key( const fc::sha512& password, + void master_key::encrypt_key( const fc::sha512& password, const extended_private_key& k ) { try { FC_ASSERT( password != fc::sha512() ); @@ -28,13 +28,13 @@ namespace bts { namespace wallet { decrypt_key( password ); } FC_CAPTURE_AND_RETHROW() } - bool key_data::has_private_key()const - { - return encrypted_private_key.size() > 0; + bool key_data::has_private_key()const + { + return encrypted_private_key.size() > 0; } - void key_data::encrypt_private_key( const fc::sha512& password, - const fc::ecc::private_key& key_to_encrypt ) + void key_data::encrypt_private_key( const fc::sha512& password, + const private_key_type& key_to_encrypt ) { try { FC_ASSERT( password != fc::sha512() ); public_key = key_to_encrypt.get_public_key(); @@ -44,11 +44,11 @@ namespace bts { namespace wallet { FC_ASSERT( key_to_encrypt == decrypt_private_key( password ) ); } FC_CAPTURE_AND_RETHROW() } - fc::ecc::private_key key_data::decrypt_private_key( const fc::sha512& password )const + private_key_type key_data::decrypt_private_key( const fc::sha512& password )const { try { FC_ASSERT( password != fc::sha512() ); const auto plain_text = fc::aes_decrypt( password, encrypted_private_key ); - return fc::raw::unpack( plain_text ); + return fc::raw::unpack( plain_text ); } FC_CAPTURE_AND_RETHROW() } order_type_enum market_order_status::get_type()const From c8b0c687519b0b3a86dbfc2a921eec598dd2fc04 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Wed, 3 Sep 2014 20:01:09 -0400 Subject: [PATCH 3/8] Attempt to clean up peer connections better at shutdown and fix crashes at shutdown by preventing new async tasks from starting after the node starts destructing, and forcibly canceling the read_loop at the beginning of shutdown --- .../bts/net/message_oriented_connection.hpp | 1 + libraries/net/message_oriented_connection.cpp | 57 ++++++++++++------- libraries/net/node.cpp | 35 +++++++++--- libraries/net/peer_connection.cpp | 2 + 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/libraries/net/include/bts/net/message_oriented_connection.hpp b/libraries/net/include/bts/net/message_oriented_connection.hpp index ea4d02c62..20057afc6 100644 --- a/libraries/net/include/bts/net/message_oriented_connection.hpp +++ b/libraries/net/include/bts/net/message_oriented_connection.hpp @@ -29,6 +29,7 @@ namespace bts { namespace net { void send_message(const message& message_to_send); void close_connection(); + void destroy_connection(); uint64_t get_total_bytes_sent() const; uint64_t get_total_bytes_received() const; diff --git a/libraries/net/message_oriented_connection.cpp b/libraries/net/message_oriented_connection.cpp index d85b48379..d71c139b1 100644 --- a/libraries/net/message_oriented_connection.cpp +++ b/libraries/net/message_oriented_connection.cpp @@ -57,6 +57,7 @@ namespace bts { namespace net { void send_message(const message& message_to_send); void close_connection(); + void destroy_connection(); uint64_t get_total_bytes_sent() const; uint64_t get_total_bytes_received() const; @@ -82,28 +83,7 @@ namespace bts { namespace net { message_oriented_connection_impl::~message_oriented_connection_impl() { VERIFY_CORRECT_THREAD(); - fc::optional remote_endpoint; - if (_sock.get_socket().is_open()) - remote_endpoint = _sock.get_socket().remote_endpoint(); - ilog( "in ~message_oriented_connection_impl() for ${endpoint}", ("endpoint", remote_endpoint) ); - - if (_send_message_in_progress) - elog("Error: message_oriented_connection is being destroyed while a send_message is in progress. " - "The task calling send_message() should have been canceled already"); - assert(!_send_message_in_progress); - - try - { - _read_loop_done.cancel_and_wait(__FUNCTION__); - } - catch ( const fc::exception& e ) - { - wlog( "Exception thrown while canceling message_oriented_connection's read_loop, ignoring: ${e}", ("e",e) ); - } - catch (...) - { - wlog( "Exception thrown while canceling message_oriented_connection's read_loop, ignoring" ); - } + destroy_connection(); } fc::tcp_socket& message_oriented_connection_impl::get_socket() @@ -261,6 +241,34 @@ namespace bts { namespace net { _sock.close(); } + void message_oriented_connection_impl::destroy_connection() + { + VERIFY_CORRECT_THREAD(); + + fc::optional remote_endpoint; + if (_sock.get_socket().is_open()) + remote_endpoint = _sock.get_socket().remote_endpoint(); + ilog( "in destroy_connection() for ${endpoint}", ("endpoint", remote_endpoint) ); + + if (_send_message_in_progress) + elog("Error: message_oriented_connection is being destroyed while a send_message is in progress. " + "The task calling send_message() should have been canceled already"); + assert(!_send_message_in_progress); + + try + { + _read_loop_done.cancel_and_wait(__FUNCTION__); + } + catch ( const fc::exception& e ) + { + wlog( "Exception thrown while canceling message_oriented_connection's read_loop, ignoring: ${e}", ("e",e) ); + } + catch (...) + { + wlog( "Exception thrown while canceling message_oriented_connection's read_loop, ignoring" ); + } + } + uint64_t message_oriented_connection_impl::get_total_bytes_sent() const { VERIFY_CORRECT_THREAD(); @@ -333,6 +341,11 @@ namespace bts { namespace net { my->close_connection(); } + void message_oriented_connection::destroy_connection() + { + my->destroy_connection(); + } + uint64_t message_oriented_connection::get_total_bytes_sent() const { return my->get_total_bytes_sent(); diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index 398cfb79d..cd3d09613 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -479,6 +479,8 @@ namespace bts { namespace net { namespace detail { std::set _allowed_peers; #endif // ENABLE_P2P_DEBUGGING_API + bool _node_is_shutting_down; // set to true when we begin our destructor, used to prevent us from starting new tasks while we're shutting down + node_impl(); virtual ~node_impl(); @@ -697,7 +699,8 @@ namespace bts { namespace net { namespace detail { _average_network_usage_minutes(60), _average_network_usage_hours(72), _average_network_usage_second_counter(0), - _average_network_usage_minute_counter(0) + _average_network_usage_minute_counter(0), + _node_is_shutting_down(false) { _rate_limiter.set_actual_rate_time_constant(fc::seconds(2)); } @@ -706,6 +709,8 @@ namespace bts { namespace net { namespace detail { { VERIFY_CORRECT_THREAD(); ilog( "cleaning up node" ); + _node_is_shutting_down = true; + for( const peer_connection_ptr& active_peer : _active_connections ) { potential_peer_record updated_peer_record = _potential_peer_db.lookup_or_create_entry_for_endpoint( *active_peer->get_remote_endpoint() ); @@ -1245,7 +1250,7 @@ namespace bts { namespace net { namespace detail { schedule_peer_for_deletion(peer); } - if( !_terminate_inactive_connections_loop_done.canceled() ) + if (!_node_is_shutting_down && !_terminate_inactive_connections_loop_done.canceled()) _terminate_inactive_connections_loop_done = fc::schedule( [this](){ terminate_inactive_connections_loop(); }, fc::time_point::now() + fc::seconds(BTS_NET_PEER_HANDSHAKE_INACTIVITY_TIMEOUT / 2), "terminate_inactive_connections_loop" ); @@ -1273,7 +1278,7 @@ namespace bts { namespace net { namespace detail { } } - if( !_fetch_updated_peer_lists_loop_done.canceled() ) + if (!_node_is_shutting_down && !_fetch_updated_peer_lists_loop_done.canceled() ) _fetch_updated_peer_lists_loop_done = fc::schedule( [this](){ fetch_updated_peer_lists_loop(); }, fc::time_point::now() + fc::minutes(15), "fetch_updated_peer_lists_loop" ); @@ -1313,7 +1318,7 @@ namespace bts { namespace net { namespace detail { update_bandwidth_data(usage_this_second); _bandwidth_monitor_last_update_time = current_time; - if (!_bandwidth_monitor_loop_done.canceled()) + if (!_node_is_shutting_down && !_bandwidth_monitor_loop_done.canceled()) _bandwidth_monitor_loop_done = fc::schedule( [=](){ bandwidth_monitor_loop(); }, fc::time_point::now() + fc::seconds(1), "bandwidth_monitor_loop" ); @@ -1323,7 +1328,7 @@ namespace bts { namespace net { namespace detail { { VERIFY_CORRECT_THREAD(); dump_node_status(); - if (!_dump_node_status_task_done.canceled()) + if (!_node_is_shutting_down && !_dump_node_status_task_done.canceled()) _dump_node_status_task_done = fc::schedule([=](){ dump_node_status_task(); }, fc::time_point::now() + fc::minutes(1), "dump_node_status_task"); @@ -1368,7 +1373,8 @@ namespace bts { namespace net { namespace detail { } dlog("peer scheduled for deletion: ${peer}", ("peer", peer_to_delete->get_remote_endpoint())); - if (!_delayed_peer_deletion_task_done.valid() || _delayed_peer_deletion_task_done.ready()) + if (!_node_is_shutting_down && + (!_delayed_peer_deletion_task_done.valid() || _delayed_peer_deletion_task_done.ready())) { dlog("asyncing delayed_peer_deletion_task to delete ${size} peers", ("size", number_of_peers_to_delete)); _delayed_peer_deletion_task_done = fc::async([this](){ delayed_peer_deletion_task(); }, "delayed_peer_deletion_task" ); @@ -1378,7 +1384,8 @@ namespace bts { namespace net { namespace detail { #else dlog("scheduling peer for deletion: ${peer} (this will not block)"); _peers_to_delete.push_back(peer_to_delete); - if (!_delayed_peer_deletion_task_done.valid() || _delayed_peer_deletion_task_done.ready()) + if (!_node_is_shutting_down && + (!_delayed_peer_deletion_task_done.valid() || _delayed_peer_deletion_task_done.ready())) { dlog("asyncing delayed_peer_deletion_task to delete ${size} peers", ("size", _peers_to_delete.size())); _delayed_peer_deletion_task_done = fc::async([this](){ delayed_peer_deletion_task(); }, "delayed_peer_deletion_task" ); @@ -2619,7 +2626,10 @@ namespace bts { namespace net { namespace detail { if (_suspend_fetching_sync_blocks) { dlog("we stopped processing the backlog because it was taking too long, rescheduling"); - _process_backlog_of_sync_blocks_done = fc::schedule([=](){ process_backlog_of_sync_blocks(); }, fc::time_point::now() + fc::milliseconds(400), "process_backlog_of_sync_blocks"); + if (!_node_is_shutting_down) + _process_backlog_of_sync_blocks_done = fc::schedule([=](){ process_backlog_of_sync_blocks(); }, + fc::time_point::now() + fc::milliseconds(400), + "process_backlog_of_sync_blocks"); } else trigger_fetch_sync_items_loop(); @@ -2627,7 +2637,8 @@ namespace bts { namespace net { namespace detail { void node_impl::trigger_process_backlog_of_sync_blocks() { - if (!_process_backlog_of_sync_blocks_done.valid() || _process_backlog_of_sync_blocks_done.ready()) + if (!_node_is_shutting_down && + (!_process_backlog_of_sync_blocks_done.valid() || _process_backlog_of_sync_blocks_done.ready())) _process_backlog_of_sync_blocks_done = fc::async([=](){ process_backlog_of_sync_blocks(); }, "process_backlog_of_sync_blocks"); } @@ -3149,6 +3160,8 @@ namespace bts { namespace net { namespace detail { { _tcp_server.accept( new_peer->get_socket() ); ilog( "accepted inbound connection from ${remote_endpoint}", ("remote_endpoint", new_peer->get_socket().remote_endpoint() ) ); + if (_node_is_shutting_down) + return; new_peer->connection_initiation_time = fc::time_point::now(); _handshaking_connections.insert( new_peer ); _rate_limiter.add_tcp_socket( &new_peer->get_socket() ); @@ -3482,6 +3495,10 @@ namespace bts { namespace net { namespace detail { new_peer->connection_initiation_time = fc::time_point::now(); _handshaking_connections.insert( new_peer ); _rate_limiter.add_tcp_socket( &new_peer->get_socket() ); + + if (_node_is_shutting_down) + return; + std::weak_ptr new_weak_peer(new_peer); new_peer->accept_or_connect_task_done = fc::async( [this, new_weak_peer, remote_endpoint](){ peer_connection_ptr new_peer(new_weak_peer.lock()); diff --git a/libraries/net/peer_connection.cpp b/libraries/net/peer_connection.cpp index f3c661cfd..ca96adccb 100644 --- a/libraries/net/peer_connection.cpp +++ b/libraries/net/peer_connection.cpp @@ -108,6 +108,8 @@ namespace bts { namespace net { wlog("Unexpected exception from peer_connection's accept_or_connect_task"); } + + _message_connection.destroy_connection(); // shut down the read loop } peer_connection::~peer_connection() From dd21cf643163f43c8c8b2982efa8a0cee2dfbfe7 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 3 Sep 2014 21:17:46 -0400 Subject: [PATCH 4/8] Return wallet transaction records for all wallet transactions --- libraries/api/wallet_api.json | 36 +- libraries/cli/cli.cpp | 28 +- libraries/client/client.cpp | 328 ++++---- .../wallet/include/bts/wallet/wallet.hpp | 307 +++---- libraries/wallet/wallet.cpp | 769 +++++++++--------- 5 files changed, 741 insertions(+), 727 deletions(-) diff --git a/libraries/api/wallet_api.json b/libraries/api/wallet_api.json index 1f0ce26a2..20e8370be 100644 --- a/libraries/api/wallet_api.json +++ b/libraries/api/wallet_api.json @@ -672,7 +672,7 @@ { "method_name" : "wallet_account_register", "description" : "Updates the data published about a given account", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "account_name", @@ -692,7 +692,7 @@ }, { "name" : "delegate_pay_rate", - "type" : "uint32_t", + "type" : "uint8_t", "description" : "A value between 0 and 100 for delegates, 255 for non delegates", "default_value" : 255 } @@ -723,7 +723,7 @@ { "method_name" : "wallet_account_update_registration", "description" : "Updates the data published about a given account", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "account_name", @@ -754,7 +754,7 @@ { "method_name" : "wallet_account_update_active_key", "description" : "Updates the specified account's active key and broadcasts the transaction.", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "account_to_update", @@ -857,7 +857,7 @@ { "method_name" : "wallet_asset_create", "description" : "Creates a new user issued asset", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "symbol", @@ -910,7 +910,7 @@ { "method_name" : "wallet_asset_issue", "description" : "Issues new shares of a given asset type", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "amount", @@ -970,7 +970,7 @@ { "method_name" : "wallet_delegate_withdraw_pay", "description" : "Used to transfer some of the delegate's pay from their balance", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "delegate_name", @@ -1029,7 +1029,7 @@ { "method_name" : "wallet_market_submit_bid", "description" : "Used to place a request to buy a quantity of assets at a price specified in another asset", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1069,7 +1069,7 @@ { "method_name" : "wallet_market_submit_ask", "description" : "Used to place a request to sell a quantity of assets at a price specified in another asset", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1109,7 +1109,7 @@ { "method_name" : "wallet_market_submit_short", "description" : "Used to place a request to short sell a quantity of assets at a price specified", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1144,7 +1144,7 @@ { "method_name" : "wallet_market_cover", "description" : "Used to place a request to cover an existing short position", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1173,7 +1173,7 @@ { "method_name" : "wallet_market_cover2", "description" : "Used to place a request to cover an existing short position", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1202,7 +1202,7 @@ { "method_name" : "wallet_market_add_collateral", "description" : "Add collateral to a short position", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1226,7 +1226,7 @@ { "method_name" : "wallet_market_add_collateral2", "description" : "Add collateral to a short position", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "from_account_name", @@ -1312,7 +1312,7 @@ { "method_name" : "wallet_market_cancel_order", "description" : "Cancel an order", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "order_id", @@ -1326,7 +1326,7 @@ { "method_name" : "wallet_market_cancel_order2", "description" : "Cancel an order", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "order_id", @@ -1486,7 +1486,7 @@ { "method_name" : "wallet_publish_slate", "description" : "Publishes the current wallet delegate slate to the public data associated with the account", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "publishing_account_name", @@ -1570,7 +1570,7 @@ { "method_name" : "wallet_publish_price_feed", "description" : "publishes a price feed for BitAssets, only active delegates may do this", - "return_type" : "signed_transaction", + "return_type" : "transaction_record", "parameters" : [ { "name" : "delegate_account", diff --git a/libraries/cli/cli.cpp b/libraries/cli/cli.cpp index 3d81ed33a..0c5bb4a0e 100644 --- a/libraries/cli/cli.cpp +++ b/libraries/cli/cli.cpp @@ -681,8 +681,26 @@ namespace bts { namespace cli { const auto& balances = result.as(); *_out << pretty_balances( balances, _client ); } - else if( method_name == "wallet_transfer" - || method_name == "wallet_get_transaction" ) + else if( + method_name == "wallet_transfer" + || method_name == "wallet_transfer_from" + || method_name == "wallet_get_transaction" + || method_name == "wallet_account_register" + || method_name == "wallet_account_update_registration" + || method_name == "wallet_account_update_active_key" + || method_name == "wallet_asset_create" + || method_name == "wallet_asset_issue" + || method_name == "wallet_delegate_withdraw_pay" + || method_name == "wallet_market_submit_bid" + || method_name == "wallet_market_submit_ask" + || method_name == "wallet_market_submit_short" + || method_name == "wallet_market_cover" + || method_name == "wallet_market_add_collateral" + || method_name == "wallet_market_cancel_order" + || method_name == "wallet_publish_slate" + || method_name == "wallet_recover_transaction" + || method_name == "wallet_publish_price_feed" + ) { const auto& record = result.as(); const auto& pretty = _client->get_wallet()->to_pretty_trx( record ); @@ -944,7 +962,7 @@ namespace bts { namespace cli { oprice median_price = _client->get_chain()->get_median_delegate_price( quote_id ); auto status = _client->get_chain()->get_market_status( quote_id, base_id ); auto max_short_price = median_price ? *median_price : ( status ? status->avg_price_1h : price(0, quote_id, base_id) ); - + while( bid_itr != bids_asks.first.end() || ask_itr != bids_asks.second.end() ) { @@ -956,10 +974,10 @@ namespace bts { namespace cli { { if( bid_itr->get_price() > *median_price ) filtered_shorts.push_back(*bid_itr++); - else + else break; } - else + else break; } } diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index 0914662e1..cca7fc2d4 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -1241,7 +1241,7 @@ config load_config( const fc::path& datadir ) // assume anything longer than our limit is an attacker (limit is currently ~26 items) if (blockchain_synopsis.size() > _blockchain_synopsis_size_limit) - FC_THROW("Peer provided unreasonably long blockchain synopsis during sync (actual length: ${size}, limit: ${blockchain_synopsis_size_limit})", + FC_THROW("Peer provided unreasonably long blockchain synopsis during sync (actual length: ${size}, limit: ${blockchain_synopsis_size_limit})", ("size", blockchain_synopsis.size()) ("blockchain_synopsis_size_limit", _blockchain_synopsis_size_limit)); @@ -1309,7 +1309,7 @@ config load_config( const fc::path& datadir ) ulog("Error: your chain database is in an inconsistent state. Please shut down and relaunch using --rebuild-index or --resync-blockchain to repair the database"); assert(!"I assume this can never happen"); // our database doesn't make sense, so just act as if we have no blocks so the remote node doesn't try to sync with us - remaining_item_count = 0; + remaining_item_count = 0; hashes_to_return.clear(); return hashes_to_return; } @@ -1831,12 +1831,12 @@ config load_config( const fc::path& datadir ) return errors; } - signed_transaction detail::client_impl::wallet_publish_slate( const string& publishing_account_name, const string& paying_account_name ) + wallet_transaction_record detail::client_impl::wallet_publish_slate( const string& publishing_account_name, + const string& paying_account_name ) { - auto trx = _wallet->publish_slate( publishing_account_name, paying_account_name ); - network_broadcast_transaction( trx ); - - return trx; + const auto record = _wallet->publish_slate( publishing_account_name, paying_account_name ); + network_broadcast_transaction( record.trx ); + return record; } int32_t detail::client_impl::wallet_recover_accounts( int32_t accounts_to_recover, int32_t maximum_number_of_attempts ) @@ -1862,20 +1862,11 @@ config load_config( const fc::path& datadir ) const string& from_account_name, const string& to_account_name, const string& memo_message, - const vote_selection_method& selection_method - ) + const vote_selection_method& selection_method ) { - const auto record = _wallet->transfer_asset( - amount_to_transfer, - asset_symbol, - from_account_name, - from_account_name, - to_account_name, - memo_message, - selection_method, - true - ); - + const auto record = _wallet->transfer_asset( amount_to_transfer, asset_symbol, + from_account_name, from_account_name, to_account_name, + memo_message, selection_method ); network_broadcast_transaction( record.trx ); return record; } @@ -1887,51 +1878,40 @@ config load_config( const fc::path& datadir ) const string& from_account_name, const string& to_account_name, const string& memo_message, - const vote_selection_method& selection_method - ) + const vote_selection_method& selection_method ) { - const auto record = _wallet->transfer_asset( - amount_to_transfer, - asset_symbol, - paying_account_name, - from_account_name, - to_account_name, - memo_message, - selection_method, - true - ); - + const auto record = _wallet->transfer_asset( amount_to_transfer, asset_symbol, + paying_account_name, from_account_name, to_account_name, + memo_message, selection_method ); network_broadcast_transaction( record.trx ); return record; } - bts::blockchain::signed_transaction detail::client_impl::wallet_asset_create(const string& symbol, - const string& asset_name, - const string& issuer_name, - const string& description, - const variant& data, - double maximum_share_supply , - int64_t precision, - bool is_market_issued /* = false */) + wallet_transaction_record detail::client_impl::wallet_asset_create( + const string& symbol, + const string& asset_name, + const string& issuer_name, + const string& description, + const variant& data, + double maximum_share_supply , + int64_t precision, + bool is_market_issued /* = false */ ) { - generate_transaction_flag flag = sign_and_broadcast; - bool sign = flag != do_not_sign; - auto create_asset_trx = - _wallet->create_asset(symbol, asset_name, description, data, issuer_name, maximum_share_supply, precision, is_market_issued, sign); - if (flag == sign_and_broadcast) - network_broadcast_transaction(create_asset_trx); - return create_asset_trx; + const auto record = _wallet->create_asset( symbol, asset_name, description, data, issuer_name, + maximum_share_supply, precision, is_market_issued ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction detail::client_impl::wallet_asset_issue(double real_amount, - const string& symbol, - const string& to_account_name, - const string& memo_message - ) + wallet_transaction_record detail::client_impl::wallet_asset_issue( + double real_amount, + const string& symbol, + const string& to_account_name, + const string& memo_message ) { - const auto issue_asset_trx = _wallet->issue_asset(real_amount,symbol,to_account_name, memo_message, true); - network_broadcast_transaction(issue_asset_trx); - return issue_asset_trx; + const auto record = _wallet->issue_asset( real_amount, symbol, to_account_name, memo_message ); + network_broadcast_transaction( record.trx ); + return record; } vector detail::client_impl::wallet_list() const @@ -2595,7 +2575,7 @@ config load_config( const fc::path& datadir ) fc::optional growl_password; if (option_variables.count("growl-password")) growl_password = option_variables["growl-password"].as(); - else + else growl_password = my->_config.growl_password; std::string bts_instance_identifier = "BitShares"; @@ -2707,16 +2687,16 @@ config load_config( const fc::path& datadir ) /* static */ fc::ip::endpoint client::string_to_endpoint(const std::string& remote_endpoint) { - try + try { ASSERT_TASK_NOT_PREEMPTED(); // make sure no cancel gets swallowed by catch(...) // first, try and parse the endpoint as a numeric_ipv4_address:port that doesn't need DNS lookup return fc::ip::endpoint::from_string(remote_endpoint.c_str()); - } - catch (...) + } + catch (...) { string::size_type colon_pos = remote_endpoint.find(':'); - try + try { uint16_t port = boost::lexical_cast( remote_endpoint.substr( colon_pos + 1, remote_endpoint.size() ) ); @@ -2724,13 +2704,13 @@ config load_config( const fc::path& datadir ) std::vector endpoints = fc::resolve(hostname, port); if ( endpoints.empty() ) FC_THROW_EXCEPTION(fc::unknown_host_exception, "The host name can not be resolved: ${hostname}", ("hostname", hostname)); - return endpoints.back(); + return endpoints.back(); } catch (const boost::bad_lexical_cast&) { FC_THROW("Bad port: ${port}", ("port", remote_endpoint.substr( colon_pos + 1, remote_endpoint.size() ))); } - } + } } void client::add_node( const string& remote_endpoint ) @@ -2742,7 +2722,7 @@ config load_config( const fc::path& datadir ) } catch (const fc::exception& e) { - ulog("Unable to add peer ${remote_endpoint}: ${error}", + ulog("Unable to add peer ${remote_endpoint}: ${error}", ("remote_endpoint", remote_endpoint)("error", e.to_string())); return; } @@ -2765,7 +2745,7 @@ config load_config( const fc::path& datadir ) } catch (const fc::exception& e) { - ulog("Unable to initiate connection to peer ${remote_endpoint}: ${error}", + ulog("Unable to initiate connection to peer ${remote_endpoint}: ${error}", ("remote_endpoint", remote_endpoint)("error", e.to_string())); return; } @@ -3103,15 +3083,14 @@ config load_config( const fc::path& datadir ) return state; } - signed_transaction client_impl::wallet_account_register( const string& account_name, - const string& pay_with_account, - const fc::variant& data, - uint32_t delegate_pay_rate ) + wallet_transaction_record client_impl::wallet_account_register( const string& account_name, + const string& pay_with_account, + const fc::variant& data, + uint8_t delegate_pay_rate ) { try { - FC_ASSERT( delegate_pay_rate <= 255 ); - const auto trx = _wallet->register_account(account_name, data, delegate_pay_rate, pay_with_account); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->register_account( account_name, data, delegate_pay_rate, pay_with_account ); + network_broadcast_transaction( record.trx ); + return record; } FC_RETHROW_EXCEPTIONS(warn, "", ("account_name", account_name)("data", data)) } variant_object client_impl::wallet_get_info() @@ -3125,28 +3104,24 @@ config load_config( const fc::path& datadir ) _wallet->update_account_private_data(account_to_update, private_data); } - signed_transaction client_impl::wallet_account_update_registration( const string& account_to_update, - const string& pay_from_account, - const variant& public_data, - uint8_t delegate_pay_rate ) + wallet_transaction_record client_impl::wallet_account_update_registration( + const string& account_to_update, + const string& pay_from_account, + const variant& public_data, + uint8_t delegate_pay_rate ) { - const auto trx = _wallet->update_registered_account( account_to_update, - pay_from_account, - public_data, - delegate_pay_rate, - true ); - - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->update_registered_account( account_to_update, pay_from_account, public_data, delegate_pay_rate ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction detail::client_impl::wallet_account_update_active_key( const std::string& account_to_update, - const std::string& pay_from_account, - const std::string& new_active_key ) + wallet_transaction_record detail::client_impl::wallet_account_update_active_key( const std::string& account_to_update, + const std::string& pay_from_account, + const std::string& new_active_key ) { - const auto trx = _wallet->update_active_key(account_to_update, pay_from_account, new_active_key); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->update_active_key( account_to_update, pay_from_account, new_active_key ); + network_broadcast_transaction( record.trx ); + return record; } fc::variant_object client_impl::network_get_info() const @@ -3201,10 +3176,13 @@ config load_config( const fc::path& datadir ) return _wallet->get_account_balances( account_name ); } - signed_transaction client_impl::wallet_market_submit_bid( const string& from_account, - double quantity, const string& quantity_symbol, - double quote_price, const string& quote_symbol, - bool allow_stupid_bid ) + wallet_transaction_record client_impl::wallet_market_submit_bid( + const string& from_account, + double quantity, + const string& quantity_symbol, + double quote_price, + const string& quote_symbol, + bool allow_stupid_bid ) { vector lowest_ask = blockchain_market_order_book(quote_symbol, quantity_symbol, 1).second; @@ -3214,17 +3192,18 @@ config load_config( const fc::path& datadir ) "This bid is based on economically unsound principles, and is ill-advised. " "If you're sure you want to do this, place your bid again and set allow_stupid_bid to true."); - auto trx = _wallet->submit_bid( from_account, quantity, quantity_symbol, - quote_price, quote_symbol, true ); - - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->submit_bid( from_account, quantity, quantity_symbol, quote_price, quote_symbol ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_submit_ask( const string& from_account, - double quantity, const string& quantity_symbol, - double quote_price, const string& quote_symbol, - bool allow_stupid_ask ) + wallet_transaction_record client_impl::wallet_market_submit_ask( + const string& from_account, + double quantity, + const string& quantity_symbol, + double quote_price, + const string& quote_symbol, + bool allow_stupid_ask ) { vector highest_bid = blockchain_market_order_book(quote_symbol, quantity_symbol, 1).first; @@ -3234,17 +3213,17 @@ config load_config( const fc::path& datadir ) "This ask is based on economically unsound principles, and is ill-advised. " "If you're sure you want to do this, place your ask again and set allow_stupid_ask to true."); - auto trx = _wallet->submit_ask( from_account, quantity, quantity_symbol, - quote_price, quote_symbol, true ); - - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->submit_ask( from_account, quantity, quantity_symbol, quote_price, quote_symbol ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_submit_short( const string& from_account, - double quantity, - double quote_price, const string& quote_symbol, - bool allow_stupid_short ) + wallet_transaction_record client_impl::wallet_market_submit_short( + const string& from_account, + double quantity, + double quote_price, + const string& quote_symbol, + bool allow_stupid_short ) { vector lowest_ask = blockchain_market_order_book(quote_symbol, _chain_db->get_asset_symbol(0), 1).second; @@ -3254,43 +3233,41 @@ config load_config( const fc::path& datadir ) "This short is based on economically unsound principles, and is ill-advised. " "If you're sure you want to do this, place your short again and set allow_stupid_short to true."); - auto trx = _wallet->submit_short( from_account, quantity, quote_price, quote_symbol, true ); - - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->submit_short( from_account, quantity, quote_price, quote_symbol ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_cover( const string& from_account, - double quantity, - const string& quantity_symbol, - const address& order_id ) + wallet_transaction_record client_impl::wallet_market_cover( + const string& from_account, + double quantity, + const string& quantity_symbol, + const address& order_id ) { - auto trx = _wallet->cover_short( from_account, quantity, quantity_symbol, order_id, true ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->cover_short( from_account, quantity, quantity_symbol, order_id ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_cover2( const string& from_account, - double quantity, - const string& quantity_symbol, - const order_id_type& short_id ) + wallet_transaction_record client_impl::wallet_market_cover2( + const string& from_account, + double quantity, + const string& quantity_symbol, + const order_id_type& short_id ) { - const auto trx = _wallet->cover_short2( from_account, quantity, quantity_symbol, short_id, true ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->cover_short2( from_account, quantity, quantity_symbol, short_id ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_delegate_withdraw_pay( const string& delegate_name, - const string& to_account_name, - double amount_to_withdraw, - const string& memo_message ) + wallet_transaction_record client_impl::wallet_delegate_withdraw_pay( const string& delegate_name, + const string& to_account_name, + double amount_to_withdraw, + const string& memo_message ) { - auto trx = _wallet->withdraw_delegate_pay( delegate_name, - amount_to_withdraw, - to_account_name, - memo_message, true ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->withdraw_delegate_pay( delegate_name, amount_to_withdraw, to_account_name, memo_message ); + network_broadcast_transaction( record.trx ); + return record; } asset client_impl::wallet_set_transaction_fee( double fee ) @@ -3381,11 +3358,11 @@ config load_config( const fc::path& datadir ) return std::make_pair(bids, asks); } - std::vector client_impl::blockchain_market_order_history(const std::string "e_symbol, - const std::string &base_symbol, - uint32_t skip_count, - uint32_t limit, - const string& owner) const + std::vector client_impl::blockchain_market_order_history( const std::string "e_symbol, + const std::string &base_symbol, + uint32_t skip_count, + uint32_t limit, + const string& owner )const { auto quote_id = _chain_db->get_asset_id(quote_symbol); auto base_id = _chain_db->get_asset_id(base_symbol); @@ -3398,35 +3375,35 @@ config load_config( const fc::path& datadir ) const std::string& base_symbol, const fc::time_point& start_time, const fc::microseconds& duration, - const market_history_key::time_granularity_enum& granularity ) const + const market_history_key::time_granularity_enum& granularity )const { return _chain_db->get_market_price_history( _chain_db->get_asset_id(quote_symbol), _chain_db->get_asset_id(base_symbol), start_time, duration, granularity ); } - signed_transaction client_impl::wallet_market_add_collateral(const std::string &from_account_name, - const address &short_id, - const share_type &collateral_to_add) + wallet_transaction_record client_impl::wallet_market_add_collateral( const std::string &from_account_name, + const address &short_id, + const share_type &collateral_to_add ) { - auto trx = _wallet->add_collateral(from_account_name, short_id, collateral_to_add); - network_broadcast_transaction(trx); - return trx; + const auto record = _wallet->add_collateral( from_account_name, short_id, collateral_to_add ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_add_collateral2(const std::string &from_account_name, - const order_id_type &short_id, - const share_type &collateral_to_add) + wallet_transaction_record client_impl::wallet_market_add_collateral2( const std::string &from_account_name, + const order_id_type &short_id, + const share_type &collateral_to_add ) { - const auto trx = _wallet->add_collateral2( from_account_name, short_id, collateral_to_add ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->add_collateral2( from_account_name, short_id, collateral_to_add ); + network_broadcast_transaction( record.trx ); + return record; } vector client_impl::wallet_market_order_list( const string& quote_symbol, const string& base_symbol, int64_t limit, - const string& account_name ) + const string& account_name ) { return _wallet->get_market_orders( quote_symbol, base_symbol, limit, account_name ); } @@ -3434,23 +3411,23 @@ config load_config( const fc::path& datadir ) map client_impl::wallet_market_order_list2( const string& quote_symbol, const string& base_symbol, int64_t limit, - const string& account_name ) + const string& account_name ) { return _wallet->get_market_orders2( quote_symbol, base_symbol, limit, account_name ); } - signed_transaction client_impl::wallet_market_cancel_order( const address& order_address ) + wallet_transaction_record client_impl::wallet_market_cancel_order( const address& order_address ) { - auto trx = _wallet->cancel_market_order( order_address ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->cancel_market_order( order_address ); + network_broadcast_transaction( record.trx ); + return record; } - signed_transaction client_impl::wallet_market_cancel_order2( const order_id_type& order_id ) + wallet_transaction_record client_impl::wallet_market_cancel_order2( const order_id_type& order_id ) { - const auto trx = _wallet->cancel_market_order2( order_id ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->cancel_market_order2( order_id ); + network_broadcast_transaction( record.trx ); + return record; } account_vote_summary_type client_impl::wallet_account_vote_summary( const string& account_name )const @@ -3724,14 +3701,15 @@ config load_config( const fc::path& datadir ) return _chain_db->unclaimed_genesis(); } - bts::blockchain::signed_transaction client_impl::wallet_publish_price_feed( const std::string& delegate_account, - double real_amount_per_xts, - const std::string& real_amount_symbol ) + wallet_transaction_record client_impl::wallet_publish_price_feed( const std::string& delegate_account, + double real_amount_per_xts, + const std::string& real_amount_symbol ) { - auto trx = _wallet->publish_price( delegate_account, real_amount_per_xts, real_amount_symbol ); - network_broadcast_transaction( trx ); - return trx; + const auto record = _wallet->publish_price( delegate_account, real_amount_per_xts, real_amount_symbol ); + network_broadcast_transaction( record.trx ); + return record; } + int32_t client_impl::wallet_regenerate_keys( const std::string& account, uint32_t number_to_regenerate ) { return _wallet->regenerate_keys( account, number_to_regenerate ); diff --git a/libraries/wallet/include/bts/wallet/wallet.hpp b/libraries/wallet/include/bts/wallet/wallet.hpp index 8bbc5a55e..9a487af90 100644 --- a/libraries/wallet/include/bts/wallet/wallet.hpp +++ b/libraries/wallet/include/bts/wallet/wallet.hpp @@ -164,12 +164,17 @@ namespace bts { namespace wallet { public_key_type create_account( const string& account_name, const variant& private_data = variant() ); + void update_account_private_data( const string& account_to_update, + const variant& private_data ); + void account_set_favorite ( const string& account_name, const bool is_favorite ); address get_new_address( const string& account_name ); public_key_type get_new_public_key( const string& account_name ); + wallet_account_record get_account( const string& account_name )const; + /** * A contact is an account for which we do not have the private key. */ @@ -274,167 +279,198 @@ namespace bts { namespace wallet { * and producing a single output. The only different aspect with transfer_asset is that * this will send to a address. */ - signed_transaction transfer_asset_to_address( double real_amount_to_transfer, - const string& amount_to_transfer_symbol, - const string& from_account_name, - const address& to_address, - const string& memo_message, - vote_selection_method selection_method, - bool sign ); + wallet_transaction_record transfer_asset_to_address( + double real_amount_to_transfer, + const string& amount_to_transfer_symbol, + const string& from_account_name, + const address& to_address, + const string& memo_message, + vote_selection_method selection_method, + bool sign = true + ); /** * This transfer works like a bitcoin sendmany transaction combining multiple inputs * and producing a single output. */ - signed_transaction transfer_asset_to_many_address( const string& amount_to_transfer_symbol, - const string& from_account_name, - const unordered_map< address, double >& to_address_amounts, - const string& memo_message, - bool sign ); + wallet_transaction_record transfer_asset_to_many_address( + const string& amount_to_transfer_symbol, + const string& from_account_name, + const unordered_map& to_address_amounts, + const string& memo_message, + bool sign = true + ); /** * This transfer works like a bitcoin transaction combining multiple inputs * and producing a single output. */ - wallet_transaction_record transfer_asset(double real_amount_to_transfer, - const string& amount_to_transfer_symbol, - const string& paying_account_name, - const string& from_account_name, - const string& to_account_name, - const string& memo_message, - vote_selection_method m, - bool sign ); - - signed_transaction withdraw_delegate_pay( const string& delegate_name, - double amount_to_withdraw, - const string& withdraw_to_account_name, - const string& memo_message, - bool sign ); - - signed_transaction create_asset( const string& symbol, - const string& asset_name, - const string& description, - const variant& data, - const string& issuer_name, - double max_share_supply, - int64_t precision, - bool is_market_issued = false, - bool sign = true ); - - signed_transaction issue_asset( double amount, - const string& symbol, - const string& to_account_name, - const string& memo_message, - bool sign = true ); - + wallet_transaction_record transfer_asset( + double real_amount_to_transfer, + const string& amount_to_transfer_symbol, + const string& paying_account_name, + const string& from_account_name, + const string& to_account_name, + const string& memo_message, + vote_selection_method m, + bool sign = true + ); + /** + * if the active_key is null then the active key will be made the same as the master key. + * if the name already exists then it will be updated if this wallet controls the active key + * or master key + */ + wallet_transaction_record register_account( + const string& account_name, + const variant& json_data, + uint8_t delegate_pay_rate, + const string& pay_with_account_name, + bool sign = true + ); + wallet_transaction_record update_registered_account( + const string& account_name, + const string& pay_from_account, + optional public_data, + uint8_t delegate_pay_rate = 255, + bool sign = true + ); + wallet_transaction_record update_active_key( + const std::string& account_to_update, + const std::string& pay_from_account, + const std::string& new_active_key, + bool sign = true + ); + wallet_transaction_record withdraw_delegate_pay( + const string& delegate_name, + double amount_to_withdraw, + const string& withdraw_to_account_name, + const string& memo_message, + bool sign = true + ); + wallet_transaction_record publish_slate( + const string& account, + string account_to_pay_with, + bool sign = true + ); + wallet_transaction_record publish_price( + const string& account, + double amount_per_xts, + const string& amount_asset_symbol, + bool sign = true + ); + wallet_transaction_record create_asset( + const string& symbol, + const string& asset_name, + const string& description, + const variant& data, + const string& issuer_name, + double max_share_supply, + int64_t precision, + bool is_market_issued = false, + bool sign = true + ); + wallet_transaction_record issue_asset( + double amount, + const string& symbol, + const string& to_account_name, + const string& memo_message, + bool sign = true + ); /** * ie: submit_bid( 10 BTC at 600.34 USD per BTC ) * * Requires the user have 6003.4 USD */ - signed_transaction submit_bid( const string& from_account_name, - double real_quantity, - const string& quantity_symbol, - double price_per_unit, - const string& quote_symbol, - bool sign = true ); - + wallet_transaction_record submit_bid( + const string& from_account_name, + double real_quantity, + const string& quantity_symbol, + double price_per_unit, + const string& quote_symbol, + bool sign = true + ); /** * ie: submit_ask( 10 BTC at 600.34 USD per BTC ) * * Requires the user have 10 BTC + fees */ - signed_transaction submit_ask( const string& from_account_name, - double real_quantity, - const string& quantity_symbol, - double price_per_unit, - const string& quote_symbol, - bool sign = true ); - + wallet_transaction_record submit_ask( + const string& from_account_name, + double real_quantity, + const string& quantity_symbol, + double price_per_unit, + const string& quote_symbol, + bool sign = true + ); /** * ie: submit_short( 10 USD at 600.34 USD per XTS ) * * Requires the user have 10 / 600.34 XTS + fees */ - signed_transaction submit_short( const string& from_account_name, - double real_quantity_usd, - double price_per_unit, - const string& quote_symbol, - bool sign = true ); - - signed_transaction cover_short( const string& from_account_name, - double real_quantity_usd, - const string& quote_symbol, - const address& owner_address, - bool sign = true ); - - signed_transaction add_collateral( const string& from_account_name, - const address& short_id, - share_type collateral_to_add, - bool sign = true ); - - signed_transaction cancel_market_order( const address& owner_address ); - + wallet_transaction_record submit_short( + const string& from_account_name, + double real_quantity_usd, + double price_per_unit, + const string& quote_symbol, + bool sign = true + ); + wallet_transaction_record cover_short( + const string& from_account_name, + double real_quantity_usd, + const string& quote_symbol, + const address& owner_address, + bool sign = true + ); + wallet_transaction_record add_collateral( + const string& from_account_name, + const address& short_id, + share_type collateral_to_add, + bool sign = true + ); + wallet_transaction_record cancel_market_order( + const address& owner_address, + bool sign = true + ); + /*************************/ /* New market order APIs */ - signed_transaction cover_short2( const string& from_account_name, - double real_quantity_usd, - const string& quote_symbol, - const order_id_type& short_id, - bool sign = true ); - - signed_transaction add_collateral2( const string& from_account_name, - const order_id_type& short_id, - share_type collateral_to_add, - bool sign = true ); - - signed_transaction cancel_market_order2( const order_id_type& order_id ); + wallet_transaction_record cover_short2( + const string& from_account_name, + double real_quantity_usd, + const string& quote_symbol, + const order_id_type& short_id, + bool sign = true + ); + wallet_transaction_record add_collateral2( + const string& from_account_name, + const order_id_type& short_id, + share_type collateral_to_add, + bool sign = true + ); + wallet_transaction_record cancel_market_order2( + const order_id_type& order_id, + bool sign = true + ); map get_market_orders2( const string& quote, const string& base, int32_t limit, const string& account_name )const; /*************************/ - - wallet_account_record get_account( const string& account_name )const; - - /** - * if the active_key is null then the active key will be made the same as the master key. - * if the name already exists then it will be updated if this wallet controls the active key - * or master key - */ - signed_transaction register_account( const string& account_name, - const variant& json_data, - uint8_t delegate_pay_rate, - const string& pay_with_account_name, - bool sign = true ); - - void update_account_private_data( const string& account_to_update, - const variant& private_data ); - - signed_transaction update_registered_account( const string& account_name, - const string& pay_from_account, - optional public_data, - uint8_t delegate_pay_rate = 255, - bool sign = true ); - - signed_transaction update_active_key( const std::string& account_to_update, - const std::string& pay_from_account, - const std::string& new_active_key, - bool sign = true ); - #if 0 - signed_transaction create_proposal( const string& delegate_account_name, - const string& subject, - const string& body, - const string& proposal_type, - const variant& data, - bool sign = true ); - - signed_transaction vote_proposal( const string& delegate_account_name, - proposal_id_type proposal_id, - proposal_vote::vote_type vote, - const string& message = string(), - bool sign = true); + wallet_transaction_record create_proposal( + const string& delegate_account_name, + const string& subject, + const string& body, + const string& proposal_type, + const variant& data, + bool sign = true + ); + wallet_transaction_record vote_proposal( + const string& delegate_account_name, + proposal_id_type proposal_id, + proposal_vote::vote_type vote, + const string& message = string(), + bool sign = tru + ); #endif - - ///@} Transaction Generation Methods + string get_key_label( const public_key_type& key )const; pretty_transaction to_pretty_trx( const wallet_transaction_record& trx_rec ) const; @@ -461,10 +497,6 @@ namespace bts { namespace wallet { const string& asset_symbol = "" )const; void remove_transaction_record( const string& record_id ); - signed_transaction publish_slate(const string& account, string account_to_pay_with, bool sign = true ); - signed_transaction publish_price( const string& account, - double amount_per_xts, - const string& amount_asset_symbol, bool sign = true ); uint32_t regenerate_keys( const string& account_name, uint32_t max_number_of_attempts ); int32_t recover_accounts(int32_t number_of_accounts , int32_t max_number_of_attempts); @@ -486,11 +518,8 @@ namespace bts { namespace wallet { */ /** signs transaction with the specified keys for the specified addresses */ - void sign_transaction( signed_transaction& trx, const unordered_set
& req_sigs ); - void sign_and_cache_transaction( - signed_transaction& transaction, - const std::unordered_set
& required_signatures, - wallet_transaction_record& record ); + void sign_transaction( signed_transaction& transaction, const unordered_set
& required_signatures )const; + void cache_transaction( const signed_transaction& transaction, wallet_transaction_record& record ); slate_id_type select_slate( signed_transaction& transaction, const asset_id_type& deposit_asset_id = asset_id_type( 0 ), vote_selection_method = vote_random ); diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 7386ff426..092c64b8f 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -50,7 +50,6 @@ namespace bts { namespace wallet { fc::sha512 _wallet_password; fc::optional _scheduled_lock_time; fc::future _relocker_done; - bool _use_deterministic_one_time_keys = true; fc::future _scan_in_progress; std::unique_ptr _scanner_thread; @@ -151,10 +150,7 @@ namespace bts { namespace wallet { private_key_type wallet_impl::create_one_time_key() { - if( !_use_deterministic_one_time_keys ) - return private_key_type::generate(); - - return _wallet_db.new_private_key( _wallet_password ); + return _wallet_db.new_private_key( _wallet_password ); } void wallet_impl::state_changed( const pending_chain_state_ptr& state ) @@ -2442,47 +2438,43 @@ namespace bts { namespace wallet { return transactions; } FC_RETHROW_EXCEPTIONS( warn, "" ) } - void wallet::sign_transaction( signed_transaction& trx, const std::unordered_set
& req_sigs ) + void wallet::sign_transaction( signed_transaction& transaction, const unordered_set
& required_signatures )const { try { - trx.expiration = blockchain::now() + get_transaction_expiration(); + transaction.expiration = blockchain::now() + get_transaction_expiration(); const auto chain_id = my->_blockchain->chain_id(); - for( const auto& addr : req_sigs ) trx.sign( get_private_key( addr ), chain_id ); - } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx)("req_sigs",req_sigs) ) } - - void wallet::sign_and_cache_transaction( - signed_transaction& transaction, - const std::unordered_set
& required_signatures, - wallet_transaction_record& record - ) + for( const auto& addr : required_signatures ) + transaction.sign( get_private_key( addr ), chain_id ); + } FC_RETHROW_EXCEPTIONS( warn, "" ) } + + void wallet::cache_transaction( const signed_transaction& transaction, wallet_transaction_record& record ) { try { - sign_transaction( transaction, required_signatures ); - my->_blockchain->store_pending_transaction( transaction, true ); + my->_blockchain->store_pending_transaction( transaction, true ); - record.record_id = transaction.id(); - record.trx = transaction; - record.created_time = blockchain::now(); - record.received_time = record.created_time; - my->_wallet_db.store_transaction( record ); + record.record_id = transaction.id(); + record.trx = transaction; + record.created_time = blockchain::now(); + record.received_time = record.created_time; + my->_wallet_db.store_transaction( record ); - for( const auto& op : transaction.operations ) - { - if( operation_type_enum( op.type ) == withdraw_op_type ) - my->sync_balance_with_blockchain( op.as().balance_id ); - } + for( const auto& op : transaction.operations ) + { + if( operation_type_enum( op.type ) == withdraw_op_type ) + my->sync_balance_with_blockchain( op.as().balance_id ); + } } FC_RETHROW_EXCEPTIONS( warn, "" ) } slate_id_type wallet::select_slate( signed_transaction& transaction, const asset_id_type& deposit_asset_id, vote_selection_method selection_method ) { - auto slate_id = slate_id_type( 0 ); - if( deposit_asset_id != asset_id_type( 0 ) ) return slate_id; + auto slate_id = slate_id_type( 0 ); + if( deposit_asset_id != asset_id_type( 0 ) ) return slate_id; - const auto slate = select_delegate_vote( selection_method ); - slate_id = slate.id(); + const auto slate = select_delegate_vote( selection_method ); + slate_id = slate.id(); - if( slate_id != slate_id_type( 0 ) && !my->_blockchain->get_delegate_slate( slate_id ).valid() ) - transaction.define_delegate_slate( slate ); + if( slate_id != slate_id_type( 0 ) && !my->_blockchain->get_delegate_slate( slate_id ).valid() ) + transaction.define_delegate_slate( slate ); - return slate_id; + return slate_id; } private_key_type wallet::get_private_key( const address& addr )const @@ -2836,9 +2828,11 @@ namespace bts { namespace wallet { FC_ASSERT( header.validate_signee( delegate_pub_key ) ); } FC_RETHROW_EXCEPTIONS( warn, "", ("header",header) ) } - signed_transaction wallet::publish_price( const string& account_to_publish_under, - double amount_per_xts, - const string& amount_asset_symbol, bool sign ) + wallet_transaction_record wallet::publish_price( + const string& account_to_publish_under, + double amount_per_xts, + const string& amount_asset_symbol, + bool sign ) { try { FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -2892,25 +2886,26 @@ namespace bts { namespace wallet { trx, required_signatures ); } required_signatures.insert( current_account->active_key() ); - if (sign) - { - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = payer_public_key; - entry.memo = "publish price " + my->_blockchain->to_pretty_price( quote_price_shares ); - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = payer_public_key; + entry.memo = "publish price " + my->_blockchain->to_pretty_price( quote_price_shares ); - sign_and_cache_transaction( trx, required_signatures, record ); - my->_blockchain->store_pending_transaction( trx ); - } - return trx; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (account_to_publish_under)(amount_per_xts)(amount_asset_symbol)(sign) ) } - signed_transaction wallet::publish_slate( const string& account_to_publish_under, string account_to_pay_with, bool sign ) + wallet_transaction_record wallet::publish_slate( + const string& account_to_publish_under, + string account_to_pay_with, + bool sign ) { try { FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -2960,21 +2955,20 @@ namespace bts { namespace wallet { trx, required_signatures ); } - if (sign) - { - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = payer_public_key; - entry.memo = "publish slate " + fc::variant(slate_id).as_string(); - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = payer_public_key; + entry.memo = "publish slate " + fc::variant(slate_id).as_string(); - sign_and_cache_transaction( trx, required_signatures, record ); - my->_blockchain->store_pending_transaction( trx ); - } - return trx; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; + + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (account_to_publish_under) ) } uint32_t wallet::regenerate_keys( const string& account_name, uint32_t count ) @@ -3376,11 +3370,12 @@ namespace bts { namespace wallet { ("to_account_name",to_account_name) ("memo_message",memo_message) ) } - signed_transaction wallet::withdraw_delegate_pay( const string& delegate_name, - double real_amount_to_withdraw, - const string& withdraw_to_account_name, - const string& memo_message, - bool sign ) + wallet_transaction_record wallet::withdraw_delegate_pay( + const string& delegate_name, + double real_amount_to_withdraw, + const string& withdraw_to_account_name, + const string& memo_message, + bool sign ) { try { FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -3421,31 +3416,31 @@ namespace bts { namespace wallet { from_memo ); - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = delegate_private_key.get_public_key(); - entry.to_account = receiver_public_key; - entry.amount = asset( amount_to_withdraw ); - entry.memo = memo_message; + auto entry = ledger_entry(); + entry.from_account = delegate_private_key.get_public_key(); + entry.to_account = receiver_public_key; + entry.amount = asset( amount_to_withdraw ); + entry.memo = memo_message; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("delegate_name",delegate_name) ("amount_to_withdraw",real_amount_to_withdraw ) ) } - signed_transaction wallet::transfer_asset_to_address( double real_amount_to_transfer, - const string& amount_to_transfer_symbol, - const string& from_account_name, - const address& to_address, - const string& memo_message, - vote_selection_method selection_method, - bool sign ) + wallet_transaction_record wallet::transfer_asset_to_address( + double real_amount_to_transfer, + const string& amount_to_transfer_symbol, + const string& from_account_name, + const address& to_address, + const string& memo_message, + vote_selection_method selection_method, + bool sign ) { try { FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -3492,19 +3487,20 @@ namespace bts { namespace wallet { trx.deposit( to_address, asset_to_transfer, slate_id); - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = sender_public_key; - entry.amount = asset_to_transfer; - entry.memo = memo_message; + auto entry = ledger_entry(); + entry.from_account = sender_public_key; + entry.amount = asset_to_transfer; + entry.memo = memo_message; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; - record.extra_addresses.push_back( to_address ); - } - return trx; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; + record.extra_addresses.push_back( to_address ); + + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("real_amount_to_transfer",real_amount_to_transfer) ("amount_to_transfer_symbol",amount_to_transfer_symbol) @@ -3512,11 +3508,12 @@ namespace bts { namespace wallet { ("to_address",to_address) ("memo_message",memo_message) ) } - signed_transaction wallet::transfer_asset_to_many_address( const string& amount_to_transfer_symbol, - const string& from_account_name, - const std::unordered_map< address, double >& to_address_amounts, - const string& memo_message, - bool sign ) + wallet_transaction_record wallet::transfer_asset_to_many_address( + const string& amount_to_transfer_symbol, + const string& from_account_name, + const std::unordered_map& to_address_amounts, + const string& memo_message, + bool sign ) { try { FC_ASSERT( is_open() ); @@ -3563,21 +3560,20 @@ namespace bts { namespace wallet { trx, required_signatures ); - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = sender_public_key; - entry.amount = total_asset_to_transfer; - entry.memo = memo_message; + auto entry = ledger_entry(); + entry.from_account = sender_public_key; + entry.amount = total_asset_to_transfer; + entry.memo = memo_message; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; - record.extra_addresses = to_addresses; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; + record.extra_addresses = to_addresses; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("amount_to_transfer_symbol",amount_to_transfer_symbol) ("from_account_name",from_account_name) @@ -3592,8 +3588,7 @@ namespace bts { namespace wallet { const string& to_account_name, const string& memo_message, vote_selection_method selection_method, - bool sign - ) + bool sign ) { try { FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -3673,24 +3668,21 @@ namespace bts { namespace wallet { from_memo ); - /* TODO: Fix this when we don't sign and broadcast transactions without user confirmation */ - //if( sign ) - //{ - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = receiver_public_key; - entry.amount = asset_to_transfer; - entry.memo = memo_message; - if( payer_public_key != sender_public_key ) - entry.memo_from_account = sender_public_key; + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = receiver_public_key; + entry.amount = asset_to_transfer; + entry.memo = memo_message; + if( payer_public_key != sender_public_key ) + entry.memo_from_account = sender_public_key; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; + + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - sign_and_cache_transaction( trx, required_signatures, record ); - //} - //return trx; return record; } FC_CAPTURE_AND_RETHROW( (real_amount_to_transfer) (amount_to_transfer_symbol) @@ -3699,11 +3691,12 @@ namespace bts { namespace wallet { (to_account_name) (memo_message ) ) } - signed_transaction wallet::register_account( const string& account_to_register, - const variant& public_data, - uint8_t delegate_pay_rate, - const string& pay_with_account_name, - bool sign ) + wallet_transaction_record wallet::register_account( + const string& account_to_register, + const variant& public_data, + uint8_t delegate_pay_rate, + const string& pay_with_account_name, + bool sign ) { try { if( !is_valid_account_name( account_to_register ) ) FC_THROW_EXCEPTION( invalid_name, "Invalid account name!", ("account_to_register",account_to_register) ); @@ -3755,36 +3748,35 @@ namespace bts { namespace wallet { trx, required_signatures ); - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = account_public_key; - entry.memo = "register " + account_to_register + (as_delegate ? " as a delegate" : ""); + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = account_public_key; + entry.memo = "register " + account_to_register + (as_delegate ? " as a delegate" : ""); - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("account_to_register",account_to_register) ("public_data", public_data) ("pay_with_account_name", pay_with_account_name) ("delegate_pay_rate",int(delegate_pay_rate)) ) } - signed_transaction wallet::create_asset( const string& symbol, - const string& asset_name, - const string& description, - const variant& data, - const string& issuer_account_name, - double max_share_supply, - int64_t precision, - bool is_market_issued, - bool sign ) + wallet_transaction_record wallet::create_asset( + const string& symbol, + const string& asset_name, + const string& description, + const variant& data, + const string& issuer_account_name, + double max_share_supply, + int64_t precision, + bool is_market_issued, + bool sign ) { try { - FC_ASSERT( create_asset_operation::is_power_of_ten( precision ) ); FC_ASSERT( is_open() ); FC_ASSERT( is_unlocked() ); @@ -3826,31 +3818,31 @@ namespace bts { namespace wallet { asset_record::market_issued_asset, max_share_supply_in_internal_units, precision ); } - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = from_account_address; - entry.to_account = from_account_address; - entry.memo = "create " + symbol + " (" + asset_name + ")"; + auto entry = ledger_entry(); + entry.from_account = from_account_address; + entry.to_account = from_account_address; + entry.memo = "create " + symbol + " (" + asset_name + ")"; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("symbol",symbol) ("name", asset_name ) ("description", description) ( "issuer_account", issuer_account_name) ) } - signed_transaction wallet::issue_asset( double amount_to_issue, - const string& symbol, - const string& to_account_name, - const string& memo_message, - bool sign ) - { + wallet_transaction_record wallet::issue_asset( + double amount_to_issue, + const string& symbol, + const string& to_account_name, + const string& memo_message, + bool sign ) + { try { if( !is_valid_account_name( to_account_name ) ) FC_THROW_EXCEPTION( invalid_name, "Invalid account name!", ("to_account_name",to_account_name) ); @@ -3894,22 +3886,21 @@ namespace bts { namespace wallet { from_memo ); - if( sign ) - { - auto entry = ledger_entry(); - entry.from_account = issuer->active_key(); - entry.to_account = receiver_public_key; - entry.amount = shares_to_issue; - entry.memo = "issue " + my->_blockchain->to_pretty_asset( shares_to_issue ); + auto entry = ledger_entry(); + entry.from_account = issuer->active_key(); + entry.to_account = receiver_public_key; + entry.amount = shares_to_issue; + entry.memo = "issue " + my->_blockchain->to_pretty_asset( shares_to_issue ); - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; + } FC_RETHROW_EXCEPTIONS( warn, "" ) } void wallet::update_account_private_data( const string& account_to_update, const variant& private_data ) @@ -3921,11 +3912,12 @@ namespace bts { namespace wallet { my->_wallet_db.cache_account( *oacct ); } - signed_transaction wallet::update_registered_account( const string& account_to_update, - const string& pay_from_account, - optional public_data, - uint8_t delegate_pay_rate, - bool sign ) + wallet_transaction_record wallet::update_registered_account( + const string& account_to_update, + const string& pay_from_account, + optional public_data, + uint8_t delegate_pay_rate, + bool sign ) { try { if( !is_valid_account_name( account_to_update ) ) FC_THROW_EXCEPTION( invalid_name, "Invalid account name!", ("account_to_update",account_to_update) ); @@ -3969,29 +3961,29 @@ namespace bts { namespace wallet { trx.update_account( account->id, delegate_pay_rate, public_data, optional() ); - if (sign) - { - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = account_public_key; - entry.memo = "update " + account_to_update; // TODO: Note if upgrading to delegate + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = account_public_key; + entry.memo = "update " + account_to_update; // TODO: Note if upgrading to delegate - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("account_to_update",account_to_update) ("pay_from_account",pay_from_account) ("public_data",public_data) ("sign",sign) ) } - signed_transaction wallet::update_active_key( const std::string& account_to_update, - const std::string& pay_from_account, - const std::string& new_active_key, - bool sign ) + wallet_transaction_record wallet::update_active_key( + const std::string& account_to_update, + const std::string& pay_from_account, + const std::string& new_active_key, + bool sign ) { try { if( !is_valid_account_name( account_to_update ) ) FC_THROW_EXCEPTION( invalid_name, "Invalid account name!", ("account_to_update",account_to_update) ); @@ -4041,20 +4033,19 @@ namespace bts { namespace wallet { trx.update_account( account->id, account->delegate_pay_rate(), optional(), account_public_key ); - if (sign) - { - auto entry = ledger_entry(); - entry.from_account = payer_public_key; - entry.to_account = account_public_key; - entry.memo = "update " + account_to_update + " active key"; + auto entry = ledger_entry(); + entry.from_account = payer_public_key; + entry.to_account = account_public_key; + entry.memo = "update " + account_to_update + " active key"; - auto record = wallet_transaction_record(); - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_RETHROW_EXCEPTIONS( warn, "", ("account_to_update",account_to_update) ("pay_from_account",pay_from_account) ("sign",sign) ) } @@ -4193,7 +4184,9 @@ namespace bts { namespace wallet { * price_per_unit = 1 / price_per_unit * @endcode */ - signed_transaction wallet::cancel_market_order( const address& owner_address ) + wallet_transaction_record wallet::cancel_market_order( + const address& owner_address, + bool sign ) { try { if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); if( NOT is_unlocked() ) FC_CAPTURE_AND_THROW( login_required ); @@ -4279,11 +4272,15 @@ namespace bts { namespace wallet { record.ledger_entries.push_back( entry ); record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (owner_address) ) } - signed_transaction wallet::cancel_market_order2( const order_id_type& order_id ) + wallet_transaction_record wallet::cancel_market_order2( + const order_id_type& order_id, + bool sign ) { try { if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); if( NOT is_unlocked() ) FC_CAPTURE_AND_THROW( login_required ); @@ -4371,11 +4368,13 @@ namespace bts { namespace wallet { record.ledger_entries.push_back( entry ); record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (order_id) ) } - signed_transaction wallet::submit_bid( + wallet_transaction_record wallet::submit_bid( const string& from_account_name, double real_quantity, const string& quantity_symbol, @@ -4459,35 +4458,34 @@ namespace bts { namespace wallet { trx.bid( cost_shares, quote_price_shares, order_address ); - if( sign ) - { - std::stringstream memo; - memo << "buy " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + std::stringstream memo; + memo << "buy " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = order_key; - entry.amount = cost_shares; - entry.memo = memo.str(); + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = order_key; + entry.amount = cost_shares; + entry.memo = memo.str(); - auto record = wallet_transaction_record(); - record.is_market = true; - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.is_market = true; + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); + auto key_rec = my->_wallet_db.lookup_key( order_key ); + FC_ASSERT( key_rec.valid() ); + key_rec->memo = "BID-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); + my->_wallet_db.store_key( *key_rec ); - auto key_rec = my->_wallet_db.lookup_key( order_key ); - FC_ASSERT( key_rec.valid() ); - key_rec->memo = "BID-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); - my->_wallet_db.store_key( *key_rec ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (from_account_name) (real_quantity)(quantity_symbol) (quote_price)(quote_symbol)(sign) ) } - signed_transaction wallet::submit_ask( + wallet_transaction_record wallet::submit_ask( const string& from_account_name, double real_quantity, const string& quantity_symbol, @@ -4571,30 +4569,29 @@ namespace bts { namespace wallet { trx.ask( cost_shares, quote_price_shares, order_address ); - if( sign ) - { - std::stringstream memo; - memo << "sell " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + std::stringstream memo; + memo << "sell " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = order_key; - entry.amount = cost_shares; - entry.memo = memo.str(); + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = order_key; + entry.amount = cost_shares; + entry.memo = memo.str(); - auto record = wallet_transaction_record(); - record.is_market = true; - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.is_market = true; + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); + auto key_rec = my->_wallet_db.lookup_key( order_key ); + FC_ASSERT( key_rec.valid() ); + key_rec->memo = "ASK-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); + my->_wallet_db.store_key( *key_rec ); - auto key_rec = my->_wallet_db.lookup_key( order_key ); - FC_ASSERT( key_rec.valid() ); - key_rec->memo = "ASK-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); - my->_wallet_db.store_key( *key_rec ); - } - return trx; + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); + + return record; } FC_CAPTURE_AND_RETHROW( (from_account_name) (real_quantity)(quantity_symbol) (quote_price)(quote_symbol)(sign) ) } @@ -4607,7 +4604,7 @@ namespace bts { namespace wallet { * @param from_account - the account that will be providing real_quantity / quote_price XTS to * fund the transaction. */ - signed_transaction wallet::submit_short( + wallet_transaction_record wallet::submit_short( const string& from_account_name, double real_quantity, double quote_price, @@ -4666,39 +4663,37 @@ namespace bts { namespace wallet { // withdraw to transaction cost_share_quantity + fee trx.short_sell( cost_shares, quote_price_shares, order_address ); - if( sign ) - { - std::stringstream memo; - memo << "short " << quote_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + std::stringstream memo; + memo << "short " << quote_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = order_key; - entry.amount = cost_shares; - entry.memo = memo.str(); + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = order_key; + entry.amount = cost_shares; + entry.memo = memo.str(); - auto record = wallet_transaction_record(); - record.is_market = true; - record.ledger_entries.push_back( entry ); - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.is_market = true; + record.ledger_entries.push_back( entry ); + record.fee = required_fees; - sign_and_cache_transaction( trx, required_signatures, record ); + auto key_rec = my->_wallet_db.lookup_key( order_key ); + FC_ASSERT( key_rec.valid() ); + key_rec->memo = "SHORT-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); + my->_wallet_db.store_key( *key_rec ); - auto key_rec = my->_wallet_db.lookup_key( order_key ); - FC_ASSERT( key_rec.valid() ); - key_rec->memo = "SHORT-" + variant( address( order_key ) ).as_string().substr( 3, 8 ); - my->_wallet_db.store_key( *key_rec ); - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - return trx; + return record; } FC_CAPTURE_AND_RETHROW( (from_account_name) (real_quantity) (quote_price)(quote_symbol)(sign) ) } - signed_transaction wallet::add_collateral( - const string& from_account_name, - const address& short_id, - share_type collateral_to_add, - bool sign) + wallet_transaction_record wallet::add_collateral( + const string& from_account_name, + const address& short_id, + share_type collateral_to_add, + bool sign ) { try { if (!is_open()) FC_CAPTURE_AND_THROW (wallet_closed); if (!is_unlocked()) FC_CAPTURE_AND_THROW (login_required); @@ -4723,30 +4718,28 @@ namespace bts { namespace wallet { trx, required_signatures); - if (sign) - { - auto record = wallet_transaction_record(); - record.is_market = true; - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.is_market = true; + record.fee = required_fees; - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = get_private_key(order_itr->second.order.get_owner()).get_public_key(); - entry.amount = asset(collateral_to_add); - entry.memo = "add collateral to short"; - record.ledger_entries.push_back(entry); + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = get_private_key(order_itr->second.order.get_owner()).get_public_key(); + entry.amount = asset(collateral_to_add); + entry.memo = "add collateral to short"; + record.ledger_entries.push_back(entry); - sign_and_cache_transaction(trx, required_signatures, record); - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - return trx; + return record; } FC_CAPTURE_AND_RETHROW((from_account_name)(short_id)(collateral_to_add)(sign)) } - signed_transaction wallet::add_collateral2( - const string& from_account_name, - const order_id_type& short_id, - share_type collateral_to_add, - bool sign) + wallet_transaction_record wallet::add_collateral2( + const string& from_account_name, + const order_id_type& short_id, + share_type collateral_to_add, + bool sign ) { try { if (!is_open()) FC_CAPTURE_AND_THROW (wallet_closed); if (!is_unlocked()) FC_CAPTURE_AND_THROW (login_required); @@ -4777,31 +4770,29 @@ namespace bts { namespace wallet { trx, required_signatures); - if (sign) - { - auto record = wallet_transaction_record(); - record.is_market = true; - record.fee = required_fees; + auto record = wallet_transaction_record(); + record.is_market = true; + record.fee = required_fees; - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = get_private_key( owner_address ).get_public_key(); - entry.amount = asset(collateral_to_add); - entry.memo = "add collateral to short"; - record.ledger_entries.push_back(entry); + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = get_private_key( owner_address ).get_public_key(); + entry.amount = asset(collateral_to_add); + entry.memo = "add collateral to short"; + record.ledger_entries.push_back(entry); - sign_and_cache_transaction(trx, required_signatures, record); - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - return trx; + return record; } FC_CAPTURE_AND_RETHROW((from_account_name)(short_id)(collateral_to_add)(sign)) } - signed_transaction wallet::cover_short( + wallet_transaction_record wallet::cover_short( const string& from_account_name, double real_quantity_usd, const string& quote_symbol, const address& owner_address, - bool sign ) + bool sign ) { try { if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); if( NOT is_unlocked() ) FC_CAPTURE_AND_THROW( login_required ); @@ -4884,41 +4875,40 @@ namespace bts { namespace wallet { my->withdraw_to_transaction( required_fees, from_address, trx, required_signatures ); } - if( sign ) + auto record = wallet_transaction_record(); + record.is_market = true; + record.fee = required_fees; + + { + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = get_private_key( order_to_cover->get_owner() ).get_public_key(); + entry.amount = amount_to_cover; + entry.memo = "payoff debt"; + record.ledger_entries.push_back( entry ); + } + if( collateral_recovered.amount > 0 ) { - auto record = wallet_transaction_record(); - record.is_market = true; - record.fee = required_fees; + auto entry = ledger_entry(); + entry.from_account = get_private_key( order_to_cover->get_owner() ).get_public_key(); + entry.to_account = from_account_key; + entry.amount = collateral_recovered; + entry.memo = "cover proceeds"; + record.ledger_entries.push_back( entry ); + } - { - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = get_private_key( order_to_cover->get_owner() ).get_public_key(); - entry.amount = amount_to_cover; - entry.memo = "payoff debt"; - record.ledger_entries.push_back( entry ); - } - if( collateral_recovered.amount > 0 ) - { - auto entry = ledger_entry(); - entry.from_account = get_private_key( order_to_cover->get_owner() ).get_public_key(); - entry.to_account = from_account_key; - entry.amount = collateral_recovered; - entry.memo = "cover proceeds"; - record.ledger_entries.push_back( entry ); - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + return record; } FC_CAPTURE_AND_RETHROW( (from_account_name)(real_quantity_usd)(quote_symbol)(owner_address)(sign) ) } - signed_transaction wallet::cover_short2( + wallet_transaction_record wallet::cover_short2( const string& from_account_name, double real_quantity_usd, const string& quote_symbol, const order_id_type& short_id, - bool sign ) + bool sign ) { try { if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); if( NOT is_unlocked() ) FC_CAPTURE_AND_THROW( login_required ); @@ -5001,33 +4991,32 @@ namespace bts { namespace wallet { my->withdraw_to_transaction( required_fees, from_address, trx, required_signatures ); } - if( sign ) + auto record = wallet_transaction_record(); + record.is_market = true; + record.fee = required_fees; + { - auto record = wallet_transaction_record(); - record.is_market = true; - record.fee = required_fees; + auto entry = ledger_entry(); + entry.from_account = from_account_key; + entry.to_account = get_private_key( owner_address ).get_public_key(); + entry.amount = amount_to_cover; + entry.memo = "payoff debt"; + record.ledger_entries.push_back( entry ); + } + if( collateral_recovered.amount > 0 ) + { + auto entry = ledger_entry(); + entry.from_account = get_private_key( owner_address ).get_public_key(); + entry.to_account = from_account_key; + entry.amount = collateral_recovered; + entry.memo = "cover proceeds"; + record.ledger_entries.push_back( entry ); + } - { - auto entry = ledger_entry(); - entry.from_account = from_account_key; - entry.to_account = get_private_key( owner_address ).get_public_key(); - entry.amount = amount_to_cover; - entry.memo = "payoff debt"; - record.ledger_entries.push_back( entry ); - } - if( collateral_recovered.amount > 0 ) - { - auto entry = ledger_entry(); - entry.from_account = get_private_key( owner_address ).get_public_key(); - entry.to_account = from_account_key; - entry.amount = collateral_recovered; - entry.memo = "cover proceeds"; - record.ledger_entries.push_back( entry ); - } + if( sign ) sign_transaction( trx, required_signatures ); + cache_transaction( trx, record ); - sign_and_cache_transaction( trx, required_signatures, record ); - } - return trx; + return record; } FC_CAPTURE_AND_RETHROW( (from_account_name)(real_quantity_usd)(quote_symbol)(short_id)(sign) ) } void wallet::set_transaction_fee( const asset& fee ) @@ -5054,8 +5043,8 @@ namespace bts { namespace wallet { if( lowest_ask ) { xts_fee += xts_fee + xts_fee; - // fees paid in something other than XTS are discounted 50% - auto alt_fees_paid = xts_fee * lowest_ask->market_index.order_price; + // fees paid in something other than XTS are discounted 50% + auto alt_fees_paid = xts_fee * lowest_ask->market_index.order_price; return alt_fees_paid; } } From 47c43dfb2dbbc69952f7a375324d2e99cdc1bef6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 4 Sep 2014 09:34:40 -0400 Subject: [PATCH 5/8] adding restrictions on when covering is enforced --- .../include/bts/blockchain/config.hpp | 1 + libraries/blockchain/market_engine.cpp | 24 +++++++++++++++++++ libraries/blockchain/market_operations.cpp | 2 +- libraries/fc | 2 +- programs/qt_wallet | 2 +- programs/web_wallet | 2 +- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index cf2fe7dfb..16ba6c23f 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -29,6 +29,7 @@ #define BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC (60*60*24*2) #define BTS_BLOCKCHAIN_DEFAULT_RELAY_FEE 10000 // XTS +#define BTS_BLOCKCHAIN_MINIMUM_SHORT_ORDER_SIZE (BTS_BLOCKCHAIN_PRECISION*100) /** * The number of delegates that the blockchain is designed to support diff --git a/libraries/blockchain/market_engine.cpp b/libraries/blockchain/market_engine.cpp index 252c354a5..ef8e615c4 100644 --- a/libraries/blockchain/market_engine.cpp +++ b/libraries/blockchain/market_engine.cpp @@ -185,6 +185,17 @@ class market_engine _current_bid.reset(); continue; } + /** + * Don't allow shorts to be executed if they are too far over priced or they will be + * immediately under collateralized. + */ + if( mtrx.bid_price < market_stat->minimum_ask() ) + { + //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); + // TODO: cancel the short order... + _current_ask.reset(); + continue; + } mtrx.ask_price = mtrx.bid_price; @@ -240,6 +251,19 @@ class market_engine if( mtrx.ask_price < mtrx.bid_price ) break; // the call price has not been reached + /** + * Don't allow margin calls to be executed too far below + * the minimum ask, this could lead to an attack where someone + * walks the whole book to steal the collateral. + */ + if( mtrx.bid_price < market_stat->minimum_ask() ) + { + //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); + // TODO: cancel the short order... + _current_ask.reset(); + continue; + } + mtrx.ask_price = mtrx.bid_price; auto max_usd_purchase = asset(*_current_ask->collateral,0) * mtrx.bid_price; diff --git a/libraries/blockchain/market_operations.cpp b/libraries/blockchain/market_operations.cpp index a2af7ff74..cb7df2b18 100644 --- a/libraries/blockchain/market_operations.cpp +++ b/libraries/blockchain/market_operations.cpp @@ -138,7 +138,6 @@ namespace bts { namespace blockchain { FC_ASSERT( asset_to_short->is_market_issued(), "${symbol} is not a market issued asset", ("symbol",asset_to_short->symbol) ); - auto current_short = eval_state._current_state->get_short_record( this->short_index ); //if( current_short ) wdump( (current_short) ); @@ -156,6 +155,7 @@ namespace bts { namespace blockchain { } else // this->amount > 0 - deposit { + FC_ASSERT( this->amount >= (BTS_BLOCKCHAIN_MINIMUM_SHORT_ORDER_SIZE) ); // 100 XTS min short order if( NOT current_short ) // then initialize to 0 current_short = order_record(); // sub the delta amount from the eval state that we deposited to the short diff --git a/libraries/fc b/libraries/fc index a0b3a9a92..3222dc7c0 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit a0b3a9a92d28ec0b3a08b45b8c1449737f56dd34 +Subproject commit 3222dc7c0be62b9ad0fdfd303c5c4f53b39063e6 diff --git a/programs/qt_wallet b/programs/qt_wallet index db356c1d5..75077f65c 160000 --- a/programs/qt_wallet +++ b/programs/qt_wallet @@ -1 +1 @@ -Subproject commit db356c1d5048f6624cf70cf2b6bfab3a6d06054b +Subproject commit 75077f65ccbfc8cc4c041eb501fb2135a74d627c diff --git a/programs/web_wallet b/programs/web_wallet index 24a391c9d..b5456af17 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit 24a391c9de88cf0161c3b5b31a42e1ba41d2e944 +Subproject commit b5456af1793debe36313ce778e47b21f542a3a93 From f80db8fb4ac358038d40cd7a70d102c841608639 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Thu, 4 Sep 2014 09:42:32 -0400 Subject: [PATCH 6/8] Don't cancel an ongoing scan when a new block comes in --- libraries/wallet/wallet.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 57669621c..2bde0e0e4 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -173,6 +173,7 @@ namespace bts { namespace wallet { if( !self->is_open() || !self->is_unlocked() ) return; if( !self->get_transaction_scanning() ) return; if( summary.block_data.block_num <= self->get_last_scanned_block_number() ) return; + if( _scan_in_progress.valid() && !_scan_in_progress.ready() ) return; self->scan_chain( self->get_last_scanned_block_number(), summary.block_data.block_num ); } @@ -1934,11 +1935,12 @@ namespace bts { namespace wallet { /* Scan blocks we have missed while locked */ const uint32_t first = get_last_scanned_block_number(); - scan_chain( first, - my->_blockchain->get_head_block_num(), - [first](uint32_t current, uint32_t end){ - std::cout << " Scanning for new transactions in block: " << current-first << '/' << end-first << "\r" << std::flush; - }); + if( first < my->_blockchain->get_head_block_num() ) + scan_chain( first, + my->_blockchain->get_head_block_num(), + [first](uint32_t current, uint32_t end){ + std::cout << " Scanning for new transactions in block: " << current-first << '/' << end-first << "\r" << std::flush; + }); std::cout << "Finished scanning for new transactions. " << std::endl; } catch( ... ) From 56f89c30d8c3638b57c02caf0a6612762de11c2c Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Thu, 4 Sep 2014 11:23:38 -0400 Subject: [PATCH 7/8] Better exceptions in get_account_vote_summary --- libraries/fc | 2 +- .../wallet/include/bts/wallet/exceptions.hpp | 1 + libraries/wallet/wallet.cpp | 4 +-- programs/qt_wallet | 2 +- programs/web_wallet | 2 +- tests/regression_tests/titan/client0.log | 29 ++----------------- 6 files changed, 9 insertions(+), 31 deletions(-) diff --git a/libraries/fc b/libraries/fc index 3222dc7c0..a0b3a9a92 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 3222dc7c0be62b9ad0fdfd303c5c4f53b39063e6 +Subproject commit a0b3a9a92d28ec0b3a08b45b8c1449737f56dd34 diff --git a/libraries/wallet/include/bts/wallet/exceptions.hpp b/libraries/wallet/include/bts/wallet/exceptions.hpp index 49f4cc0fe..dbd7ef46f 100644 --- a/libraries/wallet/include/bts/wallet/exceptions.hpp +++ b/libraries/wallet/include/bts/wallet/exceptions.hpp @@ -41,6 +41,7 @@ namespace bts { namespace wallet { FC_DECLARE_DERIVED_EXCEPTION( stupid_order, bts::wallet::wallet_exception, 20034, "stupid order" ); FC_DECLARE_DERIVED_EXCEPTION( invalid_expiration_time, bts::wallet::wallet_exception, 20035, "invalid expiration time" ); FC_DECLARE_DERIVED_EXCEPTION( bad_collateral_amount, bts::wallet::wallet_exception, 20036, "bad collateral amount" ); + FC_DECLARE_DERIVED_EXCEPTION( unknown_slate, bts::wallet::wallet_exception, 20037, "unknown slate" ); // registered in wallet.cpp } } // bts::wallet diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 605a3e42b..a820b7c45 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -5927,7 +5927,7 @@ namespace bts { namespace wallet { if( !okey_rec.valid() || !okey_rec->has_private_key() ) continue; const auto oaccount_rec = my->_wallet_db.lookup_account( okey_rec->account_address ); - FC_ASSERT( oaccount_rec.valid() ); + if( !oaccount_rec.valid() ) FC_THROW_EXCEPTION( unknown_account, "Unknown account name!" ); if( !account_name.empty() && oaccount_rec->name != account_name ) continue; const auto obalance = pending_state->get_balance_record( item.first ); @@ -5940,7 +5940,7 @@ namespace bts { namespace wallet { if( slate_id == 0 ) continue; const auto slate = pending_state->get_delegate_slate( slate_id ); - FC_ASSERT( slate.valid() ); + if( !slate.valid() ) FC_THROW_EXCEPTION( unknown_slate, "Unknown slate!" ); for( const auto& delegate_id : slate->supported_delegates ) { diff --git a/programs/qt_wallet b/programs/qt_wallet index 75077f65c..f0fc0e3ad 160000 --- a/programs/qt_wallet +++ b/programs/qt_wallet @@ -1 +1 @@ -Subproject commit 75077f65ccbfc8cc4c041eb501fb2135a74d627c +Subproject commit f0fc0e3ad04211e7ea7148f5fe7091732986829b diff --git a/programs/web_wallet b/programs/web_wallet index b5456af17..648283d69 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit b5456af1793debe36313ce778e47b21f542a3a93 +Subproject commit 648283d691288cd37c490a4726106e2fdb1cdb7f diff --git a/tests/regression_tests/titan/client0.log b/tests/regression_tests/titan/client0.log index 7fd98ee98..43b77cdfd 100644 --- a/tests/regression_tests/titan/client0.log +++ b/tests/regression_tests/titan/client0.log @@ -10,32 +10,9 @@ default (unlocked) >>> wallet_account_create test-account Account created successfully. You may give the following link to others to allow them to add you as a contact and send you funds: xts:test-account:XTS5drpKagoTFiMsg1urDXvrtY7Fkuyb4vkgBUCxrsnrer8ioRGrp default (unlocked) >>> wallet_account_register test-account delegate0 -{ - "expiration": "20140620T154750", - "delegate_slate_id": null, - "operations": [{ - "type": "register_account_op_type", - "data": { - "name": "test-account", - "public_data": null, - "owner_key": "XTS5drpKagoTFiMsg1urDXvrtY7Fkuyb4vkgBUCxrsnrer8ioRGrp", - "active_key": "XTS5drpKagoTFiMsg1urDXvrtY7Fkuyb4vkgBUCxrsnrer8ioRGrp", - "delegate_pay_rate": 255, - "meta_data": null - } - },{ - "type": "withdraw_op_type", - "data": { - "balance_id": "XTS6GvhLUV93rQZLJSstvyhMeoU9cnZ578kz", - "amount": 50000, - "claim_input_data": "" - } - } - ], - "signatures": [ - "208513ec7641898a4a37e0bfe8617a37bef25351eada00e9d0c04e79869bd335f6cf6e97e7bbabe3e17bf2f1cf2125879262636273ba022145368abaaa1c18c64c" - ] -} +RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID +====================================================================================================================================================================== +[redacted] PENDING delegate0 test-account 0.00000 XTS register test-account 0.50000 XTS [redacted] default (unlocked) >>> wallet_transfer 150 XTS delegate0 account-for-client1 "send this back" RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID ====================================================================================================================================================================== From 40ba2b85fc8db217e4e2a9c353a3ded91f31f900 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Thu, 4 Sep 2014 11:55:39 -0400 Subject: [PATCH 8/8] Market fork updates --- .../include/bts/blockchain/checkpoints.hpp | 3 +- .../include/bts/blockchain/config.hpp | 2 +- .../include/bts/blockchain/fork_blocks.hpp | 2 +- libraries/blockchain/market_engine.cpp | 46 ++++++++++--------- .../blockchain/original_market_engine.cpp | 2 +- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/libraries/blockchain/include/bts/blockchain/checkpoints.hpp b/libraries/blockchain/include/bts/blockchain/checkpoints.hpp index ddccd7f99..d4eb166cb 100644 --- a/libraries/blockchain/include/bts/blockchain/checkpoints.hpp +++ b/libraries/blockchain/include/bts/blockchain/checkpoints.hpp @@ -13,5 +13,6 @@ const static std::map CHECKPOINT_BLOCK {332000, bts::blockchain::block_id_type("2ab4e4de53568149de0a0a37f46fce05d861d43f")}, {341000, bts::blockchain::block_id_type("b77a53d3d3c8dfd1c03d04fb989606bc1a738166")}, {358310, bts::blockchain::block_id_type("4fb5498c0f1bce18740dca639389e307a194de2a")}, - {384100, bts::blockchain::block_id_type("9f2ffbebd7722b566547507028954fb81cc37271")} + {384100, bts::blockchain::block_id_type("9f2ffbebd7722b566547507028954fb81cc37271")}, + {398900, bts::blockchain::block_id_type("0260a868051d0e43316c165bc912cfb8444262ef")} }; diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index 203aca239..345f03d38 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -3,7 +3,7 @@ #include /* Define client version here */ -#define BTS_CLIENT_VERSION "0.4.11" +#define BTS_CLIENT_VERSION "0.4.12" /* Comment out this line for a non-test network */ //#define BTS_TEST_NETWORK diff --git a/libraries/blockchain/include/bts/blockchain/fork_blocks.hpp b/libraries/blockchain/include/bts/blockchain/fork_blocks.hpp index 385368556..52d5400f3 100644 --- a/libraries/blockchain/include/bts/blockchain/fork_blocks.hpp +++ b/libraries/blockchain/include/bts/blockchain/fork_blocks.hpp @@ -9,4 +9,4 @@ #define BTSX_MARKET_FORK_2_BLOCK_NUM 316001 #define BTSX_MARKET_FORK_3_BLOCK_NUM 340000 #define BTSX_MARKET_FORK_4_BLOCK_NUM 357000 -#define BTSX_MARKET_FORK_5_BLOCK_NUM 407500 +#define BTSX_MARKET_FORK_5_BLOCK_NUM 408750 diff --git a/libraries/blockchain/market_engine.cpp b/libraries/blockchain/market_engine.cpp index b966398a9..95798cf3f 100644 --- a/libraries/blockchain/market_engine.cpp +++ b/libraries/blockchain/market_engine.cpp @@ -203,6 +203,17 @@ class market_engine _current_bid.reset(); continue; } + /** + * Don't allow shorts to be executed if they are too far over priced or they will be + * immediately under collateralized. + */ + if( mtrx.bid_price < market_stat->minimum_ask() ) + { + //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); + // TODO: cancel the short order... + _current_ask.reset(); + continue; + } } else { @@ -214,18 +225,6 @@ class market_engine continue; } } - /** - * Don't allow shorts to be executed if they are too far over priced or they will be - * immediately under collateralized. - */ - if( mtrx.bid_price < market_stat->minimum_ask() ) - { - //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); - // TODO: cancel the short order... - _current_ask.reset(); - continue; - } - mtrx.ask_price = mtrx.bid_price; // we want to sell enough XTS to cover our balance. @@ -280,17 +279,20 @@ class market_engine if( mtrx.ask_price < mtrx.bid_price ) break; // the call price has not been reached - /** - * Don't allow margin calls to be executed too far below - * the minimum ask, this could lead to an attack where someone - * walks the whole book to steal the collateral. - */ - if( mtrx.bid_price < market_stat->minimum_ask() ) + if( pending_block_num >= BTSX_MARKET_FORK_5_BLOCK_NUM ) { - //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); - // TODO: cancel the short order... - _current_ask.reset(); - continue; + /** + * Don't allow margin calls to be executed too far below + * the minimum ask, this could lead to an attack where someone + * walks the whole book to steal the collateral. + */ + if( mtrx.bid_price < market_stat->minimum_ask() ) + { + //wlog( "skipping short ${x} < max_short_bid ${b}", ("x",mtrx.bid_price)("b", max_short_bid) ); + // TODO: cancel the short order... + _current_ask.reset(); + continue; + } } mtrx.ask_price = mtrx.bid_price; diff --git a/libraries/blockchain/original_market_engine.cpp b/libraries/blockchain/original_market_engine.cpp index 22406b432..20c8a9c8a 100644 --- a/libraries/blockchain/original_market_engine.cpp +++ b/libraries/blockchain/original_market_engine.cpp @@ -244,7 +244,7 @@ if( trading_volume.amount > 0 && get_next_bid() && get_next_ask() ) { market_history_key key(quote_id, base_id, market_history_key::each_block, _db_impl._head_block_header.timestamp); - market_history_record new_record(_current_bid->get_price(), _current_ask->get_price(), trading_volume.amount); + market_history_record new_record(_current_bid->get_price(), _current_ask->get_price(), price(), price(), trading_volume.amount); //LevelDB iterators are dumb and don't support proper past-the-end semantics. auto last_key_itr = _db_impl._market_history_db.lower_bound(key); if( !last_key_itr.valid() )