aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/api/pending_transaction.cpp2
-rw-r--r--src/wallet/api/unsigned_transaction.cpp10
-rw-r--r--src/wallet/api/wallet.cpp16
-rw-r--r--src/wallet/api/wallet.h1
-rw-r--r--src/wallet/wallet2.cpp76
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet2_api.h6
-rw-r--r--src/wallet/wallet_args.cpp6
-rw-r--r--src/wallet/wallet_errors.h4
-rw-r--r--src/wallet/wallet_rpc_server.cpp104
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h24
11 files changed, 189 insertions, 62 deletions
diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp
index 9798d66c6..c98a599e7 100644
--- a/src/wallet/api/pending_transaction.cpp
+++ b/src/wallet/api/pending_transaction.cpp
@@ -102,6 +102,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
}
// Commit tx
else {
+ m_wallet.pauseRefresh();
while (!m_pending_tx.empty()) {
auto & ptx = m_pending_tx.back();
m_wallet.m_wallet->commit_tx(ptx);
@@ -133,6 +134,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite)
m_status = Status_Error;
}
+ m_wallet.startRefresh();
return m_status == Status_Ok;
}
diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp
index 1d9ef5d7c..961bd772a 100644
--- a/src/wallet/api/unsigned_transaction.cpp
+++ b/src/wallet/api/unsigned_transaction.cpp
@@ -101,7 +101,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu
{
// gather info to ask the user
uint64_t amount = 0, amount_to_dests = 0, change = 0;
- size_t min_mixin = ~0;
+ size_t min_ring_size = ~0;
std::unordered_map<std::string, uint64_t> dests;
const std::string wallet_address = m_wallet.m_wallet->get_account().get_public_address_str(m_wallet.m_wallet->testnet());
int first_known_non_zero_change_index = -1;
@@ -111,9 +111,9 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu
for (size_t s = 0; s < cd.sources.size(); ++s)
{
amount += cd.sources[s].amount;
- size_t mixin = cd.sources[s].outputs.size() - 1;
- if (mixin < min_mixin)
- min_mixin = mixin;
+ size_t ring_size = cd.sources[s].outputs.size();
+ if (ring_size < min_ring_size)
+ min_ring_size = ring_size;
}
for (size_t d = 0; d < cd.splitted_dsts.size(); ++d)
{
@@ -178,7 +178,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function<size_t()> get_nu
else
change_string += tr("no change");
uint64_t fee = amount - amount_to_dests;
- m_confirmationMessage = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min mixin %lu. %s")) % (unsigned long)get_num_txes() % cryptonote::print_money(amount) % cryptonote::print_money(fee) % dest_string % change_string % (unsigned long)min_mixin % extra_message).str();
+ m_confirmationMessage = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu. %s")) % (unsigned long)get_num_txes() % cryptonote::print_money(amount) % cryptonote::print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % extra_message).str();
return true;
}
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 6a0e1727c..a2bb44cfe 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -99,7 +99,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
}
}
- virtual void on_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount)
+ virtual void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount)
{
std::string tx_hash = epee::string_tools::pod_to_hex(txid);
@@ -114,7 +114,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
}
}
- virtual void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount)
+ virtual void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount)
{
std::string tx_hash = epee::string_tools::pod_to_hex(txid);
@@ -129,8 +129,8 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
}
}
- virtual void on_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount,
- const cryptonote::transaction& spend_tx)
+ virtual void on_money_spent(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& in_tx,
+ uint64_t amount, const cryptonote::transaction& spend_tx)
{
// TODO;
std::string tx_hash = epee::string_tools::pod_to_hex(txid);
@@ -1009,9 +1009,9 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
} catch (const tools::error::not_enough_outs_to_mix& e) {
std::ostringstream writer;
- writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":";
+ writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
for (const std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.second;
+ writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
}
m_errorString = writer.str();
m_status = Status_Error;
@@ -1103,9 +1103,9 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
} catch (const tools::error::not_enough_outs_to_mix& e) {
std::ostringstream writer;
- writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":";
+ writer << tr("not enough outputs for specified ring size") << " = " << (e.mixin_count() + 1) << ":";
for (const std::pair<uint64_t, uint64_t> outs_for_amount : e.scanty_outs()) {
- writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.second;
+ writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.first) << ", " << tr("found outputs to use") << " = " << outs_for_amount.second;
}
m_errorString = writer.str();
m_status = Status_Error;
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index e9e2cc580..07b0f063b 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -98,6 +98,7 @@ public:
void setAutoRefreshInterval(int millis);
int autoRefreshInterval() const;
void setRefreshFromBlockHeight(uint64_t refresh_from_block_height);
+ uint64_t getRefreshFromBlockHeight() const { return m_wallet->get_refresh_from_block_height(); };
void setRecoveringFromSeed(bool recoveringFromSeed);
bool watchOnly() const;
bool rescanSpent();
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 6b1026a55..e569197b8 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1388,7 +1388,7 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei
}
}
//----------------------------------------------------------------------------------------------------
-void wallet2::update_pool_state()
+void wallet2::update_pool_state(bool refreshed)
{
MDEBUG("update_pool_state start");
@@ -1424,13 +1424,14 @@ void wallet2::update_pool_state()
// a tx is removed from the pool due to being found in a new block, but
// just before the block is visible by refresh. So we keep a boolean, so
// that the first time we don't see the tx, we set that boolean, and only
- // delete it the second time it is checked
+ // delete it the second time it is checked (but only when refreshed, so
+ // we're sure we've seen the blockchain state first)
if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending)
{
LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as not in pool");
pit->second.m_state = wallet2::unconfirmed_transfer_details::pending_not_in_pool;
}
- else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool)
+ else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool && refreshed)
{
LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as failed");
pit->second.m_state = wallet2::unconfirmed_transfer_details::failed;
@@ -1459,24 +1460,30 @@ void wallet2::update_pool_state()
MDEBUG("update_pool_state done first loop");
// remove pool txes to us that aren't in the pool anymore
- std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin();
- while (uit != m_unconfirmed_payments.end())
+ // but only if we just refreshed, so that the tx can go in
+ // the in transfers list instead (or nowhere if it just
+ // disappeared without being mined)
+ if (refreshed)
{
- const crypto::hash &txid = uit->second.m_tx_hash;
- bool found = false;
- for (const auto &it2: res.tx_hashes)
+ std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin();
+ while (uit != m_unconfirmed_payments.end())
{
- if (it2 == txid)
+ const crypto::hash &txid = uit->second.m_tx_hash;
+ bool found = false;
+ for (const auto &it2: res.tx_hashes)
{
- found = true;
- break;
+ if (it2 == txid)
+ {
+ found = true;
+ break;
+ }
+ }
+ auto pit = uit++;
+ if (!found)
+ {
+ MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool");
+ m_unconfirmed_payments.erase(pit);
}
- }
- auto pit = uit++;
- if (!found)
- {
- MDEBUG("Removing " << txid << " from unconfirmed payments, not found in pool");
- m_unconfirmed_payments.erase(pit);
}
}
MDEBUG("update_pool_state done second loop");
@@ -1490,7 +1497,16 @@ void wallet2::update_pool_state()
LOG_PRINT_L2("Already seen " << txid << ", skipped");
continue;
}
- if (m_unconfirmed_payments.find(txid) == m_unconfirmed_payments.end())
+ bool txid_found_in_up = false;
+ for (const auto &up: m_unconfirmed_payments)
+ {
+ if (up.second.m_tx_hash == txid)
+ {
+ txid_found_in_up = true;
+ break;
+ }
+ }
+ if (!txid_found_in_up)
{
LOG_PRINT_L1("Found new pool tx: " << txid);
bool found = false;
@@ -1685,6 +1701,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
uint64_t blocks_start_height;
std::list<cryptonote::block_complete_entry> blocks;
std::vector<COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices> o_indices;
+ bool refreshed = false;
// pull the first set of blocks
get_short_chain_history(short_chain_history);
@@ -1726,6 +1743,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
if(blocks_start_height == next_blocks_start_height)
{
m_node_rpc_proxy.set_height(m_blockchain.size());
+ refreshed = true;
break;
}
@@ -1764,7 +1782,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
{
// If stop() is called we don't need to check pending transactions
if(m_run.load(std::memory_order_relaxed))
- update_pool_state();
+ update_pool_state(refreshed);
}
catch (...)
{
@@ -3252,7 +3270,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f
for (size_t n = 0; n < exported_txs.txes.size(); ++n)
{
const tools::wallet2::tx_construction_data &sd = exported_txs.txes[n];
- LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, mixin " << (sd.sources[0].outputs.size()-1));
+ LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
signed_txes.ptx.push_back(pending_tx());
tools::wallet2::pending_tx &ptx = signed_txes.ptx.back();
crypto::secret_key tx_key;
@@ -4119,7 +4137,7 @@ static size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs)
// txnFee
size += 4;
- LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " at mixin " << mixin << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)");
+ LOG_PRINT_L2("estimated rct tx size for " << n_inputs << " with ring size " << (mixin+1) << " and " << n_outputs << ": " << size << " (" << ((32 * n_inputs/*+1*/) + 2 * 32 * (mixin+1) * n_inputs + 32 * n_outputs) << " saved)");
return size;
}
@@ -4359,7 +4377,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// try to pick outputs not from the same block. We will get two outputs, one for
// the destination, and one for change.
LOG_PRINT_L2("checking preferred");
- std::vector<size_t> prefered_inputs;
+ std::vector<size_t> preferred_inputs;
uint64_t rct_outs_needed = 2 * (fake_outs_count + 1);
rct_outs_needed += 100; // some fudge factor since we don't know how many are locked
if (use_rct && get_num_rct_outputs() >= rct_outs_needed)
@@ -4367,12 +4385,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which
// will get us a known fee.
uint64_t estimated_fee = calculate_fee(fee_per_kb, estimate_rct_tx_size(2, fake_outs_count + 1, 2), fee_multiplier);
- prefered_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee);
- if (!prefered_inputs.empty())
+ preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee);
+ if (!preferred_inputs.empty())
{
string s;
- for (auto i: prefered_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") ";
- LOG_PRINT_L1("Found prefered rct inputs for rct tx: " << s);
+ for (auto i: preferred_inputs) s += boost::lexical_cast<std::string>(i) + "(" + print_money(m_transfers[i].amount()) + ") ";
+ LOG_PRINT_L1("Found preferred rct inputs for rct tx: " << s);
}
}
LOG_PRINT_L2("done checking preferred");
@@ -4427,8 +4445,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
}
pop_if_present(unused_transfers_indices, idx);
pop_if_present(unused_dust_indices, idx);
- } else if (!prefered_inputs.empty()) {
- idx = pop_back(prefered_inputs);
+ } else if (!preferred_inputs.empty()) {
+ idx = pop_back(preferred_inputs);
pop_if_present(unused_transfers_indices, idx);
pop_if_present(unused_dust_indices, idx);
} else
@@ -4521,7 +4539,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
{
uint64_t new_paid_amount = i->amount /*+ test_ptx.fee*/ - needed_fee;
LOG_PRINT_L2("Adjusting amount paid to " << get_account_address_as_str(m_testnet, i->addr) << " from " <<
- print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accomodate " <<
+ print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accommodate " <<
print_money(needed_fee) << " fee");
dsts[0].amount += i->amount - new_paid_amount;
i->amount = new_paid_amount;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index e7692badb..b853c5f3c 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -585,7 +585,7 @@ namespace tools
uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent);
uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent);
- void update_pool_state();
+ void update_pool_state(bool refreshed = false);
std::string encrypt(const std::string &plaintext, const crypto::secret_key &skey, bool authenticated = true) const;
std::string encrypt_with_view_secret_key(const std::string &plaintext, bool authenticated = true) const;
diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h
index fd8c50b82..ce431ee6b 100644
--- a/src/wallet/wallet2_api.h
+++ b/src/wallet/wallet2_api.h
@@ -381,6 +381,12 @@ struct Wallet
virtual void setRefreshFromBlockHeight(uint64_t refresh_from_block_height) = 0;
/*!
+ * \brief getRestoreHeight - get wallet creation height
+ *
+ */
+ virtual uint64_t getRefreshFromBlockHeight() const = 0;
+
+ /*!
* \brief setRecoveringFromSeed - set state recover form seed
*
* \param recoveringFromSeed - true/false
diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp
index 1508f3791..34c5a2a5d 100644
--- a/src/wallet/wallet_args.cpp
+++ b/src/wallet/wallet_args.cpp
@@ -149,8 +149,10 @@ namespace wallet_args
if (command_line::get_arg(vm, command_line::arg_help))
{
- tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")";
- tools::msg_writer() << wallet_args::tr("Usage:") << ' ' << usage;
+ tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
+ tools::msg_writer() << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n"
+ "daemon to work correctly.") << ENDL;
+ tools::msg_writer() << wallet_args::tr("Usage:") << ENDL << " " << usage;
tools::msg_writer() << desc_all;
return boost::none;
}
diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h
index 16807e045..2e5acc8cb 100644
--- a/src/wallet/wallet_errors.h
+++ b/src/wallet/wallet_errors.h
@@ -417,7 +417,7 @@ namespace tools
typedef std::unordered_map<uint64_t, uint64_t> scanty_outs_t;
explicit not_enough_outs_to_mix(std::string&& loc, const scanty_outs_t& scanty_outs, size_t mixin_count)
- : transfer_error(std::move(loc), "not enough outputs to mix")
+ : transfer_error(std::move(loc), "not enough outputs to use")
, m_scanty_outs(scanty_outs)
, m_mixin_count(mixin_count)
{
@@ -429,7 +429,7 @@ namespace tools
std::string to_string() const
{
std::ostringstream ss;
- ss << transfer_error::to_string() << ", mixin_count = " << m_mixin_count << ", scanty_outs:";
+ ss << transfer_error::to_string() << ", ring size = " << (m_mixin_count + 1) << ", scanty_outs:";
for (const auto& out: m_scanty_outs)
{
ss << '\n' << cryptonote::print_money(out.first) << " - " << out.second;
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index e7b9b5a71..f014c573a 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -352,10 +352,25 @@ namespace tools
cryptonote::tx_destination_entry de;
bool has_payment_id;
crypto::hash8 new_payment_id;
- if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
+ if (er.message.empty())
+ er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
return false;
}
de.amount = it->amount;
@@ -441,7 +456,7 @@ namespace tools
{
uint64_t mixin = req.mixin;
if (mixin < 2 && m_wallet->use_fork_rules(2, 10)) {
- LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2");
+ LOG_PRINT_L1("Requested ring size " << (req.mixin + 1) << " too low for hard fork 2, using 3");
mixin = 2;
}
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, m_trusted_daemon);
@@ -454,7 +469,8 @@ namespace tools
return false;
}
- m_wallet->commit_tx(ptx_vector);
+ if (!req.do_not_relay)
+ m_wallet->commit_tx(ptx_vector);
// populate response with tx hash
res.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx_vector.back().tx));
@@ -463,6 +479,13 @@ namespace tools
res.tx_key = epee::string_tools::pod_to_hex(ptx_vector.back().tx_key);
}
res.fee = ptx_vector.back().fee;
+
+ if (req.get_tx_hex)
+ {
+ cryptonote::blobdata blob;
+ tx_to_blob(ptx_vector.back().tx, blob);
+ res.tx_blob = epee::string_tools::buff_to_hex_nodelimer(blob);
+ }
return true;
}
catch (const tools::error::daemon_busy& e)
@@ -511,7 +534,7 @@ namespace tools
uint64_t mixin = req.mixin;
uint64_t ptx_amount;
if (mixin < 2 && m_wallet->use_fork_rules(2, 10)) {
- LOG_PRINT_L1("Requested mixin " << req.mixin << " too low for hard fork 2, using 2");
+ LOG_PRINT_L1("Requested ring size " << (req.mixin + 1) << " too low for hard fork 2, using 3");
mixin = 2;
}
std::vector<wallet2::pending_tx> ptx_vector;
@@ -519,9 +542,12 @@ namespace tools
ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, m_trusted_daemon);
LOG_PRINT_L2("on_transfer_split called create_transactions_2");
- LOG_PRINT_L2("on_transfer_split calling commit_tx");
- m_wallet->commit_tx(ptx_vector);
- LOG_PRINT_L2("on_transfer_split called commit_tx");
+ if (!req.do_not_relay)
+ {
+ LOG_PRINT_L2("on_transfer_split calling commit_tx");
+ m_wallet->commit_tx(ptx_vector);
+ LOG_PRINT_L2("on_transfer_split called commit_tx");
+ }
// populate response with tx hashes
for (auto & ptx : ptx_vector)
@@ -538,6 +564,13 @@ namespace tools
res.amount_list.push_back(ptx_amount);
res.fee_list.push_back(ptx.fee);
+
+ if (req.get_tx_hex)
+ {
+ cryptonote::blobdata blob;
+ tx_to_blob(ptx.tx, blob);
+ res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob));
+ }
}
return true;
@@ -577,7 +610,8 @@ namespace tools
{
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions(m_trusted_daemon);
- m_wallet->commit_tx(ptx_vector);
+ if (!req.do_not_relay)
+ m_wallet->commit_tx(ptx_vector);
// populate response with tx hashes
for (auto & ptx : ptx_vector)
@@ -588,6 +622,12 @@ namespace tools
res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key));
}
res.fee_list.push_back(ptx.fee);
+ if (req.get_tx_hex)
+ {
+ cryptonote::blobdata blob;
+ tx_to_blob(ptx.tx, blob);
+ res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob));
+ }
}
return true;
@@ -640,7 +680,8 @@ namespace tools
{
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, req.mixin, req.unlock_time, req.priority, extra, m_trusted_daemon);
- m_wallet->commit_tx(ptx_vector);
+ if (!req.do_not_relay)
+ m_wallet->commit_tx(ptx_vector);
// populate response with tx hashes
for (auto & ptx : ptx_vector)
@@ -650,7 +691,12 @@ namespace tools
{
res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key));
}
- res.fee_list.push_back(ptx.fee);
+ if (req.get_tx_hex)
+ {
+ cryptonote::blobdata blob;
+ tx_to_blob(ptx.tx, blob);
+ res.tx_blob_list.push_back(epee::string_tools::buff_to_hex_nodelimer(blob));
+ }
}
return true;
@@ -1018,10 +1064,23 @@ namespace tools
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = "";
return false;
}
@@ -1412,10 +1471,25 @@ namespace tools
bool has_payment_id;
crypto::hash8 payment_id8;
crypto::hash payment_id = cryptonote::null_hash;
- if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
+ if (er.message.empty())
+ er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
return false;
}
if (has_payment_id)
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index 12ac281e4..5832bb032 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -119,6 +119,8 @@ namespace wallet_rpc
uint64_t unlock_time;
std::string payment_id;
bool get_tx_key;
+ bool do_not_relay;
+ bool get_tx_hex;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(destinations)
@@ -127,6 +129,8 @@ namespace wallet_rpc
KV_SERIALIZE(unlock_time)
KV_SERIALIZE(payment_id)
KV_SERIALIZE(get_tx_key)
+ KV_SERIALIZE_OPT(do_not_relay, false)
+ KV_SERIALIZE_OPT(get_tx_hex, false)
END_KV_SERIALIZE_MAP()
};
@@ -136,12 +140,14 @@ namespace wallet_rpc
std::string tx_key;
std::list<std::string> amount_keys;
uint64_t fee;
+ std::string tx_blob;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(tx_key)
KV_SERIALIZE(amount_keys)
KV_SERIALIZE(fee)
+ KV_SERIALIZE(tx_blob)
END_KV_SERIALIZE_MAP()
};
};
@@ -156,6 +162,8 @@ namespace wallet_rpc
uint64_t unlock_time;
std::string payment_id;
bool get_tx_keys;
+ bool do_not_relay;
+ bool get_tx_hex;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(destinations)
@@ -164,6 +172,8 @@ namespace wallet_rpc
KV_SERIALIZE(unlock_time)
KV_SERIALIZE(payment_id)
KV_SERIALIZE(get_tx_keys)
+ KV_SERIALIZE_OPT(do_not_relay, false)
+ KV_SERIALIZE_OPT(get_tx_hex, false)
END_KV_SERIALIZE_MAP()
};
@@ -182,12 +192,14 @@ namespace wallet_rpc
std::list<std::string> tx_key_list;
std::list<uint64_t> amount_list;
std::list<uint64_t> fee_list;
+ std::list<std::string> tx_blob_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
KV_SERIALIZE(tx_key_list)
KV_SERIALIZE(amount_list)
KV_SERIALIZE(fee_list)
+ KV_SERIALIZE(tx_blob_list)
END_KV_SERIALIZE_MAP()
};
};
@@ -197,9 +209,13 @@ namespace wallet_rpc
struct request
{
bool get_tx_keys;
+ bool do_not_relay;
+ bool get_tx_hex;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(get_tx_keys)
+ KV_SERIALIZE_OPT(do_not_relay, false)
+ KV_SERIALIZE_OPT(get_tx_hex, false)
END_KV_SERIALIZE_MAP()
};
@@ -217,11 +233,13 @@ namespace wallet_rpc
std::list<std::string> tx_hash_list;
std::list<std::string> tx_key_list;
std::list<uint64_t> fee_list;
+ std::list<std::string> tx_blob_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
KV_SERIALIZE(tx_key_list)
KV_SERIALIZE(fee_list)
+ KV_SERIALIZE(tx_blob_list)
END_KV_SERIALIZE_MAP()
};
};
@@ -237,6 +255,8 @@ namespace wallet_rpc
std::string payment_id;
bool get_tx_keys;
uint64_t below_amount;
+ bool do_not_relay;
+ bool get_tx_hex;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(address)
@@ -246,6 +266,8 @@ namespace wallet_rpc
KV_SERIALIZE(payment_id)
KV_SERIALIZE(get_tx_keys)
KV_SERIALIZE(below_amount)
+ KV_SERIALIZE_OPT(do_not_relay, false)
+ KV_SERIALIZE_OPT(get_tx_hex, false)
END_KV_SERIALIZE_MAP()
};
@@ -263,11 +285,13 @@ namespace wallet_rpc
std::list<std::string> tx_hash_list;
std::list<std::string> tx_key_list;
std::list<uint64_t> fee_list;
+ std::list<std::string> tx_blob_list;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash_list)
KV_SERIALIZE(tx_key_list)
KV_SERIALIZE(fee_list)
+ KV_SERIALIZE(tx_blob_list)
END_KV_SERIALIZE_MAP()
};
};