1
0
Fork 0
forked from lthn/blockchain

wallet rpc: send_ext_signed_asset_tx call implemented

This commit is contained in:
sowle 2024-09-23 05:34:55 +02:00
parent bb758a916a
commit 44b19dd070
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
5 changed files with 112 additions and 2 deletions

View file

@ -4312,6 +4312,39 @@ bool wallet2::get_utxo_distribution(std::map<uint64_t, uint64_t>& distribution)
return false;
}
//----------------------------------------------------------------------------------------------------
void wallet2::submit_externally_signed_asset_tx(const finalized_tx& ft, const crypto::eth_signature& eth_sig, bool unlock_transfers_on_fail, currency::transaction& result_tx, bool& transfers_unlocked)
{
transaction tx = ft.tx;
currency::asset_operation_ownership_proof_eth aoop_eth{};
aoop_eth.eth_sig = eth_sig;
tx.proofs.push_back(std::move(aoop_eth));
// foolproof
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ft.ftp.spend_pub_key == m_account.get_keys().account_address.spend_public_key, "The given tx was created in a different wallet, keys missmatch, tx hash: " << ft.tx_id);
try
{
send_transaction_to_network(tx);
}
catch (...)
{
// clear transfers flags if smth went wrong and it was requested
if (unlock_transfers_on_fail)
{
uint32_t flag = WALLET_TRANSFER_DETAIL_FLAG_SPENT | WALLET_TRANSFER_DETAIL_FLAG_ASSET_OP_RESERVATION;
clear_transfers_from_flag(ft.ftp.selected_transfers, flag, "broadcasting tx " + epee::string_tools::pod_to_hex(ft.tx_id) + " was unsuccessful");
transfers_unlocked = true;
}
throw;
}
m_tx_keys.insert(std::make_pair(ft.tx_id, ft.one_time_key));
add_sent_tx_detailed_info(tx, ft.ftp.attachments, ft.ftp.prepared_destinations, ft.ftp.selected_transfers);
print_tx_sent_message(tx, "from submit_externally_signed_asset_tx", true, get_tx_fee(tx));
}
//----------------------------------------------------------------------------------------------------
void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::transaction& tx)
{
// decrypt sources

View file

@ -595,6 +595,7 @@ namespace tools
void sign_transfer_files(const std::string& tx_sources_file, const std::string& signed_tx_file, currency::transaction& tx);
void submit_transfer(const std::string& signed_tx_blob, currency::transaction& tx);
void submit_transfer_files(const std::string& signed_tx_file, currency::transaction& tx);
void submit_externally_signed_asset_tx(const currency::finalized_tx& ft, const crypto::eth_signature& eth_sig, bool unlock_transfers_on_fail, currency::transaction& result_tx, bool& transfers_unlocked);
void sweep_below(size_t fake_outs_count, const currency::account_public_address& destination_addr, uint64_t threshold_amount, const currency::payment_id_t& payment_id,
uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, uint64_t& amount_swept, currency::transaction* p_result_tx = nullptr, std::string* p_filename_or_unsigned_tx_blob_str = nullptr);

View file

@ -13,7 +13,7 @@
#include "currency_core/offers_service_basics.h"
#include "currency_core/bc_escrow_service.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "currency_protocol/blobdatatype.h"
const uint64_t WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED = std::numeric_limits<uint64_t>::max();
@ -2083,5 +2083,39 @@ namespace wallet_public
};
};
struct COMMAND_ASSET_SEND_EXT_SIGNED_TX
{
DOC_COMMAND("Inserts externally made asset ownership signature into the given transaction and broadcasts it.");
struct request
{
currency::blobdata finalized_tx;
currency::blobdata unsigned_tx;
crypto::eth_signature eth_sig;
crypto::hash expected_tx_id;
bool unlock_transfers_on_fail = false;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_BLOB_AS_BASE64_STRING(finalized_tx)DOC_DSCR("Base64-encoded finalized_tx data structure, which was received from emit_asset call.") DOC_EXMP("ewogICJ2ZXJzaW9uIjogMSwgC....iAgInZpbiI6IFsgewogICAgIC") DOC_END
KV_SERIALIZE_BLOB_AS_BASE64_STRING(unsigned_tx) DOC_DSCR("Base64-encoded unsigned transaction blob, which was received from emit_asset call.") DOC_EXMP("083737bcfd826a973f74bb56a52b4fa562e6579ccaadd2697463498a66de4f1760b2cd40f11c3a00a7a80000") DOC_END
KV_SERIALIZE_POD_AS_HEX_STRING(eth_sig) DOC_DSCR("HEX-encoded ETH signature (64 bytes)") DOC_EXMP("674bb56a5b4fa562e679ccacc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6add697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END
KV_SERIALIZE_POD_AS_HEX_STRING(expected_tx_id) DOC_DSCR("The expected transaction id. Tx won't be sent if the calculated one doesn't match this one. Consider using 'verified_tx_id' returned by 'decrypt_tx_details' call.") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END
KV_SERIALIZE(unlock_transfers_on_fail) DOC_DSCR("If true, all locked wallet transfers, corresponding to the transaction, will be unlocked on sending failure. False by default.") DOC_EXMP(false) DOC_END
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
bool transfers_were_unlocked;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status) DOC_DSCR("Status of the call") DOC_EXMP("OK") DOC_END
KV_SERIALIZE(transfers_were_unlocked) DOC_DSCR("If true, all input transfers that were locked when preparing this transaction, are now unlocked and may be spent. Can be true only upon sending failure and if requested.") DOC_EXMP(false) DOC_END
END_KV_SERIALIZE_MAP()
};
};
} // namespace wallet_rpc
} // namespace tools

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -1334,6 +1334,46 @@ namespace tools
currency::transaction result_tx;
w.get_wallet()->burn_asset(req.asset_id, req.burn_amount, result_tx);
res.result_tx = currency::get_transaction_hash(result_tx);
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_asset_send_ext_signed_tx(const wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::request& req, wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
WALLET_RPC_BEGIN_TRY_ENTRY();
currency::finalized_tx ft{};
if (!t_unserializable_object_from_blob(ft, req.finalized_tx))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT;
er.message = "finalized_tx couldn't be deserialized";
return false;
}
if (t_serializable_object_to_blob(ft.tx) != req.unsigned_tx)
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT;
er.message = "unsigned_tx doesn't match finalized_tx";
return false;
}
crypto::hash tx_id = currency::get_transaction_hash(ft.tx);
if (req.expected_tx_id != tx_id)
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT;
er.message = std::string("expected_tx_id mismatch, real tx id is ") + epee::string_tools::pod_to_hex(tx_id);
return false;
}
try
{
currency::transaction result_tx{};
w.get_wallet()->submit_externally_signed_asset_tx(ft, req.eth_sig, req.unlock_transfers_on_fail, result_tx, res.transfers_were_unlocked);
}
catch(std::exception& e)
{
// doing this to be able to return 'transfers_were_unlocked' to the caller even in the case of exception
res.status = e.what();
return true;
}
return true;
WALLET_RPC_CATCH_TRY_ENTRY();
}

