diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/api/wallet.cpp | 6 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 4 | ||||
-rw-r--r-- | src/wallet/message_store.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 84 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 14 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 9 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 6 |
7 files changed, 83 insertions, 42 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 4612b0397..d89261c64 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -267,13 +267,15 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback return boost::none; } - virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device) + virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool & on_device) { if (m_listener) { auto passphrase = m_listener->onDevicePassphraseRequest(on_device); - if (!on_device && passphrase) { + if (passphrase) { return boost::make_optional(epee::wipeable_string((*passphrase).data(), (*passphrase).size())); } + } else { + on_device = true; } return boost::none; } diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 6309724a4..9c3df8988 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -400,8 +400,8 @@ struct WalletListener /** * @brief called by device when passphrase entry is needed */ - virtual optional<std::string> onDevicePassphraseRequest(bool on_device) { - if (!on_device) throw std::runtime_error("Not supported"); + virtual optional<std::string> onDevicePassphraseRequest(bool & on_device) { + on_device = true; return optional<std::string>(); } diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index 1bd462ef5..25a8bd4ef 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -724,7 +724,7 @@ void message_store::read_from_file(const multisig_wallet_state &state, const std { // Simply do nothing if the file is not there; allows e.g. easy recovery // from problems with the MMS by deleting the file - MERROR("No message store file found: " << filename); + MINFO("No message store file found: " << filename); return; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4220f18be..02a067986 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1109,10 +1109,12 @@ boost::optional<epee::wipeable_string> wallet_device_callback::on_pin_request() return boost::none; } -boost::optional<epee::wipeable_string> wallet_device_callback::on_passphrase_request(bool on_device) +boost::optional<epee::wipeable_string> wallet_device_callback::on_passphrase_request(bool & on_device) { if (wallet) return wallet->on_device_passphrase_request(on_device); + else + on_device = true; return boost::none; } @@ -1521,6 +1523,18 @@ void wallet2::add_subaddress(uint32_t index_major, const std::string& label) m_subaddress_labels[index_major][index_minor] = label; } //---------------------------------------------------------------------------------------------------- +bool wallet2::should_expand(const cryptonote::subaddress_index &index) const +{ + const uint32_t last_major = m_subaddress_labels.size() - 1 > (std::numeric_limits<uint32_t>::max() - m_subaddress_lookahead_major) ? std::numeric_limits<uint32_t>::max() : (m_subaddress_labels.size() + m_subaddress_lookahead_major - 1); + if (index.major > last_major) + return false; + const size_t nsub = index.major < m_subaddress_labels.size() ? m_subaddress_labels[index.major].size() : 0; + const uint32_t last_minor = nsub - 1 > (std::numeric_limits<uint32_t>::max() - m_subaddress_lookahead_minor) ? std::numeric_limits<uint32_t>::max() : (nsub + m_subaddress_lookahead_minor - 1); + if (index.minor > last_minor) + return false; + return true; +} +//---------------------------------------------------------------------------------------------------- void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) { hw::device &hwdev = m_account.get_device(); @@ -2106,7 +2120,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote td.m_amount = amount; td.m_pk_index = pk_index - 1; td.m_subaddr_index = tx_scan_info[o].received->index; - if (tx_scan_info[o].received->index.major < m_subaddress_labels.size() && tx_scan_info[o].received->index.minor < m_subaddress_labels[tx_scan_info[o].received->index.major].size()) + if (should_expand(tx_scan_info[o].received->index)) expand_subaddresses(tx_scan_info[o].received->index); if (tx.vout[o].amount == 0) { @@ -2185,7 +2199,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote td.m_amount = amount; td.m_pk_index = pk_index - 1; td.m_subaddr_index = tx_scan_info[o].received->index; - if (tx_scan_info[o].received->index.major < m_subaddress_labels.size() && tx_scan_info[o].received->index.minor < m_subaddress_labels[tx_scan_info[o].received->index.major].size()) + if (should_expand(tx_scan_info[o].received->index)) expand_subaddresses(tx_scan_info[o].received->index); if (tx.vout[o].amount == 0) { @@ -4846,6 +4860,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password, std::vector<crypto::secret_key> multisig_keys; rct::key spend_pkey = rct::identity(); rct::key spend_skey; + auto wiper = epee::misc_utils::create_scope_leave_handler([&](){memwipe(&spend_skey, sizeof(spend_skey));}); std::vector<crypto::public_key> multisig_signers; // decrypt keys @@ -5491,13 +5506,12 @@ bool wallet2::check_connection(uint32_t *version, bool *ssl, uint32_t timeout) cryptonote::COMMAND_RPC_GET_VERSION::request req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_VERSION::response resp_t = AUTO_VAL_INIT(resp_t); bool r = invoke_http_json_rpc("/json_rpc", "get_version", req_t, resp_t); - if(!r) { + if(!r || resp_t.status != CORE_RPC_STATUS_OK) { if(version) *version = 0; return false; } - if (resp_t.status == CORE_RPC_STATUS_OK) - m_rpc_version = resp_t.version; + m_rpc_version = resp_t.version; } if (version) *version = m_rpc_version; @@ -5910,18 +5924,22 @@ uint64_t wallet2::balance(uint32_t index_major, bool strict) const return amount; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock) const +uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const { uint64_t amount = 0; if (blocks_to_unlock) *blocks_to_unlock = 0; + if (time_to_unlock) + *time_to_unlock = 0; if(m_light_wallet) return m_light_wallet_balance; for (const auto& i : unlocked_balance_per_subaddress(index_major, strict)) { amount += i.second.first; - if (blocks_to_unlock && i.second.second > *blocks_to_unlock) - *blocks_to_unlock = i.second.second; + if (blocks_to_unlock && i.second.second.first > *blocks_to_unlock) + *blocks_to_unlock = i.second.second.first; + if (time_to_unlock && i.second.second.second > *time_to_unlock) + *time_to_unlock = i.second.second.second; } return amount; } @@ -5958,35 +5976,40 @@ std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_majo return amount_per_subaddr; } //---------------------------------------------------------------------------------------------------- -std::map<uint32_t, std::pair<uint64_t, uint64_t>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict) const +std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict) const { - std::map<uint32_t, std::pair<uint64_t, uint64_t>> amount_per_subaddr; + std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> amount_per_subaddr; const uint64_t blockchain_height = get_blockchain_current_height(); + const uint64_t now = time(NULL); for(const transfer_details& td: m_transfers) { if(td.m_subaddr_index.major == index_major && !is_spent(td, strict) && !td.m_frozen) { - uint64_t amount = 0, blocks_to_unlock = 0; + uint64_t amount = 0, blocks_to_unlock = 0, time_to_unlock = 0; if (is_transfer_unlocked(td)) { amount = td.amount(); blocks_to_unlock = 0; + time_to_unlock = 0; } else { uint64_t unlock_height = td.m_block_height + std::max<uint64_t>(CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS); if (td.m_tx.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && td.m_tx.unlock_time > unlock_height) unlock_height = td.m_tx.unlock_time; + uint64_t unlock_time = td.m_tx.unlock_time >= CRYPTONOTE_MAX_BLOCK_NUMBER ? td.m_tx.unlock_time : 0; blocks_to_unlock = unlock_height > blockchain_height ? unlock_height - blockchain_height : 0; + time_to_unlock = unlock_time > now ? unlock_time - now : 0; amount = 0; } auto found = amount_per_subaddr.find(td.m_subaddr_index.minor); if (found == amount_per_subaddr.end()) - amount_per_subaddr[td.m_subaddr_index.minor] = std::make_pair(amount, blocks_to_unlock); + amount_per_subaddr[td.m_subaddr_index.minor] = std::make_pair(amount, std::make_pair(blocks_to_unlock, time_to_unlock)); else { found->second.first += amount; - found->second.second = std::max(found->second.second, blocks_to_unlock); + found->second.second.first = std::max(found->second.second.first, blocks_to_unlock); + found->second.second.second = std::max(found->second.second.second, time_to_unlock); } } } @@ -6001,17 +6024,21 @@ uint64_t wallet2::balance_all(bool strict) const return r; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock) const +uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const { uint64_t r = 0; if (blocks_to_unlock) *blocks_to_unlock = 0; + if (time_to_unlock) + *time_to_unlock = 0; for (uint32_t index_major = 0; index_major < get_num_subaddress_accounts(); ++index_major) { - uint64_t local_blocks_to_unlock; - r += unlocked_balance(index_major, strict, blocks_to_unlock ? &local_blocks_to_unlock : NULL); + uint64_t local_blocks_to_unlock, local_time_to_unlock; + r += unlocked_balance(index_major, strict, blocks_to_unlock ? &local_blocks_to_unlock : NULL, time_to_unlock ? &local_time_to_unlock : NULL); if (blocks_to_unlock) *blocks_to_unlock = std::max(*blocks_to_unlock, local_blocks_to_unlock); + if (time_to_unlock) + *time_to_unlock = std::max(*time_to_unlock, local_time_to_unlock); } return r; } @@ -6490,7 +6517,7 @@ void wallet2::commit_tx(pending_tx& ptx) // tx generated, get rid of used k values for (size_t idx: ptx.selected_transfers) - m_transfers[idx].m_multisig_k.clear(); + memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0])); //fee includes dust if dust policy specified it. LOG_PRINT_L1("Transaction successfully sent. <" << txid << ">" << ENDL @@ -6932,13 +6959,13 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs) // txes generated, get rid of used k values for (size_t n = 0; n < txs.m_ptx.size(); ++n) for (size_t idx: txs.m_ptx[n].construction_data.selected_transfers) - m_transfers[idx].m_multisig_k.clear(); + memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0])); // zero out some data we don't want to share for (auto &ptx: txs.m_ptx) { for (auto &e: ptx.construction_data.sources) - e.multisig_kLRki.k = rct::zero(); + memwipe(&e.multisig_kLRki.k, sizeof(e.multisig_kLRki.k)); } for (auto &ptx: txs.m_ptx) @@ -7146,10 +7173,12 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto ptx.tx.rct_signatures = sig.sigs; rct::keyV k; + rct::key skey = rct::zero(); + auto wiper = epee::misc_utils::create_scope_leave_handler([&](){ memwipe(k.data(), k.size() * sizeof(k[0])); memwipe(&skey, sizeof(skey)); }); + for (size_t idx: sd.selected_transfers) k.push_back(get_multisig_k(idx, sig.used_L)); - rct::key skey = rct::zero(); for (const auto &msk: get_account().get_multisig_keys()) { crypto::public_key pmsk = get_multisig_signing_public_key(msk); @@ -7197,7 +7226,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto // txes generated, get rid of used k values for (size_t n = 0; n < exported_txs.m_ptx.size(); ++n) for (size_t idx: exported_txs.m_ptx[n].construction_data.selected_transfers) - m_transfers[idx].m_multisig_k.clear(); + memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0])); exported_txs.m_signers.insert(get_multisig_signer_public_key()); @@ -9650,7 +9679,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp // throw if attempting a transaction with no money THROW_WALLET_EXCEPTION_IF(needed_money == 0, error::zero_destination); - std::map<uint32_t, std::pair<uint64_t, uint64_t>> unlocked_balance_per_subaddr = unlocked_balance_per_subaddress(subaddr_account, false); + std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddr = unlocked_balance_per_subaddress(subaddr_account, false); std::map<uint32_t, uint64_t> balance_per_subaddr = balance_per_subaddress(subaddr_account, false); if (subaddr_indices.empty()) // "index=<N1>[,<N2>,...]" wasn't specified -> use all the indices with non-zero unlocked balance @@ -12755,7 +12784,7 @@ process: const crypto::public_key& out_key = boost::get<cryptonote::txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key; bool r = cryptonote::generate_key_image_helper(m_account.get_keys(), m_subaddresses, out_key, tx_pub_key, additional_tx_pub_keys, td.m_internal_output_index, in_ephemeral, td.m_key_image, m_account.get_device()); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image"); - if (td.m_subaddr_index.major < m_subaddress_labels.size() && td.m_subaddr_index.minor < m_subaddress_labels[td.m_subaddr_index.major].size()) + if (should_expand(td.m_subaddr_index)) expand_subaddresses(td.m_subaddr_index); td.m_key_image_known = true; td.m_key_image_request = true; @@ -12948,7 +12977,7 @@ cryptonote::blobdata wallet2::export_multisig() { transfer_details &td = m_transfers[n]; crypto::key_image ki; - td.m_multisig_k.clear(); + memwipe(td.m_multisig_k.data(), td.m_multisig_k.size() * sizeof(td.m_multisig_k[0])); info[n].m_LR.clear(); info[n].m_partial_key_images.clear(); @@ -13057,6 +13086,7 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs) CHECK_AND_ASSERT_THROW_MES(info.size() + 1 <= m_multisig_signers.size() && info.size() + 1 >= m_multisig_threshold, "Wrong number of multisig sources"); std::vector<std::vector<rct::key>> k; + auto wiper = epee::misc_utils::create_scope_leave_handler([&](){memwipe(k.data(), k.size() * sizeof(k[0]));}); k.reserve(m_transfers.size()); for (const auto &td: m_transfers) k.push_back(td.m_multisig_k); @@ -13618,10 +13648,12 @@ boost::optional<epee::wipeable_string> wallet2::on_device_pin_request() return boost::none; } //---------------------------------------------------------------------------------------------------- -boost::optional<epee::wipeable_string> wallet2::on_device_passphrase_request(bool on_device) +boost::optional<epee::wipeable_string> wallet2::on_device_passphrase_request(bool & on_device) { if (nullptr != m_callback) return m_callback->on_device_passphrase_request(on_device); + else + on_device = true; return boost::none; } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 1c3c00152..eb33713b5 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -145,7 +145,7 @@ private: virtual void on_device_button_request(uint64_t code) {} virtual void on_device_button_pressed() {} virtual boost::optional<epee::wipeable_string> on_device_pin_request() { return boost::none; } - virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device) { return boost::none; } + virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool & on_device) { on_device = true; return boost::none; } virtual void on_device_progress(const hw::device_progress& event) {}; // Common callbacks virtual void on_pool_tx_removed(const crypto::hash &txid) {} @@ -159,7 +159,7 @@ private: void on_button_request(uint64_t code=0) override; void on_button_pressed() override; boost::optional<epee::wipeable_string> on_pin_request() override; - boost::optional<epee::wipeable_string> on_passphrase_request(bool on_device) override; + boost::optional<epee::wipeable_string> on_passphrase_request(bool & on_device) override; void on_progress(const hw::device_progress& event) override; private: wallet2 * wallet; @@ -835,13 +835,13 @@ private: // locked & unlocked balance of given or current subaddress account uint64_t balance(uint32_t subaddr_index_major, bool strict) const; - uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL) const; + uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL) const; // locked & unlocked balance per subaddress of given or current subaddress account std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; - std::map<uint32_t, std::pair<uint64_t, uint64_t>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; + std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; // all locked & unlocked balances of all subaddress accounts uint64_t balance_all(bool strict) const; - uint64_t unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock = NULL) const; + uint64_t unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL) const; template<typename T> void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count, std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, @@ -1507,7 +1507,7 @@ private: void on_device_button_request(uint64_t code); void on_device_button_pressed(); boost::optional<epee::wipeable_string> on_device_pin_request(); - boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device); + boost::optional<epee::wipeable_string> on_device_passphrase_request(bool & on_device); void on_device_progress(const hw::device_progress& event); std::string get_rpc_status(const std::string &s) const; @@ -1516,6 +1516,8 @@ private: std::string get_client_signature() const; void check_rpc_cost(const char *call, uint64_t post_call_credits, uint64_t pre_credits, double expected_cost); + bool should_expand(const cryptonote::subaddress_index &index) const; + cryptonote::account_base m_account; boost::optional<epee::net_utils::http::login> m_daemon_login; std::string m_daemon_address; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index db2e2344b..30eed07e7 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -428,10 +428,10 @@ namespace tools try { res.balance = req.all_accounts ? m_wallet->balance_all(req.strict) : m_wallet->balance(req.account_index, req.strict); - res.unlocked_balance = req.all_accounts ? m_wallet->unlocked_balance_all(req.strict, &res.blocks_to_unlock) : m_wallet->unlocked_balance(req.account_index, req.strict, &res.blocks_to_unlock); + res.unlocked_balance = req.all_accounts ? m_wallet->unlocked_balance_all(req.strict, &res.blocks_to_unlock, &res.time_to_unlock) : m_wallet->unlocked_balance(req.account_index, req.strict, &res.blocks_to_unlock, &res.time_to_unlock); res.multisig_import_needed = m_wallet->multisig() && m_wallet->has_multisig_partial_key_images(); std::map<uint32_t, std::map<uint32_t, uint64_t>> balance_per_subaddress_per_account; - std::map<uint32_t, std::map<uint32_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress_per_account; + std::map<uint32_t, std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>> unlocked_balance_per_subaddress_per_account; if (req.all_accounts) { for (uint32_t account_index = 0; account_index < m_wallet->get_num_subaddress_accounts(); ++account_index) @@ -451,7 +451,7 @@ namespace tools { uint32_t account_index = p.first; std::map<uint32_t, uint64_t> balance_per_subaddress = p.second; - std::map<uint32_t, std::pair<uint64_t, uint64_t>> unlocked_balance_per_subaddress = unlocked_balance_per_subaddress_per_account[account_index]; + std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress = unlocked_balance_per_subaddress_per_account[account_index]; std::set<uint32_t> address_indices; if (!req.all_accounts && !req.address_indices.empty()) { @@ -471,7 +471,8 @@ namespace tools info.address = m_wallet->get_subaddress_as_str(index); info.balance = balance_per_subaddress[i]; info.unlocked_balance = unlocked_balance_per_subaddress[i].first; - info.blocks_to_unlock = unlocked_balance_per_subaddress[i].second; + info.blocks_to_unlock = unlocked_balance_per_subaddress[i].second.first; + info.time_to_unlock = unlocked_balance_per_subaddress[i].second.second; info.label = m_wallet->get_subaddress_label(index); info.num_unspent_outputs = std::count_if(transfers.begin(), transfers.end(), [&](const tools::wallet2::transfer_details& td) { return !td.m_spent && td.m_subaddr_index == index; }); res.per_subaddress.emplace_back(std::move(info)); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index a212b79e6..507ff4f6c 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 17 +#define WALLET_RPC_VERSION_MINOR 18 #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 @@ -84,6 +84,7 @@ namespace wallet_rpc std::string label; uint64_t num_unspent_outputs; uint64_t blocks_to_unlock; + uint64_t time_to_unlock; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(account_index) @@ -94,6 +95,7 @@ namespace wallet_rpc KV_SERIALIZE(label) KV_SERIALIZE(num_unspent_outputs) KV_SERIALIZE(blocks_to_unlock) + KV_SERIALIZE(time_to_unlock) END_KV_SERIALIZE_MAP() }; @@ -104,6 +106,7 @@ namespace wallet_rpc bool multisig_import_needed; std::vector<per_subaddress_info> per_subaddress; uint64_t blocks_to_unlock; + uint64_t time_to_unlock; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(balance) @@ -111,6 +114,7 @@ namespace wallet_rpc KV_SERIALIZE(multisig_import_needed) KV_SERIALIZE(per_subaddress) KV_SERIALIZE(blocks_to_unlock) + KV_SERIALIZE(time_to_unlock) END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init<response_t> response; |