De-nest wallet2 structs used externally

This moves the wallet structs that are needed elsewhere (for instance,
in the device drivers) from `tools::wallet2::whatever` to
`wallet::whatever`, allowing them to be included individually via
wallet/whatever.h without needing to include the entire wallet2.h.

What was particularly problematic here is that you couldn't even forward
declare them because they were nested inside the wallet2 class, but
instead had to include the full wallet2.h.
This commit is contained in:
Jason Rhinelander 2020-07-22 16:29:36 -03:00
parent 0cecc6749b
commit 4f783d3273
26 changed files with 1042 additions and 691 deletions

View File

@ -102,14 +102,14 @@ int main(int argc, char* argv[])
SL(nodetool::basic_node_data);
SL(cryptonote::CORE_SYNC_DATA);
SL(tools::wallet2::transfer_details);
SL(wallet::transfer_details);
SL(tools::wallet2::payment_details);
SL(tools::wallet2::unconfirmed_transfer_details);
SL(tools::wallet2::confirmed_transfer_details);
SL(tools::wallet2::tx_construction_data);
SL(tools::wallet2::pending_tx);
SL(tools::wallet2::unsigned_tx_set);
SL(tools::wallet2::signed_tx_set);
SL(wallet::tx_construction_data);
SL(wallet::pending_tx);
SL(wallet::unsigned_tx_set);
SL(wallet::signed_tx_set);
SL(Monero::WalletImpl);
SL(Monero::AddressBookRow);

View File

