From d1009a114f14ae25bbabb162c98eafec369fcd68 Mon Sep 17 00:00:00 2001 From: drltc Date: Mon, 8 Sep 2014 23:58:38 -0400 Subject: [PATCH 01/25] Add blockchain_description and test_network_version to "about" RPC --- libraries/client/client.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index 7ed1195b3..f70cdd8aa 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -1717,6 +1717,10 @@ config load_config( const fc::path& datadir ) info["fc_revision"] = fc::git_revision_sha; info["fc_revision_age"] = fc::get_approximate_relative_time_string(fc::time_point_sec(fc::git_revision_unix_timestamp)); info["compile_date"] = "compiled on " __DATE__ " at " __TIME__; + info["blockchain_description"] = BTS_BLOCKCHAIN_DESCRIPTION; +#ifdef BTS_TEST_NETWORK + info["test_network_version"] = std::to_string( BTS_TEST_NETWORK_VERSION ); +#endif return info; } From 0354a831d5655c28c689f415a083ac6af3d46fd2 Mon Sep 17 00:00:00 2001 From: Nikolai Mushegian Date: Tue, 9 Sep 2014 10:19:01 -0400 Subject: [PATCH 02/25] add submodule --- programs/web_wallet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/web_wallet b/programs/web_wallet index 603d95665..830595a5c 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit 603d95665a853a05dfe6e04834250bf3ab75cad5 +Subproject commit 830595a5c2a16e1b858f014a34387a8100e8182d From b5b28650a3f1d9f3aa5c2bb7aee9743eaa866fe8 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Tue, 9 Sep 2014 10:26:46 -0400 Subject: [PATCH 03/25] Accept public keys on CLI without quotes --- libraries/cli/cli.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/cli/cli.cpp b/libraries/cli/cli.cpp index 3ed266ca5..2b25a1bf3 100644 --- a/libraries/cli/cli.cpp +++ b/libraries/cli/cli.cpp @@ -447,6 +447,7 @@ namespace bts { namespace cli { this_parameter.type == "method_name" || this_parameter.type == "new_passphrase" || this_parameter.type == "filename" || + this_parameter.type == "public_key" || this_parameter.type == "passphrase") { string result; From c2652225636281a8bf950657f6365588ab47f72e Mon Sep 17 00:00:00 2001 From: Nikolai Mushegian Date: Tue, 9 Sep 2014 14:55:08 -0400 Subject: [PATCH 04/25] update web_wallet version --- programs/web_wallet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/web_wallet b/programs/web_wallet index 452b4a659..a4ccce1e1 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit 452b4a65964b37f21c5cd12a40e95f260b665ab0 +Subproject commit a4ccce1e196c9ab772b429c4dac5cde95856ce4f From 43f0fbacb1a744bed314cf0eb90567e96d00bd24 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Tue, 9 Sep 2014 16:26:54 -0400 Subject: [PATCH 05/25] Update fc submodule --- libraries/fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fc b/libraries/fc index aa6882b3b..55e7a073c 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit aa6882b3b786efb95b3bc2ca7520082a7a54040d +Subproject commit 55e7a073cf7ab19b88f90ffceba24c70e0c7b1c4 From 07b393221ab83a9b959e59ebd323f646cbde6668 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 9 Sep 2014 17:46:09 -0400 Subject: [PATCH 06/25] Add the ability to embed genesis.json in bitshares_client in pre-compiled form, avoiding the slow step of parsing the json on startup --- libraries/blockchain/CMakeLists.txt | 56 +++++---- libraries/blockchain/binary_genesis.epilogue | 13 +++ libraries/blockchain/binary_genesis.prologue | 12 ++ libraries/blockchain/chain_database.cpp | 19 +++- .../include/bts/blockchain/genesis_json.hpp | 6 + programs/utils/CMakeLists.txt | 8 +- programs/utils/bts_genesis_to_bin.cpp | 106 ++++++++++++++++-- 7 files changed, 183 insertions(+), 37 deletions(-) create mode 100644 libraries/blockchain/binary_genesis.epilogue create mode 100644 libraries/blockchain/binary_genesis.prologue diff --git a/libraries/blockchain/CMakeLists.txt b/libraries/blockchain/CMakeLists.txt index cae6ef3a3..bc8900e5f 100644 --- a/libraries/blockchain/CMakeLists.txt +++ b/libraries/blockchain/CMakeLists.txt @@ -1,29 +1,40 @@ ################################################################################################## # Magic to get the genesis.json converted to a .cpp file and compiled into the bts_client library set(genesis_json "${CMAKE_CURRENT_SOURCE_DIR}/genesis.json") -set(genesis_prologue "${CMAKE_CURRENT_SOURCE_DIR}/genesis.prologue") -set(genesis_epilogue "${CMAKE_CURRENT_SOURCE_DIR}/genesis.epilogue") -source_group("Genesis JSON Files" FILES ${genesis_json} ${genesis_prologue} ${genesis_epilogue}) -set(generated_genesis_file "${CMAKE_CURRENT_BINARY_DIR}/genesis_json.cpp") -set(rpc_stubs_output_dir "${CMAKE_BINARY_DIR}/libraries/rpc_stubs") -set(generated_rpc_stubs_files "${rpc_stubs_output_dir}/common_api_rpc_server.cpp" - "${rpc_stubs_output_dir}/common_api_rpc_client.cpp" - "${rpc_stubs_output_dir}/common_api_client.cpp" - "${rpc_stubs_output_dir}/include/bts/rpc_stubs/common_api_rpc_server.hpp" - "${rpc_stubs_output_dir}/include/bts/rpc_stubs/common_api_rpc_client.hpp" - "${rpc_stubs_output_dir}/include/bts/rpc_stubs/common_api_client.hpp" - "${rpc_stubs_output_dir}/include/bts/rpc_stubs/common_api_overrides.ipp") +set(EMBED_GENESIS_STATE_AS_TEXT TRUE CACHE BOOL "If true, genesis.json is included in text form, causing slower startup times") + +if (EMBED_GENESIS_STATE_AS_TEXT) + set(genesis_prologue "${CMAKE_CURRENT_SOURCE_DIR}/genesis.prologue") + set(genesis_epilogue "${CMAKE_CURRENT_SOURCE_DIR}/genesis.epilogue") + + set(generated_genesis_file "${CMAKE_CURRENT_BINARY_DIR}/genesis_json.cpp") + + add_custom_command(OUTPUT ${generated_genesis_file} + COMMAND bts_json_to_cpp "--json=${genesis_json}" + "--prologue=${genesis_prologue}" + "--epilogue=${genesis_epilogue}" + "--out=${generated_genesis_file}.new" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${generated_genesis_file}.new" "${generated_genesis_file}" + COMMAND ${CMAKE_COMMAND} -E remove "${generated_genesis_file}.new" + DEPENDS bts_json_to_cpp ${genesis_json} ${genesis_prologue} ${genesis_epilogue} ) +else(EMBED_GENESIS_STATE_AS_TEXT) + set(genesis_prologue "${CMAKE_CURRENT_SOURCE_DIR}/binary_genesis.prologue") + set(genesis_epilogue "${CMAKE_CURRENT_SOURCE_DIR}/binary_genesis.epilogue") -add_custom_command(OUTPUT ${generated_genesis_file} - COMMAND bts_json_to_cpp "--json=${genesis_json}" - "--prologue=${genesis_prologue}" - "--epilogue=${genesis_epilogue}" - "--out=${generated_genesis_file}.new" - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${generated_genesis_file}.new" "${generated_genesis_file}" - COMMAND ${CMAKE_COMMAND} -E remove "${generated_genesis_file}.new" - DEPENDS bts_json_to_cpp ${genesis_json} ${genesis_prologue} ${genesis_epilogue} ) + set(generated_genesis_file "${CMAKE_CURRENT_BINARY_DIR}/genesis_json.cpp") + add_custom_command(OUTPUT ${generated_genesis_file} + COMMAND bts_genesis_to_bin "--json=${genesis_json}" + "--prologue=${genesis_prologue}" + "--epilogue=${genesis_epilogue}" + "--source-out=${generated_genesis_file}.new" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${generated_genesis_file}.new" "${generated_genesis_file}" + COMMAND ${CMAKE_COMMAND} -E remove "${generated_genesis_file}.new" + DEPENDS bts_genesis_to_bin ${genesis_json} ${genesis_prologue} ${genesis_epilogue} ) +endif(EMBED_GENESIS_STATE_AS_TEXT) + +source_group("Genesis JSON Files" FILES ${genesis_json} ${genesis_prologue} ${genesis_epilogue}) ################################################################################################## # Regular stuff for the bts_client library @@ -71,6 +82,11 @@ endif() target_link_libraries( bts_blockchain fc bts_db leveldb ) target_include_directories( bts_blockchain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +if (EMBED_GENESIS_STATE_AS_TEXT) + target_compile_definitions( bts_blockchain PRIVATE EMBED_GENESIS_STATE_AS_TEXT ) +endif (EMBED_GENESIS_STATE_AS_TEXT) + if (USE_PCH) set_target_properties(bts_blockchain PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) cotire(bts_blockchain) diff --git a/libraries/blockchain/binary_genesis.epilogue b/libraries/blockchain/binary_genesis.epilogue new file mode 100644 index 000000000..1f9068a11 --- /dev/null +++ b/libraries/blockchain/binary_genesis.epilogue @@ -0,0 +1,13 @@ +}; + +genesis_block_config get_builtin_genesis_block_config() +{ + return fc::raw::unpack((const char*)raw_genesis_config, sizeof(raw_genesis_config)); +} + +fc::sha256 get_builtin_genesis_block_state_hash() +{ + return fc::sha256::hash((const char*)raw_genesis_config, sizeof(raw_genesis_config)); +} + +} } // end namespace bts::blockchain diff --git a/libraries/blockchain/binary_genesis.prologue b/libraries/blockchain/binary_genesis.prologue new file mode 100644 index 000000000..5e4865ab9 --- /dev/null +++ b/libraries/blockchain/binary_genesis.prologue @@ -0,0 +1,12 @@ +// This file is generated by bts_json_to_cpp from ${json_file_name} +#include +#include + +#include +#include +#include + +namespace bts { namespace blockchain { + +static const unsigned char raw_genesis_config[] = +{ diff --git a/libraries/blockchain/chain_database.cpp b/libraries/blockchain/chain_database.cpp index 7e5cc4111..0402cb154 100644 --- a/libraries/blockchain/chain_database.cpp +++ b/libraries/blockchain/chain_database.cpp @@ -1754,7 +1754,7 @@ namespace bts { namespace blockchain { digest_type detail::chain_database_impl::initialize_genesis( const optional& genesis_file, bool chain_id_only ) { try { - auto chain_id = self->chain_id(); + digest_type chain_id = self->chain_id(); if( chain_id != digest_type() && !chain_id_only ) { self->sanity_check(); @@ -1782,19 +1782,28 @@ namespace bts { namespace blockchain { { FC_ASSERT( !"Invalid genesis format", " '${format}'", ("format",genesis_file->extension() ) ); } + fc::sha256::encoder enc; + fc::raw::pack( enc, config ); + chain_id = enc.result(); } else { // this is the usual case std::cout << "Initializing genesis state from built-in genesis file\n"; +#ifdef EMBED_GENESIS_STATE_AS_TEXT std::string genesis_file_contents = get_builtin_genesis_json_as_string(); config = fc::json::from_string(genesis_file_contents).as(); + fc::sha256::encoder enc; + fc::raw::pack( enc, config ); + chain_id = enc.result(); +#else + config = get_builtin_genesis_block_config(); + chain_id = get_builtin_genesis_block_state_hash(); +#endif } - fc::sha256::encoder enc; - fc::raw::pack( enc, config ); - chain_id = enc.result(); - if( chain_id_only ) return chain_id; + if( chain_id_only ) + return chain_id; _chain_id = chain_id; self->set_property( bts::blockchain::chain_id, fc::variant(_chain_id) ); diff --git a/libraries/blockchain/include/bts/blockchain/genesis_json.hpp b/libraries/blockchain/include/bts/blockchain/genesis_json.hpp index f787f588f..3fbd44939 100644 --- a/libraries/blockchain/include/bts/blockchain/genesis_json.hpp +++ b/libraries/blockchain/include/bts/blockchain/genesis_json.hpp @@ -1,8 +1,14 @@ #pragma once +#include #include namespace bts { namespace blockchain { +#ifdef EMBED_GENESIS_STATE_AS_TEXT std::string get_builtin_genesis_json_as_string(); +#else + genesis_block_config get_builtin_genesis_block_config(); + fc::sha256 get_builtin_genesis_block_state_hash(); +#endif } } // bts::blockchain \ No newline at end of file diff --git a/programs/utils/CMakeLists.txt b/programs/utils/CMakeLists.txt index f1e222cdd..d5992e580 100644 --- a/programs/utils/CMakeLists.txt +++ b/programs/utils/CMakeLists.txt @@ -16,8 +16,12 @@ target_link_libraries( bts_create_genesis fc bts_blockchain bts_utilities) add_executable( key_to_wif key_to_wif.cpp ) target_link_libraries( key_to_wif fc bts_blockchain bts_utilities) -add_executable( bts_genesis_to_bin bts_genesis_to_bin.cpp ) -target_link_libraries( bts_genesis_to_bin fc bts_blockchain) +# I've added two small files here that are also compiled in bts_blockchain +# to avoid a circular dependency. The circular dependency could be broken more cleanly +# by splitting bts_blockchain, but it doesn't seem worth it just for this +add_executable( bts_genesis_to_bin bts_genesis_to_bin.cpp ${CMAKE_SOURCE_DIR}/libraries/blockchain/types.cpp ${CMAKE_SOURCE_DIR}/libraries/blockchain/pts_address.cpp ) +target_link_libraries( bts_genesis_to_bin fc ) +target_include_directories( bts_genesis_to_bin PRIVATE "${CMAKE_SOURCE_DIR}/libraries/blockchain/include" ) add_executable( bts_json_to_cpp bts_json_to_cpp.cpp ) target_link_libraries( bts_json_to_cpp fc bts_utilities) diff --git a/programs/utils/bts_genesis_to_bin.cpp b/programs/utils/bts_genesis_to_bin.cpp index 306818a9b..4b4ae1d03 100644 --- a/programs/utils/bts_genesis_to_bin.cpp +++ b/programs/utils/bts_genesis_to_bin.cpp @@ -11,20 +11,106 @@ #include #include +#include #include +#include + using namespace bts::blockchain; int main( int argc, char** argv ) { - if( argc != 3 ) - { - std::cout << "usage: "<(); - std::ofstream genesis_bin(argv[2]); - fc::raw::pack( genesis_bin, config ); - - return 0; + boost::program_options::options_description option_config("Allowed options"); + option_config.add_options()("help", "display this help message") + ("prologue" , boost::program_options::value(), "Add the contents of this file to start of generated C++ source") + ("epilogue" , boost::program_options::value(), "Add the contents of this file to end of generated C++ source") + ("json" , boost::program_options::value(), "The json file to convert to C++ source code") + ("binary-out" , boost::program_options::value(), "The raw binary file to generate") + ("source-out" , boost::program_options::value(), "The C++ source file to generate"); + boost::program_options::variables_map option_variables; + try + { + boost::program_options::store(boost::program_options::command_line_parser(argc, argv). + options(option_config).run(), option_variables); + boost::program_options::notify(option_variables); + } + catch (boost::program_options::error&) + { + std::cerr << "Error parsing command-line options\n\n"; + std::cerr << option_config << "\n"; + return 1; + } + + if (option_variables.count("help")) + { + std::cout << option_config << "\n"; + return 0; + } + + if (!option_variables.count("json")) + { + std::cout << "error: missing --json argument\n"; + return 2; + } + + genesis_block_config genesis_config = fc::json::from_file(option_variables["json"].as()).as(); + + if (option_variables.count("binary-out")) + { + std::ofstream genesis_bin(option_variables["binary-out"].as()); + fc::raw::pack(genesis_bin, genesis_config); + } + + if (option_variables.count("source-out")) + { + std::ofstream source_out(option_variables["source-out"].as()); + + if (option_variables.count("prologue")) + { + std::ifstream prologue(option_variables["prologue"].as()); + std::copy(std::istreambuf_iterator(prologue.rdbuf()), + std::istreambuf_iterator(), + std::ostream_iterator(source_out)); + } + + std::stringstream genesis_bin; + fc::raw::pack(genesis_bin, genesis_config); + int first = true; + int column = 0; + std::istreambuf_iterator end_iter; + for (std::istreambuf_iterator iter(genesis_bin.rdbuf()); + iter != end_iter; ++iter) + { + if (first) + { + first = false; + source_out << " "; + column += 2; + } + else + { + source_out << ", "; + column += 2; + + if (column > 75) + { + source_out << "\n "; + column = 2; + } + } + source_out << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)(unsigned char)*iter; + column += 4; + } + source_out << "\n"; + + if (option_variables.count("epilogue")) + { + std::ifstream epilogue(option_variables["epilogue"].as()); + std::copy(std::istreambuf_iterator(epilogue.rdbuf()), + std::istreambuf_iterator(), + std::ostream_iterator(source_out)); + } + } + + return 0; } From b5b2b3cb7756c11aa914583b4cfcfe1c7f69eee6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 9 Sep 2014 22:26:47 +0000 Subject: [PATCH 07/25] bump genesis block --- libraries/blockchain/genesis.json | 2 +- libraries/blockchain/include/bts/blockchain/config.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/blockchain/genesis.json b/libraries/blockchain/genesis.json index 9d5779ea2..d86cd64a2 100644 --- a/libraries/blockchain/genesis.json +++ b/libraries/blockchain/genesis.json @@ -1,5 +1,5 @@ { - "timestamp" : "20140901T000000", + "timestamp" : "20140908T000000", "market_assets": [ { "symbol": "PTS", diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index eaa9cb1ab..cbf59b6ca 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -3,11 +3,11 @@ #include /* Define client version here */ -#define BTS_CLIENT_VERSION "Dry Run NN" +#define BTS_CLIENT_VERSION "testnet" /* Comment out this line for a non-test network */ #define BTS_TEST_NETWORK -#define BTS_TEST_NETWORK_VERSION 23 +#define BTS_TEST_NETWORK_VERSION 24 /** @file bts/blockchain/config.hpp * @brief Defines global constants that determine blockchain behavior From c65a39008e8e02e8fe49dd2891291bb852cc798b Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Tue, 9 Sep 2014 18:02:16 -0400 Subject: [PATCH 08/25] Remove unused asset record references from wallet_db --- .../wallet/include/bts/wallet/wallet_db.hpp | 17 +++---- .../include/bts/wallet/wallet_records.hpp | 51 +++++++++---------- libraries/wallet/wallet_db.cpp | 9 ---- 3 files changed, 32 insertions(+), 45 deletions(-) diff --git a/libraries/wallet/include/bts/wallet/wallet_db.hpp b/libraries/wallet/include/bts/wallet/wallet_db.hpp index 2176a01d2..61eda6871 100644 --- a/libraries/wallet/include/bts/wallet/wallet_db.hpp +++ b/libraries/wallet/include/bts/wallet/wallet_db.hpp @@ -18,10 +18,10 @@ namespace bts { namespace wallet { public: wallet_db(); ~wallet_db(); - + void open( const fc::path& wallet_file ); void close(); - + bool is_open()const; int32_t new_wallet_record_index(); @@ -39,7 +39,7 @@ namespace bts { namespace wallet { void store_transaction( wallet_transaction_record& t ); void cache_balance( const bts::blockchain::balance_record& b ); void cache_account( const wallet_account_record& ); - void cache_memo( const memo_status& memo, + void cache_memo( const memo_status& memo, const private_key_type& account_key, const fc::sha512& password ); @@ -67,7 +67,7 @@ namespace bts { namespace wallet { bool has_private_key( const address& a )const; - void add_account( const string& new_account_name, + void add_account( const string& new_account_name, const public_key_type& new_account_key, const variant& private_data = variant() ); void add_account( const account_record& blockchain_account, @@ -83,7 +83,7 @@ namespace bts { namespace wallet { bool validate_password( const fc::sha512& password )const; optional get_master_key( const fc::sha512& password )const; - void set_master_key( const extended_private_key& key, + void set_master_key( const extended_private_key& key, const fc::sha512& new_password ); void change_password( const fc::sha512& old_password, @@ -101,7 +101,7 @@ namespace bts { namespace wallet { { return accounts; } - const unordered_map< address, wallet_key_record >& get_keys()const + const unordered_map< address, wallet_key_record >& get_keys()const { return keys; } @@ -112,7 +112,6 @@ namespace bts { namespace wallet { unordered_map< int32_t,wallet_account_record > accounts; unordered_map< address, wallet_key_record > keys; unordered_map< transaction_id_type, wallet_transaction_record > transactions; - map assets; unordered_map< balance_id_type,wallet_balance_record > balances; map properties; map< string, wallet_setting_record > settings; @@ -124,12 +123,12 @@ namespace bts { namespace wallet { void remove_item( int32_t index ); /** - * This is private + * This is private */ template void store_record( T record_to_store, bool sync = false ) { - if( record_to_store.wallet_record_index == 0 ) + if( record_to_store.wallet_record_index == 0 ) record_to_store.wallet_record_index = new_wallet_record_index(); store_generic_record( generic_wallet_record( record_to_store ), sync ); } diff --git a/libraries/wallet/include/bts/wallet/wallet_records.hpp b/libraries/wallet/include/bts/wallet/wallet_records.hpp index 1d39b957f..d70b9d25a 100644 --- a/libraries/wallet/include/bts/wallet/wallet_records.hpp +++ b/libraries/wallet/include/bts/wallet/wallet_records.hpp @@ -19,7 +19,6 @@ namespace bts { namespace wallet { account_record_type = 1, key_record_type = 2, transaction_record_type = 3, - asset_record_type = 5, balance_record_type = 6, property_record_type = 7, market_order_record_type = 8, /* No longer used for now */ @@ -38,7 +37,7 @@ namespace bts { namespace wallet { template RecordType as()const; - int32_t get_wallet_record_index()const + int32_t get_wallet_record_index()const { try { FC_ASSERT( data.is_object() ); FC_ASSERT( data.get_object().contains( "index" ) ); @@ -50,7 +49,7 @@ namespace bts { namespace wallet { }; template - struct base_record + struct base_record { enum { type = RecordType }; @@ -74,7 +73,7 @@ namespace bts { namespace wallet { */ struct wallet_property { - wallet_property( property_enum k = next_record_number, + wallet_property( property_enum k = next_record_number, fc::variant v = fc::variant() ) :key(k),value(v){} @@ -115,7 +114,7 @@ namespace bts { namespace wallet { bool validate_password( const fc::sha512& password )const; extended_private_key decrypt_key( const fc::sha512& password )const; - void encrypt_key( const fc::sha512& password, + void encrypt_key( const fc::sha512& password, const extended_private_key& k ); }; @@ -133,7 +132,7 @@ 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, + void encrypt_private_key( const fc::sha512& password, const private_key_type& ); private_key_type decrypt_private_key( const fc::sha512& password )const; }; @@ -195,7 +194,6 @@ namespace bts { namespace wallet { }; /** cached blockchain data */ - typedef wallet_record< bts::blockchain::asset_record, asset_record_type > wallet_asset_record; typedef wallet_record< bts::blockchain::balance_record, balance_record_type > wallet_balance_record; /** records unique to the wallet */ @@ -229,13 +227,12 @@ FC_REFLECT_ENUM( bts::wallet::property_enum, (transaction_expiration_sec) ) -FC_REFLECT_ENUM( bts::wallet::wallet_record_type_enum, +FC_REFLECT_ENUM( bts::wallet::wallet_record_type_enum, (master_key_record_type) - (key_record_type) (account_record_type) + (key_record_type) (transaction_record_type) (balance_record_type) - (asset_record_type) (property_record_type) (market_order_record_type) (setting_record_type) @@ -247,7 +244,7 @@ FC_REFLECT( bts::wallet::master_key, (encrypted_key)(checksum) ) FC_REFLECT( bts::wallet::key_data, (account_address)(public_key)(encrypted_private_key)(memo)(gen_seq_number) ) FC_REFLECT( bts::wallet::ledger_entry, (from_account)(to_account)(amount)(memo)(memo_from_account) ); -FC_REFLECT( bts::wallet::transaction_data, +FC_REFLECT( bts::wallet::transaction_data, (record_id) (block_num) (is_virtual) @@ -279,35 +276,35 @@ FC_REFLECT( bts::wallet::setting, (name)(value) ) */ namespace fc { - template - struct get_typename< bts::wallet::wallet_record > - { - static const char* name() - { - static std::string _name = get_typename::name() + std::string("_record"); + template + struct get_typename< bts::wallet::wallet_record > + { + static const char* name() + { + static std::string _name = get_typename::name() + std::string("_record"); return _name.c_str(); } }; - template - struct reflector> + template + struct reflector> { typedef bts::wallet::wallet_record type; typedef fc::true_type is_defined; - typedef fc::false_type is_enum; + typedef fc::false_type is_enum; enum member_count_enum { local_member_count = 1, total_member_count = local_member_count + reflector::total_member_count }; - template + template static void visit( const Visitor& visitor ) { - { - typedef decltype(((bts::wallet::base_record*)nullptr)->wallet_record_index) member_type; - visitor.TEMPLATE operator(),&bts::wallet::base_record::wallet_record_index>( "index" ); + { + typedef decltype(((bts::wallet::base_record*)nullptr)->wallet_record_index) member_type; + visitor.TEMPLATE operator(),&bts::wallet::base_record::wallet_record_index>( "index" ); } - + fc::reflector::visit( visitor ); } }; @@ -317,10 +314,10 @@ namespace bts { namespace wallet { template RecordType generic_wallet_record::as()const { - FC_ASSERT( (wallet_record_type_enum)type == RecordType::type, "", + FC_ASSERT( (wallet_record_type_enum)type == RecordType::type, "", ("type",type) ("WithdrawType",(wallet_record_type_enum)RecordType::type) ); - + return data.as(); } } } diff --git a/libraries/wallet/wallet_db.cpp b/libraries/wallet/wallet_db.cpp index 3a47e5ab3..6ddf30f83 100644 --- a/libraries/wallet/wallet_db.cpp +++ b/libraries/wallet/wallet_db.cpp @@ -44,9 +44,6 @@ namespace bts { namespace wallet { case transaction_record_type: load_transaction_record( record.as(), overwrite ); break; - case asset_record_type: - load_asset_record( record.as(), overwrite ); - break; case balance_record_type: load_balance_record( record.as(), overwrite ); break; @@ -118,11 +115,6 @@ namespace bts { namespace wallet { self->transactions[ rec.record_id ] = rec; } FC_RETHROW_EXCEPTIONS( warn, "", ("rec",rec) ) } - void load_asset_record( const wallet_asset_record& asset_rec, bool overwrite ) - { try { - self->assets[ asset_rec.symbol ] = asset_rec; - } FC_RETHROW_EXCEPTIONS( warn, "", ("asset_record",asset_rec )) } - void load_balance_record( const wallet_balance_record& rec, bool overwrite ) { try { if( !overwrite ) @@ -202,7 +194,6 @@ namespace bts { namespace wallet { accounts.clear(); keys.clear(); transactions.clear(); - assets.clear(); balances.clear(); properties.clear(); settings.clear(); From 44298f6889eadb9ec250f3deb56894a22593b6cf Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Tue, 9 Sep 2014 18:09:07 -0400 Subject: [PATCH 09/25] Remove warnings for already-merged changes yolo --- libraries/blockchain/CMakeLists.txt | 8 ++++---- libraries/blockchain/balance_operations.cpp | 13 +++---------- libraries/blockchain/market_engine.cpp | 3 --- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/libraries/blockchain/CMakeLists.txt b/libraries/blockchain/CMakeLists.txt index bc8900e5f..0f8c8e08e 100644 --- a/libraries/blockchain/CMakeLists.txt +++ b/libraries/blockchain/CMakeLists.txt @@ -10,7 +10,7 @@ if (EMBED_GENESIS_STATE_AS_TEXT) set(generated_genesis_file "${CMAKE_CURRENT_BINARY_DIR}/genesis_json.cpp") - add_custom_command(OUTPUT ${generated_genesis_file} + add_custom_command(OUTPUT ${generated_genesis_file} COMMAND bts_json_to_cpp "--json=${genesis_json}" "--prologue=${genesis_prologue}" "--epilogue=${genesis_epilogue}" @@ -24,7 +24,7 @@ else(EMBED_GENESIS_STATE_AS_TEXT) set(generated_genesis_file "${CMAKE_CURRENT_BINARY_DIR}/genesis_json.cpp") - add_custom_command(OUTPUT ${generated_genesis_file} + add_custom_command(OUTPUT ${generated_genesis_file} COMMAND bts_genesis_to_bin "--json=${genesis_json}" "--prologue=${genesis_prologue}" "--epilogue=${genesis_epilogue}" @@ -35,7 +35,7 @@ else(EMBED_GENESIS_STATE_AS_TEXT) endif(EMBED_GENESIS_STATE_AS_TEXT) source_group("Genesis JSON Files" FILES ${genesis_json} ${genesis_prologue} ${genesis_epilogue}) - + ################################################################################################## # Regular stuff for the bts_client library @@ -80,7 +80,7 @@ else() endif() target_link_libraries( bts_blockchain fc bts_db leveldb ) -target_include_directories( bts_blockchain +target_include_directories( bts_blockchain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) if (EMBED_GENESIS_STATE_AS_TEXT) diff --git a/libraries/blockchain/balance_operations.cpp b/libraries/blockchain/balance_operations.cpp index 78c96efe3..1926736cd 100644 --- a/libraries/blockchain/balance_operations.cpp +++ b/libraries/blockchain/balance_operations.cpp @@ -26,7 +26,7 @@ namespace bts { namespace blockchain { /** * If less than 1 year, the 80% of yield are scaled linearly with time and 20% scaled by time^2, * this should produce a yield curve that is "80% simple interest" and 20% simulating compound - * interest. + * interest. */ if( elapsed_time < fc::seconds( BTS_BLOCKCHAIN_BLOCKS_PER_YEAR * BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC ) ) { @@ -118,9 +118,6 @@ namespace bts { namespace blockchain { } else { -#ifndef WIN32 -#warning [HARDFORK] Yield needs testing before merging into BTSX -#endif fc::uint128 old_sec_since_epoch( cur_record->deposit_date.sec_since_epoch()); fc::uint128 new_sec_since_epoch( eval_state._current_state->now().sec_since_epoch()); @@ -251,10 +248,9 @@ namespace bts { namespace blockchain { } FC_CAPTURE_AND_RETHROW( (option) ) break; } - case withdraw_null_type: + + default: FC_CAPTURE_AND_THROW( invalid_withdraw_condition, (current_balance_record->condition) ); - break; - // default: } // update delegate vote on withdrawn account.. @@ -264,9 +260,6 @@ namespace bts { namespace blockchain { if( current_balance_record->condition.asset_id == 0 && current_balance_record->condition.delegate_slate_id ) eval_state.adjust_vote( current_balance_record->condition.delegate_slate_id, -this->amount ); -#ifndef WIN32 -#warning [HARDFORK] Yield needs testing before merging into BTSX -#endif auto asset_rec = eval_state._current_state->get_asset_record( current_balance_record->condition.asset_id ); FC_ASSERT( asset_rec.valid() ); if( asset_rec->is_market_issued() ) diff --git a/libraries/blockchain/market_engine.cpp b/libraries/blockchain/market_engine.cpp index 6c12e6d97..9f46a0bc5 100644 --- a/libraries/blockchain/market_engine.cpp +++ b/libraries/blockchain/market_engine.cpp @@ -295,9 +295,6 @@ class market_engine if( mtrx.bid_price < mtrx.ask_price ) break; FC_ASSERT( quote_asset->is_market_issued() && base_id == 0 ); -#ifndef WIN32 -#warning [HARDFORK] fix price overlap condition, needs testing. -#endif /** * If the ask is less than the "max short bid" then that means the * ask (those with XTS wanting to buy USD) are willing to accept From 0704816eaa2a30097d9a30ca8f913db2a7e415df Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Tue, 9 Sep 2014 18:58:36 -0400 Subject: [PATCH 10/25] Remove extraneous file --- programs/client/genesis.json | 1 - 1 file changed, 1 deletion(-) delete mode 120000 programs/client/genesis.json diff --git a/programs/client/genesis.json b/programs/client/genesis.json deleted file mode 120000 index 521690bab..000000000 --- a/programs/client/genesis.json +++ /dev/null @@ -1 +0,0 @@ -../../tests/genesis.json \ No newline at end of file From eaef64cc14b8ebe269be52ca6798ff658f043a6a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 9 Sep 2014 22:59:59 +0000 Subject: [PATCH 11/25] reduce market depth requirement --- libraries/blockchain/include/bts/blockchain/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index cbf59b6ca..b92d2c0e9 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -103,7 +103,7 @@ * * Currently set to 1% of the share in the DAC, or 0.5% for each side of the market. */ -#define BTS_BLOCKCHAIN_MARKET_DEPTH_REQUIREMENT (BTS_BLOCKCHAIN_INITIAL_SHARES/4000) +#define BTS_BLOCKCHAIN_MARKET_DEPTH_REQUIREMENT (BTS_BLOCKCHAIN_INITIAL_SHARES/20000) /** * The number of blocks expected per hour based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC From 17d2f881f050734f76f8ca31dbfac2dfa256fac8 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 9 Sep 2014 23:00:40 +0000 Subject: [PATCH 12/25] bump testnet --- libraries/blockchain/genesis.json | 2 +- libraries/blockchain/include/bts/blockchain/config.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/blockchain/genesis.json b/libraries/blockchain/genesis.json index d86cd64a2..7a284e0a3 100644 --- a/libraries/blockchain/genesis.json +++ b/libraries/blockchain/genesis.json @@ -1,5 +1,5 @@ { - "timestamp" : "20140908T000000", + "timestamp" : "20140908T000001", "market_assets": [ { "symbol": "PTS", diff --git a/libraries/blockchain/include/bts/blockchain/config.hpp b/libraries/blockchain/include/bts/blockchain/config.hpp index b92d2c0e9..9a1ae531b 100644 --- a/libraries/blockchain/include/bts/blockchain/config.hpp +++ b/libraries/blockchain/include/bts/blockchain/config.hpp @@ -7,7 +7,7 @@ /* Comment out this line for a non-test network */ #define BTS_TEST_NETWORK -#define BTS_TEST_NETWORK_VERSION 24 +#define BTS_TEST_NETWORK_VERSION 25 /** @file bts/blockchain/config.hpp * @brief Defines global constants that determine blockchain behavior From 360e08fab6e4760dc14bb36e9181fe0a202c43d9 Mon Sep 17 00:00:00 2001 From: grzegorzs Date: Wed, 10 Sep 2014 14:42:36 +0200 Subject: [PATCH 13/25] [GS] Update regression tests --- .../blockchain_get_block_transactions.log | 2 +- .../blockchain_get_info/blockchain_get_info.log | 2 +- .../blockchain_list_pending_transactions.log | 2 +- .../blockchain_markets/blockchain_markets.log | 16 ++++++++-------- tests/regression_tests/issue_633/issue_633.log | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/regression_tests/blockchain_get_block_transactions/blockchain_get_block_transactions.log b/tests/regression_tests/blockchain_get_block_transactions/blockchain_get_block_transactions.log index 950f49212..62ae6f4f5 100644 --- a/tests/regression_tests/blockchain_get_block_transactions/blockchain_get_block_transactions.log +++ b/tests/regression_tests/blockchain_get_block_transactions/blockchain_get_block_transactions.log @@ -87,7 +87,7 @@ default (unlocked) >>> blockchain_get_block_transactions 2 } ] ], - "rewards": [], + "yield": [], "balance": [[ 0, 50000 diff --git a/tests/regression_tests/blockchain_get_info/blockchain_get_info.log b/tests/regression_tests/blockchain_get_info/blockchain_get_info.log index 8dc9679d0..a8709fdd6 100644 --- a/tests/regression_tests/blockchain_get_info/blockchain_get_info.log +++ b/tests/regression_tests/blockchain_get_info/blockchain_get_info.log @@ -33,7 +33,7 @@ aliases: getconfig, get_config, config, blockchain_get_config "symbol_size_min": 3, "asset_reg_fee": "0.00000 XTS", "asset_shares_max": 1000000000000000, - "min_market_depth": "500,000.00000 XTS", + "min_market_depth": "100,000.00000 XTS", "max_pending_queue_size": 10, "max_trx_per_second": 1, "min_block_fee": "0.00000 XTS" diff --git a/tests/regression_tests/blockchain_list_pending_transactions/blockchain_list_pending_transactions.log b/tests/regression_tests/blockchain_list_pending_transactions/blockchain_list_pending_transactions.log index 67ef9432d..001a156c0 100644 --- a/tests/regression_tests/blockchain_list_pending_transactions/blockchain_list_pending_transactions.log +++ b/tests/regression_tests/blockchain_list_pending_transactions/blockchain_list_pending_transactions.log @@ -16,7 +16,7 @@ RECEIVED BLOCK FROM TO AMOUNT default (unlocked) >>> wallet_account_balance delegate0 ACCOUNT BALANCE ============================================================ -delegate0 19,801,980.19801 XTS +delegate0 19,801,879.69801 XTS default (unlocked) >>> wallet_account_balance test No balances found. default (unlocked) >>> help blockchain_list_pending_transactions diff --git a/tests/regression_tests/blockchain_markets/blockchain_markets.log b/tests/regression_tests/blockchain_markets/blockchain_markets.log index 019c313ff..1fb606f83 100644 --- a/tests/regression_tests/blockchain_markets/blockchain_markets.log +++ b/tests/regression_tests/blockchain_markets/blockchain_markets.log @@ -45,8 +45,8 @@ delegate1 19,801,980.19801 XTS delegate2 19,801,980.19801 XTS delegate3 19,801,980.19801 XTS delegate4 19,801,980.19801 XTS -testaccount1 10,000.00 XMO - 100.00000 XTS +testaccount1 100.00000 XTS + 10,000.00 XMO testaccount2 10,000.00000 XTS default (unlocked) >>> history RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID @@ -85,7 +85,7 @@ aliases: bid default (unlocked) >>> wallet_market_submit_bid testaccount1 500 XTS 3 XMO RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID ====================================================================================================================================================================== -[redacted] PENDING testaccount1 BID-MQcgyL7S 1,500.00 XMO buy XTS @ 3. XMO / XTS 0.50000 XTS [redacted] +[redacted] PENDING testaccount1 BID 1,500.00 XMO buy XTS @ 3. XMO / XTS 0.50000 XTS [redacted] default (unlocked) >>> debug_advance_time 1 blocks OK default (unlocked) >>> debug_wait 2 @@ -98,8 +98,8 @@ delegate1 19,801,980.19801 XTS delegate2 19,801,980.19801 XTS delegate3 19,801,980.19801 XTS delegate4 19,801,980.19801 XTS -testaccount1 8,500.00 XMO - 99.50000 XTS +testaccount1 99.50000 XTS + 8,500.00 XMO testaccount2 10,000.00000 XTS default (unlocked) >>> history RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID @@ -142,7 +142,7 @@ aliases: ask default (unlocked) >>> wallet_market_submit_ask testaccount2 100 XTS 4 XMO RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID ====================================================================================================================================================================== -[redacted] PENDING testaccount2 ASK-Puq81gDv 100.00000 XTS sell XTS @ 4. XMO / XTS 0.50000 XTS [redacted] +[redacted] PENDING testaccount2 ASK 100.00000 XTS sell XTS @ 4. XMO / XTS 0.50000 XTS [redacted] default (unlocked) >>> debug_advance_time 1 blocks OK default (unlocked) >>> debug_wait 2 @@ -155,8 +155,8 @@ delegate1 19,801,980.19801 XTS delegate2 19,801,980.19801 XTS delegate3 19,801,980.19801 XTS delegate4 19,801,980.19801 XTS -testaccount1 8,500.00 XMO - 99.50000 XTS +testaccount1 99.50000 XTS + 8,500.00 XMO testaccount2 9,899.50000 XTS default (unlocked) >>> history RECEIVED BLOCK FROM TO AMOUNT MEMO FEE ID diff --git a/tests/regression_tests/issue_633/issue_633.log b/tests/regression_tests/issue_633/issue_633.log index 935d1050d..40991fc56 100644 --- a/tests/regression_tests/issue_633/issue_633.log +++ b/tests/regression_tests/issue_633/issue_633.log @@ -48,7 +48,7 @@ RECEIVED BLOCK FROM TO AMOUNT default (unlocked) >>> balance test ACCOUNT BALANCE ============================================================ -test 99.50000 XTS +test 99.00000 XTS default (unlocked) >>> debug_advance_time 1 blocks OK default (unlocked) >>> wallet_rescan_blockchain From b10f8f3ac9f335a3320fcade8faaa569ffb2dc4b Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Wed, 10 Sep 2014 12:20:13 -0400 Subject: [PATCH 14/25] Lots of mail client updates --- libraries/api/general_api.json | 2 +- libraries/api/mail_api.json | 23 +- libraries/api/types.json | 5 + libraries/api/wallet_api.json | 2 +- .../cli/include/bts/cli/print_result.hpp | 1 + libraries/cli/print_result.cpp | 23 ++ libraries/client/client.cpp | 16 +- libraries/mail/client.cpp | 245 ++++++++++++++++-- libraries/mail/include/bts/mail/client.hpp | 32 ++- libraries/mail/include/bts/mail/message.hpp | 7 +- libraries/mail/message.cpp | 7 +- .../wallet/include/bts/wallet/wallet.hpp | 1 + libraries/wallet/wallet.cpp | 25 +- 13 files changed, 346 insertions(+), 43 deletions(-) diff --git a/libraries/api/general_api.json b/libraries/api/general_api.json index 249b308a0..9f00785b2 100644 --- a/libraries/api/general_api.json +++ b/libraries/api/general_api.json @@ -52,7 +52,7 @@ [ { "name" : "address", - "type" : "std::string", + "type" : "string", "description" : "the address or public key to validate" } ], diff --git a/libraries/api/mail_api.json b/libraries/api/mail_api.json index 69766e54b..5a064dfc9 100644 --- a/libraries/api/mail_api.json +++ b/libraries/api/mail_api.json @@ -68,6 +68,14 @@ "is_const" : true, "prerequisites" : ["json_authenticated"] }, + { + "method_name": "mail_get_archive_messages", + "description": "Get all messages in the mail client which are not in processing (sent and received).", + "return_type": "message_status_list", + "parameters" : [], + "is_const" : true, + "prerequisites" : ["json_authenticated"] + }, { "method_name": "mail_retry_send", "description": "Retries sending the specified message.", @@ -93,11 +101,18 @@ } ], "prerequisites" : ["json_authenticated"] - },, + }, { - "method_name": "mail_get_sent_message", + "method_name": "mail_check_new_messages", + "description": "Check mail server for new mail.", + "return_type": "void", + "parameters" : [], + "prerequisites" : ["json_authenticated","wallet_unlocked"] + }, + { + "method_name": "mail_get_message", "description": "Get a specific message from the client.", - "return_type": "message", + "return_type": "email_record", "parameters" : [ { "name" : "message_id", @@ -106,7 +121,7 @@ } ], "is_const" : true, - "prerequisites" : ["json_authenticated"] + "prerequisites" : ["json_authenticated","wallet_unlocked"] }, { "method_name": "mail_send", diff --git a/libraries/api/types.json b/libraries/api/types.json index c4f591b96..54a006639 100644 --- a/libraries/api/types.json +++ b/libraries/api/types.json @@ -638,6 +638,11 @@ "type_name" : "message_status_list", "cpp_return_type" : "std::multimap", "cpp_include_file" : "bts/mail/client.hpp" + }, + { + "type_name" : "email_record", + "cpp_return_type" : "bts::mail::email_record", + "cpp_include_file" : "bts/mail/client.hpp" } ] } diff --git a/libraries/api/wallet_api.json b/libraries/api/wallet_api.json index 3bad95e26..a37f59930 100644 --- a/libraries/api/wallet_api.json +++ b/libraries/api/wallet_api.json @@ -1600,7 +1600,7 @@ }, { "method_name" : "wallet_mail_create", - "description" : "Creates a new mail message.", + "description" : "Creates a new mail message and returns the encrypted message.", "return_type" : "message", "parameters" : [ { diff --git a/libraries/cli/include/bts/cli/print_result.hpp b/libraries/cli/include/bts/cli/print_result.hpp index 1b9adec9f..3bb989bdd 100644 --- a/libraries/cli/include/bts/cli/print_result.hpp +++ b/libraries/cli/include/bts/cli/print_result.hpp @@ -42,6 +42,7 @@ namespace bts { namespace cli { static void f_blockchain_market_order_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void f_blockchain_market_price_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void f_network_list_potential_peers(std::ostream& out, const fc::variants& arguments, const fc::variant& result); + static void f_mail_get_message(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void print_network_usage_graph(std::ostream& out, const std::vector& usage_data); static void print_registered_account_list(std::ostream& out, const vector& account_records, int32_t count); diff --git a/libraries/cli/print_result.cpp b/libraries/cli/print_result.cpp index d8b881af6..3c8d37744 100644 --- a/libraries/cli/print_result.cpp +++ b/libraries/cli/print_result.cpp @@ -180,6 +180,7 @@ namespace bts { namespace cli { _command_to_function["blockchain_calculate_base_supply"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ out << _client->get_chain()->to_pretty_asset(result.as()) << "\n"; }; + _command_to_function["mail_get_message"] = &f_mail_get_message; } void print_result::f_wallet_account_create(std::ostream& out, const fc::variants& arguments, const fc::variant& result) @@ -919,6 +920,28 @@ namespace bts { namespace cli { } } + void print_result::f_mail_get_message(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + { + mail::email_record email = result.as(); + mail::email_message content; + + switch (mail::message_type(email.content.type)) { + case mail::email: + content = email.content.as(); + + out << "=== Email Message ===" + "\nFrom: " << email.sender + << "\nTo: " << email.recipient + << "\nDate: " << pretty_timestamp(email.content.timestamp) + << "\nSubject: " << content.subject + << "\n\n" + << content.body << "\n"; + break; + default: + out << fc::json::to_pretty_string(result); + } + } + } } // else diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index afff8e1b4..16c2d9e4f 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -2252,7 +2252,7 @@ config load_config( const fc::path& datadir ) return _wallet->mail_create(sender, recipient_account->active_key(), subject, body); } - mail::message detail::client_impl::wallet_mail_open(const address& recipient, const message &ciphertext) + mail::message detail::client_impl::wallet_mail_open(const address& recipient, const message& ciphertext) { return _wallet->mail_open(recipient, ciphertext); } @@ -2410,6 +2410,12 @@ config load_config( const fc::path& datadir ) return _mail_client->get_processing_messages(); } + std::multimap detail::client_impl::mail_get_archive_messages() const + { + FC_ASSERT(_mail_client); + return _mail_client->get_archive_messages(); + } + void detail::client_impl::mail_retry_send(const message_id_type& message_id) { FC_ASSERT(_mail_client); @@ -2422,7 +2428,13 @@ config load_config( const fc::path& datadir ) _mail_client->remove_message(message_id); } - mail::message detail::client_impl::mail_get_sent_message(const mail::message_id_type& message_id) const + void detail::client_impl::mail_check_new_messages() + { + FC_ASSERT(_mail_client); + _mail_client->check_new_messages(); + } + + mail::email_record detail::client_impl::mail_get_message(const mail::message_id_type& message_id) const { FC_ASSERT(_mail_client); return _mail_client->get_message(message_id); diff --git a/libraries/mail/client.cpp b/libraries/mail/client.cpp index b6dc15c79..7b9ff56f9 100644 --- a/libraries/mail/client.cpp +++ b/libraries/mail/client.cpp @@ -1,8 +1,8 @@ #include +#include #include #include -#include #include #include @@ -21,6 +21,8 @@ using namespace bts::wallet; using std::string; namespace detail { +#define BTS_MAIL_CLIENT_DATABASE_VERSION 1 +#define BTS_MAIL_CLIENT_MAX_INVENTORY_SIZE 1000 struct mail_record { mail_record(string sender = string(), @@ -47,6 +49,34 @@ struct mail_record { string failure_reason; }; +struct mail_archive_record { + mail_archive_record(mail_record&& from_record = mail_record()) + : id(std::move(from_record.id)), + status(from_record.status), + sender(std::move(from_record.sender)), + recipient(std::move(from_record.recipient)), + recipient_address(address(std::move(from_record.recipient_key))), + content(std::move(from_record.content)), + mail_servers(std::move(from_record.mail_servers)) + {} + mail_archive_record(message&& from_message, string&& sender, const string& recipient, const address& recipient_address) + : id(from_message.id()), + status(client::received), + sender(std::move(sender)), + recipient(recipient), + recipient_address(recipient_address), + content(std::move(from_message)) + {} + + ripemd160 id; + client::mail_status status; + string sender; + string recipient; + address recipient_address; + message content; + std::unordered_set mail_servers; +}; + class client_impl { public: client* self; @@ -60,7 +90,8 @@ class client_impl { fc::future _transmit_message_worker; bts::db::cached_level_map _processing_db; - bts::db::level_map _archive; + bts::db::level_map _archive; + bts::db::level_map _property_db; client_impl(client* self, wallet_ptr wallet, chain_database_ptr chain) : self(self), @@ -72,6 +103,7 @@ class client_impl { _archive.close(); _processing_db.close(); + _property_db.close(); } void retry_message(mail_record email) { @@ -88,27 +120,43 @@ class client_impl { case client::accepted: finalize_message(email.id); break; - case client::failed: + default: //Do nothing break; } } void open(const fc::path& data_dir) { - _archive.open(data_dir / "archive"); - _processing_db.open(data_dir / "processing"); + try { + _archive.open(data_dir / "archive"); + _processing_db.open(data_dir / "processing"); + _property_db.open(data_dir / "properties"); + + if (!_property_db.fetch_optional("version")) + _property_db.store("version", BTS_MAIL_CLIENT_DATABASE_VERSION); + + if (_property_db.fetch("version").as_int64() != BTS_MAIL_CLIENT_DATABASE_VERSION) { + elog("Unable to open mail client: database is wrong version. Supported: ${s}, stored: ${v}", + ("s", BTS_MAIL_CLIENT_DATABASE_VERSION)("v", _property_db.fetch("version").as_int64())); + FC_ASSERT(false, "Mail client database is an unknown version."); + } - //Place all in-processing messages back in their place on the pipeline - for (auto itr = _processing_db.begin(); itr.valid(); ++itr) - retry_message(itr.value()); + //Place all in-processing messages back in their place on the pipeline + for (auto itr = _processing_db.begin(); itr.valid(); ++itr) + retry_message(itr.value()); + } catch (...) { + _archive.close(); + _processing_db.close(); + _property_db.close(); + } } bool is_open() { - return _archive.is_open(); + return _property_db.is_open(); } void process_outgoing_mail(mail_record& mail) { //Messages go through a pipeline of processing. This function starts them on that journey. - set_mail_servers_on_record(mail); + mail.mail_servers = get_mail_servers_for_recipient(mail.recipient); _processing_db.store(mail.id, mail); //The steps required to send a message: @@ -120,9 +168,9 @@ class client_impl { get_proof_of_work_target(mail.id); } - void set_mail_servers_on_record(mail_record& record) { + std::unordered_set get_mail_servers_for_recipient(string recipient) { //TODO: Check recipient's account on blockchain for his mail server - record.mail_servers.insert(ip::endpoint(ip::address("127.0.0.1"), 3000)); + return std::unordered_set({ip::endpoint(ip::address("127.0.0.1"), 3000)}); } void get_proof_of_work_target(const message_id_type& message_id) { @@ -168,6 +216,7 @@ class client_impl { if (email.proof_of_work_target != ripemd160()) { email.status = client::proof_of_work; + email.content.timestamp = fc::time_point::now(); _processing_db.store(email.id, email); } else { //Don't have a proof-of-work target; cannot continue @@ -283,28 +332,134 @@ class client_impl { void finalize_message(message_id_type message_id) { ulog("Email ${id} sent successfully.", ("id", message_id)); mail_record email = _processing_db.fetch(message_id); - email.status = client::accepted; - //TODO: Change archive to use a different struct with more appropriate contents - _archive.store(message_id, email); + _archive.store(message_id, std::move(email)); _processing_db.remove(message_id); } - std::multimap get_processing_messages() { + template + std::multimap get_database_messages(Database& db) { std::multimap messages; - for(auto itr = _processing_db.begin(); itr.valid(); ++itr) { - mail_record email = itr.value(); + for(auto itr = db.begin(); itr.valid(); ++itr) { + auto email = itr.value(); messages.insert(std::make_pair(email.status, email.id)); } return messages; } - message get_message(message_id_type message_id) { - if (_processing_db.fetch_optional(message_id)) - return _processing_db.fetch_optional(message_id)->content; - if (_archive.fetch_optional(message_id)) - return _archive.fetch_optional(message_id)->content; + email_record decrypted_email_record(mail_record&& email) { + if (email.content.type != encrypted) + return email; + email.content = _wallet->mail_decrypt(email.recipient_key, email.content); + return email; + } + email_record decrypted_email_record(mail_archive_record&& email) { + if (email.content.type != encrypted) + return email; + email.content = _wallet->mail_decrypt(email.recipient_address, email.content); + return email; + } + + email_record get_message(message_id_type message_id) { + if (auto op = _processing_db.fetch_optional(message_id)) + return decrypted_email_record(std::move(*op)); + if (auto op = _archive.fetch_optional(message_id)) + return decrypted_email_record(std::move(*op)); FC_ASSERT(false, "Message ${id} not found.", ("id", message_id)); } + + void check_new_mail() { + auto accounts = _wallet->list_my_accounts(); + for (wallet_account_record account : accounts) { + auto servers = get_mail_servers_for_recipient(account.name); + vector> fetch_tasks; + fetch_tasks.reserve(servers.size()); + + auto last_check_time = account.registration_date; + fc::time_point_sec check_time = _chain->now(); + if (auto op = _property_db.fetch_optional("last_fetch/" + account.name)) + last_check_time = op->as(); + + for (ip::endpoint server : servers) { + fetch_tasks.push_back(fc::async([=] { + //TODO: This whole design needs to be rethought. This is just a simplistic first effort. + //Right now we get the inventory, then download and store ALL of it locally. + //Downloading is done synchronously, with one message downloaded before the next starts. + //No deduplication of effort is done; i.e. if a given message is on three servers, we'll download it three times. + tcp_socket sock; + sock.connect_to(server); + + int received = BTS_MAIL_CLIENT_MAX_INVENTORY_SIZE; + while (received == BTS_MAIL_CLIENT_MAX_INVENTORY_SIZE) { + mutable_variant_object request; + request["id"] = 0; + request["method"] = "mail_fetch_inventory"; + request["params"] = vector({variant(address(account.account_address)), + variant(last_check_time), + variant(BTS_MAIL_CLIENT_MAX_INVENTORY_SIZE)}); + + fc::json::to_stream(sock, variant_object(request)); + string raw_response; + fc::getline(sock, raw_response); + variant_object response = fc::json::from_string(raw_response).as(); + + if (response["id"].as_int64() != 0) + wlog("Server response has wrong ID... attempting to press on. Expected: 0; got: ${r}", ("r", response["id"])); + if (response.contains("error")) { + elog("Server ${server} gave error ${error} on request ${request}", ("server", server)("error", response["error"])("request", request)); + sock.close(); + return; + } + + inventory_type results = response["result"].as(); + received = results.size(); + + for (std::pair email : results) { + request["id"] = 1; + request["method"] = "mail_fetch_message"; + request["params"] = vector({variant(email.second)}); + + fc::json::to_stream(sock, variant_object(request)); + fc::getline(sock, raw_response); + response = fc::json::from_string(raw_response).as(); + + if (response["id"].as_int64() != 1) + wlog("Server response has wrong ID... attempting to press on. Expected: 1; got: ${r}", ("r", response["id"])); + if (response.contains("error")) { + elog("Server ${server} gave error ${error} on request ${request}", ("server", server)("error", response["error"])("request", request)); + sock.close(); + return; + } + + + message ciphertext = response["result"].as(); + message plaintext = _wallet->mail_open(account.account_address, ciphertext); + string sender = "ANONYMOUS"; + if (plaintext.type == mail::email) + if( auto op = _chain->get_account_record(plaintext.as().from())) + sender = op->name; + mail_archive_record record(std::move(ciphertext), std::move(sender), account.name, account.account_address); + _archive.store(email.second, record); + } + } + }, "Mail client fetcher")); + } + + auto timeout_future = fc::schedule([=] { + elog("Timed out fetching new mail."); + ulog("Timed out fetching new mail."); + for (auto task_future : fetch_tasks) + task_future.cancel(); + }, fc::time_point::now() + fc::seconds(10), "Mail client fetcher timeout"); + + while (!fetch_tasks.empty()) { + fetch_tasks.back().wait(); + fetch_tasks.pop_back(); + } + + timeout_future.cancel("Finished fetching"); + _property_db.store("last_fetch/" + account.name, variant(check_time)); + } + } }; } @@ -343,12 +498,24 @@ void client::remove_message(message_id_type message_id) } } +void client::check_new_messages() +{ + FC_ASSERT(my->is_open()); + my->check_new_mail(); +} + std::multimap client::get_processing_messages() { FC_ASSERT(my->is_open()); - return my->get_processing_messages(); + return my->get_database_messages(my->_processing_db); +} + +std::multimap client::get_archive_messages() +{ + FC_ASSERT(my->is_open()); + return my->get_database_messages(my->_archive); } -message client::get_message(message_id_type message_id) { +email_record client::get_message(message_id_type message_id) { FC_ASSERT(my->is_open()); return my->get_message(message_id); } @@ -361,18 +528,40 @@ message_id_type client::send_email(const string &from, const string &to, const s //TODO: Find a thin-clienty way to do this, rather than calling a local chain_database oaccount_record recipient = my->_chain->get_account_record(to); FC_ASSERT(recipient, "Could not find recipient account: ${name}", ("name", to)); - public_key_type recipient_key = recipient->active_key(); + //All mail shall be addressed to the owner key, but it is encrypted with the active key. detail::mail_record email(from, to, - recipient_key, - my->_wallet->mail_create(from, recipient_key, subject, body)); + recipient->owner_key, + my->_wallet->mail_create(from, recipient->active_key(), subject, body)); my->process_outgoing_mail(email); return email.id; } +email_record::email_record(const detail::mail_record& processing_record) + : id(processing_record.id), + status(processing_record.status), + sender(processing_record.sender), + recipient(processing_record.recipient), + content(processing_record.content) +{ + if (processing_record.status >= client::proof_of_work && processing_record.status != client::failed) + *mail_servers = processing_record.mail_servers; + if (processing_record.status == client::failed) + *failure_reason = processing_record.failure_reason; +} +email_record::email_record(const detail::mail_archive_record& archive_record) + : id(archive_record.id), + status(client::accepted), + sender(archive_record.sender), + recipient(archive_record.recipient), + content(archive_record.content), + mail_servers(archive_record.mail_servers) +{} + } } FC_REFLECT(bts::mail::detail::mail_record, (id)(status)(sender)(recipient)(recipient_key)(content)(mail_servers)(proof_of_work_target)) +FC_REFLECT(bts::mail::detail::mail_archive_record, (id)(status)(sender)(recipient)(recipient_address)(content)(mail_servers)) diff --git a/libraries/mail/include/bts/mail/client.hpp b/libraries/mail/include/bts/mail/client.hpp index 5dc1774a9..ba3afaad4 100644 --- a/libraries/mail/include/bts/mail/client.hpp +++ b/libraries/mail/include/bts/mail/client.hpp @@ -3,12 +3,16 @@ #include #include +#include + #include namespace bts { namespace mail { -namespace detail { class client_impl; } +namespace detail { class client_impl; struct mail_record; struct mail_archive_record; } + +struct email_record; class client : public std::enable_shared_from_this { public: @@ -18,6 +22,8 @@ class client : public std::enable_shared_from_this { transmitting, //The message is being transmitted to the servers, but has not yet been accepted by all of them accepted, //The message has been acknowledged and stored by the server + received, //The message is an incoming message + failed //The message could not be processed }; @@ -29,16 +35,38 @@ class client : public std::enable_shared_from_this { void retry_message(message_id_type message_id); void remove_message(message_id_type message_id); + void check_new_messages(); + std::multimap get_processing_messages(); - message get_message(message_id_type message_id); + std::multimap get_archive_messages(); + email_record get_message(message_id_type message_id); message_id_type send_email(const string& from, const string& to, const string& subject, const string& body); private: std::shared_ptr my; }; +struct email_record { + fc::ripemd160 id; + client::mail_status status; + string sender; + string recipient; + message content; + fc::optional> mail_servers; + fc::optional failure_reason; + + email_record(){} + email_record(const detail::mail_record& processing_record); + email_record(const detail::mail_archive_record& archive_record); + + fc::ripemd160 id_on_server() { + return content.id(); + } +}; + } } FC_REFLECT_TYPENAME(bts::mail::client::mail_status) FC_REFLECT_ENUM(bts::mail::client::mail_status, (submitted)(proof_of_work)(transmitting)(accepted)(failed)) +FC_REFLECT(bts::mail::email_record, (id)(status)(sender)(recipient)(content)(mail_servers)(failure_reason)) diff --git a/libraries/mail/include/bts/mail/message.hpp b/libraries/mail/include/bts/mail/message.hpp index 184fd0f8a..3be3ee8e4 100644 --- a/libraries/mail/include/bts/mail/message.hpp +++ b/libraries/mail/include/bts/mail/message.hpp @@ -64,6 +64,7 @@ namespace bts { namespace mail { static const message_type type; message decrypt( const fc::ecc::private_key& e )const; + message decrypt( const fc::sha512& shared_secret )const; fc::ecc::public_key onetimekey; vector data; @@ -71,7 +72,7 @@ namespace bts { namespace mail { struct message { - message():nonce(0){} + message():nonce(0),timestamp(fc::time_point::now()){} message_id_type id()const; encrypted_message encrypt( const fc::ecc::private_key& onetimekey, @@ -81,6 +82,7 @@ namespace bts { namespace mail { message( const MessageType& m ) { type = MessageType::type; + timestamp = fc::time_point::now(); data = fc::raw::pack(m); } @@ -93,6 +95,7 @@ namespace bts { namespace mail { fc::enum_type type; uint64_t nonce; + fc::time_point_sec timestamp; vector data; }; @@ -100,7 +103,7 @@ namespace bts { namespace mail { FC_REFLECT_ENUM( bts::mail::message_type, (encrypted)(transaction_notice)(market_notice)(email) ) FC_REFLECT( bts::mail::encrypted_message, (onetimekey)(data) ) -FC_REFLECT( bts::mail::message, (type)(nonce)(data) ) +FC_REFLECT( bts::mail::message, (type)(nonce)(timestamp)(data) ) FC_REFLECT( bts::mail::attachment, (name)(data) ) FC_REFLECT( bts::mail::transaction_notice_message, (trx)(extended_memo) ) FC_REFLECT( bts::mail::email_message, (subject)(body)(attachments) ) diff --git a/libraries/mail/message.cpp b/libraries/mail/message.cpp index 993252477..f255273ec 100644 --- a/libraries/mail/message.cpp +++ b/libraries/mail/message.cpp @@ -43,8 +43,13 @@ namespace bts { namespace mail { message encrypted_message::decrypt( const fc::ecc::private_key& e )const { auto shared_secret = e.get_shared_secret(onetimekey); + return decrypt(shared_secret); + } + + message encrypted_message::decrypt(const fc::sha512& shared_secret) const + { auto decrypted_data = fc::aes_decrypt( shared_secret, data ); return fc::raw::unpack( decrypted_data ); - }; + } } } // bts::mail diff --git a/libraries/wallet/include/bts/wallet/wallet.hpp b/libraries/wallet/include/bts/wallet/wallet.hpp index 884c4c2f4..ae3bc248d 100644 --- a/libraries/wallet/include/bts/wallet/wallet.hpp +++ b/libraries/wallet/include/bts/wallet/wallet.hpp @@ -524,6 +524,7 @@ namespace bts { namespace wallet { const string& subject, const string& body ); mail::message mail_open( const address& recipient, const mail::message& ciphertext ); + mail::message mail_decrypt( const address& recipient, const mail::message& ciphertext ); private: unique_ptr my; diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0459c9292..d6e6f555c 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -6191,11 +6191,32 @@ namespace bts { namespace wallet { FC_ASSERT(is_open()); FC_ASSERT(is_unlocked()); if(!is_receive_address(recipient)) - FC_THROW_EXCEPTION(unknown_address, "Unknown receiving account address!", ("recipient",recipient)); + //It's not to us... maybe it's from us. + return mail_decrypt(recipient, ciphertext); - auto recipient_key = get_private_key(recipient); + auto recipient_key = get_active_private_key(my->_blockchain->get_account_record(recipient)->name); FC_ASSERT(ciphertext.type == mail::encrypted); return ciphertext.as().decrypt(recipient_key); } + mail::message wallet::mail_decrypt(const address& recipient, const mail::message& ciphertext) + { + FC_ASSERT(is_open()); + FC_ASSERT(is_unlocked()); + FC_ASSERT(ciphertext.type == mail::encrypted, "Unknown message type"); + + oaccount_record recipient_account = my->_blockchain->get_account_record(recipient); + FC_ASSERT(recipient_account, "Unknown recipient address"); + public_key_type recipient_key = recipient_account->active_key(); + FC_ASSERT(recipient_key != public_key_type(), "Unknown recipient address"); + + auto encrypted_message = ciphertext.as(); + FC_ASSERT(my->_wallet_db.has_private_key(encrypted_message.onetimekey)); + owallet_key_record one_time_key = my->_wallet_db.lookup_key(encrypted_message.onetimekey); + private_key_type one_time_private_key = one_time_key->decrypt_private_key(my->_wallet_password); + + auto secret = one_time_private_key.get_shared_secret(recipient_key); + return encrypted_message.decrypt(secret); + } + } } // bts::wallet From ddeab3da019d62d3d0b04f970eebea52fff4c7d8 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Wed, 10 Sep 2014 13:20:09 -0400 Subject: [PATCH 15/25] Parse order_id w/o quotes --- libraries/cli/cli.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/cli/cli.cpp b/libraries/cli/cli.cpp index 2b25a1bf3..8bd264a88 100644 --- a/libraries/cli/cli.cpp +++ b/libraries/cli/cli.cpp @@ -448,6 +448,7 @@ namespace bts { namespace cli { this_parameter.type == "new_passphrase" || this_parameter.type == "filename" || this_parameter.type == "public_key" || + this_parameter.type == "order_id" || this_parameter.type == "passphrase") { string result; From f954d8c1b762ac85b68f4e9d1a6f6e89a45e5acd Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Wed, 10 Sep 2014 14:56:30 -0400 Subject: [PATCH 16/25] Fix pack_web if a trailing slash is present on the packed folder --- programs/utils/pack_web.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/utils/pack_web.cpp b/programs/utils/pack_web.cpp index 3fb06171a..73b92a38a 100644 --- a/programs/utils/pack_web.cpp +++ b/programs/utils/pack_web.cpp @@ -47,6 +47,8 @@ int main(int argc, char** argv) { for (fc::recursive_directory_iterator itr(pack_dir); itr != fc::recursive_directory_iterator(); ++itr) { string relative_path = (*itr).to_native_ansi_path().erase(0, pack_dir.to_native_ansi_path().size()); + if (relative_path[0] != '/') + relative_path = "/" + relative_path; if (!fc::is_regular_file(*itr)) continue; From f7d48ef0c70e70eb4a51b6e4a265da8e3e401287 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 10 Sep 2014 15:37:12 -0400 Subject: [PATCH 17/25] updates to support multi-part transfers --- libraries/wallet/wallet.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 03e0657b8..d6c123327 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -3441,9 +3441,9 @@ namespace bts { namespace wallet { /** * TODO: until we support paying fees in other assets, this will not function * properly. - */ FC_ASSERT( asset_id == 0, "multipart transfers only support base shares", ("asset_to_transfer",asset_to_transfer)("symbol",amount_to_transfer_symbol)); + */ vector trxs; vector amount_sent; @@ -3454,7 +3454,7 @@ namespace bts { namespace wallet { public_key_type sender_public_key = sender_private_key.get_public_key(); address sender_account_address( sender_private_key.get_public_key() ); - asset total_fee = get_transaction_fee(); + asset total_fee = get_transaction_fee( asset_id ); asset amount_collected( 0, asset_id ); const auto items = my->_wallet_db.get_balances(); @@ -3553,7 +3553,7 @@ namespace bts { namespace wallet { // If we went through all our balances and still don't have enough if (amount_collected < asset( amount_to_transfer, asset_id )) { - FC_ASSERT( !"Insufficient funds."); + FC_CAPTURE_AND_THROW( insufficient_funds, (amount_to_transfer)(amount_collected) ); } if( sign ) // don't store invalid trxs.. @@ -3565,17 +3565,19 @@ namespace bts { namespace wallet { //} for( uint32_t i = 0 ; i < trxs.size(); ++i ) { - // TODO: FIXME - /* - my->_wallet_db.cache_transaction( trxs[i], asset( -amount_sent[i], asset_id), - total_fee.amount, - memo_message, - receiver_public_key, - now, - now, - sender_public_key - ); - */ + auto entry = ledger_entry(); + entry.from_account = sender_public_key; + entry.to_account = receiver_public_key; + entry.amount = asset(amount_sent[i],asset_id); //asset_to_transfer; + entry.memo = fc::to_string(i)+":"+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 = total_fee; //required_fees; + + cache_transaction( trxs[i], record ); } } From 4bc45baa139058a49bb50b7267be747330a42480 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 10 Sep 2014 15:43:39 -0400 Subject: [PATCH 18/25] fix infinite loop in get_market_orders --- libraries/blockchain/chain_database.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/blockchain/chain_database.cpp b/libraries/blockchain/chain_database.cpp index 0402cb154..1ea8172c6 100644 --- a/libraries/blockchain/chain_database.cpp +++ b/libraries/blockchain/chain_database.cpp @@ -2455,6 +2455,7 @@ namespace bts { namespace blockchain { auto order = market_order { bid_order, bid_itr.key(), bid_itr.value() }; if( filter(order) ) ret.push_back(order); + ++bid_itr; } auto ask_itr = my->_ask_db.begin(); @@ -2463,6 +2464,7 @@ namespace bts { namespace blockchain { auto order = market_order { ask_order, ask_itr.key(), ask_itr.value() }; if( filter(order) ) ret.push_back(order); + ++ask_itr; } auto short_itr = my->_short_db.begin(); @@ -2471,8 +2473,8 @@ namespace bts { namespace blockchain { auto order = market_order { short_order, short_itr.key(), short_itr.value() }; if( filter(order) ) ret.push_back(order); + ++short_itr; } - return ret; } From d52ec8395153343bafcd1fab34fcca1158100803 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 16:09:58 -0400 Subject: [PATCH 19/25] Fix some regression test failures --- libraries/api/blockchain_api.json | 2 +- libraries/api/general_api.json | 6 +- libraries/api/network_api.json | 2 +- libraries/blockchain/address.cpp | 8 +- libraries/blockchain/types.cpp | 2 +- libraries/cli/cli.cpp | 6 +- .../cli/include/bts/cli/print_result.hpp | 59 ++-- libraries/cli/print_result.cpp | 253 ++++++++++-------- libraries/client/client.cpp | 8 +- libraries/wallet/wallet.cpp | 21 +- programs/web_wallet | 2 +- tests/dev_tests.cpp | 2 +- .../regression_tests/stolen_names/client0.log | 3 +- .../regression_tests/stolen_names/client1.log | 3 +- tests/regression_tests/titan/client0.log | 1 - .../wallet_get_setting/wallet_get_setting.log | 26 +- .../wallet_import_keyhotee.log | 29 +- tests/wallet_tests.cpp | 2 +- 18 files changed, 242 insertions(+), 193 deletions(-) diff --git a/libraries/api/blockchain_api.json b/libraries/api/blockchain_api.json index 84110e4eb..19327191e 100644 --- a/libraries/api/blockchain_api.json +++ b/libraries/api/blockchain_api.json @@ -535,7 +535,7 @@ { "method_name" : "blockchain_export_fork_graph", "description" : "dumps the fork data to graphviz format", - "return_type" : "std::string", + "return_type" : "string", "parameters" : [ { "name" : "start_block", diff --git a/libraries/api/general_api.json b/libraries/api/general_api.json index 249b308a0..adaf3ab33 100644 --- a/libraries/api/general_api.json +++ b/libraries/api/general_api.json @@ -30,7 +30,7 @@ { "method_name": "help", "description": "display a list of commands, or detailed help on an individual command", - "return_type": "std::string", + "return_type": "string", "parameters" : [ { @@ -52,7 +52,7 @@ [ { "name" : "address", - "type" : "std::string", + "type" : "string", "description" : "the address or public key to validate" } ], @@ -63,7 +63,7 @@ { "method_name": "execute_command_line", "description": "Execute the given command as if it were typed on the CLI", - "return_type": "std::string", + "return_type": "string", "parameters" : [ { diff --git a/libraries/api/network_api.json b/libraries/api/network_api.json index f44870854..3ec58fc30 100644 --- a/libraries/api/network_api.json +++ b/libraries/api/network_api.json @@ -16,7 +16,7 @@ }, { "name" : "command", - "type" : "std::string", + "type" : "string", "description" : "'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once", "example" : "add", "default_value" : "add" diff --git a/libraries/blockchain/address.cpp b/libraries/blockchain/address.cpp index b0a72a7de..29244a3ef 100644 --- a/libraries/blockchain/address.cpp +++ b/libraries/blockchain/address.cpp @@ -9,7 +9,7 @@ namespace bts { address::address(){} address::address( const std::string& base58str ) - { + { FC_ASSERT( is_valid( base58str ) ); std::vector v = fc::from_base58( base58str.substr( strlen(BTS_ADDRESS_PREFIX) ) ); memcpy( (char*)addr._hash, v.data(), std::min( v.size()-4, sizeof(addr) ) ); @@ -56,7 +56,7 @@ namespace bts { { addr = fc::ripemd160::hash( fc::sha512::hash( pub.data, sizeof(pub) ) ); } - + address::address( const bts::blockchain::public_key_type& pub ) { addr = fc::ripemd160::hash( fc::sha512::hash( pub.key_data.data, sizeof(pub.key_data) ) ); @@ -73,8 +73,8 @@ namespace bts { } } // namespace bts::blockchain -namespace fc -{ +namespace fc +{ void to_variant( const bts::blockchain::address& var, variant& vo ) { vo = std::string(var); diff --git a/libraries/blockchain/types.cpp b/libraries/blockchain/types.cpp index 22072355f..e8e7b0945 100644 --- a/libraries/blockchain/types.cpp +++ b/libraries/blockchain/types.cpp @@ -28,7 +28,7 @@ namespace bts { namespace blockchain { public_key_type::operator fc::ecc::public_key_data() const { - return key_data; + return key_data; }; public_key_type::operator fc::ecc::public_key() const diff --git a/libraries/cli/cli.cpp b/libraries/cli/cli.cpp index 3ed266ca5..77d393d7c 100644 --- a/libraries/cli/cli.cpp +++ b/libraries/cli/cli.cpp @@ -433,6 +433,7 @@ namespace bts { namespace cli { return fc::variant( bts::blockchain::address(address_string) ); } else if (this_parameter.type == "string" || + this_parameter.type == "std::string" || this_parameter.type == "wallet_name" || this_parameter.type == "optional_wallet_name" || this_parameter.type == "wif_private_key" || @@ -447,6 +448,8 @@ namespace bts { namespace cli { this_parameter.type == "method_name" || this_parameter.type == "new_passphrase" || this_parameter.type == "filename" || + this_parameter.type == "keyhoteeid" || + this_parameter.type == "public_key" || this_parameter.type == "passphrase") { string result; @@ -647,7 +650,7 @@ namespace bts { namespace cli { if( !_out ) return; - _print_result.format_and_print(*_out, method_name, arguments, result); + _print_result.format_and_print( method_name, arguments, result, _client, *_out ); *_out << std::right; /* Ensure default alignment is restored */ } @@ -685,7 +688,6 @@ namespace bts { namespace cli { , _saved_out(nullptr) ,_out(output_stream ? output_stream : &nullstream) ,_command_script(command_script) - , _print_result(client) { #ifdef HAVE_READLINE //if( &output_stream == &std::cout ) // readline diff --git a/libraries/cli/include/bts/cli/print_result.hpp b/libraries/cli/include/bts/cli/print_result.hpp index 1b9adec9f..bf924c66e 100644 --- a/libraries/cli/include/bts/cli/print_result.hpp +++ b/libraries/cli/include/bts/cli/print_result.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -10,47 +10,46 @@ namespace bts { namespace cli { - using namespace bts::client; - extern bool FILTER_OUTPUT_FOR_TESTS; class print_result { public: - print_result(bts::client::client* client); + print_result(); - void format_and_print(std::ostream& out, const string& method_name, const fc::variants& arguments, const fc::variant& result) const; + void format_and_print( const string& method_name, const fc::variants& arguments, const fc::variant& result, + cptr client, std::ostream& out )const; private: void initialize(); - - static void f_wallet_account_create(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_debug_list_errors(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_market_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_wallet_list_my_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_wallet_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_wallet_transfer(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_wallet_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_network_get_usage_stats(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_list_delegates(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_get_proposal_votes(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_list_forks(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_list_pending_transactions(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_list_proposals(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_market_order_book(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_market_order_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_blockchain_market_price_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - static void f_network_list_potential_peers(std::ostream& out, const fc::variants& arguments, const fc::variant& result); - - static void print_network_usage_graph(std::ostream& out, const std::vector& usage_data); - static void print_registered_account_list(std::ostream& out, const vector& account_records, int32_t count); + + static void f_wallet_account_create( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_debug_list_errors( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_market_list( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_wallet_list_my_accounts( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_wallet_list_accounts( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_wallet_transfer( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_wallet_list( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_network_get_usage_stats( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_list_delegates( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_list_accounts( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_get_proposal_votes( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_list_forks( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_list_pending_transactions( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_list_proposals( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_market_order_book( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_market_order_history( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_blockchain_market_price_history( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + static void f_network_list_potential_peers( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ); + + static void print_network_usage_graph( std::ostream& out, const std::vector& usage_data ); + static void print_registered_account_list( std::ostream& out, const vector& account_records, int32_t count, cptr client ); private: - typedef std::function t_function; + typedef std::function t_function; typedef std::map t_command_to_function; - t_command_to_function _command_to_function; - static bts::client::client* _client; + t_command_to_function _command_to_function; }; + } } diff --git a/libraries/cli/print_result.cpp b/libraries/cli/print_result.cpp index 144a39958..30fd46104 100644 --- a/libraries/cli/print_result.cpp +++ b/libraries/cli/print_result.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -9,35 +8,32 @@ namespace bts { namespace cli { - bts::client::client* print_result::_client = nullptr; - - print_result::print_result(bts::client::client* client) + print_result::print_result() { - _client = client; initialize(); } - void print_result::format_and_print(std::ostream& out, const string& method_name, - const fc::variants& arguments, const fc::variant& result) const + void print_result::format_and_print( const string& method_name, const fc::variants& arguments, const fc::variant& result, + cptr client, std::ostream& out )const { try { - t_command_to_function::const_iterator iter = _command_to_function.find(method_name); + t_command_to_function::const_iterator iter = _command_to_function.find( method_name); - if(iter != _command_to_function.end()) - (iter->second)(out, arguments, result); + if( iter != _command_to_function.end()) + (iter->second)(out, arguments, result, client); else { // there was no custom handler for this particular command, see if the return type // is one we know how to pretty-print string result_type; - const bts::api::method_data& method_data = _client->get_rpc_server()->get_method_data(method_name); + const bts::api::method_data& method_data = client->get_rpc_server()->get_method_data( method_name); result_type = method_data.return_type; - if(result_type == "asset") + if( result_type == "asset") { - out << (string)result.as() << "\n"; + out << string( result.as() ) << "\n"; } else if(result_type == "address") { @@ -66,38 +62,50 @@ namespace bts { namespace cli { void print_result::initialize() { - _command_to_function["help"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["help"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { string help_string = result.as(); - out << help_string << "\n"; }; + out << help_string << "\n"; + }; - _command_to_function["wallet_account_vote_summary"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["wallet_account_vote_summary"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& votes = result.as(); - out << pretty_vote_summary(votes, _client); }; + out << pretty_vote_summary(votes, client); + }; _command_to_function["wallet_account_create"] = &f_wallet_account_create; _command_to_function["debug_list_errors"] = &f_debug_list_errors; - _command_to_function["get_info"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["get_info"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& info = result.as(); - out << pretty_info(info, _client); }; + out << pretty_info(info, client); + }; - _command_to_function["blockchain_get_info"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["blockchain_get_info"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& config = result.as(); - out << pretty_blockchain_info(config, _client); }; + out << pretty_blockchain_info(config, client); + }; - _command_to_function["wallet_get_info"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["wallet_get_info"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& info = result.as(); - out << pretty_wallet_info(info, _client); }; + out << pretty_wallet_info(info, client); + }; - _command_to_function["wallet_account_transaction_history"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["wallet_account_transaction_history"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& transactions = result.as>(); - out << pretty_transaction_list(transactions, _client); }; + out << pretty_transaction_list(transactions, client); + }; - _command_to_function["wallet_market_order_list"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result ) + _command_to_function["wallet_market_order_list"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& market_orders = result.as>(); - out << pretty_order_list( market_orders, _client ); + out << pretty_order_list( market_orders, client ); }; _command_to_function["blockchain_market_list_asks"] = &f_blockchain_market_list; @@ -110,16 +118,16 @@ namespace bts { namespace cli { _command_to_function["wallet_list_unregistered_accounts"] = &f_wallet_list_accounts; _command_to_function["wallet_list_favorite_accounts"] = &f_wallet_list_accounts; - _command_to_function["wallet_account_balance"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result ) + _command_to_function["wallet_account_balance"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& balances = result.as(); - out << pretty_balances( balances, _client ); + out << pretty_balances( balances, client ); }; - _command_to_function["wallet_account_yield"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result ) + _command_to_function["wallet_account_yield"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& yield = result.as(); - out << pretty_balances( yield, _client ); + out << pretty_balances( yield, client ); }; _command_to_function["wallet_transfer"] = &f_wallet_transfer; @@ -151,19 +159,25 @@ namespace bts { namespace cli { _command_to_function["blockchain_list_delegates"] = &f_blockchain_list_delegates; _command_to_function["blockchain_list_active_delegates"] = &f_blockchain_list_delegates; - _command_to_function["blockchain_list_blocks"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ + _command_to_function["blockchain_list_blocks"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { const auto& block_records = result.as>(); - out << pretty_block_list(block_records, _client); }; + out << pretty_block_list(block_records, client); + }; _command_to_function["blockchain_list_accounts"] = &f_blockchain_list_accounts; - _command_to_function["blockchain_list_assets"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ - out << pretty_asset_list(result.as>(), _client); }; + _command_to_function["blockchain_list_assets"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { + out << pretty_asset_list(result.as>(), client); + }; _command_to_function["blockchain_get_proposal_votes"] = &f_blockchain_get_proposal_votes; - _command_to_function["blockchain_get_account"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ - out << pretty_account(result.as(), _client); }; + _command_to_function["blockchain_get_account"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { + out << pretty_account(result.as(), client); + }; _command_to_function["blockchain_list_forks"] = &f_blockchain_list_forks; @@ -177,33 +191,42 @@ namespace bts { namespace cli { _command_to_function["blockchain_market_price_history"] = &f_blockchain_market_price_history; - _command_to_function["blockchain_unclaimed_genesis"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ - out << _client->get_chain()->to_pretty_asset(result.as()) << "\n"; }; + _command_to_function["blockchain_unclaimed_genesis"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { + out << client->get_chain()->to_pretty_asset(result.as()) << "\n"; + }; _command_to_function["network_list_potential_peers"] = &f_network_list_potential_peers; - _command_to_function["wallet_set_transaction_fee"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ - out << _client->get_chain()->to_pretty_asset(result.as()) << "\n"; }; - - _command_to_function["blockchain_calculate_base_supply"] = [](std::ostream& out, const fc::variants& arguments, const fc::variant& result){ - out << _client->get_chain()->to_pretty_asset(result.as()) << "\n"; }; + _command_to_function["wallet_set_transaction_fee"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { + out << client->get_chain()->to_pretty_asset(result.as()) << "\n"; + }; + _command_to_function["blockchain_calculate_base_supply"] = []( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) + { + out << client->get_chain()->to_pretty_asset(result.as()) << "\n"; + }; } - void print_result::f_wallet_account_create(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_wallet_account_create( std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { - auto account_key = result.as_string(); - auto account = _client->get_wallet()->get_account_for_address(public_key_type(account_key)); + const auto account_key = result.as(); + const auto account_record = client->get_wallet()->get_account_for_address( address( account_key ) ); - if(account) - out << "\n\nAccount created successfully. You may give the following link to others" + if( account_record.valid() ) + { + out << "\nAccount created successfully. You may give the following link to others" " to allow them to add you as a contact and send you funds:\n" CUSTOM_URL_SCHEME ":" - << account->name << ':' << account_key << '\n'; + << account_record->name << ':' << string( account_key ) << '\n'; + } else + { out << "Sorry, something went wrong when adding your account.\n"; + } } - void print_result::f_debug_list_errors(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_debug_list_errors(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto error_map = result.as >(); if(error_map.empty()) @@ -217,16 +240,16 @@ namespace bts { namespace cli { } } - void print_result::f_blockchain_market_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_market_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& market_orders = result.as>(); map order_map; for( const auto& order : market_orders ) order_map[ order.get_id() ] = order; - out << pretty_order_list( order_map, _client ); + out << pretty_order_list( order_map, client ); } - void print_result::f_wallet_list_my_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_wallet_list_my_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto accts = result.as>(); @@ -274,7 +297,7 @@ namespace bts { namespace cli { } } - void print_result::f_wallet_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_wallet_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto accts = result.as>(); @@ -309,15 +332,15 @@ namespace bts { namespace cli { } } - void print_result::f_wallet_transfer(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_wallet_transfer(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& record = result.as(); - const auto& pretty = _client->get_wallet()->to_pretty_trx(record); + const auto& pretty = client->get_wallet()->to_pretty_trx(record); const std::vector transactions = { pretty }; - out << pretty_transaction_list(transactions, _client); + out << pretty_transaction_list(transactions, client); } - void print_result::f_wallet_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_wallet_list(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto wallets = result.as>(); if(wallets.empty()) @@ -327,7 +350,7 @@ namespace bts { namespace cli { out << wallet << "\n"; } - void print_result::f_network_get_usage_stats(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_network_get_usage_stats(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto stats = result.get_object(); @@ -369,13 +392,13 @@ namespace bts { namespace cli { out << "\n"; } - void print_result::f_blockchain_list_delegates(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_list_delegates(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { const auto& delegate_records = result.as>(); - out << pretty_delegate_list(delegate_records, _client); + out << pretty_delegate_list(delegate_records, client); } - void print_result::f_blockchain_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_list_accounts(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { string start = ""; int32_t count = 25; // In CLI this is a more sane default @@ -383,10 +406,10 @@ namespace bts { namespace cli { start = arguments[0].as_string(); if(arguments.size() > 1) count = arguments[1].as(); - print_registered_account_list(out, result.as>(), count); + print_registered_account_list(out, result.as>(), count, client); } - void print_result::print_registered_account_list(std::ostream& out, const vector& account_records, int32_t count) + void print_result::print_registered_account_list(std::ostream& out, const vector& account_records, int32_t count, cptr client) { out << std::setw(35) << std::left << "NAME (* delegate)"; out << std::setw(64) << "KEY"; @@ -420,7 +443,7 @@ namespace bts { namespace cli { try { - out << std::setw(15) << std::to_string(_client->get_wallet()->get_account_approval(acct.name)); + out << std::setw(15) << std::to_string(client->get_wallet()->get_account_approval(acct.name)); } catch(...) { @@ -445,7 +468,7 @@ namespace bts { namespace cli { } } - void print_result::f_blockchain_get_proposal_votes(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_get_proposal_votes(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto votes = result.as>(); out << std::left; @@ -457,7 +480,7 @@ namespace bts { namespace cli { out << "-----------------------\n"; for(const auto& vote : votes) { - auto rec = _client->get_chain()->get_account_record(vote.id.delegate_id); + auto rec = client->get_chain()->get_account_record(vote.id.delegate_id); out << std::setw(15) << pretty_shorten(rec->name, 14); out << std::setw(20) << pretty_timestamp(vote.timestamp); if(vote.vote == proposal_vote::no) @@ -478,7 +501,7 @@ namespace bts { namespace cli { out << "\n"; } - void print_result::f_blockchain_list_forks(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_list_forks(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { std::map> forks = result.as>>(); std::map invalid_reasons; //Your reasons are invalid. @@ -506,7 +529,7 @@ namespace bts { namespace cli { { out << std::setw(45) << fc::variant(tine.block_id).as_string(); - auto delegate_record = _client->get_chain()->get_account_record(tine.signing_delegate); + auto delegate_record = client->get_chain()->get_account_record(tine.signing_delegate); if(delegate_record.valid() && delegate_record->name.size() < 29) out << std::setw(30) << delegate_record->name; else if(tine.signing_delegate > 0) @@ -554,7 +577,7 @@ namespace bts { namespace cli { } } - void print_result::f_blockchain_list_pending_transactions(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_list_pending_transactions(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto transactions = result.as>(); @@ -585,7 +608,7 @@ namespace bts { namespace cli { } } - void print_result::f_blockchain_list_proposals(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_list_proposals(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto proposals = result.as>(); out << std::left; @@ -603,7 +626,7 @@ namespace bts { namespace cli { for(const auto& prop : proposals) { out << std::setw(10) << prop.id; - auto delegate_rec = _client->get_chain()->get_account_record(prop.submitting_delegate_id); + auto delegate_rec = client->get_chain()->get_account_record(prop.submitting_delegate_id); out << std::setw(20) << pretty_shorten(delegate_rec->name, 19); out << std::setw(20) << pretty_timestamp(prop.submission_date); out << std::setw(15) << pretty_shorten(prop.proposal_type, 14); @@ -615,7 +638,7 @@ namespace bts { namespace cli { out << "\n"; } - void print_result::f_blockchain_market_order_book(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_market_order_book(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto bids_asks = result.as, vector>>(); vector filtered_shorts; @@ -651,14 +674,14 @@ namespace bts { namespace cli { base_id = ask_itr->get_price().base_asset_id; } - auto quote_asset_record = _client->get_chain()->get_asset_record(quote_id); + auto quote_asset_record = client->get_chain()->get_asset_record(quote_id); // fee order is the market order to convert fees from other asset classes to XTS bool show_fee_order_record = base_id == 0 && !quote_asset_record->is_market_issued() && quote_asset_record->collected_fees > 0; - oprice median_price = _client->get_chain()->get_median_delegate_price(quote_id); - auto status = _client->get_chain()->get_market_status(quote_id, base_id); + 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)); @@ -684,7 +707,7 @@ namespace bts { namespace cli { if(show_fee_order_record) { - out << std::left << std::setw(26) << _client->get_chain()->to_pretty_asset(asset(quote_asset_record->collected_fees, quote_id)) + out << std::left << std::setw(26) << client->get_chain()->to_pretty_asset(asset(quote_asset_record->collected_fees, quote_id)) << std::setw(20) << " " << std::right << std::setw(30) << "MARKET PRICE"; @@ -694,12 +717,12 @@ namespace bts { namespace cli { else if(bid_itr != bids_asks.first.end()) { out << std::left << std::setw(26) << (bid_itr->type == bts::blockchain::bid_order ? - _client->get_chain()->to_pretty_asset(bid_itr->get_balance()) - : _client->get_chain()->to_pretty_asset(bid_itr->get_quote_quantity())) + client->get_chain()->to_pretty_asset(bid_itr->get_balance()) + : client->get_chain()->to_pretty_asset(bid_itr->get_quote_quantity())) << std::setw(20) << (bid_itr->type == bts::blockchain::bid_order ? - _client->get_chain()->to_pretty_asset(bid_itr->get_quantity()) - : _client->get_chain()->to_pretty_asset(bid_itr->get_balance())) - << std::right << std::setw(30) << (fc::to_string(_client->get_chain()->to_pretty_price_double(bid_itr->get_price())) + " " + quote_asset_record->symbol); + client->get_chain()->to_pretty_asset(bid_itr->get_quantity()) + : client->get_chain()->to_pretty_asset(bid_itr->get_balance())) + << std::right << std::setw(30) << (fc::to_string(client->get_chain()->to_pretty_price_double(bid_itr->get_price())) + " " + quote_asset_record->symbol); if(bid_itr->type == bts::blockchain::short_order) out << '*'; @@ -717,9 +740,9 @@ namespace bts { namespace cli { { if(!ask_itr->collateral) { - out << std::left << std::setw(30) << (fc::to_string(_client->get_chain()->to_pretty_price_double(ask_itr->get_price())) + " " + quote_asset_record->symbol) - << std::right << std::setw(23) << _client->get_chain()->to_pretty_asset(ask_itr->get_quantity()) - << std::right << std::setw(26) << _client->get_chain()->to_pretty_asset(ask_itr->get_quote_quantity()); + out << std::left << std::setw(30) << (fc::to_string(client->get_chain()->to_pretty_price_double(ask_itr->get_price())) + " " + quote_asset_record->symbol) + << std::right << std::setw(23) << client->get_chain()->to_pretty_asset(ask_itr->get_quantity()) + << std::right << std::setw(26) << client->get_chain()->to_pretty_asset(ask_itr->get_quote_quantity()); ++ask_itr; break; } @@ -749,12 +772,12 @@ namespace bts { namespace cli { if(bid_itr != filtered_shorts.end()) { out << std::left << std::setw(26) << (bid_itr->type == bts::blockchain::bid_order ? - _client->get_chain()->to_pretty_asset(bid_itr->get_balance()) - : _client->get_chain()->to_pretty_asset(bid_itr->get_quote_quantity())) + client->get_chain()->to_pretty_asset(bid_itr->get_balance()) + : client->get_chain()->to_pretty_asset(bid_itr->get_quote_quantity())) << std::setw(20) << (bid_itr->type == bts::blockchain::bid_order ? - _client->get_chain()->to_pretty_asset(bid_itr->get_quantity()) - : _client->get_chain()->to_pretty_asset(bid_itr->get_balance())) - << std::right << std::setw(30) << (fc::to_string(_client->get_chain()->to_pretty_price_double(bid_itr->get_price())) + " " + quote_asset_record->symbol) + client->get_chain()->to_pretty_asset(bid_itr->get_quantity()) + : client->get_chain()->to_pretty_asset(bid_itr->get_balance())) + << std::right << std::setw(30) << (fc::to_string(client->get_chain()->to_pretty_price_double(bid_itr->get_price())) + " " + quote_asset_record->symbol) << "*"; } else @@ -766,10 +789,10 @@ namespace bts { namespace cli { ++ask_itr; if(ask_itr != bids_asks.second.rend()) { - out << std::left << std::setw(30) << std::setprecision(8) << (fc::to_string(_client->get_chain()->to_pretty_price_double(ask_itr->get_price())) + " " + quote_asset_record->symbol) - << std::right << std::setw(23) << _client->get_chain()->to_pretty_asset(ask_itr->get_quantity()) - << std::right << std::setw(26) << _client->get_chain()->to_pretty_asset(ask_itr->get_quote_quantity()); - out << " " << _client->get_chain()->to_pretty_asset(asset(*ask_itr->collateral)); + out << std::left << std::setw(30) << std::setprecision(8) << (fc::to_string(client->get_chain()->to_pretty_price_double(ask_itr->get_price())) + " " + quote_asset_record->symbol) + << std::right << std::setw(23) << client->get_chain()->to_pretty_asset(ask_itr->get_quantity()) + << std::right << std::setw(26) << client->get_chain()->to_pretty_asset(ask_itr->get_quote_quantity()); + out << " " << client->get_chain()->to_pretty_asset(asset(*ask_itr->collateral)); out << "\n"; } else @@ -782,21 +805,21 @@ namespace bts { namespace cli { } } - auto recent_average_price = _client->get_chain()->get_market_status(quote_id, base_id)->avg_price_1h; + auto recent_average_price = client->get_chain()->get_market_status(quote_id, base_id)->avg_price_1h; out << "Average Price in Recent Trades: " - << _client->get_chain()->to_pretty_price(recent_average_price) + << client->get_chain()->to_pretty_price(recent_average_price) << " "; - auto status = _client->get_chain()->get_market_status(quote_id, base_id); + auto status = client->get_chain()->get_market_status(quote_id, base_id); if(status) { out << "Maximum Short Price: " - << _client->get_chain()->to_pretty_price(max_short_price) + << client->get_chain()->to_pretty_price(max_short_price) << " "; - out << "Bid Depth: " << _client->get_chain()->to_pretty_asset(asset(status->bid_depth, base_id)) << " "; - out << "Ask Depth: " << _client->get_chain()->to_pretty_asset(asset(status->ask_depth, base_id)) << " "; - out << "Min Depth: " << _client->get_chain()->to_pretty_asset(asset(BTS_BLOCKCHAIN_MARKET_DEPTH_REQUIREMENT)) << "\n"; + out << "Bid Depth: " << client->get_chain()->to_pretty_asset(asset(status->bid_depth, base_id)) << " "; + out << "Ask Depth: " << client->get_chain()->to_pretty_asset(asset(status->ask_depth, base_id)) << " "; + out << "Min Depth: " << client->get_chain()->to_pretty_asset(asset(BTS_BLOCKCHAIN_MARKET_DEPTH_REQUIREMENT)) << "\n"; if(status->last_error) { out << "Last Error: "; @@ -814,7 +837,7 @@ namespace bts { namespace cli { } // end call section that only applies to market issued assets vs XTS else { - auto status = _client->get_chain()->get_market_status(quote_id, base_id); + auto status = client->get_chain()->get_market_status(quote_id, base_id); if(status->last_error) { out << "Last Error: "; @@ -828,7 +851,7 @@ namespace bts { namespace cli { } } - void print_result::f_blockchain_market_order_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_market_order_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { vector orders = result.as>(); if(orders.empty()) @@ -849,25 +872,25 @@ namespace bts { namespace cli { for(order_history_record order : orders) { out << std::setw(7) << "Buy " - << std::setw(30) << _client->get_chain()->to_pretty_price(order.bid_price) - << std::setw(25) << _client->get_chain()->to_pretty_asset(order.bid_paid) - << std::setw(25) << _client->get_chain()->to_pretty_asset(order.bid_received) - << std::setw(20) << _client->get_chain()->to_pretty_asset(order.bid_paid - order.ask_received) + << std::setw(30) << client->get_chain()->to_pretty_price(order.bid_price) + << std::setw(25) << client->get_chain()->to_pretty_asset(order.bid_paid) + << std::setw(25) << client->get_chain()->to_pretty_asset(order.bid_received) + << std::setw(20) << client->get_chain()->to_pretty_asset(order.bid_paid - order.ask_received) << std::setw(23) << pretty_timestamp(order.timestamp) << std::setw(37) << string(order.bid_owner) << "\n" << std::setw(7) << "Sell " - << std::setw(30) << _client->get_chain()->to_pretty_price(order.ask_price) - << std::setw(25) << _client->get_chain()->to_pretty_asset(order.ask_paid) - << std::setw(25) << _client->get_chain()->to_pretty_asset(order.ask_received) - << std::setw(20) << _client->get_chain()->to_pretty_asset(order.ask_paid - order.bid_received) + << std::setw(30) << client->get_chain()->to_pretty_price(order.ask_price) + << std::setw(25) << client->get_chain()->to_pretty_asset(order.ask_paid) + << std::setw(25) << client->get_chain()->to_pretty_asset(order.ask_received) + << std::setw(20) << client->get_chain()->to_pretty_asset(order.ask_paid - order.bid_received) << std::setw(30) << pretty_timestamp(order.timestamp) << " " << string(order.ask_owner) << "\n"; } } - void print_result::f_blockchain_market_price_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_blockchain_market_price_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { market_history_points points = result.as(); if(points.empty()) @@ -892,7 +915,7 @@ namespace bts { namespace cli { << 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)); + << 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; else @@ -901,7 +924,7 @@ namespace bts { namespace cli { } } - void print_result::f_network_list_potential_peers(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + void print_result::f_network_list_potential_peers(std::ostream& out, const fc::variants& arguments, const fc::variant& result, cptr client ) { auto peers = result.as>(); out << std::setw(25) << "ENDPOINT"; diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index d3c276475..beac45b7c 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -1935,14 +1935,17 @@ config load_config( const fc::path& datadir ) { return _wallet->list_accounts(); } + vector detail::client_impl::wallet_list_my_accounts() const { return _wallet->list_my_accounts(); } + vector detail::client_impl::wallet_list_favorite_accounts() const { return _wallet->list_favorite_accounts(); } + vector detail::client_impl::wallet_list_unregistered_accounts() const { return _wallet->list_unregistered_accounts(); @@ -2852,16 +2855,15 @@ config load_config( const fc::path& datadir ) namespace detail { void client_impl::wallet_add_contact_account( const string& account_name, - const public_key_type& contact_key ) + const public_key_type& contact_key ) { _wallet->add_contact_account( account_name, contact_key ); _wallet->auto_backup( "account_add" ); } public_key_type client_impl::wallet_account_create( const string& account_name, - const variant& private_data ) + const variant& private_data ) { - ilog( "CLIENT: creating account '${account_name}'", ("account_name",account_name) ); const auto result = _wallet->create_account( account_name, private_data ); _wallet->auto_backup( "account_create" ); return result; diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 5682eb4e1..8a51a6a62 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2080,8 +2080,8 @@ namespace bts { namespace wallet { return my->_wallet_db.lookup_setting(name); } - public_key_type wallet::create_account( const string& account_name, - const variant& private_data ) + public_key_type wallet::create_account( const string& account_name, + const variant& private_data ) { try { if( !is_valid_account_name( account_name ) ) FC_THROW_EXCEPTION( invalid_name, "Invalid account name!", ("account_name",account_name) ); @@ -5841,17 +5841,18 @@ namespace bts { namespace wallet { } FC_RETHROW_EXCEPTIONS( warn, "", ("account_name",account_name) ) } owallet_account_record wallet::get_account_record( const address& addr)const - { + { try { + FC_ASSERT( is_open() ); return my->_wallet_db.lookup_account( addr ); - } + } FC_RETHROW_EXCEPTIONS( warn, "" ) } owallet_account_record wallet::get_account_for_address( address addr_in_account )const - { - auto okey = my->_wallet_db.lookup_key( addr_in_account ); - if (! okey.valid() ) - return owallet_account_record(); - return get_account_record( okey->account_address ); - } + { try { + FC_ASSERT( is_open() ); + const auto okey = my->_wallet_db.lookup_key( addr_in_account ); + if ( !okey.valid() ) return owallet_account_record(); + return get_account_record( okey->account_address ); + } FC_RETHROW_EXCEPTIONS( warn, "" ) } account_balance_record_summary_type wallet::get_account_balance_records( const string& account_name )const { try { diff --git a/programs/web_wallet b/programs/web_wallet index a4ccce1e1..57eca201f 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit a4ccce1e196c9ab772b429c4dac5cde95856ce4f +Subproject commit 57eca201f4983a4f513be284b22106831dd56622 diff --git a/tests/dev_tests.cpp b/tests/dev_tests.cpp index 50d91e9b4..eb6d9730f 100644 --- a/tests/dev_tests.cpp +++ b/tests/dev_tests.cpp @@ -230,7 +230,7 @@ BOOST_FIXTURE_TEST_CASE( basic_commands, chain_fixture ) exec( clienta, "wallet_account_transaction_history b-account" ); wlog( "------------------ CLIENT B -----------------------------------" ); exec( clientb, "wallet_account_transaction_history b-account" ); - exec( clientb, "wallet_create_account c-account" ); + exec( clientb, "wallet_account_create c-account" ); exec( clientb, "wallet_transfer 10 XTS b-account c-account to-me" ); exec( clientb, "wallet_account_transaction_history b-account" ); exec( clientb, "wallet_account_transaction_history c-account" ); diff --git a/tests/regression_tests/stolen_names/client0.log b/tests/regression_tests/stolen_names/client0.log index 5683b0401..f27eb3cc4 100644 --- a/tests/regression_tests/stolen_names/client0.log +++ b/tests/regression_tests/stolen_names/client0.log @@ -1,5 +1,4 @@ -default (unlocked) >>> wallet_create_account thief - +default (unlocked) >>> wallet_account_create thief 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:thief:XTS5drpKagoTFiMsg1urDXvrtY7Fkuyb4vkgBUCxrsnrer8ioRGrp diff --git a/tests/regression_tests/stolen_names/client1.log b/tests/regression_tests/stolen_names/client1.log index 21ebbb46c..28f10c55c 100644 --- a/tests/regression_tests/stolen_names/client1.log +++ b/tests/regression_tests/stolen_names/client1.log @@ -1,5 +1,4 @@ -default (unlocked) >>> wallet_create_account thief - +default (unlocked) >>> wallet_account_create thief 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:thief:XTS75ngXKr5VCgxFU6iQTkwQzXXYwQz5em6AwEtH6hAzo4sW5j81v diff --git a/tests/regression_tests/titan/client0.log b/tests/regression_tests/titan/client0.log index 43b77cdfd..479147f3f 100644 --- a/tests/regression_tests/titan/client0.log +++ b/tests/regression_tests/titan/client0.log @@ -6,7 +6,6 @@ default (unlocked) >>> wallet_add_contact_account account-for-client1 "XTS5qLJBG OK 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 diff --git a/tests/regression_tests/wallet_get_setting/wallet_get_setting.log b/tests/regression_tests/wallet_get_setting/wallet_get_setting.log index 0758bf679..da8c4d44e 100644 --- a/tests/regression_tests/wallet_get_setting/wallet_get_setting.log +++ b/tests/regression_tests/wallet_get_setting/wallet_get_setting.log @@ -8,25 +8,25 @@ Parameters: Returns: optional_variant -default (unlocked) >>> wallet_set_setting abc 12345678 +default (unlocked) >>> wallet_set_setting abc "12345678" OK -default (unlocked) >>> wallet_set_setting 123 2 +default (unlocked) >>> wallet_set_setting 123 "2" OK -default (unlocked) >>> wallet_set_setting 1 abcd +default (unlocked) >>> wallet_set_setting 1 "abcd" OK -default (unlocked) >>> wallet_set_setting ac y +default (unlocked) >>> wallet_set_setting ac "y" OK default (unlocked) >>> wallet_get_setting abc { "index": 8, "name": "abc", - "value": 12345678 + "value": "12345678" } default (unlocked) >>> wallet_get_setting 123 { "index": 9, "name": "123", - "value": 2 + "value": "2" } default (unlocked) >>> wallet_get_setting 1 { @@ -40,13 +40,13 @@ default (unlocked) >>> wallet_get_setting ac "name": "ac", "value": "y" } -default (unlocked) >>> wallet_set_setting abc HHH +default (unlocked) >>> wallet_set_setting abc "HHH" OK -default (unlocked) >>> wallet_set_setting 123 F2 +default (unlocked) >>> wallet_set_setting 123 false OK -default (unlocked) >>> wallet_set_setting 1 12345 +default (unlocked) >>> wallet_set_setting 1 0 OK -default (unlocked) >>> wallet_set_setting ac 1 +default (unlocked) >>> wallet_set_setting ac null OK default (unlocked) >>> wallet_get_setting abc { @@ -58,18 +58,18 @@ default (unlocked) >>> wallet_get_setting 123 { "index": 9, "name": "123", - "value": "F2" + "value": false } default (unlocked) >>> wallet_get_setting 1 { "index": 10, "name": "1", - "value": 12345 + "value": 0 } default (unlocked) >>> wallet_get_setting ac { "index": 11, "name": "ac", - "value": 1 + "value": null } default (unlocked) >>> quit diff --git a/tests/regression_tests/wallet_import_keyhotee/wallet_import_keyhotee.log b/tests/regression_tests/wallet_import_keyhotee/wallet_import_keyhotee.log index 7abf58d15..d2829534e 100644 --- a/tests/regression_tests/wallet_import_keyhotee/wallet_import_keyhotee.log +++ b/tests/regression_tests/wallet_import_keyhotee/wallet_import_keyhotee.log @@ -12,28 +12,53 @@ Parameters: Returns: void +default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" t +Successfully imported Keyhotee private key. + +OK default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" tk +Successfully imported Keyhotee private key. + OK default (unlocked) >>> wallet_list_accounts NAME (* delegate) KEY REGISTERED FAVORITE APPROVAL +t XTS6XzybdQrxwJ55UpRrrr6QSEFPFmYSqSzeDhiTnkrhJDy7Dh38Y NO NO 0 tk XTS5BxdForQtZ33z1nuvXeNVsappJ9J7MHibzd1XyvbmxezsdZpxz NO NO 0 default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" tk +Successfully imported Keyhotee private key. + OK default (unlocked) >>> wallet_list_accounts NAME (* delegate) KEY REGISTERED FAVORITE APPROVAL +t XTS6XzybdQrxwJ55UpRrrr6QSEFPFmYSqSzeDhiTnkrhJDy7Dh38Y NO NO 0 tk XTS5BxdForQtZ33z1nuvXeNVsappJ9J7MHibzd1XyvbmxezsdZpxz NO NO 0 default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" tk +Successfully imported Keyhotee private key. + OK default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" tk1 +Successfully imported Keyhotee private key. + OK default (unlocked) >>> wallet_list_accounts NAME (* delegate) KEY REGISTERED FAVORITE APPROVAL +t XTS6XzybdQrxwJ55UpRrrr6QSEFPFmYSqSzeDhiTnkrhJDy7Dh38Y NO NO 0 tk XTS5BxdForQtZ33z1nuvXeNVsappJ9J7MHibzd1XyvbmxezsdZpxz NO NO 0 tk1 XTS5Vv5BDUdGhqxh7bsKt71QDpo5vFuJFM3nMu3izoMBG6caCPW55 NO NO 0 default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" tk1* -OK +Command failed with exception: invalid account name (20017) +Invalid Keyhotee name! +error creating private key using keyhotee info. + + + default (unlocked) >>> wallet_import_keyhotee F M L "Hello World123$$$" t* -OK +Command failed with exception: invalid account name (20017) +Invalid Keyhotee name! +error creating private key using keyhotee info. + + + default (unlocked) >>> wallet_list_accounts NAME (* delegate) KEY REGISTERED FAVORITE APPROVAL t XTS6XzybdQrxwJ55UpRrrr6QSEFPFmYSqSzeDhiTnkrhJDy7Dh38Y NO NO 0 diff --git a/tests/wallet_tests.cpp b/tests/wallet_tests.cpp index ccc65a562..8c0f424b9 100644 --- a/tests/wallet_tests.cpp +++ b/tests/wallet_tests.cpp @@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE( master_test ) std::cerr << clienta->execute_command_line( "wallet_account_transaction_history b-account" ) << "\n"; wlog( "------------------ CLIENT B -----------------------------------" ); std::cerr << clientb->execute_command_line( "wallet_account_transaction_history b-account" ) << "\n"; - std::cerr << clientb->execute_command_line( "wallet_create_account c-account" ) << "\n"; + std::cerr << clientb->execute_command_line( "wallet_account_create c-account" ) << "\n"; std::cerr << clientb->execute_command_line( "wallet_transfer 10 XTS b-account c-account to-me" ) << "\n"; std::cerr << clientb->execute_command_line( "wallet_account_transaction_history b-account" ) << "\n"; std::cerr << clientb->execute_command_line( "wallet_account_transaction_history c-account" ) << "\n"; From 585fd30b389fd3de2331e257ad647af855d8926d Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 16:20:29 -0400 Subject: [PATCH 20/25] Fix some regression tests --- .../simple_wallet_commands/simple_wallet_commands.log | 1 - tests/regression_tests/validate_address/validate_address.log | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/regression_tests/simple_wallet_commands/simple_wallet_commands.log b/tests/regression_tests/simple_wallet_commands/simple_wallet_commands.log index a622f87fa..9fd79ee51 100644 --- a/tests/regression_tests/simple_wallet_commands/simple_wallet_commands.log +++ b/tests/regression_tests/simple_wallet_commands/simple_wallet_commands.log @@ -21,7 +21,6 @@ wallet (unlocked) >>> wallet_set_automatic_backups false false wallet (unlocked) >>> wallet_account_create testaccount - 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:testaccount:XTS5drpKagoTFiMsg1urDXvrtY7Fkuyb4vkgBUCxrsnrer8ioRGrp wallet (unlocked) >>> wallet_account_balance testaccount diff --git a/tests/regression_tests/validate_address/validate_address.log b/tests/regression_tests/validate_address/validate_address.log index 1ff1a4ad2..aed05602f 100644 --- a/tests/regression_tests/validate_address/validate_address.log +++ b/tests/regression_tests/validate_address/validate_address.log @@ -4,7 +4,7 @@ validate_address
Return information about given BitShares address Parameters: - address (std::string, required): the address or public key to validate + address (string, required): the address or public key to validate Returns: json_object From 184911bf958004263ea65824cfe2fee72bb811fa Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Wed, 10 Sep 2014 17:08:07 -0400 Subject: [PATCH 21/25] Mail client stuff, including a new inbox feature! --- libraries/api/mail_api.json | 25 +++++- libraries/api/types.json | 5 ++ .../cli/include/bts/cli/print_result.hpp | 1 + libraries/cli/print_result.cpp | 35 +++++++- libraries/client/client.cpp | 12 +++ libraries/mail/client.cpp | 87 +++++++++++++++---- libraries/mail/include/bts/mail/client.hpp | 21 ++++- 7 files changed, 161 insertions(+), 25 deletions(-) diff --git a/libraries/api/mail_api.json b/libraries/api/mail_api.json index 5a064dfc9..03a534826 100644 --- a/libraries/api/mail_api.json +++ b/libraries/api/mail_api.json @@ -76,6 +76,15 @@ "is_const" : true, "prerequisites" : ["json_authenticated"] }, + { + "method_name": "mail_inbox", + "description": "Get headers of all messages in the inbox.", + "return_type": "message_header_list", + "parameters" : [], + "is_const" : true, + "prerequisites" : ["json_authenticated"], + "aliases" : ["inbox"] + }, { "method_name": "mail_retry_send", "description": "Retries sending the specified message.", @@ -91,7 +100,7 @@ }, { "method_name": "mail_remove_message", - "description": "Removes the message from the local database", + "description": "Removes the message from the local database.", "return_type": "void", "parameters" : [ { @@ -102,6 +111,20 @@ ], "prerequisites" : ["json_authenticated"] }, + { + "method_name": "mail_archive_message", + "description": "Removes the message from the inbox.", + "return_type": "void", + "parameters" : [ + { + "name" : "message_id", + "type" : "message_id", + "description" : "ID of the message to archive." + } + ], + "prerequisites" : ["json_authenticated"], + "aliases" : ["archive"] + }, { "method_name": "mail_check_new_messages", "description": "Check mail server for new mail.", diff --git a/libraries/api/types.json b/libraries/api/types.json index 2df165c96..e9181cc2b 100644 --- a/libraries/api/types.json +++ b/libraries/api/types.json @@ -647,6 +647,11 @@ "type_name" : "email_record", "cpp_return_type" : "bts::mail::email_record", "cpp_include_file" : "bts/mail/client.hpp" + }, + { + "type_name" : "message_header_list", + "cpp_return_type" : "std::vector", + "cpp_include_file" : "bts/mail/client.hpp" } ] } diff --git a/libraries/cli/include/bts/cli/print_result.hpp b/libraries/cli/include/bts/cli/print_result.hpp index 3bb989bdd..77e646fac 100644 --- a/libraries/cli/include/bts/cli/print_result.hpp +++ b/libraries/cli/include/bts/cli/print_result.hpp @@ -43,6 +43,7 @@ namespace bts { namespace cli { static void f_blockchain_market_price_history(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void f_network_list_potential_peers(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void f_mail_get_message(std::ostream& out, const fc::variants& arguments, const fc::variant& result); + static void f_mail_inbox(std::ostream& out, const fc::variants& arguments, const fc::variant& result); static void print_network_usage_graph(std::ostream& out, const std::vector& usage_data); static void print_registered_account_list(std::ostream& out, const vector& account_records, int32_t count); diff --git a/libraries/cli/print_result.cpp b/libraries/cli/print_result.cpp index 4cde71577..6c1713921 100644 --- a/libraries/cli/print_result.cpp +++ b/libraries/cli/print_result.cpp @@ -189,6 +189,7 @@ namespace bts { namespace cli { out << _client->get_chain()->to_pretty_asset(result.as()) << "\n"; }; _command_to_function["mail_get_message"] = &f_mail_get_message; + _command_to_function["mail_inbox"] = &f_mail_inbox; } void print_result::f_wallet_account_create(std::ostream& out, const fc::variants& arguments, const fc::variant& result) @@ -938,9 +939,9 @@ namespace bts { namespace cli { content = email.content.as(); out << "=== Email Message ===" - "\nFrom: " << email.sender - << "\nTo: " << email.recipient - << "\nDate: " << pretty_timestamp(email.content.timestamp) + "\nFrom: " << email.header.sender + << "\nTo: " << email.header.recipient + << "\nDate: " << pretty_timestamp(email.header.timestamp) << "\nSubject: " << content.subject << "\n\n" << content.body << "\n"; @@ -950,6 +951,34 @@ namespace bts { namespace cli { } } + void print_result::f_mail_inbox(std::ostream& out, const fc::variants& arguments, const fc::variant& result) + { + vector inbox = result.as>(); + if (inbox.empty()) + { + out << "No new mail. Why not go check out the BitUSD markets?\n"; + return; + } + + out << std::left + << std::setw(45) << "ID" + << std::setw(20) << "FROM" + << std::setw(20) << "TO" + << std::setw(61) << "SUBJECT" + << std::setw(19) << "DATE" + << "\n" << string(165, '-') << "\n"; + + for (email_header header : inbox) + { + out << std::setw(45) << header.id.str() + << std::setw(20) << pretty_shorten(header.sender, 19) + << std::setw(20) << pretty_shorten(header.recipient, 19) + << std::setw(61) << pretty_shorten(header.subject, 60) + << std::setw(19) << pretty_timestamp(header.timestamp) + << "\n"; + } + } + } } // else diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index f0c3556e4..580d1353a 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -2416,6 +2416,12 @@ config load_config( const fc::path& datadir ) return _mail_client->get_archive_messages(); } + vector detail::client_impl::mail_inbox() const + { + FC_ASSERT(_mail_client); + return _mail_client->get_inbox(); + } + void detail::client_impl::mail_retry_send(const message_id_type& message_id) { FC_ASSERT(_mail_client); @@ -2428,6 +2434,12 @@ config load_config( const fc::path& datadir ) _mail_client->remove_message(message_id); } + void detail::client_impl::mail_archive_message(const message_id_type &message_id) + { + FC_ASSERT(_mail_client); + _mail_client->archive_message(message_id); + } + void detail::client_impl::mail_check_new_messages() { FC_ASSERT(_mail_client); diff --git a/libraries/mail/client.cpp b/libraries/mail/client.cpp index 7b9ff56f9..a869db857 100644 --- a/libraries/mail/client.cpp +++ b/libraries/mail/client.cpp @@ -59,11 +59,11 @@ struct mail_archive_record { content(std::move(from_record.content)), mail_servers(std::move(from_record.mail_servers)) {} - mail_archive_record(message&& from_message, string&& sender, const string& recipient, const address& recipient_address) + mail_archive_record(message&& from_message, const email_header& header, const address& recipient_address) : id(from_message.id()), status(client::received), - sender(std::move(sender)), - recipient(recipient), + sender(header.sender), + recipient(header.recipient), recipient_address(recipient_address), content(std::move(from_message)) {} @@ -91,6 +91,7 @@ class client_impl { bts::db::cached_level_map _processing_db; bts::db::level_map _archive; + bts::db::cached_level_map _inbox; bts::db::level_map _property_db; client_impl(client* self, wallet_ptr wallet, chain_database_ptr chain) @@ -103,6 +104,7 @@ class client_impl { _archive.close(); _processing_db.close(); + _inbox.close(); _property_db.close(); } @@ -130,6 +132,7 @@ class client_impl { try { _archive.open(data_dir / "archive"); _processing_db.open(data_dir / "processing"); + _inbox.open(data_dir / "inbox"); _property_db.open(data_dir / "properties"); if (!_property_db.fetch_optional("version")) @@ -332,6 +335,7 @@ class client_impl { void finalize_message(message_id_type message_id) { ulog("Email ${id} sent successfully.", ("id", message_id)); mail_record email = _processing_db.fetch(message_id); + email.status = client::accepted; _archive.store(message_id, std::move(email)); _processing_db.remove(message_id); } @@ -349,13 +353,13 @@ class client_impl { email_record decrypted_email_record(mail_record&& email) { if (email.content.type != encrypted) return email; - email.content = _wallet->mail_decrypt(email.recipient_key, email.content); + email.content = _wallet->mail_open(email.recipient_key, email.content); return email; } email_record decrypted_email_record(mail_archive_record&& email) { if (email.content.type != encrypted) return email; - email.content = _wallet->mail_decrypt(email.recipient_address, email.content); + email.content = _wallet->mail_open(email.recipient_address, email.content); return email; } @@ -367,6 +371,21 @@ class client_impl { FC_ASSERT(false, "Message ${id} not found.", ("id", message_id)); } + vector get_inbox() { + vector inbox; + for (auto itr = _inbox.begin(); itr.valid(); ++itr) + inbox.push_back(itr.value()); + std::sort(inbox.begin(), inbox.end(), [](const email_header& a, const email_header& b) { + return a.timestamp < b.timestamp; + }); + return inbox; + } + + void archive_message(message_id_type message_id) { + if (_inbox.fetch_optional(message_id)) + _inbox.remove(message_id); + } + void check_new_mail() { auto accounts = _wallet->list_my_accounts(); for (wallet_account_record account : accounts) { @@ -433,12 +452,17 @@ class client_impl { message ciphertext = response["result"].as(); message plaintext = _wallet->mail_open(account.account_address, ciphertext); - string sender = "ANONYMOUS"; - if (plaintext.type == mail::email) - if( auto op = _chain->get_account_record(plaintext.as().from())) - sender = op->name; - mail_archive_record record(std::move(ciphertext), std::move(sender), account.name, account.account_address); + email_header header; + header.id = ciphertext.id(); + if (plaintext.type == mail::email) { + header.sender = _wallet->get_key_label(plaintext.as().from()); + header.subject = plaintext.as().subject; + } + header.recipient = account.name; + header.timestamp = plaintext.timestamp; + mail_archive_record record(std::move(ciphertext), header, account.account_address); _archive.store(email.second, record); + _inbox.store(header.id, header); } } }, "Mail client fetcher")); @@ -449,7 +473,7 @@ class client_impl { ulog("Timed out fetching new mail."); for (auto task_future : fetch_tasks) task_future.cancel(); - }, fc::time_point::now() + fc::seconds(10), "Mail client fetcher timeout"); + }, fc::time_point::now() + fc::seconds(60), "Mail client fetcher timeout"); while (!fetch_tasks.empty()) { fetch_tasks.back().wait(); @@ -498,6 +522,12 @@ void client::remove_message(message_id_type message_id) } } +void client::archive_message(message_id_type message_id_type) +{ + FC_ASSERT(my->is_open()); + my->archive_message(message_id_type); +} + void client::check_new_messages() { FC_ASSERT(my->is_open()); @@ -515,6 +545,12 @@ std::multimap client::get_archive_messages return my->get_database_messages(my->_archive); } +std::vector client::get_inbox() +{ + FC_ASSERT(my->is_open()); + return my->get_inbox(); +} + email_record client::get_message(message_id_type message_id) { FC_ASSERT(my->is_open()); return my->get_message(message_id); @@ -539,23 +575,40 @@ message_id_type client::send_email(const string &from, const string &to, const s return email.id; } -email_record::email_record(const detail::mail_record& processing_record) +email_header::email_header(const detail::mail_record &processing_record) : id(processing_record.id), - status(processing_record.status), sender(processing_record.sender), recipient(processing_record.recipient), + timestamp(processing_record.content.timestamp) +{ + if (processing_record.content.type == email) + subject = processing_record.content.as().subject; +} + +email_header::email_header(const detail::mail_archive_record& archive_record) + : id(archive_record.id), + sender(archive_record.sender), + recipient(archive_record.recipient), + timestamp(archive_record.content.timestamp) +{ + if (archive_record.content.type == email) + subject = archive_record.content.as().subject; +} + +email_record::email_record(const detail::mail_record& processing_record) + : header(processing_record), content(processing_record.content) { + header.id = processing_record.id; + header.sender = processing_record.sender; + header.recipient = processing_record.recipient; if (processing_record.status >= client::proof_of_work && processing_record.status != client::failed) *mail_servers = processing_record.mail_servers; if (processing_record.status == client::failed) *failure_reason = processing_record.failure_reason; } email_record::email_record(const detail::mail_archive_record& archive_record) - : id(archive_record.id), - status(client::accepted), - sender(archive_record.sender), - recipient(archive_record.recipient), + : header(archive_record), content(archive_record.content), mail_servers(archive_record.mail_servers) {} diff --git a/libraries/mail/include/bts/mail/client.hpp b/libraries/mail/include/bts/mail/client.hpp index ba3afaad4..27a225e8d 100644 --- a/libraries/mail/include/bts/mail/client.hpp +++ b/libraries/mail/include/bts/mail/client.hpp @@ -12,6 +12,7 @@ namespace mail { namespace detail { class client_impl; struct mail_record; struct mail_archive_record; } +struct email_header; struct email_record; class client : public std::enable_shared_from_this { @@ -34,11 +35,13 @@ class client : public std::enable_shared_from_this { void retry_message(message_id_type message_id); void remove_message(message_id_type message_id); + void archive_message(message_id_type message_id_type); void check_new_messages(); std::multimap get_processing_messages(); std::multimap get_archive_messages(); + std::vector get_inbox(); email_record get_message(message_id_type message_id); message_id_type send_email(const string& from, const string& to, const string& subject, const string& body); @@ -46,11 +49,20 @@ class client : public std::enable_shared_from_this { std::shared_ptr my; }; -struct email_record { +struct email_header { fc::ripemd160 id; - client::mail_status status; string sender; string recipient; + string subject; + fc::time_point_sec timestamp; + + email_header(){} + email_header(const detail::mail_record& processing_record); + email_header(const detail::mail_archive_record& archive_record); +}; + +struct email_record { + email_header header; message content; fc::optional> mail_servers; fc::optional failure_reason; @@ -68,5 +80,6 @@ struct email_record { } FC_REFLECT_TYPENAME(bts::mail::client::mail_status) -FC_REFLECT_ENUM(bts::mail::client::mail_status, (submitted)(proof_of_work)(transmitting)(accepted)(failed)) -FC_REFLECT(bts::mail::email_record, (id)(status)(sender)(recipient)(content)(mail_servers)(failure_reason)) +FC_REFLECT_ENUM(bts::mail::client::mail_status, (submitted)(proof_of_work)(transmitting)(accepted)(received)(failed)) +FC_REFLECT(bts::mail::email_header, (id)(sender)(recipient)(subject)(timestamp)) +FC_REFLECT(bts::mail::email_record, (header)(content)(mail_servers)(failure_reason)) From a140c3e43419f3a3dcc606865f23bc8fddbd90d3 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 17:26:51 -0400 Subject: [PATCH 22/25] Unconfirmed ledger entries still show the order ids --- .../include/bts/blockchain/market_records.hpp | 1 + libraries/blockchain/market_records.cpp | 9 +++++++++ libraries/wallet/wallet.cpp | 20 ++++++++++++------- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libraries/blockchain/include/bts/blockchain/market_records.hpp b/libraries/blockchain/include/bts/blockchain/market_records.hpp index d2e9c3340..62651277e 100644 --- a/libraries/blockchain/include/bts/blockchain/market_records.hpp +++ b/libraries/blockchain/include/bts/blockchain/market_records.hpp @@ -145,6 +145,7 @@ namespace bts { namespace blockchain { market_order():type(null_order){} order_id_type get_id()const; + string get_small_id()const; asset get_balance()const; // funds available for this order price get_price()const; price get_highest_cover_price()const; // the price that consumes all collateral diff --git a/libraries/blockchain/market_records.cpp b/libraries/blockchain/market_records.cpp index f56110c27..ba2ecdc37 100644 --- a/libraries/blockchain/market_records.cpp +++ b/libraries/blockchain/market_records.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace bts { namespace blockchain { @@ -13,6 +14,14 @@ order_id_type market_order::get_id()const return fc::ripemd160::hash( id_ss.str() ); } +string market_order::get_small_id()const +{ + string type_prefix = string( type ); + type_prefix = type_prefix.substr( 0, type_prefix.find( "_" ) ); + boost::to_upper( type_prefix ); + return type_prefix + "-" + string( get_id() ).substr( 0, 8 ); +} + asset market_order::get_balance()const { asset_id_type asset_id; diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 02186dc59..9462c9429 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -1055,7 +1055,7 @@ namespace bts { namespace wallet { const auto order = _blockchain->get_market_bid( op.bid_index ); if( order.valid() ) { - okey_rec->memo = "BID-" + string( order->get_id() ).substr( 0, 8 ); + okey_rec->memo = order->get_small_id(); _wallet_db.store_key( *okey_rec ); } else @@ -1117,7 +1117,7 @@ namespace bts { namespace wallet { const auto order = _blockchain->get_market_ask( op.ask_index ); if( order.valid() ) { - okey_rec->memo = "ASK-" + string( order->get_id() ).substr( 0, 8 ); + okey_rec->memo = order->get_small_id(); _wallet_db.store_key( *okey_rec ); } else @@ -1179,7 +1179,7 @@ namespace bts { namespace wallet { const auto order = _blockchain->get_market_short( op.short_index ); if( order.valid() ) { - okey_rec->memo = "SHORT-" + string( order->get_id() ).substr( 0, 8 ); + okey_rec->memo = order->get_small_id(); _wallet_db.store_key( *okey_rec ); } else @@ -3572,7 +3572,7 @@ namespace bts { namespace wallet { entry.memo = fc::to_string(i)+":"+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 = total_fee; //required_fees; @@ -4589,6 +4589,8 @@ namespace bts { namespace wallet { std::stringstream memo; memo << "buy " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + const market_order order( bid_order, market_index_key( quote_price_shares, order_address ), order_record( cost_shares.amount ) ); + auto entry = ledger_entry(); entry.from_account = from_account_key; entry.to_account = order_key; @@ -4602,7 +4604,7 @@ namespace bts { namespace wallet { auto key_rec = my->_wallet_db.lookup_key( order_key ); FC_ASSERT( key_rec.valid() ); - key_rec->memo = "BID"; + key_rec->memo = order.get_small_id(); my->_wallet_db.store_key( *key_rec ); if( sign ) sign_transaction( trx, required_signatures ); @@ -4700,6 +4702,8 @@ namespace bts { namespace wallet { std::stringstream memo; memo << "sell " << base_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + const market_order order( ask_order, market_index_key( quote_price_shares, order_address ), order_record( cost_shares.amount ) ); + auto entry = ledger_entry(); entry.from_account = from_account_key; entry.to_account = order_key; @@ -4713,7 +4717,7 @@ namespace bts { namespace wallet { auto key_rec = my->_wallet_db.lookup_key( order_key ); FC_ASSERT( key_rec.valid() ); - key_rec->memo = "ASK"; + key_rec->memo = order.get_small_id(); my->_wallet_db.store_key( *key_rec ); if( sign ) sign_transaction( trx, required_signatures ); @@ -4794,6 +4798,8 @@ namespace bts { namespace wallet { std::stringstream memo; memo << "short " << quote_asset_record->symbol << " @ " << my->_blockchain->to_pretty_price( quote_price_shares ); + const market_order order( short_order, market_index_key( quote_price_shares, order_address ), order_record( cost_shares.amount ) ); + auto entry = ledger_entry(); entry.from_account = from_account_key; entry.to_account = order_key; @@ -4807,7 +4813,7 @@ namespace bts { namespace wallet { auto key_rec = my->_wallet_db.lookup_key( order_key ); FC_ASSERT( key_rec.valid() ); - key_rec->memo = "SHORT"; + key_rec->memo = order.get_small_id(); my->_wallet_db.store_key( *key_rec ); if( sign ) sign_transaction( trx, required_signatures ); From f0d0da58f793ea1657c24b85851bdd13d80023f7 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 18:01:47 -0400 Subject: [PATCH 23/25] Fix wallet_market_cover --- libraries/api/wallet_api.json | 2 +- libraries/client/client.cpp | 4 ++-- libraries/wallet/wallet.cpp | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/libraries/api/wallet_api.json b/libraries/api/wallet_api.json index 81248b3b7..7a80efe2b 100644 --- a/libraries/api/wallet_api.json +++ b/libraries/api/wallet_api.json @@ -1195,7 +1195,7 @@ "description" : "the type of asset you are covering (ie: USD)" }, { - "name" : "short_id", + "name" : "cover_id", "type" : "order_id", "description" : "the order ID you would like to cover" } diff --git a/libraries/client/client.cpp b/libraries/client/client.cpp index 75e819de8..31189b743 100644 --- a/libraries/client/client.cpp +++ b/libraries/client/client.cpp @@ -3319,9 +3319,9 @@ config load_config( const fc::path& datadir ) const string& from_account, double quantity, const string& quantity_symbol, - const order_id_type& short_id ) + const order_id_type& cover_id ) { - const auto record = _wallet->cover_short( from_account, quantity, quantity_symbol, short_id ); + const auto record = _wallet->cover_short( from_account, quantity, quantity_symbol, cover_id ); network_broadcast_transaction( record.trx ); return record; } diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 9462c9429..2b12232da 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -4879,7 +4879,7 @@ namespace bts { namespace wallet { const string& from_account_name, double real_quantity_usd, const string& quote_symbol, - const order_id_type& short_id, + const order_id_type& cover_id, bool sign ) { try { if( NOT is_open() ) FC_CAPTURE_AND_THROW( wallet_closed ); @@ -4888,9 +4888,18 @@ namespace bts { namespace wallet { FC_CAPTURE_AND_THROW( unknown_receive_account, (from_account_name) ); if( real_quantity_usd < 0 ) FC_CAPTURE_AND_THROW( negative_bid, (real_quantity_usd) ); - const auto order = my->_blockchain->get_market_order( short_id ); + optional order; + const auto covers = my->_blockchain->get_market_covers( quote_symbol ); + for( const auto& cover : covers ) + { + if( cover.get_id() == cover_id ) + { + order = cover; + break; + } + } if( !order.valid() ) - FC_THROW_EXCEPTION( unknown_market_order, "Cannot find that market order!" ); + FC_THROW_EXCEPTION( unknown_market_order, "Cannot find that cover order!" ); const auto owner_address = order->get_owner(); const auto owner_key_record = my->_wallet_db.lookup_key( owner_address ); @@ -4989,7 +4998,7 @@ namespace bts { namespace wallet { cache_transaction( trx, record ); return record; - } FC_CAPTURE_AND_RETHROW( (from_account_name)(real_quantity_usd)(quote_symbol)(short_id)(sign) ) } + } FC_CAPTURE_AND_RETHROW( (from_account_name)(real_quantity_usd)(quote_symbol)(cover_id)(sign) ) } void wallet::set_transaction_fee( const asset& fee ) { try { From f158814ae18c7ee052dff93de3d25d577e8a80a1 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 18:36:03 -0400 Subject: [PATCH 24/25] Update submodules --- programs/qt_wallet | 2 +- programs/web_wallet | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/qt_wallet b/programs/qt_wallet index efa321161..8e2d602d5 160000 --- a/programs/qt_wallet +++ b/programs/qt_wallet @@ -1 +1 @@ -Subproject commit efa321161e508cb1e283c74c7a424b0c4e4b8b35 +Subproject commit 8e2d602d51789795581a41c20d5e54a946205ffd diff --git a/programs/web_wallet b/programs/web_wallet index 57eca201f..b209038d4 160000 --- a/programs/web_wallet +++ b/programs/web_wallet @@ -1 +1 @@ -Subproject commit 57eca201f4983a4f513be284b22106831dd56622 +Subproject commit b209038d477246570f13086b270af562dffbb039 From 11639ebdabf1a5fb5490556c591ba9eaa95c4d96 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 10 Sep 2014 18:44:21 -0400 Subject: [PATCH 25/25] Add checkpoint --- libraries/blockchain/include/bts/blockchain/checkpoints.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/blockchain/include/bts/blockchain/checkpoints.hpp b/libraries/blockchain/include/bts/blockchain/checkpoints.hpp index b7aa023c6..74942a771 100644 --- a/libraries/blockchain/include/bts/blockchain/checkpoints.hpp +++ b/libraries/blockchain/include/bts/blockchain/checkpoints.hpp @@ -6,5 +6,6 @@ const static std::map CHECKPOINT_BLOCK { { 1, bts::blockchain::block_id_type( "8abcfb93c52f999e3ef5288c4f837f4f15af5521" ) }, { 225000, bts::blockchain::block_id_type( "2e09195c3e4ef6d58736151ea22f78f08556e6a9" ) }, - { 442700, bts::blockchain::block_id_type( "c22e2dc1954f7d3a9620048d64587018e98c03f8" ) } + { 442700, bts::blockchain::block_id_type( "c22e2dc1954f7d3a9620048d64587018e98c03f8" ) }, + { 452700, bts::blockchain::block_id_type( "b678b7b86a8b05593df49acc5e8ba62f7177276e" ) } };