View file

@ -151,6 +151,7 @@ namespace tools
MAP_JON_RPC_WE("update_asset", on_assets_update, wallet_public::COMMAND_ASSETS_UPDATE)
MAP_JON_RPC_WE("burn_asset", on_assets_burn, wallet_public::COMMAND_ASSETS_BURN)
MAP_JON_RPC_WE("send_ext_signed_asset_tx", on_asset_send_ext_signed_tx, wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX)
//MULTIWALLET APIs
MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS)
@ -222,6 +223,7 @@ namespace tools
bool on_assets_emit(const wallet_public::COMMAND_ASSETS_EMIT::request& req, wallet_public::COMMAND_ASSETS_EMIT::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_assets_update(const wallet_public::COMMAND_ASSETS_UPDATE::request& req, wallet_public::COMMAND_ASSETS_UPDATE::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_assets_burn(const wallet_public::COMMAND_ASSETS_BURN::request& req, wallet_public::COMMAND_ASSETS_BURN::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_asset_send_ext_signed_tx(const wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::request& req, wallet_public::COMMAND_ASSET_SEND_EXT_SIGNED_TX::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_mw_select_wallet(const wallet_public::COMMAND_MW_SELECT_WALLET::request& req, wallet_public::COMMAND_MW_SELECT_WALLET::response& res, epee::json_rpc::error& er, connection_context& cntx);