@ -35,7 +35,7 @@
#include <optional>
#include <functional>
namespace tools::wallet2 {
namespace wallet {
struct transfer_details;
struct unsigned_tx_set;
struct signed_tx_set;
@ -44,7 +44,7 @@ struct signed_tx_set;
namespace hw {
struct wallet_shim {
std::function<crypto::public_key (const tools::wallet2::transfer_details &td)> get_tx_pub_key_from_received_outs;
std::function<crypto::public_key (const wallet::transfer_details &td)> get_tx_pub_key_from_received_outs;
};
class tx_aux_data {
@ -112,15 +112,15 @@ namespace hw {
* Key image sync with the cold protocol.
*/
virtual void ki_sync(wallet_shim * wallet,
const std::vector<::tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
exported_key_image & ski) =0;
/**
* Signs unsigned transaction with the cold protocol.
*/
virtual void tx_sign(wallet_shim * wallet,
const ::tools::wallet2::unsigned_tx_set & unsigned_tx,
::tools::wallet2::signed_tx_set & signed_tx,
const wallet::unsigned_tx_set & unsigned_tx,
wallet::signed_tx_set & signed_tx,
tx_aux_data & aux_data) =0;
/**

View File

@ -288,7 +288,7 @@ namespace trezor {
}
void device_trezor::ki_sync(wallet_shim * wallet,
const std::vector<tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
hw::device_cold::exported_key_image & ski)
{
#define EVENT_PROGRESS(P) do { if (m_callback) {(m_callback)->on_progress(device_cold::op_progress(P)); } }while(0)
@ -485,8 +485,8 @@ namespace trezor {
}
void device_trezor::tx_sign(wallet_shim * wallet,
const tools::wallet2::unsigned_tx_set & unsigned_tx,
tools::wallet2::signed_tx_set & signed_tx,
const wallet::unsigned_tx_set & unsigned_tx,
wallet::signed_tx_set & signed_tx,
hw::tx_aux_data & aux_data)
{
CHECK_AND_ASSERT_THROW_MES(unsigned_tx.transfers.first == 0, "Unsuported non zero offset");
@ -573,7 +573,7 @@ namespace trezor {
}
void device_trezor::tx_sign(wallet_shim * wallet,
const tools::wallet2::unsigned_tx_set & unsigned_tx,
const wallet::unsigned_tx_set & unsigned_tx,
size_t idx,
hw::tx_aux_data & aux_data,
std::shared_ptr<protocol::tx::Signer> & signer)
@ -591,7 +591,7 @@ namespace trezor {
CHECK_AND_ASSERT_THROW_MES(idx < unsigned_tx.txes.size(), "Invalid transaction index");
signer = std::make_shared<protocol::tx::Signer>(wallet, &unsigned_tx, idx, &aux_data);
const tools::wallet2::tx_construction_data & cur_tx = unsigned_tx.txes[idx];
const auto& cur_tx = unsigned_tx.txes[idx];
unsigned long num_sources = cur_tx.sources.size();
unsigned long num_outputs = cur_tx.splitted_dsts.size();
@ -695,7 +695,7 @@ namespace trezor {
return client_version;
}
void device_trezor::transaction_versions_check(const ::tools::wallet2::unsigned_tx_set & unsigned_tx, hw::tx_aux_data & aux_data)
void device_trezor::transaction_versions_check(const wallet::unsigned_tx_set & unsigned_tx, hw::tx_aux_data & aux_data)
{
unsigned cversion = client_version();

View File

@ -42,6 +42,9 @@
#include "device/device_cold.hpp"
#include "cryptonote_config.h"
#include "device_trezor_base.hpp"
#include "wallet/transfer_details.h"
#include "wallet/tx_sets.h"
#endif
namespace hw {
@ -66,7 +69,7 @@ namespace trezor {
size_t m_num_transations_to_sign;
unsigned client_version();
void transaction_versions_check(const ::tools::wallet2::unsigned_tx_set & unsigned_tx, hw::tx_aux_data & aux_data);
void transaction_versions_check(const wallet::unsigned_tx_set & unsigned_tx, hw::tx_aux_data & aux_data);
void transaction_pre_check(std::shared_ptr<messages::monero::MoneroTransactionInitRequest> init_msg);
void transaction_check(const protocol::tx::TData & tdata, const hw::tx_aux_data & aux_data);
void device_state_initialize_unsafe() override;
@ -78,7 +81,7 @@ namespace trezor {
* Signs particular transaction idx in the unsigned set, keeps state in the signer
*/
virtual void tx_sign(wallet_shim * wallet,
const ::tools::wallet2::unsigned_tx_set & unsigned_tx,
const wallet::unsigned_tx_set & unsigned_tx,
size_t idx,
hw::tx_aux_data & aux_data,
std::shared_ptr<protocol::tx::Signer> & signer);
@ -154,7 +157,7 @@ namespace trezor {
* Key image sync with the Trezor.
*/
void ki_sync(wallet_shim * wallet,
const std::vector<::tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
hw::device_cold::exported_key_image & ski) override;
bool is_live_refresh_supported() const override;
@ -200,8 +203,8 @@ namespace trezor {
* Signs unsigned transaction with the Trezor.
*/
void tx_sign(wallet_shim * wallet,
const ::tools::wallet2::unsigned_tx_set & unsigned_tx,
::tools::wallet2::signed_tx_set & signed_tx,
const wallet::unsigned_tx_set & unsigned_tx,
wallet::signed_tx_set & signed_tx,
hw::tx_aux_data & aux_data) override;
};

View File

@ -144,7 +144,7 @@ namespace chacha {
namespace ki {
bool key_image_data(wallet_shim * wallet,
const std::vector<tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
std::vector<MoneroTransferDetails> & res,
bool need_all_additionals)
{
@ -195,7 +195,7 @@ namespace ki {
}
void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
const std::vector<tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
bool need_subaddr_indices)
{
@ -396,7 +396,7 @@ namespace tx {
cur_output_in_batch_idx = 0;
}
Signer::Signer(wallet_shim *wallet2, const unsigned_tx_set * unsigned_tx, size_t tx_idx, hw::tx_aux_data * aux_data) {
Signer::Signer(wallet_shim *wallet2, const wallet::unsigned_tx_set * unsigned_tx, size_t tx_idx, hw::tx_aux_data * aux_data) {
m_wallet2 = wallet2;
m_unsigned_tx = unsigned_tx;
m_aux_data = aux_data;
@ -471,7 +471,7 @@ namespace tx {
void Signer::set_tx_input(MoneroTransactionSourceEntry * dst, size_t idx, bool need_ring_keys, bool need_ring_indices){
const cryptonote::tx_source_entry & src = cur_tx().sources[idx];
const tools::wallet2::transfer_details & transfer = get_source_transfer(idx);
const wallet::transfer_details & transfer = get_source_transfer(idx);
dst->set_real_output(src.real_output);
for(size_t i = 0; i < src.outputs.size(); ++i){

View File

@ -34,7 +34,8 @@
#include "device/device_cold.hpp"
#include "messages_map.hpp"
#include "transport.hpp"
#include "wallet/wallet2.h"
#include "wallet/tx_construction_data.h"
#include "wallet/tx_sets.h"
namespace hw{
namespace trezor{
@ -111,7 +112,7 @@ namespace ki {
* Converts transfer details to the MoneroTransferDetails required for KI sync
*/
bool key_image_data(wallet_shim * wallet,
const std::vector<tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
std::vector<MoneroTransferDetails> & res,
bool need_all_additionals=false);
@ -124,7 +125,7 @@ namespace ki {
* Generates KI sync request with commitments computed.
*/
void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
const std::vector<tools::wallet2::transfer_details> & transfers,
const std::vector<wallet::transfer_details> & transfers,
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
bool need_subaddr_indices=false);
@ -149,9 +150,6 @@ namespace tx {
using MoneroRctKey = messages::monero::MoneroTransactionSourceEntry_MoneroOutputEntry_MoneroRctKeyPublic;
using MoneroRsigData = messages::monero::MoneroTransactionRsigData;
using tx_construction_data = tools::wallet2::tx_construction_data;
using unsigned_tx_set = tools::wallet2::unsigned_tx_set;
void translate_address(MoneroAccountPublicAddress * dst, const cryptonote::account_public_address * src);
void translate_dst_entry(MoneroTransactionDestinationEntry * dst, const cryptonote::tx_destination_entry * src);
void translate_klrki(MoneroMultisigKLRki * dst, const rct::multisig_kLRki * src);
@ -170,7 +168,7 @@ namespace tx {
class TData {
public:
TsxData tsx_data;
tx_construction_data tx_data;
wallet::tx_construction_data tx_data;
cryptonote::transaction tx;
unsigned rsig_type;
int bp_version;
@ -212,27 +210,27 @@ namespace tx {
wallet_shim * m_wallet2;
size_t m_tx_idx;
const unsigned_tx_set * m_unsigned_tx;
const wallet::unsigned_tx_set * m_unsigned_tx;
hw::tx_aux_data * m_aux_data;
unsigned m_client_version;
bool m_multisig;
const tx_construction_data & cur_src_tx() const {
const wallet::tx_construction_data & cur_src_tx() const {
CHECK_AND_ASSERT_THROW_MES(m_tx_idx < m_unsigned_tx->txes.size(), "Invalid transaction index");
return m_unsigned_tx->txes[m_tx_idx];
}
const tx_construction_data & cur_tx() const {
const wallet::tx_construction_data & cur_tx() const {
return m_ct.tx_data;
}
const tools::wallet2::transfer_details & get_transfer(size_t idx) const {
const wallet::transfer_details & get_transfer(size_t idx) const {
CHECK_AND_ASSERT_THROW_MES(idx < m_unsigned_tx->transfers.second.size() + m_unsigned_tx->transfers.first && idx >= m_unsigned_tx->transfers.first, "Invalid transfer index");
return m_unsigned_tx->transfers.second[idx - m_unsigned_tx->transfers.first];
}
const tools::wallet2::transfer_details & get_source_transfer(size_t idx) const {
const wallet::transfer_details & get_source_transfer(size_t idx) const {
const auto & sel_transfers = cur_tx().selected_transfers;
CHECK_AND_ASSERT_THROW_MES(idx < m_ct.source_permutation.size(), "Invalid source index - permutation");
CHECK_AND_ASSERT_THROW_MES(m_ct.source_permutation[idx] < sel_transfers.size(), "Invalid source index");
@ -247,7 +245,7 @@ namespace tx {
void set_tx_input(MoneroTransactionSourceEntry * dst, size_t idx, bool need_ring_keys=false, bool need_ring_indices=false);
public:
Signer(wallet_shim * wallet2, const unsigned_tx_set * unsigned_tx, size_t tx_idx = 0, hw::tx_aux_data * aux_data = nullptr);
Signer(wallet_shim * wallet2, const wallet::unsigned_tx_set * unsigned_tx, size_t tx_idx = 0, hw::tx_aux_data * aux_data = nullptr);
std::shared_ptr<messages::monero::MoneroTransactionInitRequest> step_init();
void step_init_ack(std::shared_ptr<const messages::monero::MoneroTransactionInitAck> ack);

View File

@ -1326,7 +1326,7 @@ bool simple_wallet::import_multisig_main(const std::vector<std::string> &args, b
bool simple_wallet::accept_loaded_tx(const tools::wallet2::multisig_tx_set &txs)
{
std::string extra_message;
return accept_loaded_tx([&txs](){return txs.m_ptx.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.m_ptx[n].construction_data;}, extra_message);
return accept_loaded_tx([&txs](){return txs.m_ptx.size();}, [&txs](size_t n)->const wallet::tx_construction_data&{return txs.m_ptx[n].construction_data;}, extra_message);
}
bool simple_wallet::sign_multisig(const std::vector<std::string> &args)
@ -2084,7 +2084,7 @@ bool simple_wallet::frozen(const std::vector<std::string> &args)
{
if (!m_wallet->frozen(i))
continue;
const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(i);
const auto& td = m_wallet->get_transfer_details(i);
message_writer() << tr("Frozen: ") << td.m_key_image << " " << cryptonote::print_money(td.amount());
}
}
@ -5124,13 +5124,13 @@ bool simple_wallet::show_balance_unlocked(bool detailed)
return true;
success_msg_writer() << tr("Balance per address:");
success_msg_writer() << boost::format("%15s %21s %21s %7s %21s") % tr("Address") % tr("Balance") % tr("Unlocked balance") % tr("Outputs") % tr("Label");
std::vector<tools::wallet2::transfer_details> transfers;
std::vector<wallet::transfer_details> transfers;
m_wallet->get_transfers(transfers);
for (const auto& i : balance_per_subaddress)
{
cryptonote::subaddress_index subaddr_index = {m_current_subaddress_account, i.first};
std::string address_str = m_wallet->get_subaddress_as_str(subaddr_index).substr(0, 6);
uint64_t num_unspent_outputs = std::count_if(transfers.begin(), transfers.end(), [&subaddr_index](const tools::wallet2::transfer_details& td) { return !td.m_spent && td.m_subaddr_index == subaddr_index; });
uint64_t num_unspent_outputs = std::count_if(transfers.begin(), transfers.end(), [&subaddr_index](const wallet::transfer_details& td) { return !td.m_spent && td.m_subaddr_index == subaddr_index; });
success_msg_writer() << boost::format(tr("%8u %6s %21s %21s %7u %21s")) % i.first % address_str % print_money(i.second) % print_money(unlocked_balance_per_subaddress[i.first].first) % num_unspent_outputs % m_wallet->get_subaddress_label(subaddr_index);
}
return true;
@ -5458,7 +5458,7 @@ bool simple_wallet::process_ring_members(const std::vector<tools::wallet2::pendi
for (size_t n = 0; n < ptx_vector.size(); ++n)
{
const cryptonote::transaction& tx = ptx_vector[n].tx;
const tools::wallet2::tx_construction_data& construction_data = ptx_vector[n].construction_data;
const wallet::tx_construction_data& construction_data = ptx_vector[n].construction_data;
if (verbose)
ostr << boost::format(tr("\nTransaction %llu/%llu: txid=%s")) % (n + 1) % ptx_vector.size() % cryptonote::get_transaction_hash(tx);
// for each input
@ -5469,7 +5469,7 @@ bool simple_wallet::process_ring_members(const std::vector<tools::wallet2::pendi
if (!std::holds_alternative<cryptonote::txin_to_key>(tx.vin[i]))
continue;
const cryptonote::txin_to_key& in_key = std::get<cryptonote::txin_to_key>(tx.vin[i]);
const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(construction_data.selected_transfers[i]);
const wallet::transfer_details &td = m_wallet->get_transfer_details(construction_data.selected_transfers[i]);
const cryptonote::tx_source_entry *sptr = NULL;
for (const auto &src: construction_data.sources)
if (src.outputs[src.real_output].second.dest == td.get_public_key())
@ -7382,7 +7382,7 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args_)
return sweep_main(m_current_subaddress_account, below, Transfer::Normal, std::vector<std::string>(++args_.begin(), args_.end()));
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const wallet::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
{
// gather info to ask the user
uint64_t amount = 0, amount_to_dests = 0, change = 0;
@ -7392,7 +7392,7 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
std::string payment_id_string = "";
for (size_t n = 0; n < get_num_txes(); ++n)
{
const tools::wallet2::tx_construction_data &cd = get_tx(n);
const wallet::tx_construction_data &cd = get_tx(n);
std::vector<tx_extra_field> tx_extra_fields;
bool has_encrypted_payment_id = false;
@ -7534,7 +7534,7 @@ bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
std::string extra_message;
if (!txs.transfers.second.empty())
extra_message = (boost::format("%u outputs to import. ") % (unsigned)txs.transfers.second.size()).str();
return accept_loaded_tx([&txs](){return txs.txes.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.txes[n];}, extra_message);
return accept_loaded_tx([&txs](){return txs.txes.size();}, [&txs](size_t n)->const wallet::tx_construction_data&{return txs.txes[n];}, extra_message);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const tools::wallet2::signed_tx_set &txs)
@ -7542,7 +7542,7 @@ bool simple_wallet::accept_loaded_tx(const tools::wallet2::signed_tx_set &txs)
std::string extra_message;
if (!txs.key_images.empty())
extra_message = (boost::format("%u key images to import. ") % (unsigned)txs.key_images.size()).str();
return accept_loaded_tx([&txs](){return txs.ptx.size();}, [&txs](size_t n)->const tools::wallet2::tx_construction_data&{return txs.ptx[n].construction_data;}, extra_message);
return accept_loaded_tx([&txs](){return txs.ptx.size();}, [&txs](size_t n)->const wallet::tx_construction_data&{return txs.ptx[n].construction_data;}, extra_message);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sign_transfer(const std::vector<std::string> &args_)
@ -8220,7 +8220,7 @@ static bool parse_get_transfers_args(std::vector<std::string>& local_args, tools
}
//----------------------------------------------------------------------------------------------------
// mutates local_args as it parses and consumes arguments
bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vector<tools::transfer_view>& transfers)
bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vector<wallet::transfer_view>& transfers)
{
tools::wallet2::get_transfers_args_t args = {};
if (!parse_get_transfers_args(local_args, args))
@ -8245,7 +8245,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
LOCK_IDLE_SCOPE();
std::vector<tools::transfer_view> all_transfers;
std::vector<wallet::transfer_view> all_transfers;
if (!get_transfers(local_args, all_transfers))
return true;
@ -8258,12 +8258,12 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
{
switch (transfer.pay_type)
{
case tools::pay_type::in: color = epee::console_color_green; break;
case tools::pay_type::out: color = epee::console_color_yellow; break;
case tools::pay_type::miner: color = epee::console_color_cyan; break;
case tools::pay_type::governance: color = epee::console_color_cyan; break;
case tools::pay_type::stake: color = epee::console_color_blue; break;
case tools::pay_type::service_node: color = epee::console_color_cyan; break;
case wallet::pay_type::in: color = epee::console_color_green; break;
case wallet::pay_type::out: color = epee::console_color_yellow; break;
case wallet::pay_type::miner: color = epee::console_color_cyan; break;
case wallet::pay_type::governance: color = epee::console_color_cyan; break;
case wallet::pay_type::stake: color = epee::console_color_blue; break;
case wallet::pay_type::service_node: color = epee::console_color_cyan; break;
default: color = epee::console_color_magenta; break;
}
}
@ -8280,10 +8280,10 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
if (!destinations.empty())
destinations += ", ";
if (transfer.pay_type == tools::pay_type::in ||
transfer.pay_type == tools::pay_type::governance ||
transfer.pay_type == tools::pay_type::service_node ||
transfer.pay_type == tools::pay_type::miner)
if (transfer.pay_type == wallet::pay_type::in ||
transfer.pay_type == wallet::pay_type::governance ||
transfer.pay_type == wallet::pay_type::service_node ||
transfer.pay_type == wallet::pay_type::miner)
destinations += output.address.substr(0, 6);
else
destinations += output.address;
@ -8300,7 +8300,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
message_writer(color, false) << formatter
% (transfer.type.size() ? transfer.type : (transfer.height == 0 && transfer.blink_mempool) ? "blink" : std::to_string(transfer.height))
% tools::pay_type_string(transfer.pay_type)
% wallet::pay_type_string(transfer.pay_type)
% transfer.lock_msg
% (transfer.checkpointed ? "checkpointed" : transfer.was_blink ? "blink" : "no")
% tools::get_human_readable_timestamp(transfer.timestamp)
@ -8328,7 +8328,7 @@ bool simple_wallet::export_transfers(const std::vector<std::string>& args_)
LOCK_IDLE_SCOPE();
std::vector<tools::transfer_view> all_transfers;
std::vector<wallet::transfer_view> all_transfers;
// might consumes arguments in local_args
if (!get_transfers(local_args, all_transfers))
@ -8976,7 +8976,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
{
bool used = std::find_if(
transfers.begin(), transfers.end(),
[this, &index](const tools::wallet2::transfer_details& td) {
[this, &index](const wallet::transfer_details& td) {
return td.m_subaddr_index == cryptonote::subaddress_index{ m_current_subaddress_account, index };
}) != transfers.end();
success_msg_writer() << index << " " << m_wallet->get_subaddress_as_str({m_current_subaddress_account, index}) << " " << (index == 0 ? tr("Primary address") : m_wallet->get_subaddress_label({m_current_subaddress_account, index})) << " " << (used ? tr("(used)") : "");

View File

@ -291,7 +291,7 @@ namespace cryptonote
uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon(bool silent = false, rpc::version_t* version = nullptr);
bool ask_wallet_create_if_needed();
bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message = std::string());
bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const wallet::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message = std::string());
bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs);
bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs);
bool process_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr, bool verbose);
@ -305,7 +305,7 @@ namespace cryptonote
bool on_cancelled_command();
void check_for_inactivity_lock(bool user);
bool get_transfers(std::vector<std::string>& args_, std::vector<tools::transfer_view>& transfers);
bool get_transfers(std::vector<std::string>& args_, std::vector<wallet::transfer_view>& transfers);
/*!
* \brief Prints the seed with a nice message

View File

@ -34,6 +34,7 @@ add_library(wallet
node_rpc_proxy.cpp
message_store.cpp
message_transporter.cpp
transfer_view.cpp
)
target_link_libraries(wallet

View File

@ -97,7 +97,7 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName)
}
//----------------------------------------------------------------------------------------------------
bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const wallet::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message)
{
// gather info to ask the user
uint64_t amount = 0, amount_to_dests = 0, change = 0;
@ -107,7 +107,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu
std::string payment_id_string = "";
for (size_t n = 0; n < get_num_txes(); ++n)
{
const tools::wallet2::tx_construction_data &cd = get_tx(n);
const wallet::tx_construction_data &cd = get_tx(n);
std::vector<cryptonote::tx_extra_field> tx_extra_fields;
bool has_encrypted_payment_id = false;

View File

@ -58,7 +58,7 @@ public:
private:
// Callback function to check all loaded tx's and generate confirmationMessage
bool checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message);
bool checkLoadedTx(const std::function<size_t()> get_num_txes, const std::function<const wallet::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message);
friend class WalletImpl;
WalletImpl &m_wallet;

View File

@ -1169,7 +1169,7 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
std::string extra_message;
if (!transaction->m_unsigned_tx_set.transfers.second.empty())
extra_message = (boost::format("%u outputs to import. ") % (unsigned)transaction->m_unsigned_tx_set.transfers.second.size()).str();
transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message);
transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const wallet::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message);
setStatus(transaction->status(), transaction->errorString());
return transaction;

View File

@ -0,0 +1,84 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <ringct/rctTypes.h>
#include <boost/serialization/version.hpp>
namespace wallet {
struct multisig_info
{
struct LR
{
rct::key m_L;
rct::key m_R;
};
crypto::public_key m_signer;
std::vector<LR> m_LR;
std::vector<crypto::key_image> m_partial_key_images; // one per key the participant has
};
template <class Archive>
void serialize_value(Archive& ar, multisig_info::LR& x) {
field(ar, "m_L", x.m_L);
field(ar, "m_R", x.m_R);
}
template <class Archive>
void serialize_value(Archive& ar, multisig_info& x) {
field(ar, "m_signer", x.m_signer);
field(ar, "m_LR", x.m_LR);
field(ar, "m_partial_key_images", x.m_partial_key_images);
}
}
BOOST_CLASS_VERSION(wallet::multisig_info::LR, 0)
BOOST_CLASS_VERSION(wallet::multisig_info, 1)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::multisig_info::LR &x, const unsigned int /*ver*/)
{
a & x.m_L;
a & x.m_R;
}
template <class Archive>
void serialize(Archive &a, wallet::multisig_info &x, const unsigned int /*ver*/)
{
a & x.m_signer;
a & x.m_LR;
a & x.m_partial_key_images;
}
}

63
src/wallet/multisig_sig.h Normal file
View File

@ -0,0 +1,63 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <unordered_set>
#include <boost/serialization/version.hpp>
#include "ringct/rctTypes.h"
namespace wallet {
struct multisig_sig
{
rct::rctSig sigs;
std::unordered_set<crypto::public_key> ignore;
std::unordered_set<rct::key> used_L;
std::unordered_set<crypto::public_key> signing_keys;
rct::multisig_out msout;
};
}
BOOST_CLASS_VERSION(wallet::multisig_sig, 0)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::multisig_sig &x, const unsigned int ver)
{
a & x.sigs;
a & x.ignore;
a & x.used_L;
a & x.signing_keys;
a & x.msout;
}
}

111
src/wallet/pending_tx.h Normal file
View File

@ -0,0 +1,111 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <cryptonote_core/cryptonote_tx_utils.h>
#include "tx_construction_data.h"
#include "multisig_sig.h"
namespace wallet {
// The convention for destinations is:
// dests does not include change
// splitted_dsts (in construction_data) does
struct pending_tx
{
cryptonote::transaction tx;
uint64_t dust, fee;
bool dust_added_to_fee;
cryptonote::tx_destination_entry change_dts;
std::vector<size_t> selected_transfers;
std::string key_images;
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::vector<cryptonote::tx_destination_entry> dests;
std::vector<multisig_sig> multisig_sigs;
wallet::tx_construction_data construction_data;
};
template <class Archive>
void serialize_value(Archive& ar, pending_tx& x) {
field(ar, "tx", x.tx);
field(ar, "dust", x.dust);
field(ar, "fee", x.fee);
field(ar, "dust_added_to_fee", x.dust_added_to_fee);
field(ar, "change_dts", x.change_dts);
field(ar, "selected_transfers", x.selected_transfers);
field(ar, "key_images", x.key_images);
field(ar, "tx_key", x.tx_key);
field(ar, "additional_tx_keys", x.additional_tx_keys);
field(ar, "dests", x.dests);
field(ar, "construction_data", x.construction_data);
field(ar, "multisig_sigs", x.multisig_sigs);
};
}
BOOST_CLASS_VERSION(wallet::pending_tx, 3)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::pending_tx &x, const unsigned int ver)
{
a & x.tx;
a & x.dust;
a & x.fee;
a & x.dust_added_to_fee;
a & x.change_dts;
if (ver < 2)
{
// load list to vector
std::list<size_t> selected_transfers;
a & selected_transfers;
x.selected_transfers.clear();
x.selected_transfers.reserve(selected_transfers.size());
for (size_t t: selected_transfers)
x.selected_transfers.push_back(t);
}
a & x.key_images;
a & x.tx_key;
a & x.dests;
a & x.construction_data;
if (ver < 1)
return;
a & x.additional_tx_keys;
if (ver < 2)
return;
a & x.selected_transfers;
if (ver < 3)
return;
a & x.multisig_sigs;
}
}

View File

@ -0,0 +1,50 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "common/loki.h"
#include <string>
#include <cstdint>
#include "serialization/keyvalue_serialization.h"
namespace wallet {
LOKI_RPC_DOC_INTROSPECT
struct transfer_destination
{
std::string address; // Destination public address.
uint64_t amount; // Amount to send to each destination, in atomic units.
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE(address)
END_KV_SERIALIZE_MAP()
};
}

View File

@ -0,0 +1,147 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/subaddress_index.h"
#include "multisig_info.h"
namespace wallet {
struct transfer_details
{
uint64_t m_block_height;
cryptonote::transaction_prefix m_tx;
crypto::hash m_txid;
size_t m_internal_output_index;
uint64_t m_global_output_index;
bool m_spent;
bool m_frozen;
bool m_unmined_blink;
bool m_was_blink;
uint64_t m_spent_height;
crypto::key_image m_key_image; //TODO: key_image stored twice :(
rct::key m_mask;
uint64_t m_amount;
bool m_rct;
bool m_key_image_known;
bool m_key_image_request; // view wallets: we want to request it; cold wallets: it was requested
size_t m_pk_index;
cryptonote::subaddress_index m_subaddr_index;
bool m_key_image_partial;
std::vector<rct::key> m_multisig_k;
std::vector<multisig_info> m_multisig_info; // one per other participant
std::vector<std::pair<uint64_t, crypto::hash>> m_uses;
bool is_rct() const { return m_rct; }
uint64_t amount() const { return m_amount; }
const crypto::public_key &get_public_key() const {
return std::get<cryptonote::txout_to_key>(m_tx.vout[m_internal_output_index].target).key;
}
};
template <class Archive>
void serialize_value(Archive& ar, transfer_details& x) {
field(ar, "m_block_height", x.m_block_height);
field(ar, "m_tx", x.m_tx);
field(ar, "m_txid", x.m_txid);
field(ar, "m_internal_output_index", x.m_internal_output_index);
field(ar, "m_global_output_index", x.m_global_output_index);
field(ar, "m_spent", x.m_spent);
field(ar, "m_frozen", x.m_frozen);
field(ar, "m_unmined_blink", x.m_unmined_blink);
field(ar, "m_was_blink", x.m_was_blink);
field(ar, "m_spent_height", x.m_spent_height);
field(ar, "m_key_image", x.m_key_image);
field(ar, "m_mask", x.m_mask);
field(ar, "m_amount", x.m_amount);
field(ar, "m_rct", x.m_rct);
field(ar, "m_key_image_known", x.m_key_image_known);
field(ar, "m_key_image_request", x.m_key_image_request);
field(ar, "m_pk_index", x.m_pk_index);
field(ar, "m_subaddr_index", x.m_subaddr_index);
field(ar, "m_key_image_partial", x.m_key_image_partial);
field(ar, "m_multisig_k", x.m_multisig_k);
field(ar, "m_multisig_info", x.m_multisig_info);
field(ar, "m_uses", x.m_uses);
}
}
BOOST_CLASS_VERSION(wallet::transfer_details, 14)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::transfer_details &x, const unsigned int ver)
{
a & x.m_block_height;
a & x.m_global_output_index;
a & x.m_internal_output_index;
a & x.m_tx;
a & x.m_spent;
a & x.m_key_image;
a & x.m_mask;
a & x.m_amount;
a & x.m_spent_height;
a & x.m_txid;
a & x.m_rct;
a & x.m_key_image_known;
a & x.m_pk_index;
a & x.m_subaddr_index;
a & x.m_multisig_info;
a & x.m_multisig_k;
a & x.m_key_image_partial;
if (ver > 9)
a & x.m_key_image_request;
if (ver > 10)
a & x.m_uses;
if (ver > 11)
a & x.m_frozen;
if (ver > 12)
a & x.m_unmined_blink;
if (ver > 13)
a & x.m_was_blink;
if constexpr (typename Archive::is_loading())
{
if (ver < 10)
x.m_key_image_request = false;
if (ver < 12)
x.m_frozen = false;
if (ver < 13)
x.m_unmined_blink = false;
if (ver < 14)
x.m_was_blink = false;
}
}
}

View File

@ -0,0 +1,39 @@
#include "transfer_view.h"
namespace wallet {
KV_SERIALIZE_MAP_CODE_BEGIN(transfer_view)
KV_SERIALIZE(txid);
KV_SERIALIZE(payment_id);
KV_SERIALIZE(height);
KV_SERIALIZE(timestamp);
KV_SERIALIZE(amount);
KV_SERIALIZE(fee);
KV_SERIALIZE(note);
KV_SERIALIZE(destinations);
// TODO(loki): This discrepancy between having to use pay_type if type is
// empty and type if pay type is neither is super unintuitive.
if (this_ref.type.empty())
{
std::string type = pay_type_string(this_ref.pay_type);
KV_SERIALIZE_VALUE(type)
}
else
{
KV_SERIALIZE(type)
}
KV_SERIALIZE(unlock_time)
KV_SERIALIZE(subaddr_index);
KV_SERIALIZE(subaddr_indices);
KV_SERIALIZE(address);
KV_SERIALIZE(double_spend_seen)
KV_SERIALIZE_OPT(confirmations, (uint64_t)0)
KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0)
KV_SERIALIZE(checkpointed)
KV_SERIALIZE(blink_mempool)
KV_SERIALIZE(was_blink)
KV_SERIALIZE_MAP_CODE_END()
}

View File

@ -0,0 +1,99 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "common/loki.h"
#include <string>
#include <vector>
#include "cryptonote_basic/subaddress_index.h"
#include "transfer_destination.h"
#include "crypto/hash.h"
namespace wallet {
enum struct pay_type
{
unspecified, // For serialized data before this was introduced in hardfork 10
in,
out,
stake,
miner,
service_node,
governance
};
inline const char *pay_type_string(pay_type type)
{
switch(type)
{
case pay_type::unspecified: return "n/a";
case pay_type::in: return "in";
case pay_type::out: return "out";
case pay_type::stake: return "stake";
case pay_type::miner: return "miner";
case pay_type::service_node: return "snode";
case pay_type::governance: return "gov";
default: assert(false); return "xxxxx";
}
}
LOKI_RPC_DOC_INTROSPECT
struct transfer_view
{
std::string txid; // Transaction ID for this transfer.
std::string payment_id; // Payment ID for this transfer.
uint64_t height; // Height of the first block that confirmed this transfer (0 if not mined yet).
uint64_t timestamp; // UNIX timestamp for when this transfer was first confirmed in a block (or timestamp submission if not mined yet).
uint64_t amount; // Amount transferred.
uint64_t fee; // Transaction fee for this transfer.
std::string note; // Note about this transfer.
std::list<transfer_destination> destinations; // Array of transfer destinations.
std::string type; // Type of transfer, one of the following: "in", "out", "stake", "miner", "snode", "gov", "pending", "failed", "pool".
uint64_t unlock_time; // Number of blocks until transfer is safely spendable.
bool locked; // If the transfer is locked or not
cryptonote::subaddress_index subaddr_index; // Major & minor index, account and subaddress index respectively.
std::vector<cryptonote::subaddress_index> subaddr_indices;
std::string address; // Address that transferred the funds.
bool double_spend_seen; // True if the key image(s) for the transfer have been seen before.
uint64_t confirmations; // Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
uint64_t suggested_confirmations_threshold; // Estimation of the confirmations needed for the transaction to be included in a block.
uint64_t checkpointed; // If transfer is backed by atleast 2 Service Node Checkpoints, 0 if it is not, see immutable_height in the daemon rpc call get_info
bool blink_mempool; // True if this is an approved blink tx in the mempool
bool was_blink; // True if we saw this as an approved blink (either in the mempool or a recent, uncheckpointed block). Note that if we didn't see it while an active blink this won't be set.
// Not serialized, for internal wallet2 use
wallet::pay_type pay_type; // @NoLokiRPCDocGen Internal use only, not serialized
bool confirmed; // @NoLokiRPCDocGen Internal use only, not serialized
crypto::hash hash; // @NoLokiRPCDocGen Internal use only, not serialized
std::string lock_msg; // @NoLokiRPCDocGen Internal use only, not serialized
KV_MAP_SERIALIZABLE
};
}

View File

@ -0,0 +1,133 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
#include "cryptonote_core/cryptonote_tx_utils.h"
namespace wallet {
struct tx_construction_data
{
std::vector<cryptonote::tx_source_entry> sources;
cryptonote::tx_destination_entry change_dts;
std::vector<cryptonote::tx_destination_entry> splitted_dsts; // split, includes change
std::vector<size_t> selected_transfers;
std::vector<uint8_t> extra;
uint64_t unlock_time;
rct::RCTConfig rct_config;
std::vector<cryptonote::tx_destination_entry> dests; // original setup, does not include change
uint32_t subaddr_account; // subaddress account of your wallet to be used in this transfer
std::set<uint32_t> subaddr_indices; // set of address indices used as inputs in this transfer
uint8_t hf_version;
cryptonote::txtype tx_type;
};
template <class Archive>
void serialize_value(Archive& ar, tx_construction_data& x) {
field(ar, "sources", x.sources);
field(ar, "change_dts", x.change_dts);
field(ar, "splitted_dsts", x.splitted_dsts);
field(ar, "selected_transfers", x.selected_transfers);
field(ar, "extra", x.extra);
field(ar, "unlock_time", x.unlock_time);
field(ar, "rct_config", x.rct_config);
field(ar, "dests", x.dests);
field(ar, "subaddr_account", x.subaddr_account);
field(ar, "subaddr_indices", x.subaddr_indices);
field(ar, "hf_version", x.hf_version);
field_varint(ar, "tx_type", x.tx_type, [](auto& t) { return t < cryptonote::txtype::_count; });
}
}
BOOST_CLASS_VERSION(wallet::tx_construction_data, 6)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::tx_construction_data &x, const unsigned int ver)
{
a & x.sources;
a & x.change_dts;
a & x.splitted_dsts;
if (ver < 2)
{
// load list to vector
std::list<size_t> selected_transfers;
a & selected_transfers;
x.selected_transfers.clear();
x.selected_transfers.reserve(selected_transfers.size());
for (size_t t: selected_transfers)
x.selected_transfers.push_back(t);
}
a & x.extra;
a & x.unlock_time;
a & x.dests;
if (ver < 1)
{
x.subaddr_account = 0;
return;
}
a & x.subaddr_account;
a & x.subaddr_indices;
if (!typename Archive::is_saving())
{
x.rct_config = { rct::RangeProofBorromean, 0 };
if (ver < 6)
{
x.tx_type = cryptonote::txtype::standard;
x.hf_version = cryptonote::network_version_13_enforce_checkpoints;
}
}
if (ver < 2)
return;
a & x.selected_transfers;
if (ver < 3)
return;
if (ver < 5)
{
bool use_bulletproofs = x.rct_config.range_proof_type != rct::RangeProofBorromean;
a & use_bulletproofs;
if (!typename Archive::is_saving())
x.rct_config = { use_bulletproofs ? rct::RangeProofBulletproof : rct::RangeProofBorromean, 0 };
return;
}
a & x.rct_config;
if (ver < 6) return;
a & x.tx_type;
a & x.hf_version;
}
}

98
src/wallet/tx_sets.h Normal file
View File

@ -0,0 +1,98 @@
// Copyright (c) 2018-2020, The Loki Project
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "tx_construction_data.h"
#include "transfer_details.h"
#include "pending_tx.h"
namespace wallet {
// The term "Unsigned tx" is not really a tx since it's not signed yet.
// It doesnt have tx hash, key and the integrated address is not separated into addr + payment id.
struct unsigned_tx_set
{
std::vector<wallet::tx_construction_data> txes;
std::pair<size_t, std::vector<wallet::transfer_details>> transfers;
};
struct signed_tx_set
{
std::vector<pending_tx> ptx;
std::vector<crypto::key_image> key_images;
std::unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
};
struct multisig_tx_set
{
std::vector<pending_tx> m_ptx;
std::unordered_set<crypto::public_key> m_signers;
};
template <class Archive>
void serialize_value(Archive& ar, multisig_tx_set& x) {
field(ar, "m_ptx", x.m_ptx);
field(ar, "m_signers", x.m_signers);
};
}
BOOST_CLASS_VERSION(wallet::unsigned_tx_set, 0)
BOOST_CLASS_VERSION(wallet::signed_tx_set, 1)
BOOST_CLASS_VERSION(wallet::multisig_tx_set, 1)
namespace boost::serialization {
template <class Archive>
void serialize(Archive &a, wallet::unsigned_tx_set &x, const unsigned int ver)
{
a & x.txes;
a & x.transfers;
}
template <class Archive>
void serialize(Archive &a, wallet::signed_tx_set &x, const unsigned int ver)
{
a & x.ptx;
a & x.key_images;
if (ver < 1)
return;
a & x.tx_key_images;
}
template <class Archive>
void serialize(Archive &a, wallet::multisig_tx_set &x, const unsigned int ver)
{
a & x.m_ptx;
a & x.m_signers;
}
}

View File

@ -875,9 +875,9 @@ bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pend
return false;
}
tools::wallet2::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
wallet::tx_construction_data get_construction_data_with_decrypted_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
{
tools::wallet2::tx_construction_data construction_data = ptx.construction_data;
wallet::tx_construction_data construction_data = ptx.construction_data;
crypto::hash8 payment_id = null_hash8;
if (get_short_payment_id(payment_id, ptx, hwdev))
{
@ -1779,7 +1779,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
uint64_t unlock_time = tx.get_unlock_time(vout_index);
tx_money_got_in_out entry = {};
entry.type = pay_type::in;
entry.type = wallet::pay_type::in;
entry.index = tx_scan_info.received->index;
entry.amount = tx_scan_info.money_transfered;
entry.unlock_time = unlock_time;
@ -1787,9 +1787,9 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
if (cryptonote::is_coinbase(tx))
{
// TODO(doyle): When batched governance comes in, this needs to check that the TX has a governance output, can't assume last one is governance
if (vout_index == 0) entry.type = pay_type::miner;
// else if (vout_index == tx.vout.size() - 1) entry.type = pay_type::governance;
else entry.type = pay_type::service_node;
if (vout_index == 0) entry.type = wallet::pay_type::miner;
// else if (vout_index == tx.vout.size() - 1) entry.type = wallet::pay_type::governance;
else entry.type = wallet::pay_type::service_node;
}
tx_money_got_in_outs.push_back(entry);
@ -2540,7 +2540,7 @@ void wallet2::process_unconfirmed(const crypto::hash &txid, const cryptonote::tr
// TODO(doyle): LNS introduces tx type stake, we can use this to quickly determine if a transaction is staking
// transaction without having to parse tx_extra.
bool stake = service_nodes::tx_get_staking_components(tx, nullptr /*stake*/);
tools::pay_type pay_type = stake ? tools::pay_type::stake : tools::pay_type::out;
wallet::pay_type pay_type = stake ? wallet::pay_type::stake : wallet::pay_type::out;
m_confirmed_txs.insert(std::make_pair(txid, confirmed_transfer_details(unconf_it->second, height)));
}
catch (...) {
@ -2580,7 +2580,7 @@ void wallet2::process_outgoing(const crypto::hash &txid, const cryptonote::trans
entry.first->second.m_subaddr_indices = subaddr_indices;
bool stake = service_nodes::tx_get_staking_components(tx, nullptr /*stake*/);
entry.first->second.m_pay_type = stake ? tools::pay_type::stake : tools::pay_type::out;
entry.first->second.m_pay_type = stake ? wallet::pay_type::stake : wallet::pay_type::out;
}
entry.first->second.m_rings.clear();
@ -6222,7 +6222,7 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con
incoming_transfers = m_transfers;
}
//------------------------------------------------------------------------------------------------------------------------------
static void set_confirmations(transfer_view &entry, uint64_t blockchain_height, uint64_t block_reward)
static void set_confirmations(wallet::transfer_view &entry, uint64_t blockchain_height, uint64_t block_reward)
{
if (entry.height >= blockchain_height || (entry.height == 0 && (entry.blink_mempool || entry.type == "pending" || entry.type == "pool")))
entry.confirmations = 0;
@ -6235,9 +6235,9 @@ static void set_confirmations(transfer_view &entry, uint64_t blockchain_height,
entry.suggested_confirmations_threshold = (entry.amount + block_reward - 1) / block_reward;
}
//----------------------------------------------------------------------------------------------------
transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const
wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const
{
transfer_view result = {};
wallet::transfer_view result = {};
result.txid = string_tools::pod_to_hex(pd.m_tx_hash);
result.hash = txid;
result.payment_id = string_tools::pod_to_hex(payment_id);
@ -6265,9 +6265,9 @@ transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const crypto
return result;
}
//------------------------------------------------------------------------------------------------------------------------------
transfer_view wallet2::wallet2::make_transfer_view(const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const
wallet::transfer_view wallet2::wallet2::make_transfer_view(const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const
{
transfer_view result = {};
wallet::transfer_view result = {};
result.txid = string_tools::pod_to_hex(txid);
result.hash = txid;
result.payment_id = string_tools::pod_to_hex(pd.m_payment_id);
@ -6284,7 +6284,7 @@ transfer_view wallet2::wallet2::make_transfer_view(const crypto::hash &txid, con
for (const auto &d: pd.m_dests) {
result.destinations.push_back({});
transfer_destination &td = result.destinations.back();
auto& td = result.destinations.back();
td.amount = d.amount;
td.address = d.address(nettype(), pd.m_payment_id);
}
@ -6300,9 +6300,9 @@ transfer_view wallet2::wallet2::make_transfer_view(const crypto::hash &txid, con
return result;
}
//------------------------------------------------------------------------------------------------------------------------------
transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const tools::wallet2::unconfirmed_transfer_details &pd) const
wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const tools::wallet2::unconfirmed_transfer_details &pd) const
{
transfer_view result = {};
wallet::transfer_view result = {};
bool is_failed = pd.m_state == tools::wallet2::unconfirmed_transfer_details::failed;
result.txid = string_tools::pod_to_hex(txid);
result.hash = txid;
@ -6320,7 +6320,7 @@ transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const tools:
for (const auto &d: pd.m_dests) {
result.destinations.push_back({});
transfer_destination &td = result.destinations.back();
auto& td = result.destinations.back();
td.amount = d.amount;
td.address = d.address(nettype(), pd.m_payment_id);
}
@ -6335,9 +6335,9 @@ transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const tools:
return result;
}
//------------------------------------------------------------------------------------------------------------------------------
transfer_view wallet2::make_transfer_view(const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &ppd) const
wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &ppd) const
{
transfer_view result = {};
wallet::transfer_view result = {};
const tools::wallet2::payment_details &pd = ppd.m_pd;
result.txid = string_tools::pod_to_hex(pd.m_tx_hash);
result.hash = pd.m_tx_hash;
@ -6352,7 +6352,7 @@ transfer_view wallet2::make_transfer_view(const crypto::hash &payment_id, const
result.fee = pd.m_fee;
result.note = get_tx_note(pd.m_tx_hash);
result.double_spend_seen = ppd.m_double_spend_seen;
result.pay_type = pay_type::unspecified;
result.pay_type = wallet::pay_type::unspecified;
result.type = "pool";
result.subaddr_index = pd.m_subaddr_index;
result.subaddr_indices.push_back(pd.m_subaddr_index);
@ -6361,7 +6361,7 @@ transfer_view wallet2::make_transfer_view(const crypto::hash &payment_id, const
return result;
}
//----------------------------------------------------------------------------------------------------
void wallet2::get_transfers(get_transfers_args_t args, std::vector<transfer_view>& transfers)
void wallet2::get_transfers(get_transfers_args_t args, std::vector<wallet::transfer_view>& transfers)
{
std::optional<uint32_t> account_index = args.account_index;
if (args.all_accounts)
@ -6419,7 +6419,7 @@ void wallet2::get_transfers(get_transfers_args_t args, std::vector<transfer_view
{
bool add_entry = true;
if (args.stake && args_count == 1)
add_entry = o.second.m_pay_type == tools::pay_type::stake;
add_entry = o.second.m_pay_type == wallet::pay_type::stake;
if (add_entry)
transfers.push_back(make_transfer_view(o.first, o.second));
@ -6433,7 +6433,7 @@ void wallet2::get_transfers(get_transfers_args_t args, std::vector<transfer_view
for (const auto &p : pool)
transfers.push_back(make_transfer_view(p.first, p.second));
std::sort(transfers.begin(), transfers.end(), [](const transfer_view& a, const transfer_view& b) -> bool {
std::sort(transfers.begin(), transfers.end(), [](const auto& a, const auto& b) -> bool {
if (a.confirmed != b.confirmed)
return a.confirmed;
if (a.blink_mempool != b.blink_mempool)
@ -6446,7 +6446,7 @@ void wallet2::get_transfers(get_transfers_args_t args, std::vector<transfer_view
});
}
std::string wallet2::transfers_to_csv(const std::vector<transfer_view>& transfers, bool formatting) const
std::string wallet2::transfers_to_csv(const std::vector<wallet::transfer_view>& transfers, bool formatting) const
{
uint64_t running_balance = 0;
auto data_formatter = boost::format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,'%s',%s");
@ -6490,16 +6490,16 @@ std::string wallet2::transfers_to_csv(const std::vector<transfer_view>& transfer
{
switch (transfer.pay_type)
{
case tools::pay_type::in:
case tools::pay_type::miner:
case tools::pay_type::service_node:
case tools::pay_type::governance:
case wallet::pay_type::in:
case wallet::pay_type::miner:
case wallet::pay_type::service_node:
case wallet::pay_type::governance:
running_balance += transfer.amount;
break;
case tools::pay_type::stake:
case wallet::pay_type::stake:
running_balance -= transfer.fee;
break;
case tools::pay_type::out:
case wallet::pay_type::out:
running_balance -= transfer.amount + transfer.fee;
break;
default:
@ -6963,7 +6963,7 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amo
utd.m_subaddr_account = subaddr_account;
utd.m_subaddr_indices = subaddr_indices;
bool stake = service_nodes::tx_get_staking_components(tx, nullptr /*stake*/);
utd.m_pay_type = stake ? tools::pay_type::stake : tools::pay_type::out;
utd.m_pay_type = stake ? wallet::pay_type::stake : wallet::pay_type::out;
for (const auto &in: tx.vin)
{
if (!std::holds_alternative<cryptonote::txin_to_key>(in))
@ -7006,8 +7006,6 @@ crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const
// take a pending tx and actually send it to the daemon
void wallet2::commit_tx(pending_tx& ptx, bool blink)
{
using namespace cryptonote;
if(m_light_wallet)
{
light_rpc::SUBMIT_RAW_TX::request oreq{};
@ -7227,7 +7225,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
// sign the transactions
for (size_t n = 0; n < exported_txs.txes.size(); ++n)
{
tools::wallet2::tx_construction_data &sd = exported_txs.txes[n];
auto &sd = exported_txs.txes[n];
THROW_WALLET_EXCEPTION_IF(sd.sources.empty(), error::wallet_internal_error, "Empty sources");
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
signed_txes.ptx.push_back(pending_tx());
@ -7704,7 +7702,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
{
tools::wallet2::pending_tx &ptx = exported_txs.m_ptx[n];
THROW_WALLET_EXCEPTION_IF(ptx.multisig_sigs.empty(), error::wallet_internal_error, "No signatures found in multisig tx");
tools::wallet2::tx_construction_data &sd = ptx.construction_data;
auto &sd = ptx.construction_data;
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, mixin " << (sd.sources[0].outputs.size()-1) <<
", signed by " << exported_txs.m_signers.size() << "/" << m_multisig_threshold);
cryptonote::transaction tx;
@ -9885,7 +9883,6 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const loki_construct_tx_params &tx_params)
{
using namespace cryptonote;
// throw if attempting a transaction with no destinations
THROW_WALLET_EXCEPTION_IF(dsts.empty(), error::zero_destination);
@ -10117,7 +10114,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
}
THROW_WALLET_EXCEPTION_IF(ins_order.size() != sources.size(), error::wallet_internal_error, "Failed to work out sources permutation");
std::vector<tools::wallet2::multisig_sig> multisig_sigs;
std::vector<wallet::multisig_sig> multisig_sigs;
if (m_multisig)
{
auto ignore = ignore_sets.empty() ? std::unordered_set<crypto::public_key>() : ignore_sets.front();
@ -10633,7 +10630,7 @@ void wallet2::light_wallet_get_address_txs()
address_tx.m_block_height = t.height;
address_tx.m_unlock_time = t.unlock_time;
address_tx.m_timestamp = t.timestamp;
address_tx.m_type = t.coinbase ? pay_type::miner : pay_type::in; // TODO(loki): Only accounts for miner, but wait, do we even care about this code? Looks like openmonero code
address_tx.m_type = t.coinbase ? wallet::pay_type::miner : wallet::pay_type::in; // TODO(loki): Only accounts for miner, but wait, do we even care about this code? Looks like openmonero code
address_tx.m_mempool = t.mempool;
m_light_wallet_address_txs.emplace(tx_hash,address_tx);
@ -10649,7 +10646,7 @@ void wallet2::light_wallet_get_address_txs()
payment.m_block_height = t.height;
payment.m_unlock_time = t.unlock_time;
payment.m_timestamp = t.timestamp;
payment.m_type = t.coinbase ? pay_type::miner : pay_type::in; // TODO(loki): Only accounts for miner, but wait, do we even care about this code? Looks like openmonero code
payment.m_type = t.coinbase ? wallet::pay_type::miner : wallet::pay_type::in; // TODO(loki): Only accounts for miner, but wait, do we even care about this code? Looks like openmonero code
if (t.mempool) {
if (std::find(unconfirmed_payments_txs.begin(), unconfirmed_payments_txs.end(), tx_hash) == unconfirmed_payments_txs.end()) {
@ -13711,7 +13708,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
pd.m_block_height = 0; // spent block height is unknown
const crypto::hash &spent_txid = crypto::null_hash; // spent txid is unknown
bool stake = service_nodes::tx_get_staking_components(td.m_tx, nullptr /*stake*/, td.m_txid);
pd.m_pay_type = stake ? tools::pay_type::stake : tools::pay_type::out;
pd.m_pay_type = stake ? wallet::pay_type::stake : wallet::pay_type::out;
m_confirmed_txs.insert(std::make_pair(spent_txid, pd));
}
PERF_TIMER_STOP(import_key_images_G);
@ -14107,7 +14104,7 @@ crypto::key_image wallet2::get_multisig_composite_key_image(size_t n) const
//----------------------------------------------------------------------------------------------------
cryptonote::blobdata wallet2::export_multisig()
{
std::vector<tools::wallet2::multisig_info> info;
std::vector<wallet::multisig_info> info;
const crypto::public_key signer = get_multisig_signer_public_key();
@ -14156,7 +14153,7 @@ cryptonote::blobdata wallet2::export_multisig()
return ciphertext;
}
//----------------------------------------------------------------------------------------------------
void wallet2::update_multisig_rescan_info(const std::vector<std::vector<rct::key>> &multisig_k, const std::vector<std::vector<tools::wallet2::multisig_info>> &info, size_t n)
void wallet2::update_multisig_rescan_info(const std::vector<std::vector<rct::key>> &multisig_k, const std::vector<std::vector<wallet::multisig_info>> &info, size_t n)
{
CHECK_AND_ASSERT_THROW_MES(n < m_transfers.size(), "Bad index in update_multisig_info");
CHECK_AND_ASSERT_THROW_MES(multisig_k.size() >= m_transfers.size(), "Mismatched sizes of multisig_k and info");
@ -14182,7 +14179,7 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
{
CHECK_AND_ASSERT_THROW_MES(m_multisig, "Wallet is not multisig");
std::vector<std::vector<tools::wallet2::multisig_info>> info;
std::vector<std::vector<wallet::multisig_info>> info;
std::unordered_set<crypto::public_key> seen;
for (cryptonote::blobdata &data: blobs)
{
@ -14216,7 +14213,7 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
body.remove_prefix(headerlen);
std::stringstream iss;
iss << body;
std::vector<tools::wallet2::multisig_info> i;
std::vector<wallet::multisig_info> i;
boost::archive::portable_binary_iarchive ar(iss);
ar >> i;
MINFO(i.size() << " outputs found");

View File

@ -66,6 +66,15 @@
#include "message_store.h"
#include "wallet_light_rpc.h"
#include "tx_construction_data.h"
#include "tx_sets.h"
#include "transfer_destination.h"
#include "transfer_details.h"
#include "transfer_view.h"
#include "multisig_info.h"
#include "pending_tx.h"
#include "multisig_sig.h"
#include "common/loki_integration_test_hooks.h"
#include "wipeable_string.h"
@ -170,36 +179,10 @@ private:
wallet2 * wallet;
};
enum struct pay_type
{
unspecified, // For serialized data before this was introduced in hardfork 10
in,
out,
stake,
miner,
service_node,
governance
};
inline const char *pay_type_string(pay_type type)
{
switch(type)
{
case pay_type::unspecified: return "n/a";
case pay_type::in: return "in";
case pay_type::out: return "out";
case pay_type::stake: return "stake";
case pay_type::miner: return "miner";
case pay_type::service_node: return "snode";
case pay_type::governance: return "gov";
default: assert(false); return "xxxxx";
}
}
struct tx_money_got_in_out
{
cryptonote::subaddress_index index;
pay_type type;
wallet::pay_type type;
uint64_t amount;
uint64_t unlock_time;
};
@ -223,7 +206,7 @@ private:
void refill(const crypto::hash &hash) { m_blockchain.push_back(hash); --m_offset; }
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
void serialize(t_archive &a, const unsigned int ver)
{
a & m_offset;
a & m_genesis;
@ -236,84 +219,7 @@ private:
std::deque<crypto::hash> m_blockchain;
};
enum class stake_check_result { allowed, not_allowed, try_later };
LOKI_RPC_DOC_INTROSPECT
struct transfer_destination
{
std::string address; // Destination public address.
uint64_t amount; // Amount to send to each destination, in atomic units.
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE(address)
END_KV_SERIALIZE_MAP()
};
LOKI_RPC_DOC_INTROSPECT
struct transfer_view
{
std::string txid; // Transaction ID for this transfer.
std::string payment_id; // Payment ID for this transfer.
uint64_t height; // Height of the first block that confirmed this transfer (0 if not mined yet).
uint64_t timestamp; // UNIX timestamp for when this transfer was first confirmed in a block (or timestamp submission if not mined yet).
uint64_t amount; // Amount transferred.
uint64_t fee; // Transaction fee for this transfer.
std::string note; // Note about this transfer.
std::list<transfer_destination> destinations; // Array of transfer destinations.
std::string type; // Type of transfer, one of the following: "in", "out", "stake", "miner", "snode", "gov", "pending", "failed", "pool".
uint64_t unlock_time; // Number of blocks until transfer is safely spendable.
bool locked; // If the transfer is locked or not
cryptonote::subaddress_index subaddr_index; // Major & minor index, account and subaddress index respectively.
std::vector<cryptonote::subaddress_index> subaddr_indices;
std::string address; // Address that transferred the funds.
bool double_spend_seen; // True if the key image(s) for the transfer have been seen before.
uint64_t confirmations; // Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
uint64_t suggested_confirmations_threshold; // Estimation of the confirmations needed for the transaction to be included in a block.
uint64_t checkpointed; // If transfer is backed by atleast 2 Service Node Checkpoints, 0 if it is not, see immutable_height in the daemon rpc call get_info
bool blink_mempool; // True if this is an approved blink tx in the mempool
bool was_blink; // True if we saw this as an approved blink (either in the mempool or a recent, uncheckpointed block). Note that if we didn't see it while an active blink this won't be set.
// Not serialized, for internal wallet2 use
tools::pay_type pay_type; // @NoLokiRPCDocGen Internal use only, not serialized
bool confirmed; // @NoLokiRPCDocGen Internal use only, not serialized
crypto::hash hash; // @NoLokiRPCDocGen Internal use only, not serialized
std::string lock_msg; // @NoLokiRPCDocGen Internal use only, not serialized
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txid);
KV_SERIALIZE(payment_id);
KV_SERIALIZE(height);
KV_SERIALIZE(timestamp);
KV_SERIALIZE(amount);
KV_SERIALIZE(fee);
KV_SERIALIZE(note);
KV_SERIALIZE(destinations);
// TODO(loki): This discrepancy between having to use pay_type if type is
// empty and type if pay type is neither is super unintuitive.
if (this_ref.type.empty())
{
std::string type = pay_type_string(this_ref.pay_type);
KV_SERIALIZE_VALUE(type)
}
else
{
KV_SERIALIZE(type)
}
KV_SERIALIZE(unlock_time)
KV_SERIALIZE(subaddr_index);
KV_SERIALIZE(subaddr_indices);
KV_SERIALIZE(address);
KV_SERIALIZE(double_spend_seen)
KV_SERIALIZE_OPT(confirmations, (uint64_t)0)
KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0)
KV_SERIALIZE(checkpointed)
KV_SERIALIZE(blink_mempool)
KV_SERIALIZE(was_blink)
END_KV_SERIALIZE_MAP()
};
//enum class stake_check_result { allowed, not_allowed, try_later };
enum tx_priority
{
@ -381,30 +287,6 @@ private:
wallet2(cryptonote::network_type nettype = cryptonote::MAINNET, uint64_t kdf_rounds = 1, bool unattended = false, std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory = std::unique_ptr<epee::net_utils::http::http_simple_client_factory>(new epee::net_utils::http::http_simple_client_factory()));
~wallet2();
struct multisig_info
{
struct LR
{
rct::key m_L;
rct::key m_R;
BEGIN_SERIALIZE_OBJECT()
FIELD(m_L)
FIELD(m_R)
END_SERIALIZE()
};
crypto::public_key m_signer;
std::vector<LR> m_LR;
std::vector<crypto::key_image> m_partial_key_images; // one per key the participant has
BEGIN_SERIALIZE_OBJECT()
FIELD(m_signer)
FIELD(m_LR)
FIELD(m_partial_key_images)
END_SERIALIZE()
};
struct tx_scan_info_t
{
cryptonote::keypair in_ephemeral;
@ -419,61 +301,6 @@ private:
tx_scan_info_t(): amount(0), money_transfered(0), error(true) {}
};
struct transfer_details
{
uint64_t m_block_height;
cryptonote::transaction_prefix m_tx;
crypto::hash m_txid;
size_t m_internal_output_index;
uint64_t m_global_output_index;
bool m_spent;
bool m_frozen;
bool m_unmined_blink;
bool m_was_blink;
uint64_t m_spent_height;
crypto::key_image m_key_image; //TODO: key_image stored twice :(
rct::key m_mask;
uint64_t m_amount;
bool m_rct;
bool m_key_image_known;
bool m_key_image_request; // view wallets: we want to request it; cold wallets: it was requested
size_t m_pk_index;
cryptonote::subaddress_index m_subaddr_index;
bool m_key_image_partial;
std::vector<rct::key> m_multisig_k;
std::vector<multisig_info> m_multisig_info; // one per other participant
std::vector<std::pair<uint64_t, crypto::hash>> m_uses;
bool is_rct() const { return m_rct; }
uint64_t amount() const { return m_amount; }
const crypto::public_key &get_public_key() const { return std::get<cryptonote::txout_to_key>(m_tx.vout[m_internal_output_index].target).key; }
BEGIN_SERIALIZE_OBJECT()
FIELD(m_block_height)
FIELD(m_tx)
FIELD(m_txid)
FIELD(m_internal_output_index)
FIELD(m_global_output_index)
FIELD(m_spent)
FIELD(m_frozen)
FIELD(m_unmined_blink)
FIELD(m_was_blink)
FIELD(m_spent_height)
FIELD(m_key_image)
FIELD(m_mask)
FIELD(m_amount)
FIELD(m_rct)
FIELD(m_key_image_known)
FIELD(m_key_image_request)
FIELD(m_pk_index)
FIELD(m_subaddr_index)
FIELD(m_key_image_partial)
FIELD(m_multisig_k)
FIELD(m_multisig_info)
FIELD(m_uses)
END_SERIALIZE()
};
struct payment_details
{
crypto::hash m_tx_hash;
@ -482,12 +309,12 @@ private:
uint64_t m_block_height;
uint64_t m_unlock_time;
uint64_t m_timestamp;
pay_type m_type;
wallet::pay_type m_type;
cryptonote::subaddress_index m_subaddr_index;
bool m_unmined_blink;
bool m_was_blink;
bool is_coinbase() const { return ((m_type == pay_type::miner) || (m_type == pay_type::service_node) || (m_type == pay_type::governance)); }
bool is_coinbase() const { return ((m_type == wallet::pay_type::miner) || (m_type == wallet::pay_type::service_node) || (m_type == wallet::pay_type::governance)); }
};
struct address_tx : payment_details
@ -516,7 +343,7 @@ private:
uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer
std::set<uint32_t> m_subaddr_indices; // set of address indices used as inputs in this transfer
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> m_rings; // relative
tools::pay_type m_pay_type = tools::pay_type::out;
wallet::pay_type m_pay_type = wallet::pay_type::out;
};
struct confirmed_transfer_details
@ -533,7 +360,7 @@ private:
uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer
std::set<uint32_t> m_subaddr_indices; // set of address indices used as inputs in this transfer
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> m_rings; // relative
tools::pay_type m_pay_type = tools::pay_type::out;
wallet::pay_type m_pay_type = wallet::pay_type::out;
confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(crypto::null_hash), m_timestamp(0), m_unlock_time(0), m_subaddr_account((uint32_t)-1) {}
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height)
@ -554,109 +381,13 @@ private:
}
};
struct tx_construction_data
{
std::vector<cryptonote::tx_source_entry> sources;
cryptonote::tx_destination_entry change_dts;
std::vector<cryptonote::tx_destination_entry> splitted_dsts; // split, includes change
std::vector<size_t> selected_transfers;
std::vector<uint8_t> extra;
uint64_t unlock_time;
rct::RCTConfig rct_config;
std::vector<cryptonote::tx_destination_entry> dests; // original setup, does not include change
uint32_t subaddr_account; // subaddress account of your wallet to be used in this transfer
std::set<uint32_t> subaddr_indices; // set of address indices used as inputs in this transfer
uint8_t hf_version;
cryptonote::txtype tx_type;
BEGIN_SERIALIZE_OBJECT()
FIELD(sources)
FIELD(change_dts)
FIELD(splitted_dsts)
FIELD(selected_transfers)
FIELD(extra)
FIELD(unlock_time)
FIELD(rct_config)
FIELD(dests)
FIELD(subaddr_account)
FIELD(subaddr_indices)
FIELD(hf_version)
ENUM_FIELD(tx_type, tx_type < cryptonote::txtype::_count)
END_SERIALIZE()
};
typedef std::vector<transfer_details> transfer_container;
typedef std::unordered_multimap<crypto::hash, payment_details> payment_container;
struct multisig_sig
{
rct::rctSig sigs;
std::unordered_set<crypto::public_key> ignore;
std::unordered_set<rct::key> used_L;
std::unordered_set<crypto::public_key> signing_keys;
rct::multisig_out msout;
};
// The convention for destinations is:
// dests does not include change
// splitted_dsts (in construction_data) does
struct pending_tx
{
cryptonote::transaction tx;
uint64_t dust, fee;
bool dust_added_to_fee;
cryptonote::tx_destination_entry change_dts;
std::vector<size_t> selected_transfers;
std::string key_images;
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::vector<cryptonote::tx_destination_entry> dests;
std::vector<multisig_sig> multisig_sigs;
tx_construction_data construction_data;
BEGIN_SERIALIZE_OBJECT()
FIELD(tx)
FIELD(dust)
FIELD(fee)
FIELD(dust_added_to_fee)
FIELD(change_dts)
FIELD(selected_transfers)
FIELD(key_images)
FIELD(tx_key)
FIELD(additional_tx_keys)
FIELD(dests)
FIELD(construction_data)
FIELD(multisig_sigs)
END_SERIALIZE()
};
// The term "Unsigned tx" is not really a tx since it's not signed yet.
// It doesnt have tx hash, key and the integrated address is not separated into addr + payment id.
struct unsigned_tx_set
{
std::vector<tx_construction_data> txes;
std::pair<size_t, wallet2::transfer_container> transfers;
};
struct signed_tx_set
{
std::vector<pending_tx> ptx;
std::vector<crypto::key_image> key_images;
std::unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
};
struct multisig_tx_set
{
std::vector<pending_tx> m_ptx;
std::unordered_set<crypto::public_key> m_signers;
BEGIN_SERIALIZE_OBJECT()
FIELD(m_ptx)
FIELD(m_signers)
END_SERIALIZE()
};
using transfer_details = wallet::transfer_details;
using transfer_container = std::vector<transfer_details>;
using pending_tx = wallet::pending_tx;
using unsigned_tx_set = wallet::unsigned_tx_set;
using signed_tx_set = wallet::signed_tx_set;
using multisig_tx_set = wallet::multisig_tx_set;
using payment_container = std::unordered_multimap<crypto::hash, payment_details>;
struct keys_file_data
{
@ -994,23 +725,23 @@ private:
bool save_multisig_tx(const std::vector<pending_tx>& ptx_vector, const std::string &filename);
multisig_tx_set make_multisig_tx_set(const std::vector<pending_tx>& ptx_vector) const;
// load unsigned tx from file and sign it. Takes confirmation callback as argument. Used by the cli wallet
bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<wallet2::pending_tx> &ptx, std::function<bool(const unsigned_tx_set&)> accept_func = NULL, bool export_raw = false);
bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<pending_tx> &ptx, std::function<bool(const unsigned_tx_set&)> accept_func = NULL, bool export_raw = false);
// sign unsigned tx. Takes unsigned_tx_set as argument. Used by GUI
bool sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_filename, std::vector<wallet2::pending_tx> &ptx, bool export_raw = false);
bool sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pending_tx> &ptx, signed_tx_set &signed_txs);
std::string sign_tx_dump_to_str(unsigned_tx_set &exported_txs, std::vector<wallet2::pending_tx> &ptx, signed_tx_set &signed_txes);
bool sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_filename, std::vector<pending_tx> &ptx, bool export_raw = false);
bool sign_tx(unsigned_tx_set &exported_txs, std::vector<pending_tx> &ptx, signed_tx_set &signed_txs);
std::string sign_tx_dump_to_str(unsigned_tx_set &exported_txs, std::vector<pending_tx> &ptx, signed_tx_set &signed_txes);
// load unsigned_tx_set from file.
bool load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const;
bool parse_unsigned_tx_from_str(std::string_view unsigned_tx_st, unsigned_tx_set &exported_txs) const;
bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
bool parse_tx_from_str(std::string_view signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra_base, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, cryptonote::loki_construct_tx_params &tx_params);
bool load_tx(const std::string &signed_filename, std::vector<pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
bool parse_tx_from_str(std::string_view signed_tx_st, std::vector<pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
std::vector<pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra_base, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, cryptonote::loki_construct_tx_params &tx_params);
std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, cryptonote::txtype tx_type = cryptonote::txtype::standard);
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, cryptonote::txtype tx_type = cryptonote::txtype::standard);
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, cryptonote::txtype tx_type = cryptonote::txtype::standard);
std::vector<pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, cryptonote::txtype tx_type = cryptonote::txtype::standard);
std::vector<pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, cryptonote::txtype tx_type = cryptonote::txtype::standard);
std::vector<pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, cryptonote::txtype tx_type = cryptonote::txtype::standard);
bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, std::vector<cryptonote::tx_destination_entry> dsts) const;
bool sanity_check(const std::vector<pending_tx> &ptx_vector, std::vector<cryptonote::tx_destination_entry> dsts) const;
void cold_tx_aux_import(const std::vector<pending_tx>& ptx, const std::vector<std::string>& tx_device_aux);
void cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_set &exported_txs, std::vector<cryptonote::address_parse_info> const &dsts_info, std::vector<std::string> & tx_device_aux);
uint64_t cold_key_image_sync(uint64_t &spent, uint64_t &unspent);
@ -1025,10 +756,10 @@ private:
void discard_unmixable_outputs();
bool is_connected() const;
bool check_connection(cryptonote::rpc::version_t *version = NULL, bool *ssl = NULL, uint32_t timeout = 200000);
transfer_view make_transfer_view(const crypto::hash &txid, const crypto::hash &payment_id, const wallet2::payment_details &pd) const;
transfer_view make_transfer_view(const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const;
transfer_view make_transfer_view(const crypto::hash &txid, const tools::wallet2::unconfirmed_transfer_details &pd) const;
transfer_view make_transfer_view(const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &pd) const;
wallet::transfer_view make_transfer_view(const crypto::hash &txid, const crypto::hash &payment_id, const wallet2::payment_details &pd) const;
wallet::transfer_view make_transfer_view(const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const;
wallet::transfer_view make_transfer_view(const crypto::hash &txid, const tools::wallet2::unconfirmed_transfer_details &pd) const;
wallet::transfer_view make_transfer_view(const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &pd) const;
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
struct get_transfers_args_t
@ -1047,8 +778,8 @@ private:
uint32_t account_index;
bool all_accounts;
};
void get_transfers(get_transfers_args_t args, std::vector<transfer_view>& transfers);
std::string transfers_to_csv(const std::vector<transfer_view>& transfers, bool formatting = false) const;
void get_transfers(get_transfers_args_t args, std::vector<wallet::transfer_view>& transfers);
std::string transfers_to_csv(const std::vector<wallet::transfer_view>& transfers, bool formatting = false) const;
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0, const std::optional<uint32_t>& subaddr_account = std::nullopt, const std::set<uint32_t>& subaddr_indices = {}) const;
void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height, uint64_t max_height = (uint64_t)-1, const std::optional<uint32_t>& subaddr_account = std::nullopt, const std::set<uint32_t>& subaddr_indices = {}) const;
void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments,
@ -1074,7 +805,7 @@ private:
uint64_t get_immutable_height() const { return m_immutable_height; }
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
void serialize(t_archive &a, const unsigned int ver)
{
uint64_t dummy_refresh_height = 0; // moved to keys file
if(ver < 5)
@ -1253,7 +984,7 @@ private:
const std::string & device_derivation_path() const { return m_device_derivation_path; }
void device_derivation_path(const std::string &device_derivation_path) { m_device_derivation_path = device_derivation_path; }
const ExportFormat & export_format() const { return m_export_format; }
inline void set_export_format(const ExportFormat& export_format) { m_export_format = export_format; }
void set_export_format(const ExportFormat& export_format) { m_export_format = export_format; }
bool get_tx_key_cached(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
void set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys);
@ -1370,9 +1101,9 @@ private:
bool verify_with_public_key(std::string_view data, const crypto::public_key &public_key, std::string_view signature) const;
// Import/Export wallet data
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> export_outputs(bool all = false) const;
std::pair<size_t, std::vector<transfer_details>> export_outputs(bool all = false) const;
std::string export_outputs_to_str(bool all = false) const;
size_t import_outputs(const std::pair<size_t, std::vector<tools::wallet2::transfer_details>> &outputs);
size_t import_outputs(const std::pair<size_t, std::vector<transfer_details>> &outputs);
size_t import_outputs_from_str(std::string outputs_st);
payment_container export_payments() const;
void import_payments(const payment_container &payments);
@ -1385,7 +1116,7 @@ private:
uint64_t import_key_images_from_file(const std::string &filename, uint64_t &spent, uint64_t &unspent);
bool import_key_images(std::vector<crypto::key_image> key_images, size_t offset=0, std::optional<std::unordered_set<size_t>> selected_transfers=std::nullopt);
bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false);
crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const;
crypto::public_key get_tx_pub_key_from_received_outs(const transfer_details &td) const;
crypto::hash get_long_poll_tx_pool_checksum() const
{
@ -1482,7 +1213,7 @@ private:
crypto::public_key get_multisig_signing_public_key(const crypto::secret_key &skey) const;
template <typename RPC>
inline bool invoke_http(const typename RPC::request& req, typename RPC::response& res)
bool invoke_http(const typename RPC::request& req, typename RPC::response& res)
{
using namespace cryptonote::rpc;
static_assert(std::is_base_of_v<RPC_COMMAND, RPC> || std::is_base_of_v<tools::light_rpc::LIGHT_RPC_COMMAND, RPC>);
@ -1588,13 +1319,13 @@ private:
pending_tx ptx;
};
request_stake_unlock_result can_request_stake_unlock(const crypto::public_key &sn_key);
std::vector<wallet2::pending_tx> lns_create_buy_mapping_tx(lns::mapping_type type, std::string const *owner, std::string const *backup_owner, std::string name, std::string const &value, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
std::vector<wallet2::pending_tx> lns_create_buy_mapping_tx(std::string const &type, std::string const *owner, std::string const *backup_owner, std::string const &name, std::string const &value, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
std::vector<pending_tx> lns_create_buy_mapping_tx(lns::mapping_type type, std::string const *owner, std::string const *backup_owner, std::string name, std::string const &value, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
std::vector<pending_tx> lns_create_buy_mapping_tx(std::string const &type, std::string const *owner, std::string const *backup_owner, std::string const &name, std::string const &value, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
// signature: (Optional) If set, use the signature given, otherwise by default derive the signature from the wallet spend key as an ed25519 key.
// The signature is derived from the hash of the previous txid blob and previous value blob of the mapping. By default this is signed using the wallet's spend key as an ed25519 keypair.
std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(lns::mapping_type type, std::string name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {}, std::vector<cryptonote::rpc::LNS_NAMES_TO_OWNERS::response_entry> *response = {});
std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(std::string const &type, std::string const &name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {}, std::vector<cryptonote::rpc::LNS_NAMES_TO_OWNERS::response_entry> *response = {});
std::vector<pending_tx> lns_create_update_mapping_tx(lns::mapping_type type, std::string name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {}, std::vector<cryptonote::rpc::LNS_NAMES_TO_OWNERS::response_entry> *response = {});
std::vector<pending_tx> lns_create_update_mapping_tx(std::string const &type, std::string const &name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {}, std::vector<cryptonote::rpc::LNS_NAMES_TO_OWNERS::response_entry> *response = {});
// Generate just the signature required for putting into lns_update_mapping command in the wallet
bool lns_make_update_mapping_signature(lns::mapping_type type, std::string name, std::string const *value, std::string const *owner, std::string const *backup_owner, lns::generic_signature &signature, uint32_t account_index = 0, std::string *reason = nullptr);
@ -1715,7 +1446,7 @@ private:
rct::multisig_kLRki get_multisig_composite_kLRki(size_t n, const std::unordered_set<crypto::public_key> &ignore_set, std::unordered_set<rct::key> &used_L, std::unordered_set<rct::key> &new_used_L) const;
rct::multisig_kLRki get_multisig_kLRki(size_t n, const rct::key &k) const;
rct::key get_multisig_k(size_t idx, const std::unordered_set<rct::key> &used_L) const;
void update_multisig_rescan_info(const std::vector<std::vector<rct::key>> &multisig_k, const std::vector<std::vector<tools::wallet2::multisig_info>> &info, size_t n);
void update_multisig_rescan_info(const std::vector<std::vector<rct::key>> &multisig_k, const std::vector<std::vector<wallet::multisig_info>> &info, size_t n);
bool add_rings(const crypto::chacha_key &key, const cryptonote::transaction_prefix &tx);
bool add_rings(const cryptonote::transaction_prefix &tx);
bool remove_rings(const cryptonote::transaction_prefix &tx);
@ -1789,7 +1520,7 @@ private:
std::vector<tools::wallet2::address_book_row> m_address_book;
std::pair<std::map<std::string, std::string>, std::vector<std::string>> m_account_tags;
uint64_t m_upper_transaction_weight_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
const std::vector<std::vector<tools::wallet2::multisig_info>> *m_multisig_rescan_info;
const std::vector<std::vector<wallet::multisig_info>> *m_multisig_rescan_info;
const std::vector<std::vector<rct::key>> *m_multisig_rescan_k;
std::unordered_map<crypto::public_key, crypto::key_image> m_cold_key_images;
@ -1909,105 +1640,17 @@ private:
}
BOOST_CLASS_VERSION(tools::wallet2, 29)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 14)
BOOST_CLASS_VERSION(tools::wallet2::multisig_info, 1)
BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0)
BOOST_CLASS_VERSION(tools::wallet2::multisig_tx_set, 1)
BOOST_CLASS_VERSION(tools::wallet2::payment_details, 6)
BOOST_CLASS_VERSION(tools::wallet2::pool_payment_details, 1)
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 9)
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 8)
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 18)
BOOST_CLASS_VERSION(tools::wallet2::reserve_proof_entry, 0)
BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 0)
BOOST_CLASS_VERSION(tools::wallet2::signed_tx_set, 1)
BOOST_CLASS_VERSION(tools::wallet2::tx_construction_data, 6)
BOOST_CLASS_VERSION(tools::wallet2::pending_tx, 3)
BOOST_CLASS_VERSION(tools::wallet2::multisig_sig, 0)
namespace boost
namespace boost::serialization
{
namespace serialization
{
template <class Archive>
inline typename std::enable_if<!Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
}
template <class Archive>
inline typename std::enable_if<Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
if (ver < 10)
{
x.m_key_image_request = false;
}
if (ver < 12)
{
x.m_frozen = false;
}
if (ver < 13)
x.m_unmined_blink = false;
if (ver < 14)
x.m_was_blink = false;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
a & x.m_block_height;
a & x.m_global_output_index;
a & x.m_internal_output_index;
a & x.m_tx;
a & x.m_spent;
a & x.m_key_image;
a & x.m_mask;
a & x.m_amount;
a & x.m_spent_height;
a & x.m_txid;
a & x.m_rct;
a & x.m_key_image_known;
a & x.m_pk_index;
a & x.m_subaddr_index;
a & x.m_multisig_info;
a & x.m_multisig_k;
a & x.m_key_image_partial;
if (ver > 9)
a & x.m_key_image_request;
if (ver > 10)
a & x.m_uses;
if (ver > 11)
a & x.m_frozen;
if (ver > 12)
a & x.m_unmined_blink;
if (ver > 13)
a & x.m_was_blink;
initialize_transfer_details(a, x, ver);
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::multisig_info::LR &x, const boost::serialization::version_type ver)
{
a & x.m_L;
a & x.m_R;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::multisig_info &x, const boost::serialization::version_type ver)
{
a & x.m_signer;
a & x.m_LR;
a & x.m_partial_key_images;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::multisig_tx_set &x, const boost::serialization::version_type ver)
{
a & x.m_ptx;
a & x.m_signers;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::unconfirmed_transfer_details &x, const boost::serialization::version_type ver)
void serialize(Archive &a, tools::wallet2::unconfirmed_transfer_details &x, const unsigned int ver)
{
a & x.m_change;
a & x.m_sent_time;
@ -2022,7 +1665,7 @@ namespace boost
a & x.m_tx;
}
if (ver < 9)
x.m_pay_type = tools::pay_type::out;
x.m_pay_type = wallet::pay_type::out;
if (ver < 1)
return;
a & x.m_dests;
@ -2061,14 +1704,14 @@ namespace boost
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::confirmed_transfer_details &x, const boost::serialization::version_type ver)
void serialize(Archive &a, tools::wallet2::confirmed_transfer_details &x, const unsigned int ver)
{
a & x.m_amount_in;
a & x.m_amount_out;
a & x.m_change;
a & x.m_block_height;
if (ver < 8)
x.m_pay_type = tools::pay_type::out;
x.m_pay_type = wallet::pay_type::out;
if (ver < 1)
return;
a & x.m_dests;
@ -2117,7 +1760,7 @@ namespace boost
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::payment_details& x, const boost::serialization::version_type ver)
void serialize(Archive& a, tools::wallet2::payment_details& x, const unsigned int ver)
{
a & x.m_tx_hash;
a & x.m_amount;
@ -2132,7 +1775,7 @@ namespace boost
if (ver < 3)
x.m_fee = 0;
if (ver < 4)
x.m_type = tools::pay_type::in;
x.m_type = wallet::pay_type::in;
if (ver < 5)
x.m_unmined_blink = false;
if (ver < 6)
@ -2154,14 +1797,14 @@ namespace boost
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::pool_payment_details& x, const boost::serialization::version_type ver)
void serialize(Archive& a, tools::wallet2::pool_payment_details& x, const unsigned int ver)
{
a & x.m_pd;
a & x.m_double_spend_seen;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::address_book_row& x, const boost::serialization::version_type ver)
void serialize(Archive& a, tools::wallet2::address_book_row& x, const unsigned int ver)
{
a & x.m_address;
if (ver < 18)
@ -2199,7 +1842,7 @@ namespace boost
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::reserve_proof_entry& x, const boost::serialization::version_type ver)
void serialize(Archive& a, tools::wallet2::reserve_proof_entry& x, const unsigned int ver)
{
a & x.txid;
a & x.index_in_tx;
@ -2209,120 +1852,4 @@ namespace boost
a & x.key_image_sig;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::unsigned_tx_set &x, const boost::serialization::version_type ver)
{
a & x.txes;
a & x.transfers;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::signed_tx_set &x, const boost::serialization::version_type ver)
{
a & x.ptx;
a & x.key_images;
if (ver < 1)
return;
a & x.tx_key_images;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::tx_construction_data &x, const boost::serialization::version_type ver)
{
a & x.sources;
a & x.change_dts;
a & x.splitted_dsts;
if (ver < 2)
{
// load list to vector
std::list<size_t> selected_transfers;
a & selected_transfers;
x.selected_transfers.clear();
x.selected_transfers.reserve(selected_transfers.size());
for (size_t t: selected_transfers)
x.selected_transfers.push_back(t);
}
a & x.extra;
a & x.unlock_time;
a & x.dests;
if (ver < 1)
{
x.subaddr_account = 0;
return;
}
a & x.subaddr_account;
a & x.subaddr_indices;
if (!typename Archive::is_saving())
{
x.rct_config = { rct::RangeProofBorromean, 0 };
if (ver < 6)
{
x.tx_type = cryptonote::txtype::standard;
x.hf_version = cryptonote::network_version_13_enforce_checkpoints;
}
}
if (ver < 2)
return;
a & x.selected_transfers;
if (ver < 3)
return;
if (ver < 5)
{
bool use_bulletproofs = x.rct_config.range_proof_type != rct::RangeProofBorromean;
a & use_bulletproofs;
if (!typename Archive::is_saving())
x.rct_config = { use_bulletproofs ? rct::RangeProofBulletproof : rct::RangeProofBorromean, 0 };
return;
}
a & x.rct_config;
if (ver < 6) return;
a & x.tx_type;
a & x.hf_version;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::multisig_sig &x, const boost::serialization::version_type ver)
{
a & x.sigs;
a & x.ignore;
a & x.used_L;
a & x.signing_keys;
a & x.msout;
}
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::pending_tx &x, const boost::serialization::version_type ver)
{
a & x.tx;
a & x.dust;
a & x.fee;
a & x.dust_added_to_fee;
a & x.change_dts;
if (ver < 2)
{
// load list to vector
std::list<size_t> selected_transfers;
a & selected_transfers;
x.selected_transfers.clear();
x.selected_transfers.reserve(selected_transfers.size());
for (size_t t: selected_transfers)
x.selected_transfers.push_back(t);
}
a & x.key_images;
a & x.tx_key;
a & x.dests;
a & x.construction_data;
if (ver < 1)
return;
a & x.additional_tx_keys;
if (ver < 2)
return;
a & x.selected_transfers;
if (ver < 3)
return;
a & x.multisig_sigs;
}
}
}

View File

@ -307,7 +307,7 @@ namespace tools
balance_per_subaddress_per_account[req.account_index] = m_wallet->balance_per_subaddress(req.account_index, req.strict);
unlocked_balance_per_subaddress_per_account[req.account_index] = m_wallet->unlocked_balance_per_subaddress(req.account_index, req.strict);
}
std::vector<tools::wallet2::transfer_details> transfers;
std::vector<wallet::transfer_details> transfers;
m_wallet->get_transfers(transfers);
for (const auto& p : balance_per_subaddress_per_account)
{
@ -336,7 +336,7 @@ namespace tools
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; });
info.num_unspent_outputs = std::count_if(transfers.begin(), transfers.end(), [&](const wallet::transfer_details& td) { return !td.m_spent && td.m_subaddr_index == index; });
res.per_subaddress.emplace_back(std::move(info));
}
}
@ -377,7 +377,7 @@ namespace tools
info.address = m_wallet->get_subaddress_as_str(index);
info.label = m_wallet->get_subaddress_label(index);
info.address_index = index.minor;
info.used = std::find_if(transfers.begin(), transfers.end(), [&](const tools::wallet2::transfer_details& td) { return td.m_subaddr_index == index; }) != transfers.end();
info.used = std::find_if(transfers.begin(), transfers.end(), [&](const wallet::transfer_details& td) { return td.m_subaddr_index == index; }) != transfers.end();
}
res.address = m_wallet->get_subaddress_as_str({req.account_index, 0});
}
@ -648,7 +648,7 @@ namespace tools
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::validate_transfer(const std::list<transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
bool wallet_rpc_server::validate_transfer(const std::list<wallet::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
{
crypto::hash8 integrated_payment_id = crypto::null_hash8;
std::string extra_nonce;
@ -703,7 +703,7 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
static std::string ptx_to_string(const tools::wallet2::pending_tx &ptx)
static std::string ptx_to_string(const wallet::pending_tx &ptx)
{
std::ostringstream oss;
boost::archive::portable_binary_oarchive ar(oss);
@ -737,7 +737,7 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
static uint64_t total_amount(const tools::wallet2::pending_tx &ptx)
static uint64_t total_amount(const wallet::pending_tx &ptx)
{
uint64_t amount = 0;
for (const auto &dest: ptx.dests) amount += dest.amount;
@ -745,7 +745,7 @@ namespace tools
}
//------------------------------------------------------------------------------------------------------------------------------
template<typename Ts, typename Tu>
bool wallet_rpc_server::fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
bool wallet_rpc_server::fill_response(std::vector<wallet::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 blink,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er)
{
@ -954,7 +954,7 @@ namespace tools
return false;
}
tools::wallet2::unsigned_tx_set exported_txs;
wallet::unsigned_tx_set exported_txs;
if(!m_wallet->parse_unsigned_tx_from_str(blob, exported_txs))
{
er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA;
@ -962,10 +962,10 @@ namespace tools
return false;
}
std::vector<tools::wallet2::pending_tx> ptxs;
std::vector<wallet::pending_tx> ptxs;
try
{
tools::wallet2::signed_tx_set signed_txs;
wallet::signed_tx_set signed_txs;
std::string ciphertext = m_wallet->sign_tx_dump_to_str(exported_txs, ptxs, signed_txs);
if (ciphertext.empty())
{
@ -1033,10 +1033,10 @@ namespace tools
return false;
}
std::vector <wallet2::tx_construction_data> tx_constructions;
std::vector <wallet::tx_construction_data> tx_constructions;
if (!req.unsigned_txset.empty()) {
try {
tools::wallet2::unsigned_tx_set exported_txs;
wallet::unsigned_tx_set exported_txs;
cryptonote::blobdata blob;
if (!epee::string_tools::parse_hexstr_to_binbuff(req.unsigned_txset, blob)) {
er.code = WALLET_RPC_ERROR_CODE_BAD_HEX;
@ -1057,7 +1057,7 @@ namespace tools
}
} else if (!req.multisig_txset.empty()) {
try {
tools::wallet2::multisig_tx_set exported_txs;
wallet::multisig_tx_set exported_txs;
cryptonote::blobdata blob;
if (!epee::string_tools::parse_hexstr_to_binbuff(req.multisig_txset, blob)) {
er.code = WALLET_RPC_ERROR_CODE_BAD_HEX;
@ -1088,7 +1088,7 @@ namespace tools
int first_known_non_zero_change_index = -1;
for (size_t n = 0; n < tx_constructions.size(); ++n)
{
const tools::wallet2::tx_construction_data &cd = tx_constructions[n];
const auto &cd = tx_constructions[n];
res.desc.push_back({0, 0, std::numeric_limits<uint32_t>::max(), 0, {}, "", 0, "", 0, 0, ""});
wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::transfer_description &desc = res.desc.back();
@ -1155,7 +1155,7 @@ namespace tools
{
if (first_known_non_zero_change_index == -1)
first_known_non_zero_change_index = n;
const tools::wallet2::tx_construction_data &cdn = tx_constructions[first_known_non_zero_change_index];
const auto &cdn = tx_constructions[first_known_non_zero_change_index];
if (memcmp(&cd.change_dts.addr, &cdn.change_dts.addr, sizeof(cd.change_dts.addr)))
{
er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA;
@ -1183,7 +1183,7 @@ namespace tools
if (desc.change_amount > 0)
{
const tools::wallet2::tx_construction_data &cd0 = tx_constructions[0];
const auto &cd0 = tx_constructions[0];
desc.change_address = get_account_address_as_str(m_wallet->nettype(), cd0.subaddr_account > 0, cd0.change_dts.addr);
}
@ -1226,7 +1226,7 @@ namespace tools
return false;
}
std::vector<tools::wallet2::pending_tx> ptx_vector;
std::vector<wallet::pending_tx> ptx_vector;
try
{
bool r = m_wallet->parse_tx_from_str(blob, ptx_vector, nullptr);
@ -1301,8 +1301,8 @@ namespace tools
}
// validate the transfer requested and populate dsts & extra
std::list<transfer_destination> destination;
destination.push_back({});
std::list<wallet::transfer_destination> destination;
destination.emplace_back();
destination.back().amount = 0;
destination.back().address = req.address;
if (!validate_transfer(destination, req.payment_id, dsts, extra, true, er))
@ -1368,8 +1368,8 @@ namespace tools
}
// validate the transfer requested and populate dsts & extra
std::list<transfer_destination> destination;
destination.push_back(transfer_destination());
std::list<wallet::transfer_destination> destination;
destination.emplace_back();
destination.back().amount = 0;
destination.back().address = req.address;
if (!validate_transfer(destination, req.payment_id, dsts, extra, true, er))
@ -1442,7 +1442,7 @@ namespace tools
return false;
}
tools::wallet2::pending_tx ptx;
wallet::pending_tx ptx;
try
{
std::istringstream iss(blob);
@ -2323,21 +2323,21 @@ namespace tools
args.account_index = req.account_index;
args.all_accounts = req.all_accounts;
std::vector<transfer_view> transfers;
std::vector<wallet::transfer_view> transfers;
m_wallet->get_transfers(args, transfers);
for (tools::transfer_view const &entry : transfers)
for (wallet::transfer_view const &entry : transfers)
{
// TODO(loki): This discrepancy between having to use pay_type if type is
// empty and type if pay type is neither is super unintuitive.
if (entry.pay_type == tools::pay_type::in ||
entry.pay_type == tools::pay_type::miner ||
entry.pay_type == tools::pay_type::governance ||
entry.pay_type == tools::pay_type::service_node)
if (entry.pay_type == wallet::pay_type::in ||
entry.pay_type == wallet::pay_type::miner ||
entry.pay_type == wallet::pay_type::governance ||
entry.pay_type == wallet::pay_type::service_node)
{
res.in.push_back(entry);
}
else if (entry.pay_type == tools::pay_type::out || entry.pay_type == tools::pay_type::stake)
else if (entry.pay_type == wallet::pay_type::out || entry.pay_type == wallet::pay_type::stake)
{
res.out.push_back(entry);
}
@ -2375,7 +2375,7 @@ namespace tools
args.account_index = req.account_index;
args.all_accounts = req.all_accounts;
std::vector<transfer_view> transfers;
std::vector<wallet::transfer_view> transfers;
m_wallet->get_transfers(args, transfers);
const bool formatting = false;
@ -2858,7 +2858,7 @@ namespace tools
rpc::START_MINING::request daemon_req{};
daemon_req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->nettype());
daemon_req.threads_count = req.threads_count;
daemon_req.threads_count = req.threads_count;
rpc::START_MINING::response daemon_res{};
bool r = m_wallet->invoke_http<rpc::START_MINING>(daemon_req, daemon_res);
@ -3866,7 +3866,7 @@ namespace tools
return false;
}
tools::wallet2::multisig_tx_set txs;
wallet::multisig_tx_set txs;
bool r = m_wallet->load_multisig_tx(blob, txs, nullptr);
if (!r)
{

View File

@ -280,7 +280,7 @@ namespace tools
bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay, bool blink,
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er);
bool validate_transfer(const std::list<transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
bool validate_transfer(const std::list<wallet::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
std::unique_ptr<wallet2> m_wallet;
std::string m_wallet_dir;

View File

@ -33,7 +33,8 @@
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/subaddress_index.h"
#include "wallet_rpc_server_error_codes.h"
#include "wallet2.h"
#include "wallet/transfer_destination.h"
#include "wallet/transfer_view.h"
#include "common/loki.h"
@ -461,7 +462,7 @@ namespace wallet_rpc
{
struct request
{
std::list<transfer_destination> destinations; // Array of destinations to receive LOKI.
std::list<wallet::transfer_destination> destinations; // Array of destinations to receive LOKI.
uint32_t account_index; // (Optional) Transfer from this account index. (Defaults to 0)
std::set<uint32_t> subaddr_indices; // (Optional) Transfer from this set of subaddresses. (Defaults to 0)
uint32_t priority; // Set a priority for the transaction. Accepted values are: 1 for unimportant or 5 for blink. (0 and 2-4 are accepted for backwards compatibility and are equivalent to 5)
@ -518,7 +519,7 @@ namespace wallet_rpc
{
struct request
{
std::list<transfer_destination> destinations; // Array of destinations to receive LOKI:
std::list<wallet::transfer_destination> destinations; // Array of destinations to receive LOKI:
uint32_t account_index; // (Optional) Transfer from this account index. (Defaults to 0)
std::set<uint32_t> subaddr_indices; // (Optional) Transfer from this set of subaddresses. (Defaults to 0)
uint32_t priority; // Set a priority for the transaction. Accepted values are: 1 for unimportant or 5 for blink. (0 and 2-4 are accepted for backwards compatibility and are equivalent to 5)
@ -1531,11 +1532,11 @@ namespace wallet_rpc
struct response
{
std::list<transfer_view> in; //
std::list<transfer_view> out; //
std::list<transfer_view> pending; //
std::list<transfer_view> failed; //
std::list<transfer_view> pool; //
std::list<wallet::transfer_view> in; //
std::list<wallet::transfer_view> out; //
std::list<wallet::transfer_view> pending; //
std::list<wallet::transfer_view> failed; //
std::list<wallet::transfer_view> pool; //
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(in);
@ -1580,8 +1581,8 @@ namespace wallet_rpc
struct response
{
transfer_view transfer; //
std::list<transfer_view> transfers; //
wallet::transfer_view transfer; //
std::list<wallet::transfer_view> transfers; //
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(transfer);