Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ find_package(pybind11 REQUIRED)
set(SOURCES
src/cpp/common/py_monero_common.cpp
src/cpp/daemon/py_monero_daemon_model.cpp
src/cpp/daemon/py_monero_daemon.cpp
src/cpp/daemon/py_monero_daemon_default.cpp
src/cpp/daemon/py_monero_daemon_rpc.cpp
src/cpp/wallet/py_monero_wallet_model.cpp
src/cpp/wallet/py_monero_wallet.cpp
src/cpp/wallet/py_monero_wallet_full.cpp
src/cpp/wallet/py_monero_wallet_rpc.cpp
src/cpp/py_monero.cpp
)

Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
[
'src/cpp/common/py_monero_common.cpp',
'src/cpp/daemon/py_monero_daemon_model.cpp',
'src/cpp/daemon/py_monero_daemon.cpp',
'src/cpp/daemon/py_monero_daemon_default.cpp',
'src/cpp/daemon/py_monero_daemon_rpc.cpp',
'src/cpp/wallet/py_monero_wallet_model.cpp',
'src/cpp/wallet/py_monero_wallet.cpp',
'src/cpp/wallet/py_monero_wallet_full.cpp',
'src/cpp/wallet/py_monero_wallet_rpc.cpp',
'src/cpp/py_monero.cpp'
],
include_dirs=[
Expand Down
142 changes: 1 addition & 141 deletions src/cpp/daemon/py_monero_daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PyMoneroDaemonListener : public monero_daemon_listener {
public:
virtual void on_block_header(const std::shared_ptr<monero::monero_block_header> &header) {
PYBIND11_OVERRIDE(
void,
void,
monero_daemon_listener,
on_block_header,
header
Expand Down Expand Up @@ -111,143 +111,3 @@ class PyMoneroDaemon {
virtual void stop() { throw std::runtime_error("PyMoneroDaemon: not implemented"); }
virtual std::shared_ptr<monero::monero_block_header> wait_for_next_block_header() { throw std::runtime_error("PyMoneroDaemon: not implemented"); }
};

class PyMoneroDaemonDefault : public PyMoneroDaemon {
public:

std::vector<std::shared_ptr<PyMoneroDaemonListener>> get_listeners() override { return m_listeners; }
void add_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) override;
void remove_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) override;
void remove_listeners() override;
std::optional<std::shared_ptr<monero::monero_tx>> get_tx(const std::string& tx_hash, bool prune = false) override;
void relay_tx_by_hash(std::string& tx_hash) override;
PyMoneroKeyImageSpentStatus get_key_image_spent_status(std::string& key_image) override;
std::optional<std::string> get_tx_hex(const std::string& tx_hash, bool prune = false);
void submit_block(const std::string& block_blob) override;
void set_peer_ban(const std::shared_ptr<PyMoneroBan>& ban) override;

protected:
mutable boost::recursive_mutex m_listeners_mutex;
std::vector<std::shared_ptr<PyMoneroDaemonListener>> m_listeners;

virtual void refresh_listening() { }
};

class PyMoneroDaemonPoller {
public:
explicit PyMoneroDaemonPoller(PyMoneroDaemon* daemon, uint64_t poll_period_ms = 5000): m_poll_period_ms(poll_period_ms), m_is_polling(false) {
m_daemon = daemon;
}

~PyMoneroDaemonPoller();
void set_is_polling(bool is_polling);

private:
PyMoneroDaemon* m_daemon;
std::shared_ptr<monero::monero_block_header> m_last_header;
uint64_t m_poll_period_ms;
std::atomic<bool> m_is_polling;
std::thread m_thread;

void loop();
void poll();
void announce_block_header(const std::shared_ptr<monero::monero_block_header>& header);
};


class PyMoneroDaemonRpc : public PyMoneroDaemonDefault {
public:
PyMoneroDaemonRpc() {
m_rpc = std::make_shared<PyMoneroRpcConnection>();
}

PyMoneroDaemonRpc(std::shared_ptr<PyMoneroRpcConnection> rpc) {
m_rpc = rpc;
if (!rpc->is_online() && !rpc->m_uri->empty()) rpc->check_connection();
}

PyMoneroDaemonRpc(const std::string& uri, const std::string& username = "", const std::string& password = "") {
m_rpc = std::make_shared<PyMoneroRpcConnection>();
m_rpc->m_uri = uri;
if (!username.empty() && !password.empty()) m_rpc->set_credentials(username, password);
if (!uri.empty()) m_rpc->check_connection();
}

~PyMoneroDaemonRpc();

std::shared_ptr<PyMoneroRpcConnection> get_rpc_connection() const;
bool is_connected();
monero::monero_version get_version() override;
bool is_trusted() override;
uint64_t get_height() override;
std::string get_block_hash(uint64_t height) override;
std::shared_ptr<PyMoneroBlockTemplate> get_block_template(std::string& wallet_address, int reserve_size) override;
std::shared_ptr<PyMoneroBlockTemplate> get_block_template(std::string& wallet_address) override;
std::shared_ptr<monero::monero_block_header> get_last_block_header() override;
std::shared_ptr<monero::monero_block_header> get_block_header_by_hash(const std::string& hash) override;
std::shared_ptr<monero::monero_block_header> get_block_header_by_height(uint64_t height) override;
std::vector<std::shared_ptr<monero::monero_block_header>> get_block_headers_by_range(uint64_t start_height, uint64_t end_height) override;
std::shared_ptr<monero::monero_block> get_block_by_hash(const std::string& hash) override;
std::vector<std::shared_ptr<monero::monero_block>> get_blocks_by_hash(const std::vector<std::string>& block_hashes, uint64_t start_height, bool prune) override;
std::shared_ptr<monero::monero_block> get_block_by_height(uint64_t height) override;
std::vector<std::shared_ptr<monero::monero_block>> get_blocks_by_height(const std::vector<uint64_t>& heights) override;
std::vector<std::shared_ptr<monero::monero_block>> get_blocks_by_range(boost::optional<uint64_t> start_height, boost::optional<uint64_t> end_height) override;
std::vector<std::shared_ptr<monero::monero_block>> get_blocks_by_range_chunked(boost::optional<uint64_t> start_height, boost::optional<uint64_t> end_height, boost::optional<uint64_t> max_chunk_size) override;
std::vector<std::string> get_block_hashes(std::vector<std::string> block_hashes, uint64_t start_height) override;
std::vector<std::shared_ptr<monero::monero_tx>> get_txs(const std::vector<std::string>& tx_hashes, bool prune = false) override;
std::vector<std::string> get_tx_hexes(const std::vector<std::string>& tx_hashes, bool prune = false) override;
std::shared_ptr<PyMoneroMinerTxSum> get_miner_tx_sum(uint64_t height, uint64_t num_blocks) override;
std::shared_ptr<PyMoneroFeeEstimate> get_fee_estimate(uint64_t grace_blocks = 0) override;
std::shared_ptr<PyMoneroSubmitTxResult> submit_tx_hex(std::string& tx_hex, bool do_not_relay = false) override;
void relay_txs_by_hash(std::vector<std::string>& tx_hashes) override;
std::shared_ptr<PyMoneroTxPoolStats> get_tx_pool_stats() override;
std::vector<std::shared_ptr<monero::monero_tx>> get_tx_pool() override;
std::vector<std::string> get_tx_pool_hashes() override;
void flush_tx_pool(const std::vector<std::string> &hashes) override;
void flush_tx_pool() override;
void flush_tx_pool(const std::string &hash) override;
std::vector<PyMoneroKeyImageSpentStatus> get_key_image_spent_statuses(std::vector<std::string>& key_images) override;
std::vector<std::shared_ptr<monero::monero_output>> get_outputs(std::vector<monero::monero_output>& outputs) override;
std::vector<std::shared_ptr<PyMoneroOutputHistogramEntry>> get_output_histogram(std::vector<uint64_t> amounts, int min_count, int max_count, bool is_unlocked, int recent_cutoff) override;
std::shared_ptr<PyMoneroDaemonInfo> get_info() override;
std::shared_ptr<PyMoneroDaemonSyncInfo> get_sync_info() override;
std::shared_ptr<PyMoneroHardForkInfo> get_hard_fork_info() override;
std::vector<std::shared_ptr<PyMoneroAltChain>> get_alt_chains() override;
std::vector<std::string> get_alt_block_hashes() override;
int get_download_limit() override;
int set_download_limit(int limit) override;
int reset_download_limit() override;
int get_upload_limit() override;
int set_upload_limit(int limit) override;
int reset_upload_limit() override;
std::vector<std::shared_ptr<PyMoneroPeer>> get_peers() override;
std::vector<std::shared_ptr<PyMoneroPeer>> get_known_peers() override;
void set_outgoing_peer_limit(int limit) override;
void set_incoming_peer_limit(int limit) override;
std::vector<std::shared_ptr<PyMoneroBan>> get_peer_bans() override;
void set_peer_bans(const std::vector<std::shared_ptr<PyMoneroBan>>& bans) override;
void start_mining(const std::string &address, int num_threads, bool is_background, bool ignore_battery) override;
void stop_mining() override;
std::shared_ptr<PyMoneroMiningStatus> get_mining_status() override;
void submit_blocks(const std::vector<std::string>& block_blobs) override;
std::shared_ptr<PyMoneroPruneResult> prune_blockchain(bool check) override;
std::shared_ptr<PyMoneroDaemonUpdateCheckResult> check_for_update() override;
std::shared_ptr<PyMoneroDaemonUpdateDownloadResult> download_update(const std::string& path) override;
std::shared_ptr<PyMoneroDaemonUpdateDownloadResult> download_update() override;
void stop() override;
std::shared_ptr<monero::monero_block_header> wait_for_next_block_header();
static void check_response_status(std::shared_ptr<PyMoneroPathResponse> response);
static void check_response_status(std::shared_ptr<PyMoneroJsonResponse> response);

protected:
std::shared_ptr<PyMoneroRpcConnection> m_rpc;
std::shared_ptr<PyMoneroDaemonPoller> m_poller;
std::unordered_map<uint64_t, std::shared_ptr<monero::monero_block_header>> m_cached_headers;

std::vector<std::shared_ptr<monero::monero_block>> get_max_blocks(boost::optional<uint64_t> start_height, boost::optional<uint64_t> max_height, boost::optional<uint64_t> chunk_size);
std::shared_ptr<monero::monero_block_header> get_block_header_by_height_cached(uint64_t height, uint64_t max_height);
std::shared_ptr<PyMoneroBandwithLimits> get_bandwidth_limits();
std::shared_ptr<PyMoneroBandwithLimits> set_bandwidth_limits(int up, int down);
void refresh_listening() override;
static void check_response_status(const boost::property_tree::ptree& node);
};
72 changes: 72 additions & 0 deletions src/cpp/daemon/py_monero_daemon_default.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "py_monero_daemon_default.h"


void PyMoneroDaemonDefault::add_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.push_back(listener);
refresh_listening();
}

void PyMoneroDaemonDefault::remove_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.erase(std::remove_if(m_listeners.begin(), m_listeners.end(), [&listener](std::shared_ptr<PyMoneroDaemonListener> iter){ return iter == listener; }), m_listeners.end());
refresh_listening();
}

