diff options
Diffstat (limited to 'src/wallet/wallet_rpc_server.cpp')
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 157 |
1 files changed, 69 insertions, 88 deletions
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index de501f056..2a051553b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -326,6 +326,7 @@ namespace tools entry.height = pd.m_block_height; entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; + entry.amounts = pd.m_amounts; 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; @@ -408,6 +409,7 @@ namespace tools entry.height = 0; entry.timestamp = pd.m_timestamp; entry.amount = pd.m_amount; + entry.amounts = pd.m_amounts; entry.unlock_time = pd.m_unlock_time; entry.locked = true; entry.fee = pd.m_fee; @@ -550,9 +552,29 @@ namespace tools if (!m_wallet) return not_open(er); try { - m_wallet->add_subaddress(req.account_index, req.label); - res.address_index = m_wallet->get_num_subaddresses(req.account_index) - 1; - res.address = m_wallet->get_subaddress_as_str({req.account_index, res.address_index}); + if (req.count < 1 || req.count > 64) { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Count must be between 1 and 64."; + return false; + } + + std::vector<std::string> addresses; + std::vector<uint32_t> address_indices; + + addresses.reserve(req.count); + address_indices.reserve(req.count); + + for (uint32_t i = 0; i < req.count; i++) { + m_wallet->add_subaddress(req.account_index, req.label); + uint32_t new_address_index = m_wallet->get_num_subaddresses(req.account_index) - 1; + address_indices.push_back(new_address_index); + addresses.push_back(m_wallet->get_subaddress_as_str({req.account_index, new_address_index})); + } + + res.address = addresses[0]; + res.address_index = address_indices[0]; + res.addresses = addresses; + res.address_indices = address_indices; } catch (const std::exception& e) { @@ -843,7 +865,7 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ template<typename Ts, typename Tu> bool wallet_rpc_server::fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector, - bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay, + bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay, Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er) { for (const auto & ptx : ptx_vector) @@ -858,6 +880,7 @@ namespace tools // Compute amount leaving wallet in tx. By convention dests does not include change outputs fill(amount, total_amount(ptx)); fill(fee, ptx.fee); + fill(weight, cryptonote::get_transaction_weight(ptx.tx)); } if (m_wallet->multisig()) @@ -943,7 +966,7 @@ namespace tools return false; } - return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er); } catch (const std::exception& e) @@ -989,7 +1012,7 @@ namespace tools return false; } - return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er); } catch (const std::exception& e) @@ -1353,7 +1376,7 @@ namespace tools { std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions(); - return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er); } catch (const std::exception& e) @@ -1400,7 +1423,7 @@ namespace tools uint32_t priority = m_wallet->adjust_priority(req.priority); std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices); - return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er); } catch (const std::exception& e) @@ -1475,7 +1498,7 @@ namespace tools return false; } - return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, + return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er); } catch (const std::exception& e) @@ -1943,7 +1966,7 @@ namespace tools return false; } - res.signature = m_wallet->sign(req.data); + res.signature = m_wallet->sign(req.data, {req.account_index, req.address_index}); return true; } //------------------------------------------------------------------------------------------------------------------------------ @@ -2725,7 +2748,14 @@ namespace tools { uint64_t idx = 0; for (const auto &entry: ab) - res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx++, get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address), epee::string_tools::pod_to_hex(entry.m_payment_id), entry.m_description}); + { + std::string address; + if (entry.m_has_payment_id) + address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id); + else + address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address); + res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx++, address, entry.m_description}); + } } else { @@ -2738,7 +2768,12 @@ namespace tools return false; } const auto &entry = ab[idx]; - res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx, get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address), epee::string_tools::pod_to_hex(entry.m_payment_id), entry.m_description}); + std::string address; + if (entry.m_has_payment_id) + address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id); + else + address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address); + res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx, address, entry.m_description}); } } return true; @@ -2755,7 +2790,6 @@ namespace tools } cryptonote::address_parse_info info; - crypto::hash payment_id = crypto::null_hash; 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 { @@ -2777,39 +2811,7 @@ namespace tools er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address; return false; } - if (info.has_payment_id) - { - memcpy(payment_id.data, info.payment_id.data, 8); - memset(payment_id.data + 8, 0, 24); - } - if (!req.payment_id.empty()) - { - if (info.has_payment_id) - { - er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; - er.message = "Separate payment ID given with integrated address"; - return false; - } - - crypto::hash long_payment_id; - - if (!wallet2::parse_long_payment_id(req.payment_id, payment_id)) - { - if (!wallet2::parse_short_payment_id(req.payment_id, info.payment_id)) - { - 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; - } - } - } - if (!m_wallet->add_address_book_row(info.address, payment_id, req.description, info.is_subaddress)) + if (!m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, req.description, info.is_subaddress)) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; er.message = "Failed to add address book entry"; @@ -2840,7 +2842,6 @@ namespace tools 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 = ""; @@ -2867,52 +2868,13 @@ namespace tools 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; + entry.m_payment_id = info.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)) + if (!m_wallet->set_address_book_row(req.index, entry.m_address, req.set_address && entry.m_has_payment_id ? &entry.m_payment_id : NULL, entry.m_description, entry.m_is_subaddress)) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; er.message = "Failed to edit address book entry"; @@ -4291,6 +4253,25 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_estimate_tx_size_and_weight(const wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::request& req, wallet_rpc::COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + try + { + size_t extra_size = 34 /* pubkey */ + 10 /* encrypted payment id */; // typical makeup + const std::pair<size_t, uint64_t> sw = m_wallet->estimate_tx_size_and_weight(req.rct, req.n_inputs, req.ring_size, req.n_outputs, extra_size); + res.size = sw.first; + res.weight = sw.second; + } + catch (const std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "Failed to determine size and weight"; + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.version = WALLET_RPC_VERSION; |