aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ringct/rctTypes.h6
-rw-r--r--src/rpc/CMakeLists.txt1
-rw-r--r--src/simplewallet/simplewallet.cpp40
-rw-r--r--src/simplewallet/simplewallet.h1
-rw-r--r--src/wallet/CMakeLists.txt2
-rw-r--r--src/wallet/api/address_book.cpp2
-rw-r--r--src/wallet/api/address_book.h2
-rw-r--r--src/wallet/api/wallet.cpp67
-rw-r--r--src/wallet/api/wallet.h11
-rw-r--r--src/wallet/wallet2.cpp4
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet2_api.h17
12 files changed, 120 insertions, 35 deletions
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h
index 71cc61ddc..6b24fc470 100644
--- a/src/ringct/rctTypes.h
+++ b/src/ringct/rctTypes.h
@@ -308,10 +308,10 @@ namespace rct {
ar.tag("cc");
FIELDS(MGs[i].cc)
// MGs[i].II not saved, it can be reconstructed
- if (mg_elements - i > 1)
- ar.delimit_array();
-
ar.end_object();
+
+ if (mg_elements - i > 1)
+ ar.delimit_array();
}
ar.end_array();
return true;
diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt
index 050b5e569..6df93cde1 100644
--- a/src/rpc/CMakeLists.txt
+++ b/src/rpc/CMakeLists.txt
@@ -46,6 +46,7 @@ target_link_libraries(rpc
PUBLIC
cryptonote_core
cryptonote_protocol
+ epee
${Boost_THREAD_LIBRARY}
PRIVATE
${EXTRA_LIBRARIES})
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 85bdee16f..b46447975 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -663,6 +663,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]"));
m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with mixin 0"));
m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [mixin] address [payment_id] - Send all unlocked balance an address"));
+ m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)"));
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file"));
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file"));
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log <level> - Change current log detail level, <0-4>"));
@@ -2826,6 +2827,45 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_)
return true;
}
//----------------------------------------------------------------------------------------------------
+bool simple_wallet::donate(const std::vector<std::string> &args_)
+{
+ std::vector<std::string> local_args = args_;
+ if(local_args.empty() || local_args.size() > 3)
+ {
+ fail_msg_writer() << tr("wrong number of arguments");
+ return true;
+ }
+ std::string mixin_str;
+ std::string address_str = "donate.getmonero.org";
+ std::string amount_str;
+ std::string payment_id_str;
+ // check payment id
+ crypto::hash payment_id;
+ crypto::hash8 payment_id8;
+ if (tools::wallet2::parse_long_payment_id (local_args.back(), payment_id ) ||
+ tools::wallet2::parse_short_payment_id(local_args.back(), payment_id8))
+ {
+ payment_id_str = local_args.back();
+ local_args.pop_back();
+ }
+ // check mixin
+ if (local_args.size() > 1)
+ {
+ mixin_str = local_args[0];
+ local_args.erase(local_args.begin());
+ }
+ amount_str = local_args[0];
+ // refill args as necessary
+ local_args.clear();
+ if (!mixin_str.empty())
+ local_args.push_back(mixin_str);
+ local_args.push_back(address_str);
+ local_args.push_back(amount_str);
+ if (!payment_id_str.empty())
+ local_args.push_back(payment_id_str);
+ transfer_new(local_args);
+}
+//----------------------------------------------------------------------------------------------------
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)
{
// gather info to ask the user
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 0d83f429b..420597699 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -124,6 +124,7 @@ namespace cryptonote
bool locked_transfer(const std::vector<std::string> &args);
bool sweep_all(const std::vector<std::string> &args);
bool sweep_unmixable(const std::vector<std::string> &args);
+ bool donate(const std::vector<std::string> &args);
bool sign_transfer(const std::vector<std::string> &args);
bool submit_transfer(const std::vector<std::string> &args);
std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts(
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index ba5c6b5ac..056a1ca10 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -34,7 +34,6 @@ set(wallet_sources
password_container.cpp
wallet2.cpp
wallet_args.cpp
- wallet_rpc_server.cpp
api/wallet.cpp
api/wallet_manager.cpp
api/transaction_info.cpp
@@ -103,6 +102,7 @@ if (NOT BUILD_GUI_DEPS)
target_link_libraries(wallet_rpc_server
PRIVATE
wallet
+ epee
rpc
cryptonote_core
crypto
diff --git a/src/wallet/api/address_book.cpp b/src/wallet/api/address_book.cpp
index 1847e1496..bbf96c81a 100644
--- a/src/wallet/api/address_book.cpp
+++ b/src/wallet/api/address_book.cpp
@@ -94,7 +94,7 @@ void AddressBookImpl::refresh()
}
-bool AddressBookImpl::deleteRow(int rowId)
+bool AddressBookImpl::deleteRow(std::size_t rowId)
{
LOG_PRINT_L2("Deleting address book row " << rowId);
bool r = m_wallet->m_wallet->delete_address_book_row(rowId);
diff --git a/src/wallet/api/address_book.h b/src/wallet/api/address_book.h
index c3a24eff9..7f30e4387 100644
--- a/src/wallet/api/address_book.h
+++ b/src/wallet/api/address_book.h
@@ -46,7 +46,7 @@ public:
void refresh();
std::vector<AddressBookRow*> getAll() const;
bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description);
- bool deleteRow(int rowId);
+ bool deleteRow(std::size_t rowId);
// Error codes. See AddressBook:ErrorCode enum in wallet2_api.h
std::string errorString() const {return m_errorString;}
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 6d8e48deb..3a4493ec3 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -204,6 +204,7 @@ WalletImpl::WalletImpl(bool testnet)
, m_recoveringFromSeed(false)
, m_synchronized(false)
, m_rebuildWalletCache(false)
+ , m_is_connected(false)
{
m_wallet = new tools::wallet2(testnet);
m_history = new TransactionHistoryImpl(this);
@@ -224,11 +225,19 @@ WalletImpl::WalletImpl(bool testnet)
WalletImpl::~WalletImpl()
{
+
+ LOG_PRINT_L1(__FUNCTION__);
+ // Pause refresh thread - prevents refresh from starting again
+ pauseRefresh();
+ // Close wallet - stores cache and stops ongoing refresh operation
+ close();
+ // Stop refresh thread
stopRefresh();
+ delete m_wallet2Callback;
delete m_history;
delete m_addressBook;
delete m_wallet;
- delete m_wallet2Callback;
+ LOG_PRINT_L1(__FUNCTION__ << " finished");
}
bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language)
@@ -329,7 +338,7 @@ bool WalletImpl::close()
{
bool result = false;
- LOG_PRINT_L3("closing wallet...");
+ LOG_PRINT_L1("closing wallet...");
try {
// Do not store wallet with invalid status
// Status Critical refers to errors on opening or creating wallets.
@@ -337,10 +346,10 @@ bool WalletImpl::close()
m_wallet->store();
else
LOG_PRINT_L3("Status_Critical - not storing wallet");
- LOG_PRINT_L3("wallet::store done");
- LOG_PRINT_L3("Calling wallet::stop...");
+ LOG_PRINT_L1("wallet::store done");
+ LOG_PRINT_L1("Calling wallet::stop...");
m_wallet->stop();
- LOG_PRINT_L3("wallet::stop done");
+ LOG_PRINT_L1("wallet::stop done");
result = true;
clearStatus();
} catch (const std::exception &e) {
@@ -487,6 +496,8 @@ uint64_t WalletImpl::approximateBlockChainHeight() const
}
uint64_t WalletImpl::daemonBlockChainHeight() const
{
+ if (!m_is_connected)
+ return 0;
std::string err;
uint64_t result = m_wallet->get_daemon_blockchain_height(err);
if (!err.empty()) {
@@ -504,6 +515,8 @@ uint64_t WalletImpl::daemonBlockChainHeight() const
uint64_t WalletImpl::daemonBlockChainTargetHeight() const
{
+ if (!m_is_connected)
+ return 0;
std::string err;
uint64_t result = m_wallet->get_daemon_blockchain_target_height(err);
if (!err.empty()) {
@@ -516,9 +529,20 @@ uint64_t WalletImpl::daemonBlockChainTargetHeight() const
m_status = Status_Ok;
m_errorString = "";
}
+ // Target height can be 0 when daemon is synced. Use blockchain height instead.
+ if(result == 0)
+ result = daemonBlockChainHeight();
return result;
}
+bool WalletImpl::daemonSynced() const
+{
+ if(connected() == Wallet::ConnectionStatus_Disconnected)
+ return false;
+ uint64_t blockChainHeight = daemonBlockChainHeight();
+ return (blockChainHeight >= daemonBlockChainTargetHeight() && blockChainHeight > 1);
+}
+
bool WalletImpl::synchronized() const
{
return m_synchronized;
@@ -924,8 +948,8 @@ bool WalletImpl::connectToDaemon()
Wallet::ConnectionStatus WalletImpl::connected() const
{
uint32_t version = 0;
- bool is_connected = m_wallet->check_connection(&version);
- if (!is_connected)
+ m_is_connected = m_wallet->check_connection(&version);
+ if (!m_is_connected)
return Wallet::ConnectionStatus_Disconnected;
if ((version >> 16) != CORE_RPC_VERSION_MAJOR)
return Wallet::ConnectionStatus_WrongVersion;
@@ -970,7 +994,7 @@ void WalletImpl::refreshThreadFunc()
LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired...");
LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled);
LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << m_status);
- if (m_refreshEnabled /*&& m_status == Status_Ok*/) {
+ if (m_refreshEnabled) {
LOG_PRINT_L3(__FUNCTION__ << ": refreshing...");
doRefresh();
}
@@ -983,16 +1007,23 @@ void WalletImpl::doRefresh()
// synchronizing async and sync refresh calls
boost::lock_guard<boost::mutex> guarg(m_refreshMutex2);
try {
- m_wallet->refresh();
- if (!m_synchronized) {
- m_synchronized = true;
- }
- // assuming if we have empty history, it wasn't initialized yet
- // for futher history changes client need to update history in
- // "on_money_received" and "on_money_sent" callbacks
- if (m_history->count() == 0) {
- m_history->refresh();
- }
+ // Syncing daemon and refreshing wallet simultaneously is very resource intensive.
+ // Disable refresh if wallet is disconnected or daemon isn't synced.
+ if (daemonSynced()) {
+ // Use fast refresh for new wallets
+ if (isNewWallet())
+ m_wallet->set_refresh_from_block_height(daemonBlockChainHeight());
+ m_wallet->refresh();
+ if (!m_synchronized) {
+ m_synchronized = true;
+ }
+ // assuming if we have empty history, it wasn't initialized yet
+ // for futher history changes client need to update history in
+ // "on_money_received" and "on_money_sent" callbacks
+ if (m_history->count() == 0) {
+ m_history->refresh();
+ }
+ }
} catch (const std::exception &e) {
m_status = Status_Error;
m_errorString = e.what();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 5046fbf0f..d245a78d0 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -107,14 +107,15 @@ public:
virtual std::string getTxKey(const std::string &txid) const;
virtual std::string signMessage(const std::string &message);
virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const;
+ virtual void startRefresh();
+ virtual void pauseRefresh();
private:
void clearStatus();
void refreshThreadFunc();
void doRefresh();
- void startRefresh();
+ bool daemonSynced() const;
void stopRefresh();
- void pauseRefresh();
bool isNewWallet() const;
void doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit);
@@ -148,9 +149,11 @@ private:
// flag indicating wallet is recovering from seed
// so it shouldn't be considered as new and pull blocks (slow-refresh)
// instead of pulling hashes (fast-refresh)
- bool m_recoveringFromSeed;
+ std::atomic<bool> m_recoveringFromSeed;
std::atomic<bool> m_synchronized;
- bool m_rebuildWalletCache;
+ std::atomic<bool> m_rebuildWalletCache;
+ // cache connection status to avoid unnecessary RPC calls
+ mutable std::atomic<bool> m_is_connected;
};
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 60fa1d266..db4fae557 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1569,14 +1569,14 @@ bool wallet2::add_address_book_row(const cryptonote::account_public_address &add
a.m_payment_id = payment_id;
a.m_description = description;
- int old_size = m_address_book.size();
+ auto old_size = m_address_book.size();
m_address_book.push_back(a);
if(m_address_book.size() == old_size+1)
return true;
return false;
}
-bool wallet2::delete_address_book_row(int row_id) {
+bool wallet2::delete_address_book_row(std::size_t row_id) {
if(m_address_book.size() <= row_id)
return false;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 36b9b3d1f..c3381730b 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -525,7 +525,7 @@ namespace tools
*/
std::vector<address_book_row> get_address_book() const { return m_address_book; }
bool add_address_book_row(const cryptonote::account_public_address &address, const crypto::hash &payment_id, const std::string &description);
- bool delete_address_book_row(int row_id);
+ bool delete_address_book_row(std::size_t row_id);
uint64_t get_num_rct_outputs();
const transfer_details &get_transfer_details(size_t idx) const;
diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h
index cd2e7230a..6651b876d 100644
--- a/src/wallet/wallet2_api.h
+++ b/src/wallet/wallet2_api.h
@@ -137,14 +137,14 @@ struct TransactionHistory
*/
struct AddressBookRow {
public:
- AddressBookRow(int _rowId, const std::string &_address, const std::string &_paymentId, const std::string &_description):
+ AddressBookRow(std::size_t _rowId, const std::string &_address, const std::string &_paymentId, const std::string &_description):
m_rowId(_rowId),
m_address(_address),
m_paymentId(_paymentId),
m_description(_description) {}
private:
- int m_rowId;
+ std::size_t m_rowId;
std::string m_address;
std::string m_paymentId;
std::string m_description;
@@ -153,7 +153,7 @@ public:
std::string getAddress() const {return m_address;}
std::string getDescription() const {return m_description;}
std::string getPaymentId() const {return m_paymentId;}
- int getRowId() const {return m_rowId;}
+ std::size_t getRowId() const {return m_rowId;}
};
/**
@@ -171,7 +171,7 @@ struct AddressBook
virtual ~AddressBook() = 0;
virtual std::vector<AddressBookRow*> getAll() const = 0;
virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0;
- virtual bool deleteRow(int rowId) = 0;
+ virtual bool deleteRow(std::size_t rowId) = 0;
virtual void refresh() = 0;
virtual std::string errorString() const = 0;
virtual int errorCode() const = 0;
@@ -364,6 +364,15 @@ struct Wallet
static std::string paymentIdFromAddress(const std::string &str, bool testnet);
static uint64_t maximumAllowedAmount();
+ /**
+ * @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
+ */
+ virtual void startRefresh() = 0;
+ /**
+ * @brief pauseRefresh - pause refresh thread
+ */
+ virtual void pauseRefresh() = 0;
+
/**
* @brief refresh - refreshes the wallet, updating transactions from daemon
* @return - true if refreshed successfully;