void PyMoneroDaemonDefault::remove_listeners() {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.clear();
refresh_listening();
}

std::optional<std::shared_ptr<monero::monero_tx>> PyMoneroDaemonDefault::get_tx(const std::string& tx_hash, bool prune) {
std::vector<std::string> hashes;
hashes.push_back(tx_hash);
auto txs = get_txs(hashes, prune);
std::optional<std::shared_ptr<monero::monero_tx>> tx;

if (txs.size() > 0) {
tx = txs[0];
}

return tx;
}

void PyMoneroDaemonDefault::relay_tx_by_hash(std::string& tx_hash) {
std::vector<std::string> tx_hashes;
tx_hashes.push_back(tx_hash);
relay_txs_by_hash(tx_hashes);
}

PyMoneroKeyImageSpentStatus PyMoneroDaemonDefault::get_key_image_spent_status(std::string& key_image) {
std::vector<std::string> key_images;
key_images.push_back(key_image);
auto statuses = get_key_image_spent_statuses(key_images);
if (statuses.empty()) throw std::runtime_error("Could not get key image spent status");
return statuses[0];
}

std::optional<std::string> PyMoneroDaemonDefault::get_tx_hex(const std::string& tx_hash, bool prune) {
std::vector<std::string> hashes;
hashes.push_back(tx_hash);
auto hexes = get_tx_hexes(hashes, prune);
std::optional<std::string> hex;
if (hexes.size() > 0) {
hex = hexes[0];
}

return hex;
}

