diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/wallet/api/subaddress_account.cpp | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 8 | ||||
-rw-r--r-- | src/wallet/message_store.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 50 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 1 | ||||
-rw-r--r-- | src/wallet/wallet_light_rpc.h | 47 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 110 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 38 |
10 files changed, 251 insertions, 13 deletions
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index d0fc21f51..553445a39 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -117,12 +117,14 @@ if (BUILD_GUI_DEPS) wallet_api wallet multisig + blockchain_db cryptonote_core cryptonote_basic mnemonics common cncrypto device + hardforks ringct ringct_basic checkpoints diff --git a/src/wallet/api/subaddress_account.cpp b/src/wallet/api/subaddress_account.cpp index 9bc9d1d91..eaaddc11f 100644 --- a/src/wallet/api/subaddress_account.cpp +++ b/src/wallet/api/subaddress_account.cpp @@ -64,8 +64,8 @@ void SubaddressAccountImpl::refresh() i, m_wallet->m_wallet->get_subaddress_as_str({i,0}), m_wallet->m_wallet->get_subaddress_label({i,0}), - cryptonote::print_money(m_wallet->m_wallet->balance(i)), - cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i)) + cryptonote::print_money(m_wallet->m_wallet->balance(i, false)), + cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i, false)) )); } } diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index e632b8d23..6200c7a1f 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -993,12 +993,12 @@ void WalletImpl::setSubaddressLookahead(uint32_t major, uint32_t minor) uint64_t WalletImpl::balance(uint32_t accountIndex) const { - return m_wallet->balance(accountIndex); + return m_wallet->balance(accountIndex, false); } uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const { - return m_wallet->unlocked_balance(accountIndex); + return m_wallet->unlocked_balance(accountIndex, false); } uint64_t WalletImpl::blockChainHeight() const @@ -1123,6 +1123,10 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this); if (!m_wallet->load_unsigned_tx(unsigned_filename, transaction->m_unsigned_tx_set)){ setStatusError(tr("Failed to load unsigned transactions")); + transaction->m_status = UnsignedTransaction::Status::Status_Error; + transaction->m_errorString = errorString(); + + return transaction; } // Check tx data and construct confirmation message diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index 96d4ef3ce..6e2cb933f 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -699,7 +699,7 @@ void message_store::write_to_file(const multisig_wallet_state &state, const std: crypto::chacha_key key; crypto::generate_chacha_key(&state.view_secret_key, sizeof(crypto::secret_key), key, 1); - file_data write_file_data = boost::value_initialized<file_data>(); + file_data write_file_data = {}; write_file_data.magic_string = "MMS"; write_file_data.file_version = 0; write_file_data.iv = crypto::rand<crypto::chacha_iv>(); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 871eafdeb..4f7b6bbd3 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -32,7 +32,6 @@ #include <tuple> #include <boost/format.hpp> #include <boost/optional/optional.hpp> -#include <boost/utility/value_init.hpp> #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/split.hpp> @@ -1999,7 +1998,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount; if (!pool) { - m_transfers.push_back(boost::value_initialized<transfer_details>()); + m_transfers.push_back(transfer_details{}); transfer_details& td = m_transfers.back(); td.m_block_height = height; td.m_internal_output_index = o; @@ -3080,6 +3079,21 @@ bool wallet2::add_address_book_row(const cryptonote::account_public_address &add return false; } +bool wallet2::set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash &payment_id, const std::string &description, bool is_subaddress) +{ + wallet2::address_book_row a; + a.m_address = address; + a.m_payment_id = payment_id; + a.m_description = description; + a.m_is_subaddress = is_subaddress; + + const auto size = m_address_book.size(); + if (row_id >= size) + return false; + m_address_book[row_id] = a; + return true; +} + bool wallet2::delete_address_book_row(std::size_t row_id) { if(m_address_book.size() <= row_id) return false; @@ -3557,7 +3571,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable bool r = epee::serialization::store_t_to_binary(account, account_data); CHECK_AND_ASSERT_MES(r, false, "failed to serialize wallet keys"); - wallet2::keys_file_data keys_file_data = boost::value_initialized<wallet2::keys_file_data>(); + wallet2::keys_file_data keys_file_data = {}; // Create a JSON object with "key_data" and "seed_language" as keys. rapidjson::Document json; @@ -5530,7 +5544,7 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas boost::archive::portable_binary_oarchive ar(oss); ar << *this; - wallet2::cache_file_data cache_file_data = boost::value_initialized<wallet2::cache_file_data>(); + wallet2::cache_file_data cache_file_data = {}; cache_file_data.cache_data = oss.str(); std::string cipher; cipher.resize(cache_file_data.cache_data.size()); @@ -7457,8 +7471,8 @@ void wallet2::light_wallet_get_outs(std::vector<std::vector<tools::wallet2::get_ MDEBUG("LIGHTWALLET - Getting random outs"); - cryptonote::COMMAND_RPC_GET_RANDOM_OUTS::request oreq; - cryptonote::COMMAND_RPC_GET_RANDOM_OUTS::response ores; + tools::COMMAND_RPC_GET_RANDOM_OUTS::request oreq; + tools::COMMAND_RPC_GET_RANDOM_OUTS::response ores; size_t light_wallet_requested_outputs_count = (size_t)((fake_outputs_count + 1) * 1.5 + 1); @@ -8813,7 +8827,7 @@ void wallet2::light_wallet_get_unspent_outs() if(!add_transfer) continue; - m_transfers.push_back(boost::value_initialized<transfer_details>()); + m_transfers.push_back(transfer_details{}); transfer_details& td = m_transfers.back(); td.m_block_height = o.height; @@ -9786,6 +9800,17 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below std::vector<size_t> unused_dust_indices; const bool use_rct = use_fork_rules(4, 0); + // determine threshold for fractional amount + const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0); + const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0); + const uint64_t base_fee = get_base_fee(); + const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm()); + const size_t tx_weight_one_ring = estimate_tx_weight(use_rct, 1, fake_outs_count, 2, 0, bulletproof); + const size_t tx_weight_two_rings = estimate_tx_weight(use_rct, 2, fake_outs_count, 2, 0, bulletproof); + THROW_WALLET_EXCEPTION_IF(tx_weight_one_ring > tx_weight_two_rings, error::wallet_internal_error, "Estimated tx weight with 1 input is larger than with 2 inputs!"); + const size_t tx_weight_per_ring = tx_weight_two_rings - tx_weight_one_ring; + const uint64_t fractional_threshold = (fee_multiplier * base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024); + THROW_WALLET_EXCEPTION_IF(unlocked_balance(subaddr_account, false) == 0, error::wallet_internal_error, "No unlocked balance in the entire wallet"); std::map<uint32_t, std::pair<std::vector<size_t>, std::vector<size_t>>> unused_transfer_dust_indices_per_subaddr; @@ -9795,6 +9820,11 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below for (size_t i = 0; i < m_transfers.size(); ++i) { const transfer_details& td = m_transfers[i]; + if (m_ignore_fractional_outputs && td.amount() < fractional_threshold) + { + MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold)); + continue; + } if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && (subaddr_indices.empty() || subaddr_indices.count(td.m_subaddr_index.minor) == 1)) { fund_found = true; @@ -13165,6 +13195,12 @@ bool wallet2::save_to_file(const std::string& path_to_file, const std::string& r } FILE *fp = fopen(path_to_file.c_str(), "w+"); + if (!fp) + { + MERROR("Failed to open wallet file for writing: " << path_to_file << ": " << strerror(errno)); + return false; + } + // Save the result b/c we need to close the fp before returning success/failure. int write_result = PEM_write(fp, ASCII_OUTPUT_MAGIC.c_str(), "", (const unsigned char *) raw.c_str(), raw.length()); fclose(fp); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 95f6f507a..1469b4c00 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1098,6 +1098,7 @@ private: */ std::vector<address_book_row> get_address_book() const { return m_address_book; } bool add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash &payment_id, const std::string &description, bool is_subaddress); + bool set_address_book_row(size_t row_id, const cryptonote::account_public_address &address, const crypto::hash &payment_id, const std::string &description, bool is_subaddress); bool delete_address_book_row(std::size_t row_id); uint64_t get_num_rct_outputs(); diff --git a/src/wallet/wallet_light_rpc.h b/src/wallet/wallet_light_rpc.h index 1d35cec33..c2a7dc021 100644 --- a/src/wallet/wallet_light_rpc.h +++ b/src/wallet/wallet_light_rpc.h @@ -317,4 +317,51 @@ namespace tools typedef epee::misc_utils::struct_init<response_t> response; }; //----------------------------------------------- + struct COMMAND_RPC_GET_RANDOM_OUTS + { + struct request_t + { + std::vector<std::string> amounts; + uint32_t count; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amounts) + KV_SERIALIZE(count) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<request_t> request; + + struct output { + std::string public_key; + uint64_t global_index; + std::string rct; // 64+64+64 characters long (<rct commit> + <encrypted mask> + <rct amount>) + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(public_key) + KV_SERIALIZE(global_index) + KV_SERIALIZE(rct) + END_KV_SERIALIZE_MAP() + }; + + struct amount_out { + uint64_t amount; + std::vector<output> outputs; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount) + KV_SERIALIZE(outputs) + END_KV_SERIALIZE_MAP() + }; + + struct response_t + { + std::vector<amount_out> amount_outs; + std::string Error; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_outs) + KV_SERIALIZE(Error) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<response_t> response; + }; + //----------------------------------------------- } diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 896f8f48e..0e0221c03 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -151,6 +151,7 @@ namespace tools if (m_wallet) { m_wallet->store(); + m_wallet->deinit(); delete m_wallet; m_wallet = NULL; } @@ -326,6 +327,7 @@ namespace tools entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; entry.unlock_time = pd.m_unlock_time; + entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height); entry.fee = pd.m_fee; entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.type = pd.m_coinbase ? "block" : "in"; @@ -344,6 +346,7 @@ namespace tools entry.height = pd.m_block_height; entry.timestamp = pd.m_timestamp; entry.unlock_time = pd.m_unlock_time; + entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height); entry.fee = pd.m_amount_in - pd.m_amount_out; uint64_t change = pd.m_change == (uint64_t)-1 ? 0 : pd.m_change; // change may not be known entry.amount = pd.m_amount_in - change - entry.fee; @@ -377,6 +380,7 @@ namespace tools entry.fee = pd.m_amount_in - pd.m_amount_out; entry.amount = pd.m_amount_in - pd.m_change - entry.fee; entry.unlock_time = pd.m_tx.unlock_time; + entry.locked = true; entry.note = m_wallet->get_tx_note(txid); for (const auto &d: pd.m_dests) { @@ -405,6 +409,7 @@ namespace tools entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; entry.unlock_time = pd.m_unlock_time; + entry.locked = true; entry.fee = pd.m_fee; entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.double_spend_seen = ppd.m_double_spend_seen; @@ -1698,6 +1703,7 @@ namespace tools rpc_payment.amount = payment.m_amount; rpc_payment.block_height = payment.m_block_height; rpc_payment.unlock_time = payment.m_unlock_time; + rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height); rpc_payment.subaddr_index = payment.m_subaddr_index; rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); res.payments.push_back(rpc_payment); @@ -1727,6 +1733,7 @@ namespace tools rpc_payment.unlock_time = payment.second.m_unlock_time; rpc_payment.subaddr_index = payment.second.m_subaddr_index; rpc_payment.address = m_wallet->get_subaddress_as_str(payment.second.m_subaddr_index); + rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.second.m_unlock_time, payment.second.m_block_height); res.payments.push_back(std::move(rpc_payment)); } @@ -1781,6 +1788,7 @@ namespace tools rpc_payment.unlock_time = payment.m_unlock_time; rpc_payment.subaddr_index = payment.m_subaddr_index; rpc_payment.address = m_wallet->get_subaddress_as_str(payment.m_subaddr_index); + rpc_payment.locked = !m_wallet->is_transfer_unlocked(payment.m_unlock_time, payment.m_block_height); res.payments.push_back(std::move(rpc_payment)); } } @@ -2816,6 +2824,108 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_edit_address_book(const wallet_rpc::COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + const auto ab = m_wallet->get_address_book(); + if (req.index >= ab.size()) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_INDEX; + er.message = "Index out of range: " + std::to_string(req.index); + return false; + } + + tools::wallet2::address_book_row entry = ab[req.index]; + + cryptonote::address_parse_info info; + crypto::hash payment_id = crypto::null_hash; + if (req.set_address) + { + er.message = ""; + if(!get_account_address_from_str_or_url(info, m_wallet->nettype(), req.address, + [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string { + if (!dnssec_valid) + { + er.message = std::string("Invalid DNSSEC for ") + url; + return {}; + } + if (addresses.empty()) + { + er.message = std::string("No Monero address found at ") + url; + return {}; + } + return addresses[0]; + })) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + if (er.message.empty()) + er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address; + return false; + } + entry.m_address = info.address; + entry.m_is_subaddress = info.is_subaddress; + if (info.has_payment_id) + { + memcpy(entry.m_payment_id.data, info.payment_id.data, 8); + memset(entry.m_payment_id.data + 8, 0, 24); + } + } + + if (req.set_payment_id) + { + if (req.payment_id.empty()) + { + payment_id = crypto::null_hash; + } + else + { + if (req.set_address && info.has_payment_id) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Separate payment ID given with integrated address"; + return false; + } + + if (!wallet2::parse_long_payment_id(req.payment_id, payment_id)) + { + crypto::hash8 spid; + if (!wallet2::parse_short_payment_id(req.payment_id, spid)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Payment id has invalid format: \"" + req.payment_id + "\", expected 64 character string"; + return false; + } + else + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Payment id has invalid format: standalone short payment IDs are forbidden, they must be part of an integrated address"; + return false; + } + } + } + + entry.m_payment_id = payment_id; + } + + if (req.set_description) + entry.m_description = req.description; + + if (!m_wallet->set_address_book_row(req.index, entry.m_address, entry.m_payment_id, entry.m_description, entry.m_is_subaddress)) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Failed to edit address book entry"; + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index a327ed908..b2b5e7116 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -127,6 +127,7 @@ namespace tools MAP_JON_RPC_WE("parse_uri", on_parse_uri, wallet_rpc::COMMAND_RPC_PARSE_URI) MAP_JON_RPC_WE("get_address_book", on_get_address_book, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY) MAP_JON_RPC_WE("add_address_book", on_add_address_book, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY) + MAP_JON_RPC_WE("edit_address_book", on_edit_address_book, wallet_rpc::COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY) MAP_JON_RPC_WE("delete_address_book",on_delete_address_book,wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY) MAP_JON_RPC_WE("refresh", on_refresh, wallet_rpc::COMMAND_RPC_REFRESH) MAP_JON_RPC_WE("auto_refresh", on_auto_refresh, wallet_rpc::COMMAND_RPC_AUTO_REFRESH) @@ -212,6 +213,7 @@ namespace tools bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_add_address_book(const wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_edit_address_book(const wallet_rpc::COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_delete_address_book(const wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_refresh(const wallet_rpc::COMMAND_RPC_REFRESH::request& req, wallet_rpc::COMMAND_RPC_REFRESH::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_auto_refresh(const wallet_rpc::COMMAND_RPC_AUTO_REFRESH::request& req, wallet_rpc::COMMAND_RPC_AUTO_REFRESH::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index e9b8b60f5..0c86f404d 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -47,7 +47,7 @@ // advance which version they will stop working with // Don't go over 32767 for any of these #define WALLET_RPC_VERSION_MAJOR 1 -#define WALLET_RPC_VERSION_MINOR 14 +#define WALLET_RPC_VERSION_MINOR 16 #define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools @@ -916,6 +916,7 @@ namespace wallet_rpc uint64_t amount; uint64_t block_height; uint64_t unlock_time; + bool locked; cryptonote::subaddress_index subaddr_index; std::string address; @@ -925,6 +926,7 @@ namespace wallet_rpc KV_SERIALIZE(amount) KV_SERIALIZE(block_height) KV_SERIALIZE(unlock_time) + KV_SERIALIZE(locked) KV_SERIALIZE(subaddr_index) KV_SERIALIZE(address) END_KV_SERIALIZE_MAP() @@ -1364,6 +1366,7 @@ namespace wallet_rpc std::list<transfer_destination> destinations; std::string type; uint64_t unlock_time; + bool locked; cryptonote::subaddress_index subaddr_index; std::vector<cryptonote::subaddress_index> subaddr_indices; std::string address; @@ -1382,6 +1385,7 @@ namespace wallet_rpc KV_SERIALIZE(destinations); KV_SERIALIZE(type); KV_SERIALIZE(unlock_time) + KV_SERIALIZE(locked) KV_SERIALIZE(subaddr_index); KV_SERIALIZE(subaddr_indices); KV_SERIALIZE(address); @@ -1841,6 +1845,38 @@ namespace wallet_rpc typedef epee::misc_utils::struct_init<response_t> response; }; + struct COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY + { + struct request_t + { + uint64_t index; + bool set_address; + std::string address; + bool set_payment_id; + std::string payment_id; + bool set_description; + std::string description; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + KV_SERIALIZE(set_address) + KV_SERIALIZE(address) + KV_SERIALIZE(set_payment_id) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(set_description) + KV_SERIALIZE(description) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<request_t> request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init<response_t> response; + }; + struct COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY { struct request_t |