From 9e6f747410675fd10a4a97b7b905b977ca754bf1 Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 17 Dec 2019 12:24:28 +0300 Subject: [PATCH] RPC: sweep_below method implemented --- src/wallet/wallet_public_structs_defs.h | 39 +++++++++++ src/wallet/wallet_rpc_server.cpp | 87 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.h | 2 + 3 files changed, 128 insertions(+) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 5b5f150f..b24e92c2 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -375,6 +375,45 @@ namespace wallet_public }; }; + struct COMMAND_SWEEP_BELOW + { + struct request + { + uint64_t mixin; + std::string address; + uint64_t amount; + std::string payment_id_hex; + uint64_t fee; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(mixin) + KV_SERIALIZE(address) + KV_SERIALIZE(amount) + KV_SERIALIZE(payment_id_hex) + KV_SERIALIZE(fee) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string tx_hash; + std::string tx_unsigned_hex; + uint64_t outs_total; + uint64_t amount_total; + uint64_t outs_swept; + uint64_t amount_swept; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(tx_unsigned_hex) + KV_SERIALIZE(outs_total) + KV_SERIALIZE(amount_total) + KV_SERIALIZE(outs_swept) + KV_SERIALIZE(amount_swept) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_SIGN_TRANSFER { struct request diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 1d3f58ef..19d8ee78 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -402,6 +402,93 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_sweep_below(const wallet_public::COMMAND_SWEEP_BELOW::request& req, wallet_public::COMMAND_SWEEP_BELOW::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + currency::payment_id_t payment_id; + if (!req.payment_id_hex.empty() && !currency::parse_payment_id_from_hex_str(req.payment_id_hex, payment_id)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = std::string("Invalid payment id: ") + req.payment_id_hex; + return false; + } + + currency::account_public_address addr; + currency::payment_id_t integrated_payment_id; + if (!m_wallet.get_transfer_address(req.address, addr, integrated_payment_id)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = std::string("Invalid address: ") + req.address; + return false; + } + + if (!integrated_payment_id.empty()) + { + if (!payment_id.empty()) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = std::string("address ") + req.address + " has integrated payment id " + epee::string_tools::buff_to_hex_nodelimer(integrated_payment_id) + + " which is incompatible with payment id " + epee::string_tools::buff_to_hex_nodelimer(payment_id) + " that was already assigned to this transfer"; + return false; + } + payment_id = integrated_payment_id; + } + + if (req.fee < m_wallet.get_core_runtime_config().tx_pool_min_fee) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT; + er.message = std::string("Given fee is too low: ") + epee::string_tools::num_to_string_fast(req.fee) + ", minimum is: " + epee::string_tools::num_to_string_fast(m_wallet.get_core_runtime_config().tx_pool_min_fee); + return false; + } + + try + { + currency::transaction tx = AUTO_VAL_INIT(tx); + size_t outs_total = 0, outs_swept = 0; + uint64_t amount_total = 0, amount_swept = 0; + + std::string unsigned_tx_blob_str; + m_wallet.sweep_below(req.mixin, addr, req.amount, payment_id, req.fee, outs_total, amount_total, outs_swept, &tx, &unsigned_tx_blob_str); + + get_inputs_money_amount(tx, amount_swept); + res.amount_swept = amount_swept; + res.amount_total = amount_total; + res.outs_swept = outs_swept; + res.outs_total = outs_total; + + if (m_wallet.is_watch_only()) + { + res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets can't sign and relay transactions + // leave res.tx_hash empty, because tx has will change after signing + } + else + { + res.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(tx)); + } + + + } + catch (const tools::error::daemon_busy& e) + { + er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; + er.message = e.what(); + return false; + } + catch (const std::exception& e) + { + er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; + er.message = e.what(); + return false; + } + catch (...) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR"; + return false; + } + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index dca8bd53..0da4f17c 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -47,6 +47,7 @@ namespace tools MAP_JON_RPC_WE("get_bulk_payments", on_get_bulk_payments, wallet_public::COMMAND_RPC_GET_BULK_PAYMENTS) MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS) MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS) + MAP_JON_RPC_WE("sweep_below", on_sweep_below, wallet_public::COMMAND_SWEEP_BELOW) MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER) MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER) //contracts API @@ -73,6 +74,7 @@ namespace tools bool on_get_bulk_payments(const wallet_public::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_public::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_make_integrated_address(const wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_split_integrated_address(const wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_sweep_below(const wallet_public::COMMAND_SWEEP_BELOW::request& req, wallet_public::COMMAND_SWEEP_BELOW::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_submit_transfer(const wallet_public::COMMAND_SUBMIT_TRANSFER::request& req, wallet_public::COMMAND_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);