void PyMoneroDaemonDefault::submit_block(const std::string& block_blob) {
std::vector<std::string> block_blobs;
block_blobs.push_back(block_blob);
return submit_blocks(block_blobs);
}

void PyMoneroDaemonDefault::set_peer_ban(const std::shared_ptr<PyMoneroBan>& ban) {
if (ban == nullptr) throw std::runtime_error("Ban is none");
std::vector<std::shared_ptr<PyMoneroBan>> bans;
bans.push_back(ban);
set_peer_bans(bans);
}
25 changes: 25 additions & 0 deletions src/cpp/daemon/py_monero_daemon_default.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "py_monero_daemon.h"

class PyMoneroDaemonDefault : public PyMoneroDaemon {
public:

std::vector<std::shared_ptr<PyMoneroDaemonListener>> get_listeners() override { return m_listeners; }
void add_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) override;
void remove_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) override;
void remove_listeners() override;
std::optional<std::shared_ptr<monero::monero_tx>> get_tx(const std::string& tx_hash, bool prune = false) override;
void relay_tx_by_hash(std::string& tx_hash) override;
PyMoneroKeyImageSpentStatus get_key_image_spent_status(std::string& key_image) override;
std::optional<std::string> get_tx_hex(const std::string& tx_hash, bool prune = false);
void submit_block(const std::string& block_blob) override;
void set_peer_ban(const std::shared_ptr<PyMoneroBan>& ban) override;

protected:
mutable boost::recursive_mutex m_listeners_mutex;
std::vector<std::shared_ptr<PyMoneroDaemonListener>> m_listeners;

virtual void refresh_listening() { }
};

2 changes: 1 addition & 1 deletion src/cpp/daemon/py_monero_daemon_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ bool PyMoneroRpcConnection::check_connection(int timeout_ms) {
throw std::runtime_error("Could not set rpc connection: " + m_uri.get());
}

bool connected = m_http_client->connect(std::chrono::milliseconds(timeout_ms));
m_http_client->connect(std::chrono::milliseconds(timeout_ms));
auto start = std::chrono::high_resolution_clock::now();
PyMoneroJsonRequest request("get_version");
auto response = send_json_request(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,8 @@
#include "py_monero_daemon.h"
#include "py_monero_daemon_rpc.h"

static const uint64_t MAX_REQ_SIZE = 3000000;
static const uint64_t NUM_HEADERS_PER_REQ = 750;

void PyMoneroDaemonDefault::add_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.push_back(listener);
refresh_listening();
}

void PyMoneroDaemonDefault::remove_listener(const std::shared_ptr<PyMoneroDaemonListener> &listener) {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.erase(std::remove_if(m_listeners.begin(), m_listeners.end(), [&listener](std::shared_ptr<PyMoneroDaemonListener> iter){ return iter == listener; }), m_listeners.end());
refresh_listening();
}

void PyMoneroDaemonDefault::remove_listeners() {
boost::lock_guard<boost::recursive_mutex> lock(m_listeners_mutex);
m_listeners.clear();
refresh_listening();
}

std::optional<std::shared_ptr<monero::monero_tx>> PyMoneroDaemonDefault::get_tx(const std::string& tx_hash, bool prune) {
std::vector<std::string> hashes;
hashes.push_back(tx_hash);
auto txs = get_txs(hashes, prune);
std::optional<std::shared_ptr<monero::monero_tx>> tx;

if (txs.size() > 0) {
tx = txs[0];
}

return tx;
}

void PyMoneroDaemonDefault::relay_tx_by_hash(std::string& tx_hash) {
std::vector<std::string> tx_hashes;
tx_hashes.push_back(tx_hash);
relay_txs_by_hash(tx_hashes);
}

PyMoneroKeyImageSpentStatus PyMoneroDaemonDefault::get_key_image_spent_status(std::string& key_image) {
std::vector<std::string> key_images;
key_images.push_back(key_image);
auto statuses = get_key_image_spent_statuses(key_images);
if (statuses.empty()) throw std::runtime_error("Could not get key image spent status");
return statuses[0];
}

std::optional<std::string> PyMoneroDaemonDefault::get_tx_hex(const std::string& tx_hash, bool prune) {
std::vector<std::string> hashes;
hashes.push_back(tx_hash);
auto hexes = get_tx_hexes(hashes, prune);
std::optional<std::string> hex;
if (hexes.size() > 0) {
hex = hexes[0];
}

return hex;
}

void PyMoneroDaemonDefault::submit_block(const std::string& block_blob) {
std::vector<std::string> block_blobs;
block_blobs.push_back(block_blob);
return submit_blocks(block_blobs);
}

void PyMoneroDaemonDefault::set_peer_ban(const std::shared_ptr<PyMoneroBan>& ban) {
if (ban == nullptr) throw std::runtime_error("Ban is none");
std::vector<std::shared_ptr<PyMoneroBan>> bans;
bans.push_back(ban);
set_peer_bans(bans);
}

PyMoneroDaemonPoller::~PyMoneroDaemonPoller() {
set_is_polling(false);
}
Expand Down Expand Up @@ -893,3 +823,4 @@ void PyMoneroDaemonRpc::check_response_status(std::shared_ptr<PyMoneroJsonRespon

PyMoneroDaemonRpc::~PyMoneroDaemonRpc() {
}

Loading