From 9b337ca01fbd775ac188fe7adc7c0c2702235f79 Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Fri, 5 May 2023 12:12:52 -0500 Subject: [PATCH] rpc: remove pay-to-use RPC on node side Co-authored-by: tobtoht Co-authored-by: SNeedlewoods --- src/cryptonote_config.h | 2 - src/daemon/command_parser_executor.cpp | 10 - src/daemon/command_parser_executor.h | 2 - src/daemon/command_server.cpp | 5 - src/daemon/daemon.cpp | 4 +- src/daemon/rpc.h | 3 +- src/daemon/rpc_command_executor.cpp | 42 -- src/daemon/rpc_command_executor.h | 2 - src/rpc/CMakeLists.txt | 4 - src/rpc/bootstrap_daemon.cpp | 6 +- src/rpc/bootstrap_daemon.h | 3 - src/rpc/core_rpc_server.cpp | 452 +----------------- src/rpc/core_rpc_server.h | 21 - src/rpc/core_rpc_server_commands_defs.h | 200 -------- src/rpc/rpc_payment.cpp | 429 ----------------- src/rpc/rpc_payment.h | 191 -------- src/rpc/rpc_payment_costs.h | 50 -- src/rpc/rpc_payment_signature.cpp | 112 ----- src/rpc/rpc_payment_signature.h | 39 -- src/wallet/wallet2.h | 1 - tests/functional_tests/CMakeLists.txt | 14 - .../functional_tests/functional_tests_rpc.py | 5 +- tests/functional_tests/make_test_signature.cc | 79 --- tests/functional_tests/rpc_payment.py | 452 ------------------ tests/fuzz/fuzz_rpc/initialisation.cpp | 39 -- tests/fuzz/fuzz_rpc/rpc_endpoints.cpp | 63 --- tests/fuzz/fuzz_rpc/rpc_endpoints.h | 6 - utils/fish/monero-wallet-cli.fish | 1 - utils/fish/monero-wallet-rpc.fish | 1 - utils/fish/monerod.fish | 4 - utils/python-rpc/framework/daemon.py | 70 --- 31 files changed, 12 insertions(+), 2300 deletions(-) delete mode 100644 src/rpc/rpc_payment.cpp delete mode 100644 src/rpc/rpc_payment.h delete mode 100644 src/rpc/rpc_payment_costs.h delete mode 100644 src/rpc/rpc_payment_signature.cpp delete mode 100644 src/rpc/rpc_payment_signature.h delete mode 100644 tests/functional_tests/make_test_signature.cc delete mode 100755 tests/functional_tests/rpc_payment.py diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 35b86d6e9..e60d356d9 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -169,7 +169,6 @@ #define CRYPTONOTE_BLOCKCHAINDATA_FILENAME "data.mdb" #define CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME "lock.mdb" #define P2P_NET_DATA_FILENAME "p2pstate.bin" -#define RPC_PAYMENTS_DATA_FILENAME "rpcpayments.bin" #define MINER_CONFIG_FILE_NAME "miner_conf.json" #define THREAD_STACK_SIZE 5 * 1024 * 1024 @@ -251,7 +250,6 @@ namespace config const unsigned char HASH_KEY_WALLET_CACHE = 0x8d; const unsigned char HASH_KEY_BACKGROUND_CACHE = 0x8e; const unsigned char HASH_KEY_BACKGROUND_KEYS_FILE = 0x8f; - const unsigned char HASH_KEY_RPC_PAYMENT_NONCE = 0x58; const unsigned char HASH_KEY_MEMORY = 'k'; const unsigned char HASH_KEY_MULTISIG[] = {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char HASH_KEY_MULTISIG_KEY_AGGREGATION[] = "Multisig_key_agg"; diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index f971e6f5e..728df58af 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -954,16 +954,6 @@ bool t_command_parser_executor::pop_blocks(const std::vector& args) return true; } -bool t_command_parser_executor::rpc_payments(const std::vector& args) -{ - if (args.size() != 0) { - std::cout << "Invalid syntax: No parameters expected. For more details, use the help command." << std::endl; - return true; - } - - return m_executor.rpc_payments(); -} - bool t_command_parser_executor::version(const std::vector& args) { return m_executor.version(); diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index 741fafdc4..a053d0154 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -142,8 +142,6 @@ public: bool pop_blocks(const std::vector& args); - bool rpc_payments(const std::vector& args); - bool version(const std::vector& args); bool prune_blockchain(const std::vector& args); diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 8170fa36b..1950b22a6 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -302,11 +302,6 @@ t_command_server::t_command_server( , "pop_blocks " , "Remove blocks from end of blockchain" ); - m_command_lookup.set_handler( - "rpc_payments" - , std::bind(&t_command_parser_executor::rpc_payments, &m_parser, p::_1) - , "Print information about RPC payments." - ); m_command_lookup.set_handler( "version" , std::bind(&t_command_parser_executor::version, &m_parser, p::_1) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 7391f90c9..cbd4a668a 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -124,12 +124,12 @@ public: const auto main_rpc_port = command_line::get_arg(vm, cryptonote::core_rpc_server::arg_rpc_bind_port); const auto restricted_rpc_port_arg = cryptonote::core_rpc_server::arg_rpc_restricted_bind_port; const bool has_restricted_rpc_port_arg = !command_line::is_arg_defaulted(vm, restricted_rpc_port_arg); - rpcs.emplace_back(new t_rpc{vm, core, p2p, restricted, main_rpc_port, "core", !has_restricted_rpc_port_arg}); + rpcs.emplace_back(new t_rpc{vm, core, p2p, restricted, main_rpc_port, "core"}); if(has_restricted_rpc_port_arg) { auto restricted_rpc_port = command_line::get_arg(vm, restricted_rpc_port_arg); - rpcs.emplace_back(new t_rpc{vm, core, p2p, true, restricted_rpc_port, "restricted", true}); + rpcs.emplace_back(new t_rpc{vm, core, p2p, true, restricted_rpc_port, "restricted"}); } if (!command_line::get_arg(vm, daemon_args::arg_zmq_rpc_disabled)) diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h index 11eb5cfbf..3fafec2d7 100644 --- a/src/daemon/rpc.h +++ b/src/daemon/rpc.h @@ -59,13 +59,12 @@ public: , const bool restricted , const std::string & port , const std::string & description - , bool allow_rpc_payment ) : m_server{core.get(), p2p.get()}, m_description{description} { MGINFO("Initializing " << m_description << " RPC server..."); - if (!m_server.init(vm, restricted, port, allow_rpc_payment, command_line::get_arg(vm, daemon_args::arg_proxy))) + if (!m_server.init(vm, restricted, port, command_line::get_arg(vm, daemon_args::arg_proxy))) { throw std::runtime_error("Failed to initialize " + m_description + " RPC server."); } diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 63a11b9f4..1385a85ee 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -37,7 +37,6 @@ #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_basic/difficulty.h" #include "cryptonote_basic/hardfork.h" -#include "rpc/rpc_payment_signature.h" #include "rpc/rpc_version_str.h" #include #include @@ -2469,47 +2468,6 @@ bool t_rpc_command_executor::flush_cache(bool bad_blocks) return true; } -bool t_rpc_command_executor::rpc_payments() -{ - cryptonote::COMMAND_RPC_ACCESS_DATA::request req; - cryptonote::COMMAND_RPC_ACCESS_DATA::response res; - std::string fail_message = "Unsuccessful"; - epee::json_rpc::error error_resp; - - if (m_is_rpc) - { - if (!m_rpc_client->json_rpc_request(req, res, "rpc_access_data", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_rpc_access_data(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK) - { - tools::fail_msg_writer() << make_error(fail_message, res.status); - return true; - } - } - - const uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - uint64_t balance = 0; - tools::msg_writer() << boost::format("%64s %16u %16u %8u %8u %8u %8u %s") - % "Client ID" % "Balance" % "Total mined" % "Good" % "Stale" % "Bad" % "Dupes" % "Last update"; - for (const auto &entry: res.entries) - { - tools::msg_writer() << boost::format("%64s %16u %16u %8u %8u %8u %8u %s") - % entry.client % entry.balance % entry.credits_total - % entry.nonces_good % entry.nonces_stale % entry.nonces_bad % entry.nonces_dupe - % (entry.last_update_time == 0 ? "never" : get_human_time_ago(entry.last_update_time, now).c_str()); - balance += entry.balance; - } - tools::msg_writer() << res.entries.size() << " clients with a total of " << balance << " credits"; - tools::msg_writer() << "Aggregated client hash rate: " << get_mining_speed(res.hashrate); - - return true; -} - bool t_rpc_command_executor::version() { cryptonote::COMMAND_RPC_GET_INFO::request req; diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index cfde536ca..0469c9fff 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -170,8 +170,6 @@ public: const std::string &password, const std::string &proxy); - bool rpc_payments(); - bool flush_cache(bool invalid_blocks); }; diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index b7c21b9f4..a1d3d9f60 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -28,14 +28,12 @@ set(rpc_base_sources rpc_args.cpp - rpc_payment_signature.cpp rpc_handler.cpp) set(rpc_sources bootstrap_daemon.cpp bootstrap_node_selector.cpp core_rpc_server.cpp - rpc_payment.cpp rpc_version_str.cpp instanciations.cpp) @@ -54,7 +52,6 @@ set(daemon_rpc_server_sources set(rpc_base_headers rpc_args.h - rpc_payment_signature.h rpc_handler.h) set(rpc_headers @@ -68,7 +65,6 @@ set(daemon_rpc_server_headers) set(rpc_private_headers bootstrap_daemon.h core_rpc_server.h - rpc_payment.h core_rpc_server_commands_defs.h core_rpc_server_error_codes.h) diff --git a/src/rpc/bootstrap_daemon.cpp b/src/rpc/bootstrap_daemon.cpp index ffea906d5..b3aecb3bb 100644 --- a/src/rpc/bootstrap_daemon.cpp +++ b/src/rpc/bootstrap_daemon.cpp @@ -17,10 +17,8 @@ namespace cryptonote bootstrap_daemon::bootstrap_daemon( std::function()> get_public_nodes, - bool rpc_payment_enabled, const std::string &proxy) : m_selector(new bootstrap_node::selector_auto(std::move(get_public_nodes))) - , m_rpc_payment_enabled(rpc_payment_enabled) { set_proxy(proxy); } @@ -28,10 +26,8 @@ namespace cryptonote bootstrap_daemon::bootstrap_daemon( const std::string &address, boost::optional credentials, - bool rpc_payment_enabled, const std::string &proxy) : m_selector(nullptr) - , m_rpc_payment_enabled(rpc_payment_enabled) { set_proxy(proxy); if (!set_server(address, std::move(credentials))) @@ -70,7 +66,7 @@ namespace cryptonote bool bootstrap_daemon::handle_result(bool success, const std::string &status) { - const bool failed = !success || (!m_rpc_payment_enabled && status == CORE_RPC_STATUS_PAYMENT_REQUIRED); + const bool failed = !success || (status == CORE_RPC_STATUS_PAYMENT_REQUIRED); if (failed && m_selector) { const std::string current_address = address(); diff --git a/src/rpc/bootstrap_daemon.h b/src/rpc/bootstrap_daemon.h index 1e4477123..b49ccb00f 100644 --- a/src/rpc/bootstrap_daemon.h +++ b/src/rpc/bootstrap_daemon.h @@ -21,12 +21,10 @@ namespace cryptonote public: bootstrap_daemon( std::function()> get_public_nodes, - bool rpc_payment_enabled, const std::string &proxy); bootstrap_daemon( const std::string &address, boost::optional credentials, - bool rpc_payment_enabled, const std::string &proxy); std::string address() const noexcept; @@ -82,7 +80,6 @@ namespace cryptonote private: net::http::client m_http_client; - const bool m_rpc_payment_enabled; const std::unique_ptr m_selector; boost::mutex m_selector_mutex; }; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index d34624169..a6885a659 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -54,8 +54,6 @@ using namespace epee; #include "crypto/hash.h" #include "rpc/rpc_args.h" #include "rpc/rpc_handler.h" -#include "rpc/rpc_payment_costs.h" -#include "rpc/rpc_payment_signature.h" #include "core_rpc_server_error_codes.h" #include "p2p/net_node.h" #include "version.h" @@ -159,10 +157,6 @@ namespace cryptonote command_line::add_arg(desc, arg_bootstrap_daemon_login); command_line::add_arg(desc, arg_bootstrap_daemon_proxy); cryptonote::rpc_args::init_options(desc, true); - command_line::add_arg(desc, arg_rpc_payment_address); - command_line::add_arg(desc, arg_rpc_payment_difficulty); - command_line::add_arg(desc, arg_rpc_payment_credits); - command_line::add_arg(desc, arg_rpc_payment_allow_free_loopback); command_line::add_arg(desc, arg_rpc_max_connections_per_public_ip); command_line::add_arg(desc, arg_rpc_max_connections_per_private_ip); command_line::add_arg(desc, arg_rpc_max_connections); @@ -177,7 +171,6 @@ namespace cryptonote , m_p2p(p2p) , m_was_bootstrap_ever_used(false) , disable_rpc_ban(false) - , m_rpc_payment_allow_free_loopback(false) {} //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::set_bootstrap_daemon( @@ -194,7 +187,7 @@ namespace cryptonote return set_bootstrap_daemon(address, credentials, proxy); } //------------------------------------------------------------------------------------------------------------------------------ - std::map core_rpc_server::get_public_nodes(uint32_t credits_per_hash_threshold/* = 0*/) + std::map core_rpc_server::get_public_nodes(uint32_t/* = 0*/) { COMMAND_RPC_GET_PUBLIC_NODES::request request; COMMAND_RPC_GET_PUBLIC_NODES::response response; @@ -209,16 +202,10 @@ namespace cryptonote std::map result; - const auto append = [&result, &credits_per_hash_threshold](const std::vector &nodes, bool white) { + const auto append = [&result](const std::vector &nodes, bool white) { for (const auto &node : nodes) { - const bool rpc_payment_enabled = credits_per_hash_threshold > 0; - const bool node_rpc_payment_enabled = node.rpc_credits_per_hash > 0; - if (!node_rpc_payment_enabled || - (rpc_payment_enabled && node.rpc_credits_per_hash >= credits_per_hash_threshold)) - { - result.insert(std::make_pair(node.host + ":" + std::to_string(node.rpc_port), white)); - } + result.insert(std::make_pair(node.host + ":" + std::to_string(node.rpc_port), white)); } }; @@ -235,9 +222,6 @@ namespace cryptonote { boost::unique_lock lock(m_bootstrap_daemon_mutex); - constexpr const uint32_t credits_per_hash_threshold = 0; - constexpr const bool rpc_payment_enabled = credits_per_hash_threshold != 0; - if (address.empty()) { m_bootstrap_daemon.reset(nullptr); @@ -245,13 +229,13 @@ namespace cryptonote else if (address == "auto") { auto get_nodes = [this]() { - return get_public_nodes(credits_per_hash_threshold); + return get_public_nodes(0); }; - m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy)); + m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy)); } else { - m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy)); + m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy)); } m_should_use_bootstrap_daemon = m_bootstrap_daemon.get() != nullptr; @@ -260,15 +244,12 @@ namespace cryptonote } core_rpc_server::~core_rpc_server() { - if (m_rpc_payment) - m_rpc_payment->store(); } //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::init( const boost::program_options::variables_map& vm , const bool restricted , const std::string& port - , bool allow_rpc_payment , const std::string& proxy ) { @@ -295,45 +276,6 @@ namespace cryptonote } disable_rpc_ban = rpc_config->disable_rpc_ban; const std::string data_dir{command_line::get_arg(vm, cryptonote::arg_data_dir)}; - std::string address = command_line::get_arg(vm, arg_rpc_payment_address); - if (!address.empty() && allow_rpc_payment) - { - if (!m_restricted && nettype() != FAKECHAIN) - { - MFATAL("RPC payment enabled, but server is not restricted, anyone can adjust their balance to bypass payment"); - return false; - } - cryptonote::address_parse_info info; - if (!get_account_address_from_str(info, nettype(), address)) - { - MFATAL("Invalid payment address: " << address); - return false; - } - if (info.is_subaddress) - { - MFATAL("Payment address may not be a subaddress: " << address); - return false; - } - uint64_t diff = command_line::get_arg(vm, arg_rpc_payment_difficulty); - uint64_t credits = command_line::get_arg(vm, arg_rpc_payment_credits); - if (diff == 0 || credits == 0) - { - MFATAL("Payments difficulty and/or payments credits are 0, but a payment address was given"); - return false; - } - m_rpc_payment_allow_free_loopback = command_line::get_arg(vm, arg_rpc_payment_allow_free_loopback); - m_rpc_payment.reset(new rpc_payment(info.address, diff, credits)); - m_rpc_payment->load(data_dir); - m_p2p.set_rpc_credits_per_hash(RPC_CREDITS_PER_HASH_SCALE * (credits / (float)diff)); - } - - if (!m_rpc_payment) - { - uint32_t bind_ip; - bool ok = epee::string_tools::get_ip_int32_from_string(bind_ip, bind_ip_str); - if (ok & !epee::net_utils::is_ip_loopback(bind_ip)) - MWARNING("The RPC server is accessible from the outside, but no RPC payment was setup. RPC access will be free for all."); - } if (!set_bootstrap_daemon( command_line::get_arg(vm, arg_bootstrap_daemon_address), @@ -349,9 +291,6 @@ namespace cryptonote if (rpc_config->login) http_login.emplace(std::move(rpc_config->login->username), std::move(rpc_config->login->password).password()); - if (m_rpc_payment) - m_net_server.add_idle_handler([this](){ return m_rpc_payment->on_idle(); }, std::chrono::minutes{1}); - bool store_ssl_key = !restricted && rpc_config->ssl_options && rpc_config->ssl_options.auth.certificate_path.empty(); const auto ssl_base_path = (boost::filesystem::path{data_dir} / "rpc_ssl").string(); const bool ssl_cert_file_exists = boost::filesystem::exists(ssl_base_path + ".crt"); @@ -436,44 +375,6 @@ namespace cryptonote } return inited; } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::check_payment(const std::string &client_message, uint64_t payment, const std::string &rpc, bool same_ts, std::string &message, uint64_t &credits, std::string &top_hash) - { - if (m_rpc_payment == NULL) - { - credits = 0; - return true; - } - uint64_t height; - crypto::hash hash; - m_core.get_blockchain_top(height, hash); - top_hash = epee::string_tools::pod_to_hex(hash); - crypto::public_key client; - uint64_t ts; -#ifndef NDEBUG - if (nettype() == TESTNET && client_message == "debug") - { - credits = 0; - return true; - } -#endif - if (!cryptonote::verify_rpc_payment_signature(client_message, client, ts)) - { - credits = 0; - message = "Client signature does not verify for " + rpc; - return false; - } - if (!m_rpc_payment->pay(client, ts, payment, rpc, same_ts, credits)) - { - message = CORE_RPC_STATUS_PAYMENT_REQUIRED; - return false; - } - return true; - } -#define CHECK_PAYMENT_BASE(req, res, payment, same_ts) do { if (!ctx) break; uint64_t P = (uint64_t)payment; if (P > 0 && !check_payment(req.client, P, tracker.rpc_name(), same_ts, res.status, res.credits, res.top_hash)){return true;} tracker.pay(P); } while(0) -#define CHECK_PAYMENT(req, res, payment) CHECK_PAYMENT_BASE(req, res, payment, false) -#define CHECK_PAYMENT_SAME_TS(req, res, payment) CHECK_PAYMENT_BASE(req, res, payment, true) -#define CHECK_PAYMENT_MIN1(req, res, payment, same_ts) do { if (!ctx || (m_rpc_payment_allow_free_loopback && ctx->m_remote_address.is_loopback())) break; uint64_t P = (uint64_t)payment; if (P == 0) P = 1; if(!check_payment(req.client, P, tracker.rpc_name(), same_ts, res.status, res.credits, res.top_hash)){return true;} tracker.pay(P); } while(0) //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::check_core_ready() { @@ -539,8 +440,6 @@ namespace cryptonote return r; } - CHECK_PAYMENT_MIN1(req, res, COST_PER_GET_INFO, false); - const bool restricted = m_restricted && ctx; crypto::hash top_hash; @@ -644,8 +543,6 @@ namespace cryptonote return use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/getblocks.bin", req, res, r); } - CHECK_PAYMENT(req, res, 1); - res.daemon_time = (uint64_t)time(NULL); // Always set daemon time, and set it early rather than late, as delivering some incremental pool // info twice because of slightly overlapping time intervals is no problem, whereas producing gaps @@ -698,16 +595,6 @@ namespace cryptonote ? std::min(req.max_block_count, (uint64_t)COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT) : COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT; - if (m_rpc_payment) - { - max_blocks = std::min((size_t)(res.credits / COST_PER_BLOCK), max_blocks); - if (max_blocks == 0) - { - res.status = CORE_RPC_STATUS_PAYMENT_REQUIRED; - return true; - } - } - std::vector, std::vector > > > bs; if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.top_block_hash, res.start_height, req.prune, !req.no_miner_tx, req.block_ids_exclusive, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) { @@ -716,8 +603,6 @@ namespace cryptonote return true; } - CHECK_PAYMENT_SAME_TS(req, res, bs.size() * COST_PER_BLOCK); - size_t ntxes = 0; res.blocks.reserve(bs.size()); res.output_indices.reserve(bs.size()); @@ -797,12 +682,6 @@ namespace cryptonote } res.added_pool_txs.clear(); - if (m_rpc_payment) - { - CHECK_PAYMENT_SAME_TS(req, res, - added_pool_txs.size() * COST_PER_TX + - (res.remaining_added_pool_txids.size() + res.removed_pool_txids.size()) * COST_PER_POOL_HASH); - } for (const auto &added_pool_tx: added_pool_txs) { COMMAND_RPC_GET_BLOCKS_FAST::pool_tx_info info; @@ -875,7 +754,6 @@ namespace cryptonote res.status = "Failed"; res.blocks.clear(); res.blocks.reserve(req.heights.size()); - CHECK_PAYMENT_MIN1(req, res, req.heights.size() * COST_PER_BLOCK, false); for (uint64_t height : req.heights) { block blk; @@ -907,8 +785,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/gethashes.bin", req, res, r)) return r; - CHECK_PAYMENT(req, res, 1); - res.start_height = req.start_height; if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, res.m_block_ids, NULL, res.start_height, res.current_height, false)) { @@ -917,8 +793,6 @@ namespace cryptonote return true; } - CHECK_PAYMENT_SAME_TS(req, res, res.m_block_ids.size() * COST_PER_BLOCK_HASH); - res.status = CORE_RPC_STATUS_OK; return true; } @@ -930,8 +804,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/get_outs.bin", req, res, r)) return r; - CHECK_PAYMENT_MIN1(req, res, req.outputs.size() * COST_PER_OUT, false); - res.status = "Failed"; const bool restricted = m_restricted && ctx; @@ -960,8 +832,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_outs", req, res, r)) return r; - CHECK_PAYMENT_MIN1(req, res, req.outputs.size() * COST_PER_OUT, false); - res.status = "Failed"; const bool restricted = m_restricted && ctx; @@ -1007,8 +877,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/get_o_indexes.bin", req, res, ok)) return ok; - CHECK_PAYMENT_MIN1(req, res, COST_PER_OUTPUT_INDEXES, false); - bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes); if(!r) { @@ -1036,8 +904,6 @@ namespace cryptonote return true; } - CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false); - std::vector vh; for(const auto& tx_hex_str: req.txs_hashes) { @@ -1284,8 +1150,6 @@ namespace cryptonote return true; } - CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false); - // parse key images from request std::vector key_images; for(const auto& ki_hex_str: req.key_images) @@ -1387,8 +1251,6 @@ namespace cryptonote CHECK_CORE_READY(); } - CHECK_PAYMENT_MIN1(req, res, COST_PER_TX_RELAY, false); - std::string tx_blob; if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob)) { @@ -1721,8 +1583,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool", req, res, r)) return r; - CHECK_PAYMENT(req, res, 1); - const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; const bool allow_sensitive = !request_has_rpc_origin || !restricted; @@ -1730,7 +1590,6 @@ namespace cryptonote size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { - CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_TX); m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, allow_sensitive); for (tx_info& txi : res.transactions) txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob); @@ -1747,8 +1606,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_hashes.bin", req, res, r)) return r; - CHECK_PAYMENT(req, res, 1); - const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; const bool allow_sensitive = !request_has_rpc_origin || !restricted; @@ -1756,7 +1613,6 @@ namespace cryptonote size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { - CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_POOL_HASH); m_core.get_pool_transaction_hashes(res.tx_hashes, allow_sensitive); } @@ -1771,8 +1627,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_hashes", req, res, r)) return r; - CHECK_PAYMENT(req, res, 1); - const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; const bool allow_sensitive = !request_has_rpc_origin || !restricted; @@ -1780,7 +1634,6 @@ namespace cryptonote size_t n_txes = m_core.get_pool_transactions_count(allow_sensitive); if (n_txes > 0) { - CHECK_PAYMENT_SAME_TS(req, res, n_txes * COST_PER_POOL_HASH); std::vector tx_hashes; m_core.get_pool_transaction_hashes(tx_hashes, allow_sensitive); res.tx_hashes.reserve(tx_hashes.size()); @@ -1799,8 +1652,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_stats", req, res, r)) return r; - CHECK_PAYMENT_MIN1(req, res, COST_PER_TX_POOL_STATS, false); - const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; m_core.get_pool_transaction_stats(res.pool_stats, !request_has_rpc_origin || !restricted); @@ -2561,7 +2412,6 @@ namespace cryptonote return r; CHECK_CORE_READY(); - CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false); uint64_t last_block_height; crypto::hash last_block_hash; m_core.get_blockchain_top(last_block_height, last_block_hash); @@ -2592,8 +2442,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblockheaderbyhash", req, res, r)) return r; - CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false); - const bool restricted = m_restricted && ctx; if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT) { @@ -2676,7 +2524,6 @@ namespace cryptonote return false; } - CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false); for (uint64_t h = req.start_height; h <= req.end_height; ++h) { crypto::hash block_hash = m_core.get_block_id_by_height(h); @@ -2727,7 +2574,6 @@ namespace cryptonote error_resp.message = std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(m_core.get_current_blockchain_height() - 1); return false; } - CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false); crypto::hash block_hash = m_core.get_block_id_by_height(req.height); block blk; bool have_block = m_core.get_block_by_hash(block_hash, blk); @@ -2756,8 +2602,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblock", req, res, r)) return r; - CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK, false); - crypto::hash block_hash; if (!req.hash.empty()) { @@ -2843,7 +2687,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "hard_fork_info", req, res, r)) return r; - CHECK_PAYMENT(req, res, COST_PER_HARD_FORK_INFO); const Blockchain &blockchain = m_core.get_blockchain_storage(); uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version(); res.version = blockchain.get_current_hard_fork_version(); @@ -3040,9 +2883,6 @@ namespace cryptonote return true; } - uint64_t cost = req.amounts.empty() ? COST_PER_FULL_OUTPUT_HISTOGRAM : (COST_PER_OUTPUT_HISTOGRAM * amounts); - CHECK_PAYMENT_MIN1(req, res, cost, false); - if (restricted && req.recent_cutoff > 0 && req.recent_cutoff < (uint64_t)time(NULL) - OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION) { res.status = "Recent cutoff is too old"; @@ -3098,7 +2938,6 @@ namespace cryptonote res.status = "requested range exceeds blockchain height"; return true; } - CHECK_PAYMENT_MIN1(req, res, COST_PER_COINBASE_TX_SUM_BLOCK * req.count, false); std::pair amounts = m_core.get_coinbase_tx_sum(req.height, req.count); store_128(amounts.first, res.emission_amount, res.wide_emission_amount, res.emission_amount_top64); store_128(amounts.second, res.fee_amount, res.wide_fee_amount, res.fee_amount_top64); @@ -3113,8 +2952,6 @@ namespace cryptonote if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_fee_estimate", req, res, r)) return r; - CHECK_PAYMENT(req, res, COST_PER_FEE_ESTIMATE); - { m_core.get_blockchain_storage().get_dynamic_base_fee_estimate_2021_scaling(req.grace_blocks, res.fees); res.fee = res.fees[0]; @@ -3348,7 +3185,6 @@ namespace cryptonote bool core_rpc_server::on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { RPC_TRACKER(relay_tx); - CHECK_PAYMENT_MIN1(req, res, req.txids.size() * COST_PER_TX_RELAY, false); const bool restricted = m_restricted && ctx; @@ -3400,7 +3236,6 @@ namespace cryptonote bool core_rpc_server::on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { RPC_TRACKER(sync_info); - CHECK_PAYMENT(req, res, COST_PER_SYNC_INFO); crypto::hash top_hash; m_core.get_blockchain_top(res.height, top_hash); @@ -3429,8 +3264,6 @@ namespace cryptonote bool r; if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_txpool_backlog", req, res, r)) return r; - size_t n_txes = m_core.get_pool_transactions_count(); - CHECK_PAYMENT_MIN1(req, res, COST_PER_TX_POOL_STATS * n_txes, false); if (!m_core.get_txpool_backlog(res.backlog)) { @@ -3458,11 +3291,6 @@ namespace cryptonote return false; } - size_t n_0 = 0, n_non0 = 0; - for (uint64_t amount: req.amounts) - if (amount) ++n_non0; else ++n_0; - CHECK_PAYMENT_MIN1(req, res, n_0 * COST_PER_OUTPUT_DISTRIBUTION_0 + n_non0 * COST_PER_OUTPUT_DISTRIBUTION, false); - try { // 0 is placeholder for the whole chain @@ -3506,11 +3334,6 @@ namespace cryptonote return false; } - size_t n_0 = 0, n_non0 = 0; - for (uint64_t amount: req.amounts) - if (amount) ++n_non0; else ++n_0; - CHECK_PAYMENT_MIN1(req, res, n_0 * COST_PER_OUTPUT_DISTRIBUTION_0 + n_non0 * COST_PER_OUTPUT_DISTRIBUTION, false); - res.status = "Failed"; if (!req.binary) @@ -3569,70 +3392,6 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_info(const COMMAND_RPC_ACCESS_INFO::request& req, COMMAND_RPC_ACCESS_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_info); - - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "rpc_access_info", req, res, r)) - return r; - - // if RPC payment is not enabled - if (m_rpc_payment == NULL) - { - res.diff = 0; - res.credits_per_hash_found = 0; - res.credits = 0; - res.height = 0; - res.seed_height = 0; - res.status = CORE_RPC_STATUS_OK; - return true; - } - - crypto::public_key client; - uint64_t ts; - if (!cryptonote::verify_rpc_payment_signature(req.client, client, ts)) - { - error_resp.code = CORE_RPC_ERROR_CODE_INVALID_CLIENT; - error_resp.message = "Invalid client ID"; - return false; - } - - crypto::hash top_hash; - m_core.get_blockchain_top(res.height, top_hash); - ++res.height; - cryptonote::blobdata hashing_blob; - crypto::hash seed_hash, next_seed_hash; - if (!m_rpc_payment->get_info(client, [&](const cryptonote::blobdata &extra_nonce, cryptonote::block &b, uint64_t &seed_height, crypto::hash &seed_hash)->bool{ - cryptonote::difficulty_type difficulty; - uint64_t height, expected_reward, cumulative_weight; - size_t reserved_offset; - if (!get_block_template(m_rpc_payment->get_payment_address(), NULL, extra_nonce, reserved_offset, difficulty, height, expected_reward, cumulative_weight, b, seed_height, seed_hash, next_seed_hash, error_resp)) - return false; - return true; - }, hashing_blob, res.seed_height, seed_hash, top_hash, res.diff, res.credits_per_hash_found, res.credits, res.cookie)) - { - return false; - } - if (hashing_blob.empty()) - { - error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB; - error_resp.message = "Invalid hashing blob"; - return false; - } - res.hashing_blob = epee::string_tools::buff_to_hex_nodelimer(hashing_blob); - res.top_hash = epee::string_tools::pod_to_hex(top_hash); - if (hashing_blob[0] >= RX_BLOCK_VERSION) - { - res.seed_hash = string_tools::pod_to_hex(seed_hash); - if (seed_hash != next_seed_hash) - res.next_seed_hash = string_tools::pod_to_hex(next_seed_hash); - } - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_flush_cache(const COMMAND_RPC_FLUSH_CACHE::request& req, COMMAND_RPC_FLUSH_CACHE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) { RPC_TRACKER(flush_cache); @@ -3718,181 +3477,6 @@ namespace cryptonote #endif } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_submit_nonce(const COMMAND_RPC_ACCESS_SUBMIT_NONCE::request& req, COMMAND_RPC_ACCESS_SUBMIT_NONCE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_submit_nonce); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "rpc_access_submit_nonce", req, res, r)) - return r; - - // if RPC payment is not enabled - if (m_rpc_payment == NULL) - { - res.status = "Payment not necessary"; - return true; - } - - crypto::public_key client; - uint64_t ts; - if (!cryptonote::verify_rpc_payment_signature(req.client, client, ts)) - { - res.credits = 0; - error_resp.code = CORE_RPC_ERROR_CODE_INVALID_CLIENT; - error_resp.message = "Invalid client ID"; - return false; - } - - crypto::hash hash; - cryptonote::block block; - crypto::hash top_hash; - uint64_t height; - bool stale; - m_core.get_blockchain_top(height, top_hash); - if (!m_rpc_payment->submit_nonce(client, req.nonce, top_hash, error_resp.code, error_resp.message, res.credits, hash, block, req.cookie, stale)) - { - return false; - } - - if (!stale) - { - // it might be a valid block! - const difficulty_type current_difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block(); - if (check_hash(hash, current_difficulty)) - { - MINFO("This payment meets the current network difficulty"); - block_verification_context bvc; - if(m_core.handle_block_found(block, bvc)) - MGINFO_GREEN("Block found by RPC user at height " << get_block_height(block) << ": " << - print_money(cryptonote::get_outs_money_amount(block.miner_tx))); - else - MERROR("Seemingly valid block was not accepted"); - } - } - - m_core.get_blockchain_top(height, top_hash); - res.top_hash = epee::string_tools::pod_to_hex(top_hash); - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_pay(const COMMAND_RPC_ACCESS_PAY::request& req, COMMAND_RPC_ACCESS_PAY::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_pay); - - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "rpc_access_pay", req, res, r)) - return r; - - // if RPC payment is not enabled - if (m_rpc_payment == NULL) - { - res.status = "Payment not necessary"; - return true; - } - - crypto::public_key client; - uint64_t ts; - if (!cryptonote::verify_rpc_payment_signature(req.client, client, ts)) - { - res.credits = 0; - error_resp.code = CORE_RPC_ERROR_CODE_INVALID_CLIENT; - error_resp.message = "Invalid client ID"; - return false; - } - - RPCTracker ext_tracker(("external:" + req.paying_for).c_str(), PERF_TIMER_NAME(rpc_access_pay)); - if (!check_payment(req.client, req.payment, req.paying_for, false, res.status, res.credits, res.top_hash)) - return true; - ext_tracker.pay(req.payment); - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_tracking(const COMMAND_RPC_ACCESS_TRACKING::request& req, COMMAND_RPC_ACCESS_TRACKING::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_tracking); - - if (req.clear) - { - RPCTracker::clear(); - res.status = CORE_RPC_STATUS_OK; - return true; - } - - auto data = RPCTracker::data(); - for (const auto &d: data) - { - res.data.resize(res.data.size() + 1); - res.data.back().rpc = d.first; - res.data.back().count = d.second.count; - res.data.back().time = d.second.time; - res.data.back().credits = d.second.credits; - } - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_data(const COMMAND_RPC_ACCESS_DATA::request& req, COMMAND_RPC_ACCESS_DATA::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_data); - - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "rpc_access_data", req, res, r)) - return r; - - if (!m_rpc_payment) - { - error_resp.code = CORE_RPC_ERROR_CODE_PAYMENTS_NOT_ENABLED; - error_resp.message = "Payments not enabled"; - return false; - } - - m_rpc_payment->foreach([&](const crypto::public_key &client, const rpc_payment::client_info &info){ - res.entries.push_back({ - epee::string_tools::pod_to_hex(client), info.credits, std::max(info.last_request_timestamp / 1000000, info.update_time), - info.credits_total, info.credits_used, info.nonces_good, info.nonces_stale, info.nonces_bad, info.nonces_dupe - }); - return true; - }); - - res.hashrate = m_rpc_payment->get_hashes(600) / 600; - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_rpc_access_account(const COMMAND_RPC_ACCESS_ACCOUNT::request& req, COMMAND_RPC_ACCESS_ACCOUNT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) - { - RPC_TRACKER(rpc_access_account); - - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "rpc_access_account", req, res, r)) - return r; - - if (!m_rpc_payment) - { - error_resp.code = CORE_RPC_ERROR_CODE_PAYMENTS_NOT_ENABLED; - error_resp.message = "Payments not enabled"; - return false; - } - - crypto::public_key client; - if (!epee::string_tools::hex_to_pod(req.client.substr(0, 2 * sizeof(client)), client)) - { - error_resp.code = CORE_RPC_ERROR_CODE_INVALID_CLIENT; - error_resp.message = "Invalid client ID"; - return false; - } - - res.credits = m_rpc_payment->balance(client, req.delta_balance); - - res.status = CORE_RPC_STATUS_OK; - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ const command_line::arg_descriptor core_rpc_server::arg_rpc_bind_port = { "rpc-bind-port" , "Port for RPC server" @@ -3938,30 +3522,6 @@ namespace cryptonote , "" }; - const command_line::arg_descriptor core_rpc_server::arg_rpc_payment_address = { - "rpc-payment-address" - , "Restrict RPC to clients sending micropayment to this address" - , "" - }; - - const command_line::arg_descriptor core_rpc_server::arg_rpc_payment_difficulty = { - "rpc-payment-difficulty" - , "Restrict RPC to clients sending micropayment at this difficulty" - , DEFAULT_PAYMENT_DIFFICULTY - }; - - const command_line::arg_descriptor core_rpc_server::arg_rpc_payment_credits = { - "rpc-payment-credits" - , "Restrict RPC to clients sending micropayment, yields that many credits per payment" - , DEFAULT_PAYMENT_CREDITS_PER_HASH - }; - - const command_line::arg_descriptor core_rpc_server::arg_rpc_payment_allow_free_loopback = { - "rpc-payment-allow-free-loopback" - , "Allow free access from the loopback address (ie, the local host)" - , false - }; - const command_line::arg_descriptor core_rpc_server::arg_rpc_max_connections_per_public_ip = { "rpc-max-connections-per-public-ip" , "Max RPC connections per public IP permitted" diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index dac9b476f..f263101c8 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -42,7 +42,6 @@ #include "cryptonote_core/cryptonote_core.h" #include "p2p/net_node.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" -#include "rpc_payment.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc" @@ -68,10 +67,6 @@ namespace cryptonote static const command_line::arg_descriptor arg_bootstrap_daemon_address; static const command_line::arg_descriptor arg_bootstrap_daemon_login; static const command_line::arg_descriptor arg_bootstrap_daemon_proxy; - static const command_line::arg_descriptor arg_rpc_payment_address; - static const command_line::arg_descriptor arg_rpc_payment_difficulty; - static const command_line::arg_descriptor arg_rpc_payment_credits; - static const command_line::arg_descriptor arg_rpc_payment_allow_free_loopback; static const command_line::arg_descriptor arg_rpc_max_connections_per_public_ip; static const command_line::arg_descriptor arg_rpc_max_connections_per_private_ip; static const command_line::arg_descriptor arg_rpc_max_connections; @@ -90,7 +85,6 @@ namespace cryptonote const boost::program_options::variables_map& vm, const bool restricted, const std::string& port, - bool allow_rpc_payment, const std::string& proxy = {} ); network_type nettype() const { return m_core.get_nettype(); } @@ -182,12 +176,6 @@ namespace cryptonote MAP_JON_RPC_WE_IF("prune_blockchain", on_prune_blockchain, COMMAND_RPC_PRUNE_BLOCKCHAIN, !m_restricted) MAP_JON_RPC_WE_IF("flush_cache", on_flush_cache, COMMAND_RPC_FLUSH_CACHE, !m_restricted) MAP_JON_RPC_WE("get_txids_loose", on_get_txids_loose, COMMAND_RPC_GET_TXIDS_LOOSE) - MAP_JON_RPC_WE("rpc_access_info", on_rpc_access_info, COMMAND_RPC_ACCESS_INFO) - MAP_JON_RPC_WE("rpc_access_submit_nonce",on_rpc_access_submit_nonce, COMMAND_RPC_ACCESS_SUBMIT_NONCE) - MAP_JON_RPC_WE("rpc_access_pay", on_rpc_access_pay, COMMAND_RPC_ACCESS_PAY) - MAP_JON_RPC_WE_IF("rpc_access_tracking", on_rpc_access_tracking, COMMAND_RPC_ACCESS_TRACKING, !m_restricted) - MAP_JON_RPC_WE_IF("rpc_access_data", on_rpc_access_data, COMMAND_RPC_ACCESS_DATA, !m_restricted) - MAP_JON_RPC_WE_IF("rpc_access_account", on_rpc_access_account, COMMAND_RPC_ACCESS_ACCOUNT, !m_restricted) END_JSON_RPC_MAP() END_URI_MAP2() @@ -260,12 +248,6 @@ namespace cryptonote bool on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); bool on_flush_cache(const COMMAND_RPC_FLUSH_CACHE::request& req, COMMAND_RPC_FLUSH_CACHE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); bool on_get_txids_loose(const COMMAND_RPC_GET_TXIDS_LOOSE::request& req, COMMAND_RPC_GET_TXIDS_LOOSE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_info(const COMMAND_RPC_ACCESS_INFO::request& req, COMMAND_RPC_ACCESS_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_submit_nonce(const COMMAND_RPC_ACCESS_SUBMIT_NONCE::request& req, COMMAND_RPC_ACCESS_SUBMIT_NONCE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_pay(const COMMAND_RPC_ACCESS_PAY::request& req, COMMAND_RPC_ACCESS_PAY::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_tracking(const COMMAND_RPC_ACCESS_TRACKING::request& req, COMMAND_RPC_ACCESS_TRACKING::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_data(const COMMAND_RPC_ACCESS_DATA::request& req, COMMAND_RPC_ACCESS_DATA::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); - bool on_rpc_access_account(const COMMAND_RPC_ACCESS_ACCOUNT::request& req, COMMAND_RPC_ACCESS_ACCOUNT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL); //----------------------- private: @@ -289,7 +271,6 @@ private: template bool use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r); bool get_block_template(const account_public_address &address, const crypto::hash *prev_block, const cryptonote::blobdata &extra_nonce, size_t &reserved_offset, cryptonote::difficulty_type &difficulty, uint64_t &height, uint64_t &expected_reward, uint64_t& cumulative_weight, block &b, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, epee::json_rpc::error &error_resp); - bool check_payment(const std::string &client, uint64_t payment, const std::string &rpc, bool same_ts, std::string &message, uint64_t &credits, std::string &top_hash); core& m_core; nodetool::node_server >& m_p2p; @@ -302,9 +283,7 @@ private: bool m_restricted; epee::critical_section m_host_fails_score_lock; std::map m_host_fails_score; - std::unique_ptr m_rpc_payment; bool disable_rpc_ban; - bool m_rpc_payment_allow_free_loopback; }; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index e5524706a..7815964f6 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -2493,206 +2493,6 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st typedef epee::misc_utils::struct_init response; }; - struct COMMAND_RPC_ACCESS_INFO - { - struct request_t: public rpc_access_request_base - { - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_request_base) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t: public rpc_access_response_base - { - std::string hashing_blob; - uint64_t seed_height; - std::string seed_hash; - std::string next_seed_hash; - uint32_t cookie; - uint64_t diff; - uint64_t credits_per_hash_found; - uint64_t height; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_response_base) - KV_SERIALIZE(hashing_blob) - KV_SERIALIZE(seed_height) - KV_SERIALIZE(seed_hash) - KV_SERIALIZE(next_seed_hash) - KV_SERIALIZE(cookie) - KV_SERIALIZE(diff) - KV_SERIALIZE(credits_per_hash_found) - KV_SERIALIZE(height) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_ACCESS_SUBMIT_NONCE - { - struct request_t: public rpc_access_request_base - { - uint32_t nonce; - uint32_t cookie; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_request_base) - KV_SERIALIZE(nonce) - KV_SERIALIZE(cookie) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t: public rpc_access_response_base - { - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_response_base) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_ACCESS_PAY - { - struct request_t: public rpc_access_request_base - { - std::string paying_for; - uint64_t payment; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_request_base) - KV_SERIALIZE(paying_for) - KV_SERIALIZE(payment) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t: public rpc_access_response_base - { - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_access_response_base) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_ACCESS_TRACKING - { - struct request_t: public rpc_request_base - { - bool clear; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_request_base) - KV_SERIALIZE(clear) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct entry - { - std::string rpc; - uint64_t count; - uint64_t time; - uint64_t credits; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(rpc) - KV_SERIALIZE(count) - KV_SERIALIZE(time) - KV_SERIALIZE(credits) - END_KV_SERIALIZE_MAP() - }; - - struct response_t: public rpc_response_base - { - std::vector data; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_response_base) - KV_SERIALIZE(data) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_ACCESS_DATA - { - struct request_t: public rpc_request_base - { - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_request_base) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct entry - { - std::string client; - uint64_t balance; - uint64_t last_update_time; - uint64_t credits_total; - uint64_t credits_used; - uint64_t nonces_good; - uint64_t nonces_stale; - uint64_t nonces_bad; - uint64_t nonces_dupe; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(client) - KV_SERIALIZE(balance) - KV_SERIALIZE(last_update_time) - KV_SERIALIZE(credits_total) - KV_SERIALIZE(credits_used) - KV_SERIALIZE(nonces_good) - KV_SERIALIZE(nonces_stale) - KV_SERIALIZE(nonces_bad) - KV_SERIALIZE(nonces_dupe) - END_KV_SERIALIZE_MAP() - }; - - struct response_t: public rpc_response_base - { - std::list entries; - uint32_t hashrate; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_response_base) - KV_SERIALIZE(entries) - KV_SERIALIZE(hashrate) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_ACCESS_ACCOUNT - { - struct request_t: public rpc_request_base - { - std::string client; - int64_t delta_balance; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_request_base) - KV_SERIALIZE(client) - KV_SERIALIZE_OPT(delta_balance, (int64_t)0) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t: public rpc_response_base - { - uint64_t credits; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_PARENT(rpc_response_base) - KV_SERIALIZE(credits) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_POP_BLOCKS { struct request_t: public rpc_request_base diff --git a/src/rpc/rpc_payment.cpp b/src/rpc/rpc_payment.cpp deleted file mode 100644 index 36fb92abf..000000000 --- a/src/rpc/rpc_payment.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) 2018-2024, 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. - -#include -#include -#include "cryptonote_config.h" -#include "include_base_utils.h" -#include "string_tools.h" -#include "file_io_utils.h" -#include "int-util.h" -#include "common/util.h" -#include "common/unordered_containers_boost_serialization.h" -#include "cryptonote_basic/cryptonote_boost_serialization.h" -#include "cryptonote_basic/cryptonote_format_utils.h" -#include "cryptonote_basic/difficulty.h" -#include "core_rpc_server_error_codes.h" -#include "rpc_payment.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc.payment" - -#define STALE_THRESHOLD 15 /* seconds */ - -#define PENALTY_FOR_STALE 0 -#define PENALTY_FOR_BAD_HASH 20 -#define PENALTY_FOR_DUPLICATE 20 - -#define DEFAULT_FLUSH_AGE (3600 * 24 * 180) // half a year -#define DEFAULT_ZERO_FLUSH_AGE (60 * 2) // 2 minutes - -namespace cryptonote -{ - rpc_payment::client_info::client_info(): - previous_seed_height(0), - seed_height(0), - previous_seed_hash(crypto::null_hash), - seed_hash(crypto::null_hash), - cookie(0), - top(crypto::null_hash), - previous_top(crypto::null_hash), - credits(0), - update_time(time(NULL)), - last_request_timestamp(0), - block_template_update_time(0), - credits_total(0), - credits_used(0), - nonces_good(0), - nonces_stale(0), - nonces_bad(0), - nonces_dupe(0) - { - } - - rpc_payment::rpc_payment(const cryptonote::account_public_address &address, uint64_t diff, uint64_t credits_per_hash_found): - m_address(address), - m_diff(diff), - m_credits_per_hash_found(credits_per_hash_found), - m_credits_total(0), - m_credits_used(0), - m_nonces_good(0), - m_nonces_stale(0), - m_nonces_bad(0), - m_nonces_dupe(0) - { - } - - uint64_t rpc_payment::balance(const crypto::public_key &client, int64_t delta) - { - boost::lock_guard lock(mutex); - client_info &info = m_client_info[client]; // creates if not found - uint64_t credits = info.credits; - if (delta > 0 && credits > std::numeric_limits::max() - delta) - credits = std::numeric_limits::max(); - else if (delta < 0 && credits < (uint64_t)-delta) - credits = 0; - else - credits += delta; - if (delta) - MINFO("Client " << client << ": balance change from " << info.credits << " to " << credits); - return info.credits = credits; - } - - bool rpc_payment::pay(const crypto::public_key &client, uint64_t ts, uint64_t payment, const std::string &rpc, bool same_ts, uint64_t &credits) - { - boost::lock_guard lock(mutex); - client_info &info = m_client_info[client]; // creates if not found - if (ts < info.last_request_timestamp || (ts == info.last_request_timestamp && !same_ts)) - { - MDEBUG("Invalid ts: " << ts << " <= " << info.last_request_timestamp); - return false; - } - info.last_request_timestamp = ts; - if (info.credits < payment) - { - MDEBUG("Not enough credits: " << info.credits << " < " << payment); - credits = info.credits; - return false; - } - info.credits -= payment; - add64clamp(&info.credits_used, payment); - add64clamp(&m_credits_used, payment); - MDEBUG("client " << client << " paying " << payment << " for " << rpc << ", " << info.credits << " left"); - credits = info.credits; - return true; - } - - bool rpc_payment::get_info(const crypto::public_key &client, const std::function &get_block_template, cryptonote::blobdata &hashing_blob, uint64_t &seed_height, crypto::hash &seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie) - { - boost::lock_guard lock(mutex); - client_info &info = m_client_info[client]; // creates if not found - const uint64_t now = time(NULL); - bool need_template = top != info.top || now >= info.block_template_update_time + STALE_THRESHOLD; - if (need_template) - { - cryptonote::block new_block; - uint64_t new_seed_height; - crypto::hash new_seed_hash; - cryptonote::blobdata extra_nonce("\x42\x42\x42\x42", 4); - if (!get_block_template(extra_nonce, new_block, new_seed_height, new_seed_hash)) - return false; - if(!remove_field_from_tx_extra(new_block.miner_tx.extra, typeid(cryptonote::tx_extra_nonce))) - return false; - char data[33]; - memcpy(data, &client, 32); - data[32] = config::HASH_KEY_RPC_PAYMENT_NONCE; - crypto::hash hash; - cn_fast_hash(data, sizeof(data), hash); - extra_nonce = cryptonote::blobdata((const char*)&hash, 4); - if(!add_extra_nonce_to_tx_extra(new_block.miner_tx.extra, extra_nonce)) - return false; - info.previous_block = info.block; - info.block = std::move(new_block); - hashing_blob = get_block_hashing_blob(info.block); - info.previous_hashing_blob = info.hashing_blob; - info.hashing_blob = hashing_blob; - info.previous_top = info.top; - info.previous_seed_height = info.seed_height; - info.seed_height = new_seed_height; - info.previous_seed_hash = info.seed_hash; - info.seed_hash = new_seed_hash; - std::swap(info.previous_payments, info.payments); - info.payments.clear(); - ++info.cookie; - info.block_template_update_time = now; - } - info.top = top; - info.update_time = now; - hashing_blob = info.hashing_blob; - diff = m_diff; - credits_per_hash_found = m_credits_per_hash_found; - credits = info.credits; - seed_height = info.seed_height; - seed_hash = info.seed_hash; - cookie = info.cookie; - return true; - } - - bool rpc_payment::submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale) - { - boost::lock_guard lock(mutex); - client_info &info = m_client_info[client]; // creates if not found - if (cookie != info.cookie && cookie != info.cookie - 1) - { - MWARNING("Very stale nonce"); - ++m_nonces_stale; - ++info.nonces_stale; - sub64clamp(&info.credits, PENALTY_FOR_STALE * m_credits_per_hash_found); - error_code = CORE_RPC_ERROR_CODE_STALE_PAYMENT; - error_message = "Very stale payment"; - return false; - } - const bool is_current = cookie == info.cookie; - MINFO("client " << client << " sends nonce: " << nonce << ", " << (is_current ? "current" : "stale")); - std::unordered_set &payments = is_current ? info.payments : info.previous_payments; - if (!payments.insert(nonce).second) - { - MWARNING("Duplicate nonce " << nonce << " from " << (is_current ? "current" : "previous")); - ++m_nonces_dupe; - ++info.nonces_dupe; - sub64clamp(&info.credits, PENALTY_FOR_DUPLICATE * m_credits_per_hash_found); - error_code = CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT; - error_message = "Duplicate payment"; - return false; - } - - const uint64_t now = time(NULL); - if (!is_current) - { - if (now > info.update_time + STALE_THRESHOLD) - { - MWARNING("Nonce is stale (top " << top << ", should be " << info.top << " or within " << STALE_THRESHOLD << " seconds"); - ++m_nonces_stale; - ++info.nonces_stale; - sub64clamp(&info.credits, PENALTY_FOR_STALE * m_credits_per_hash_found); - error_code = CORE_RPC_ERROR_CODE_STALE_PAYMENT; - error_message = "stale payment"; - return false; - } - } - - cryptonote::blobdata hashing_blob = is_current ? info.hashing_blob : info.previous_hashing_blob; - if (hashing_blob.size() < 43) - { - // not initialized ? - error_code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB; - error_message = "not initialized"; - return false; - } - - block = is_current ? info.block : info.previous_block; - *(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(nonce); - if (block.major_version >= RX_BLOCK_VERSION) - { - const crypto::hash &seed_hash = is_current ? info.seed_hash : info.previous_seed_hash; - crypto::rx_slow_hash(seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash.data); - } - else - { - const int cn_variant = hashing_blob[0] >= 7 ? hashing_blob[0] - 6 : 0; - crypto::cn_slow_hash(hashing_blob.data(), hashing_blob.size(), hash, cn_variant, cryptonote::get_block_height(block)); - } - if (!check_hash(hash, m_diff)) - { - MWARNING("Payment too low"); - ++m_nonces_bad; - ++info.nonces_bad; - error_code = CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW; - error_message = "Hash does not meet difficulty (could be wrong PoW hash, or mining at lower difficulty than required, or attempt to defraud)"; - sub64clamp(&info.credits, PENALTY_FOR_BAD_HASH * m_credits_per_hash_found); - return false; - } - - add64clamp(&info.credits, m_credits_per_hash_found); - MINFO("client " << client << " credited for " << m_credits_per_hash_found << ", now " << info.credits << (is_current ? "" : " (close)")); - - m_hashrate[now] += m_diff; - add64clamp(&m_credits_total, m_credits_per_hash_found); - add64clamp(&info.credits_total, m_credits_per_hash_found); - ++m_nonces_good; - ++info.nonces_good; - - credits = info.credits; - block = info.block; - block.nonce = nonce; - stale = !is_current; - return true; - } - - bool rpc_payment::foreach(const std::function &f) const - { - boost::lock_guard lock(mutex); - for (std::unordered_map::const_iterator i = m_client_info.begin(); i != m_client_info.end(); ++i) - { - if (!f(i->first, i->second)) - return false; - } - return true; - } - - bool rpc_payment::load(std::string directory) - { - TRY_ENTRY(); - boost::lock_guard lock(mutex); - m_directory = std::move(directory); - std::string state_file_path = m_directory + "/" + RPC_PAYMENTS_DATA_FILENAME; - MINFO("loading rpc payments data from " << state_file_path); - std::ifstream data; - data.open(state_file_path, std::ios_base::binary | std::ios_base::in); - std::string bytes(std::istream_iterator{data}, std::istream_iterator{}); - if (!data.fail()) - { - bool loaded = false; - try - { - binary_archive ar{epee::strspan(bytes)}; - if (::serialization::serialize(ar, *this)) - if (::serialization::check_stream_state(ar)) - loaded = true; - } - catch (...) {} - if (!loaded) - { - bytes.clear(); - bytes.shrink_to_fit(); - try - { - boost::archive::portable_binary_iarchive a(data); - a >> *this; - loaded = true; - } - catch (...) {} - } - if (!loaded) - { - MERROR("Failed to load RPC payments file"); - m_client_info.clear(); - } - } - else - { - m_client_info.clear(); - } - - CATCH_ENTRY_L0("rpc_payment::load", false); - return true; - } - - bool rpc_payment::store(const std::string &directory_) const - { - TRY_ENTRY(); - boost::lock_guard lock(mutex); - const std::string &directory = directory_.empty() ? m_directory : directory_; - MDEBUG("storing rpc payments data to " << directory); - if (!tools::create_directories_if_necessary(directory)) - { - MWARNING("Failed to create data directory: " << directory); - return false; - } - const boost::filesystem::path state_file_path = (boost::filesystem::path(directory) / RPC_PAYMENTS_DATA_FILENAME); - if (boost::filesystem::exists(state_file_path)) - { - std::string state_file_path_old = state_file_path.string() + ".old"; - boost::system::error_code ec; - boost::filesystem::remove(state_file_path_old, ec); - std::error_code e = tools::replace_file(state_file_path.string(), state_file_path_old); - if (e) - MWARNING("Failed to rename " << state_file_path << " to " << state_file_path_old << ": " << e); - } - std::ofstream data; - data.open(state_file_path.string(), std::ios_base::binary | std::ios_base::out | std::ios::trunc); - if (data.fail()) - { - MWARNING("Failed to save RPC payments to file " << state_file_path); - return false; - }; - binary_archive ar(data); - if (!::serialization::serialize(ar, *const_cast(this))) - return false; - return true; - CATCH_ENTRY_L0("rpc_payment::store", false); - } - - unsigned int rpc_payment::flush_by_age(time_t seconds) - { - boost::lock_guard lock(mutex); - unsigned int count = 0; - const time_t now = time(NULL); - time_t seconds0 = seconds; - if (seconds == 0) - { - seconds = DEFAULT_FLUSH_AGE; - seconds0 = DEFAULT_ZERO_FLUSH_AGE; - } - const time_t threshold = seconds > now ? 0 : now - seconds; - const time_t threshold0 = seconds0 > now ? 0 : now - seconds0; - for (std::unordered_map::iterator i = m_client_info.begin(); i != m_client_info.end(); ) - { - std::unordered_map::iterator j = i++; - const time_t t = std::max(j->second.last_request_timestamp / 1000000, j->second.update_time); - const bool erase = t < ((j->second.credits == 0) ? threshold0 : threshold); - if (erase) - { - MINFO("Erasing " << j->first << " with " << j->second.credits << " credits, inactive for " << (now-t)/86400 << " days"); - m_client_info.erase(j); - ++count; - } - } - return count; - } - - uint64_t rpc_payment::get_hashes(unsigned int seconds) const - { - boost::lock_guard lock(mutex); - const uint64_t now = time(NULL); - uint64_t hashes = 0; - for (std::map::const_reverse_iterator i = m_hashrate.crbegin(); i != m_hashrate.crend(); ++i) - { - if (now > i->first + seconds) - break; - hashes += i->second; - } - return hashes; - } - - void rpc_payment::prune_hashrate(unsigned int seconds) - { - boost::lock_guard lock(mutex); - const uint64_t now = time(NULL); - std::map::iterator i; - for (i = m_hashrate.begin(); i != m_hashrate.end(); ++i) - { - if (now <= i->first + seconds) - break; - } - m_hashrate.erase(m_hashrate.begin(), i); - } - - bool rpc_payment::on_idle() - { - flush_by_age(); - prune_hashrate(3600); - return true; - } -} diff --git a/src/rpc/rpc_payment.h b/src/rpc/rpc_payment.h deleted file mode 100644 index 227d937dd..000000000 --- a/src/rpc/rpc_payment.h +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) 2018-2024, 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 -#include -#include -#include -#include -#include -#include "cryptonote_basic/blobdatatype.h" -#include "cryptonote_basic/cryptonote_basic.h" -#include -#include -#include "serialization/crypto.h" -#include "serialization/string.h" -#include "serialization/pair.h" -#include "serialization/containers.h" - -namespace cryptonote -{ - class rpc_payment - { - public: - struct client_info - { - cryptonote::block block; - cryptonote::block previous_block; - cryptonote::blobdata hashing_blob; - cryptonote::blobdata previous_hashing_blob; - uint64_t previous_seed_height; - uint64_t seed_height; - crypto::hash previous_seed_hash; - crypto::hash seed_hash; - uint32_t cookie; - crypto::hash top; - crypto::hash previous_top; - uint64_t credits; - std::unordered_set payments; - std::unordered_set previous_payments; - uint64_t update_time; - uint64_t last_request_timestamp; - uint64_t block_template_update_time; - uint64_t credits_total; - uint64_t credits_used; - uint64_t nonces_good; - uint64_t nonces_stale; - uint64_t nonces_bad; - uint64_t nonces_dupe; - - client_info(); - - template - inline void serialize(t_archive &a, const unsigned int ver) - { - a & block; - a & previous_block; - a & hashing_blob; - a & previous_hashing_blob; - a & seed_height; - a & previous_seed_height; - a & seed_hash; - a & previous_seed_hash; - a & cookie; - a & top; - a & previous_top; - a & credits; - a & payments; - a & previous_payments; - a & update_time; - a & last_request_timestamp; - a & block_template_update_time; - a & credits_total; - a & credits_used; - a & nonces_good; - a & nonces_stale; - a & nonces_bad; - a & nonces_dupe; - } - - BEGIN_SERIALIZE_OBJECT() - VERSION_FIELD(0) - FIELD(block) - FIELD(previous_block) - FIELD(hashing_blob) - FIELD(previous_hashing_blob) - VARINT_FIELD(seed_height) - VARINT_FIELD(previous_seed_height) - FIELD(seed_hash) - FIELD(previous_seed_hash) - VARINT_FIELD(cookie) - FIELD(top) - FIELD(previous_top) - VARINT_FIELD(credits) - FIELD(payments) - FIELD(previous_payments) - FIELD(update_time) - FIELD(last_request_timestamp) - FIELD(block_template_update_time) - VARINT_FIELD(credits_total) - VARINT_FIELD(credits_used) - VARINT_FIELD(nonces_good) - VARINT_FIELD(nonces_stale) - VARINT_FIELD(nonces_bad) - VARINT_FIELD(nonces_dupe) - END_SERIALIZE() - }; - - public: - rpc_payment(const cryptonote::account_public_address &address, uint64_t diff, uint64_t credits_per_hash_found); - uint64_t balance(const crypto::public_key &client, int64_t delta = 0); - bool pay(const crypto::public_key &client, uint64_t ts, uint64_t payment, const std::string &rpc, bool same_ts, uint64_t &credits); - bool get_info(const crypto::public_key &client, const std::function &get_block_template, cryptonote::blobdata &hashing_blob, uint64_t &seed_height, crypto::hash &seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie); - bool submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale); - const cryptonote::account_public_address &get_payment_address() const { return m_address; } - bool foreach(const std::function &f) const; - unsigned int flush_by_age(time_t seconds = 0); - uint64_t get_hashes(unsigned int seconds) const; - void prune_hashrate(unsigned int seconds); - bool on_idle(); - - template - inline void serialize(t_archive &a, const unsigned int ver) - { - a & m_client_info; - a & m_hashrate; - a & m_credits_total; - a & m_credits_used; - a & m_nonces_good; - a & m_nonces_stale; - a & m_nonces_bad; - a & m_nonces_dupe; - } - - BEGIN_SERIALIZE_OBJECT() - VERSION_FIELD(0) - FIELD(m_client_info) - FIELD(m_hashrate) - VARINT_FIELD(m_credits_total) - VARINT_FIELD(m_credits_used) - VARINT_FIELD(m_nonces_good) - VARINT_FIELD(m_nonces_stale) - VARINT_FIELD(m_nonces_bad) - VARINT_FIELD(m_nonces_dupe) - END_SERIALIZE() - - bool load(std::string directory); - bool store(const std::string &directory = std::string()) const; - - private: - cryptonote::account_public_address m_address; - uint64_t m_diff; - uint64_t m_credits_per_hash_found; - std::unordered_map m_client_info; - std::string m_directory; - std::map m_hashrate; - uint64_t m_credits_total; - uint64_t m_credits_used; - uint64_t m_nonces_good; - uint64_t m_nonces_stale; - uint64_t m_nonces_bad; - uint64_t m_nonces_dupe; - mutable boost::mutex mutex; - }; -} diff --git a/src/rpc/rpc_payment_costs.h b/src/rpc/rpc_payment_costs.h deleted file mode 100644 index 37d6635c0..000000000 --- a/src/rpc/rpc_payment_costs.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2019-2024, 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 - -#define COST_PER_BLOCK 0.05 -#define COST_PER_TX_RELAY 100 -#define COST_PER_OUT 1 -#define COST_PER_OUTPUT_INDEXES 1 -#define COST_PER_TX 0.5 -#define COST_PER_KEY_IMAGE 0.01 -#define COST_PER_POOL_HASH 0.01 -#define COST_PER_TX_POOL_STATS 0.2 -#define COST_PER_BLOCK_HEADER 0.1 -#define COST_PER_GET_INFO 1 -#define COST_PER_OUTPUT_HISTOGRAM 25000 -#define COST_PER_FULL_OUTPUT_HISTOGRAM 5000000 -#define COST_PER_OUTPUT_DISTRIBUTION_0 20 -#define COST_PER_OUTPUT_DISTRIBUTION 50000 -#define COST_PER_COINBASE_TX_SUM_BLOCK 2 -#define COST_PER_BLOCK_HASH 0.002 -#define COST_PER_FEE_ESTIMATE 1 -#define COST_PER_SYNC_INFO 2 -#define COST_PER_HARD_FORK_INFO 1 -#define COST_PER_PEER_LIST 2 diff --git a/src/rpc/rpc_payment_signature.cpp b/src/rpc/rpc_payment_signature.cpp deleted file mode 100644 index 3e7f5fd7d..000000000 --- a/src/rpc/rpc_payment_signature.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2018-2024, 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. - -#include -#include -#include -#include "include_base_utils.h" -#include "string_tools.h" -#include "rpc_payment_signature.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc.payment" - -#define TIMESTAMP_LEEWAY (60 * 1000000) /* 60 seconds, in microseconds */ - -namespace cryptonote -{ - std::string make_rpc_payment_signature(const crypto::secret_key &skey) - { - std::string s; - crypto::public_key pkey; - crypto::secret_key_to_public_key(skey, pkey); - crypto::signature sig; - const uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - char ts[17]; - int ret = snprintf(ts, sizeof(ts), "%16.16" PRIx64, now); - CHECK_AND_ASSERT_MES(ret == 16, "", "snprintf failed"); - ts[16] = 0; - CHECK_AND_ASSERT_MES(strlen(ts) == 16, "", "Invalid time conversion"); - crypto::hash hash; - crypto::cn_fast_hash(ts, 16, hash); - crypto::generate_signature(hash, pkey, skey, sig); - s = epee::string_tools::pod_to_hex(pkey) + ts + epee::string_tools::pod_to_hex(sig); - return s; - } - - bool verify_rpc_payment_signature(const std::string &message, crypto::public_key &pkey, uint64_t &ts) - { - if (message.size() != 2 * sizeof(crypto::public_key) + 16 + 2 * sizeof(crypto::signature)) - { - MDEBUG("Bad message size: " << message.size()); - return false; - } - const std::string pkey_string = message.substr(0, 2 * sizeof(crypto::public_key)); - const std::string ts_string = message.substr(2 * sizeof(crypto::public_key), 16); - const std::string signature_string = message.substr(2 * sizeof(crypto::public_key) + 16); - if (!epee::string_tools::hex_to_pod(pkey_string, pkey)) - { - MDEBUG("Bad client id"); - return false; - } - crypto::signature signature; - if (!epee::string_tools::hex_to_pod(signature_string, signature)) - { - MDEBUG("Bad signature"); - return false; - } - crypto::hash hash; - crypto::cn_fast_hash(ts_string.data(), 16, hash); - if (!crypto::check_signature(hash, pkey, signature)) - { - MDEBUG("signature does not verify"); - return false; - } - char *endptr = NULL; - errno = 0; - unsigned long long ull = strtoull(ts_string.c_str(), &endptr, 16); - if (ull == ULLONG_MAX && errno == ERANGE) - { - MDEBUG("bad timestamp"); - return false; - } - ts = ull; - const uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - if (ts > now + TIMESTAMP_LEEWAY) - { - MDEBUG("Timestamp is in the future"); - return false; - } - if (ts < now - TIMESTAMP_LEEWAY) - { - MDEBUG("Timestamp is too old"); - return false; - } - return true; - } -} diff --git a/src/rpc/rpc_payment_signature.h b/src/rpc/rpc_payment_signature.h deleted file mode 100644 index dea6bac05..000000000 --- a/src/rpc/rpc_payment_signature.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2018-2024, 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 -#include -#include "crypto/crypto.h" - -namespace cryptonote -{ - std::string make_rpc_payment_signature(const crypto::secret_key &skey); - bool verify_rpc_payment_signature(const std::string &message, crypto::public_key &pkey, uint64_t &ts); -} diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 85047c930..eee9eb7ec 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1717,7 +1717,6 @@ private: bool m_show_wallet_name_when_locked; uint32_t m_inactivity_lock_timeout; BackgroundMiningSetupType m_setup_background_mining; - float m_auto_mine_for_rpc_payment_threshold; bool m_is_initialized; NodeRPCProxy m_node_rpc_proxy; std::unordered_set m_scanned_pool_txs[2]; diff --git a/tests/functional_tests/CMakeLists.txt b/tests/functional_tests/CMakeLists.txt index 41b8231b0..f42b59140 100644 --- a/tests/functional_tests/CMakeLists.txt +++ b/tests/functional_tests/CMakeLists.txt @@ -50,20 +50,6 @@ target_link_libraries(functional_tests ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBRARIES}) -set(make_test_signature_sources - make_test_signature.cc) - -monero_add_minimal_executable(make_test_signature - ${make_test_signature_sources}) - -target_link_libraries(make_test_signature - PRIVATE - rpc_base - cncrypto - epee - ${CMAKE_THREAD_LIBS_INIT} - ${EXTRA_LIBRARIES}) - monero_add_minimal_executable(cpu_power_test cpu_power_test.cpp) find_package(Python3 REQUIRED) diff --git a/tests/functional_tests/functional_tests_rpc.py b/tests/functional_tests/functional_tests_rpc.py index a6300484d..febcf932f 100755 --- a/tests/functional_tests/functional_tests_rpc.py +++ b/tests/functional_tests/functional_tests_rpc.py @@ -13,7 +13,7 @@ USAGE = 'usage: functional_tests_rpc.py [ -#include "misc_language.h" -#include "misc_log_ex.h" -#include "string_tools.h" -#include "rpc/rpc_payment_signature.h" - -int main(int argc, const char **argv) -{ - TRY_ENTRY(); - if (argc > 3) - { - fprintf(stderr, "usage: %s [ [N]]\n", argv[0]); - return 1; - } - - crypto::secret_key skey; - - if (argc == 1) - { - crypto::public_key pkey; - crypto::random32_unbiased((unsigned char*)skey.data); - crypto::secret_key_to_public_key(skey, pkey); - printf("%s %s\n", epee::to_hex::string({to_bytes(skey), 32}).c_str(), epee::string_tools::pod_to_hex(pkey).c_str()); - return 0; - } - - if (!epee::string_tools::hex_to_pod(argv[1], skey)) - { - fprintf(stderr, "invalid secret key\n"); - return 1; - } - uint32_t count = 1; - if (argc == 3) - { - int i = atoi(argv[2]); - if (i <= 0) - { - fprintf(stderr, "invalid count\n"); - return 1; - } - count = (uint32_t)i; - } - while (count--) - { - std::string signature = cryptonote::make_rpc_payment_signature(skey); - epee::misc_utils::sleep_no_w(1); - printf("%s\n", signature.c_str()); - } - return 0; - CATCH_ENTRY_L0("main()", 1); -} diff --git a/tests/functional_tests/rpc_payment.py b/tests/functional_tests/rpc_payment.py deleted file mode 100755 index b2a9ca47d..000000000 --- a/tests/functional_tests/rpc_payment.py +++ /dev/null @@ -1,452 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2019-2024, 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. - -import subprocess -import os -import time - -"""Test daemon RPC payment calls -""" - -from framework.daemon import Daemon -from framework.wallet import Wallet - -class RPCPaymentTest(): - def run_test(self): - self.make_test_signature = os.environ['MAKE_TEST_SIGNATURE'] - assert len(self.make_test_signature) > 0 - self.secret_key, self.public_key = self.get_keys() - self.signatures = [] - self.reset() - self.test_access_tracking() - self.test_access_mining() - self.test_access_payment() - self.test_access_account() - self.test_free_access() - - def get_keys(self): - output = subprocess.check_output([self.make_test_signature]).decode('utf-8').rstrip() - fields = output.split() - assert len(fields) == 2 - return fields - - def refill_signatures(self): - self.signatures_time = time.time() - self.signatures = [] - signatures = subprocess.check_output([self.make_test_signature, self.secret_key, '256']).decode('utf-8') - for line in signatures.split(): - self.signatures.append(line.rstrip()) - - def get_signature(self): - if len(self.signatures) == 0 or self.signatures_time + 10 < time.time(): - self.refill_signatures() - s = self.signatures[0] - self.signatures = self.signatures[1:] - return s - - def reset(self): - print('Resetting blockchain') - daemon = Daemon(idx=1) - res = daemon.get_height() - daemon.pop_blocks(res.height - 1) - daemon.flush_txpool() - - def test_access_tracking(self): - print('Testing access tracking') - daemon = Daemon(idx=1) - - res = daemon.rpc_access_tracking(True) - - res = daemon.rpc_access_tracking() - data = sorted(res.data, key = lambda k: k['rpc']) - assert len(data) == 1 - entry = data[0] - assert entry.rpc == 'rpc_access_tracking' - assert entry.count == 1 - assert entry.time >= 0 - assert entry.credits == 0 - - daemon.get_connections() - res = daemon.rpc_access_tracking() - data = sorted(res.data, key = lambda k: k['rpc']) - assert len(data) == 2 - entry = data[0] - assert entry.rpc == 'get_connections' - assert entry.count == 1 - assert entry.time >= 0 - assert entry.credits == 0 - - daemon.get_connections() - res = daemon.rpc_access_tracking() - data = sorted(res.data, key = lambda k: k['rpc']) - assert len(data) == 2 - entry = data[0] - assert entry.rpc == 'get_connections' - assert entry.count == 2 - assert entry.time >= 0 - assert entry.credits == 0 - - daemon.get_alternate_chains() - res = daemon.rpc_access_tracking() - data = sorted(res.data, key = lambda k: k['rpc']) - assert len(data) == 3 - entry = data[0] - assert entry.rpc == 'get_alternate_chains' - assert entry.count == 1 - assert entry.time >= 0 - assert entry.credits == 0 - entry = res.data[1] - assert entry.rpc == 'get_connections' - assert entry.count == 2 - assert entry.time >= 0 - assert entry.credits == 0 - - res = daemon.rpc_access_tracking(True) - res = daemon.rpc_access_tracking() - data = sorted(res.data, key = lambda k: k['rpc']) - assert len(data) == 1 - entry = data[0] - assert entry.rpc == 'rpc_access_tracking' - assert entry.count == 1 - - def test_access_mining(self): - print('Testing access mining') - daemon = Daemon(idx=1) - wallet = Wallet(idx=3) - - res = daemon.rpc_access_info(client = self.get_signature()) - assert len(res.hashing_blob) > 39 - assert res.height == 1 - assert res.top_hash == '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3' - assert res.credits_per_hash_found == 5000 - assert res.diff == 10 - assert res.credits == 0 - cookie = res.cookie - - # Try random nonces till we find one that's valid and one that's invalid - nonce = 0 - found_valid = 0 - found_invalid = 0 - last_credits = 0 - loop_time = time.time() - while found_valid == 0 or found_invalid == 0: - nonce += 1 - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - found_valid += 1 - assert res.credits == last_credits + 5000 - except Exception as e: - found_invalid += 1 - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie - loop_time = time.time() - assert res.credits < last_credits or res.credits == 0 - assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails - last_credits = res.credits - - if time.time() >= loop_time + 10: - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie - loop_time = time.time() - - # we should now have 1 valid nonce, and a number of bad ones - res = daemon.rpc_access_info(client = self.get_signature()) - assert len(res.hashing_blob) > 39 - assert res.height > 1 - assert res.top_hash != '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3' # here, any share matches network diff - assert res.credits_per_hash_found == 5000 - assert res.diff == 10 - cookie = res.cookie - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == 0 - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 0 - - # Try random nonces till we find one that's valid so we get a load of credits - loop_time = time.time() - while last_credits == 0: - nonce += 1 - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - found_valid += 1 - last_credits = res.credits - break - except: - found_invalid += 1 - assert nonce < 1000 # can't find a valid none -> the RPC probably fails - if time.time() >= loop_time + 10: - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie - loop_time = time.time() - - # we should now have at least 5000 - res = daemon.rpc_access_info(client = self.get_signature()) - assert res.credits == last_credits - assert res.credits >= 5000 # last one was a valid nonce - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == 0 - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 0 - assert e.balance == 5000 - assert e.credits_total >= 5000 - - # find a valid one, then check dupes aren't allowed - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie - old_cookie = cookie # we keep that so can submit a stale later - loop_time = time.time() - while True: - nonce += 1 - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - found_valid += 1 - break - except: - found_invalid += 1 - assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails - - if time.time() >= loop_time + 10: - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie - loop_time = time.time() - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == 0 - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 0 - - ok = False - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - except: - ok = True - assert ok - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == 0 - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 1 - - # find stales without updating cookie, one within 5 seconds (accepted), one later (rejected) - res = daemon.rpc_access_info(client = self.get_signature()) - cookie = res.cookie # let the daemon update its timestamp, but use old cookie - found_close_stale = 0 - found_late_stale = 0 - loop_time = time.time() - while found_close_stale == 0 or found_late_stale == 0: - nonce += 1 - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - found_close_stale += 1 - found_valid += 1 - time.sleep(15) # now we've got an early stale, wait till they become late stales - except Exception as e: - #if e[0]['error']['code'] == -18: # stale - if "'code': -18" in str(e): # stale (ugly version, but also works with python 3) - found_late_stale += 1 - else: - found_invalid += 1 - assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails - - if time.time() >= loop_time + 10: - res = daemon.rpc_access_info(client = self.get_signature()) - # cookie = res.cookie # let the daemon update its timestamp, but use old cookie - loop_time = time.time() - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == found_late_stale # close stales are accepted, don't count here - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 1 - - # find very stale with old cookie (rejected) - res = daemon.rpc_access_info(client = self.get_signature()) - nonce += 1 - ok = False - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = old_cookie, client = self.get_signature()) - except: - found_late_stale += 1 - ok = True - assert ok - - res = daemon.rpc_access_data() - assert len(res.entries) > 0 - e = [x for x in res.entries if x['client'] == self.public_key] - assert len(e) == 1 - e = e[0] - assert e.nonces_stale == found_late_stale - assert e.nonces_bad == found_invalid - assert e.nonces_good == found_valid - assert e.nonces_dupe == 1 - - def test_access_payment(self): - print('Testing access payment') - daemon = Daemon(idx=1) - wallet = Wallet(idx=3) - - # Try random nonces till we find one that's valid so we get a load of credits - res = daemon.rpc_access_info(client = self.get_signature()) - credits = res.credits - cookie = res.cookie - nonce = 0 - while credits <= 100: - nonce += 1 - try: - res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) - break - except: - pass - assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails - - res = daemon.rpc_access_info(client = self.get_signature()) - credits = res.credits - assert credits > 0 - - res = daemon.get_info(client = self.get_signature()) - assert res.credits == credits - 1 - credits = res.credits - - res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 100) - block_hashes = res.blocks - - # ask for 1 block -> 1 credit - res = daemon.getblockheadersrange(0, 0, client = self.get_signature()) - assert res.credits == credits - 1 - credits = res.credits - - # ask for 100 blocks -> >1 credit - res = daemon.getblockheadersrange(1, 100, client = self.get_signature()) - assert res.credits < credits - 1 - credits = res.credits - - # external users - res = daemon.rpc_access_pay(payment = 1, paying_for = 'foo', client = self.get_signature()) - assert res.credits == credits - 1 - res = daemon.rpc_access_pay(payment = 4, paying_for = 'bar', client = self.get_signature()) - assert res.credits == credits - 5 - res = daemon.rpc_access_pay(payment = credits, paying_for = 'baz', client = self.get_signature()) - assert "PAYMENT REQUIRED" in res.status - res = daemon.rpc_access_pay(payment = 2, paying_for = 'quux', client = self.get_signature()) - assert res.credits == credits - 7 - res = daemon.rpc_access_pay(payment = 3, paying_for = 'bar', client = self.get_signature()) - assert res.credits == credits - 10 - - # that should be rejected because its cost is massive - ok = False - try: res = daemon.get_output_histogram(amounts = [], client = self.get_signature()) - except Exception as e: print('e: ' + str(e)); ok = "PAYMENT REQUIRED" in e.status - assert ok or "PAYMENT REQUIRED" in res.status - - def test_access_account(self): - print('Testing access account') - daemon = Daemon(idx=1) - wallet = Wallet(idx=3) - - res = daemon.rpc_access_info(client = self.get_signature()) - credits = res.credits - res = daemon.rpc_access_account(self.get_signature(), 0) - assert res.credits == credits - res = daemon.rpc_access_account(self.get_signature(), 50) - assert res.credits == credits + 50 - res = daemon.rpc_access_account(self.get_signature(), -10) - assert res.credits == credits + 40 - res = daemon.rpc_access_account(self.get_signature(), -(credits + 50)) - assert res.credits == 0 - res = daemon.rpc_access_account(self.get_signature(), 2**63 - 5) - assert res.credits == 2**63 - 5 - res = daemon.rpc_access_account(self.get_signature(), 2**63 - 1) - assert res.credits == 2**64 - 6 - res = daemon.rpc_access_account(self.get_signature(), 2) - assert res.credits == 2**64 - 4 - res = daemon.rpc_access_account(self.get_signature(), 8) - assert res.credits == 2**64 - 1 - res = daemon.rpc_access_account(self.get_signature(), -1) - assert res.credits == 2**64 - 2 - res = daemon.rpc_access_account(self.get_signature(), -(2**63 - 1)) - assert res.credits == 2**64 - 2 -(2**63 - 1) - res = daemon.rpc_access_account(self.get_signature(), -(2**63 - 1)) - assert res.credits == 0 - - def test_free_access(self): - print('Testing free access') - daemon = Daemon(idx=0) - wallet = Wallet(idx=0) - - res = daemon.rpc_access_info(client = self.get_signature()) - assert res.credits_per_hash_found == 0 - assert res.diff == 0 - assert res.credits == 0 - - res = daemon.get_info(client = self.get_signature()) - assert res.credits == 0 - - # any nonce will do here - res = daemon.rpc_access_submit_nonce(nonce = 0, cookie = 0, client = self.get_signature()) - assert res.credits == 0 - - -class Guard: - def __enter__(self): - for i in range(4): - Wallet(idx = i).auto_refresh(False) - def __exit__(self, exc_type, exc_value, traceback): - for i in range(4): - Wallet(idx = i).auto_refresh(True) - -if __name__ == '__main__': - with Guard() as guard: - RPCPaymentTest().run_test() diff --git a/tests/fuzz/fuzz_rpc/initialisation.cpp b/tests/fuzz/fuzz_rpc/initialisation.cpp index 15eca335d..9d9a8aeaf 100644 --- a/tests/fuzz/fuzz_rpc/initialisation.cpp +++ b/tests/fuzz/fuzz_rpc/initialisation.cpp @@ -75,45 +75,6 @@ std::unique_ptr initialise_rpc_server(cryptonote::core& dummy_c bundle->dummy_p2p = std::make_unique>>(*bundle->proto_handler); bundle->rpc = std::make_unique(dummy_core, *bundle->dummy_p2p); - // Set up dummy variable map for rpc initialisation with payment - if (need_payment) { - boost::program_options::variables_map vm; - boost::program_options::options_description desc{"fuzz"}; - command_line::add_arg(desc, cryptonote::arg_data_dir); - command_line::add_arg(desc, cryptonote::arg_testnet_on); - command_line::add_arg(desc, cryptonote::arg_stagenet_on); - cryptonote::core_rpc_server::init_options(desc); - - // Generate random address and use it if it is a valid address with valid format - std::string address_arg; - if (provider.remaining_bytes() > 95) { - std::string random_str = provider.ConsumeBytesAsString(95); - if (!random_str.empty() && std::all_of(random_str.begin(), random_str.end(), [](char c) { - return isalnum(c); - })) { - address_arg = "--rpc-payment-address=" + random_str; - } - } - - // Fall back to default hardcoded address if generated address is invalid - if (address_arg.empty()) { - address_arg = "--rpc-payment-address=44AFFq5kSiGBoZKfRLKFY7bUuS5JxqLkZ3Zf1diYv5ZdfTP7hS5gZtSGdgjNXmYGFzRiV3yTgF8Yf4zrhGcq14D3z8PUnHT"; - } - - // Provide needed payment related configuration for init of core_rpc_server - std::vector argv = { - "fuzz", - address_arg.c_str() - }; - boost::program_options::store(boost::program_options::parse_command_line(argv.size(), argv.data(), desc), vm); - boost::program_options::notify(vm); - bool success = bundle->rpc->init(vm, true, "18089", true, ""); - if (!success) { - // Revert back to a fresh core_rpc_server if payment module init is failed - bundle->rpc = std::make_unique(dummy_core, *bundle->dummy_p2p); - } - } - return bundle; } diff --git a/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp b/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp index 028ea25f3..b794e916d 100644 --- a/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp +++ b/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp @@ -1,6 +1,5 @@ #include "rpc_endpoints.h" #include "initialisation.h" -#include "rpc/rpc_payment_signature.h" #include #include @@ -799,62 +798,6 @@ void fuzz_get_txids_loose(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& rpc.on_get_txids_loose(req, res, error_resp, &ctx); } -void fuzz_rpc_access_info(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_INFO::request req; - cryptonote::COMMAND_RPC_ACCESS_INFO::response res; - req.client = "fuzz"; - - rpc.on_rpc_access_info(req, res, error_resp, &ctx); -} - -void fuzz_rpc_access_submit_nonce(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_SUBMIT_NONCE::request req; - cryptonote::COMMAND_RPC_ACCESS_SUBMIT_NONCE::response res; - req.client = "fuzz"; - - req.nonce = provider.ConsumeIntegral(); - req.cookie = provider.ConsumeIntegral(); - - rpc.on_rpc_access_submit_nonce(req, res, error_resp, &ctx); -} - -void fuzz_rpc_access_pay(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_PAY::request req; - cryptonote::COMMAND_RPC_ACCESS_PAY::response res; - req.client = "fuzz"; - - req.paying_for = provider.ConsumeRandomLengthString(32); - req.payment = provider.ConsumeIntegral(); - - rpc.on_rpc_access_pay(req, res, error_resp, &ctx); -} - -void fuzz_rpc_access_tracking(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_TRACKING::request req; - cryptonote::COMMAND_RPC_ACCESS_TRACKING::response res; - - req.clear = provider.ConsumeBool(); - - rpc.on_rpc_access_tracking(req, res, error_resp, &ctx); -} - -void fuzz_rpc_access_data(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_DATA::request req; - cryptonote::COMMAND_RPC_ACCESS_DATA::response res; - - rpc.on_rpc_access_data(req, res, error_resp, &ctx); -} - -void fuzz_rpc_access_account(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) { - cryptonote::COMMAND_RPC_ACCESS_ACCOUNT::request req; - cryptonote::COMMAND_RPC_ACCESS_ACCOUNT::response res; - req.client = "fuzz"; - - req.delta_balance = provider.ConsumeIntegral(); - - rpc.on_rpc_access_account(req, res, error_resp, &ctx); -} - // Maps storing all fuzzing functions std::map> priority_fuzz_targets = { {0, fuzz_get_blocks}, @@ -929,11 +872,5 @@ std::map> priority_fuzz_targets; diff --git a/utils/fish/monero-wallet-cli.fish b/utils/fish/monero-wallet-cli.fish index 2dc6db55d..b5aaef7d0 100644 --- a/utils/fish/monero-wallet-cli.fish +++ b/utils/fish/monero-wallet-cli.fish @@ -52,7 +52,6 @@ complete -c monero-wallet-cli -l do-not-relay -d "The newly created transaction complete -c monero-wallet-cli -l create-address-file -d "Create an address file for new wallets" complete -c monero-wallet-cli -l subaddress-lookahead -r -d "Set subaddress lookahead sizes to :" complete -c monero-wallet-cli -l use-english-language-names -d "Display English language names" -complete -c monero-wallet-cli -l rpc-client-secret-key -r -d "Set RPC client secret key for RPC payments" complete -c monero-wallet-cli -l log-file -r -F -d "Specify log file" complete -c monero-wallet-cli -l log-level -r -a "0 1 2 3 4" -d "0-4 or categories" complete -c monero-wallet-cli -l max-log-file-size -r -d "Specify maximum log file size [B]. Default: 104850000" diff --git a/utils/fish/monero-wallet-rpc.fish b/utils/fish/monero-wallet-rpc.fish index 6dc10e15b..b73c3e6fa 100644 --- a/utils/fish/monero-wallet-rpc.fish +++ b/utils/fish/monero-wallet-rpc.fish @@ -54,7 +54,6 @@ complete -c monero-wallet-rpc -l wallet-file -r -F -d "Use wallet " complete -c monero-wallet-rpc -l generate-from-json -r -k -a "(__fish_complete_suffix .json)" -d "Generate wallet from JSON format file" complete -c monero-wallet-rpc -l wallet-dir -r -F -d "Directory for newly created wallets" complete -c monero-wallet-rpc -l prompt-for-password -d "Prompts for password when not provided" -complete -c monero-wallet-rpc -l rpc-client-secret-key -r -d "Set RPC client secret key for RPC payments" complete -c monero-wallet-rpc -l detach -d "Run as daemon" complete -c monero-wallet-rpc -l pidfile -r -F -d "File path to write the daemon's PID to (optional, requires --detach)" complete -c monero-wallet-rpc -l non-interactive -d "Run non-interactive" diff --git a/utils/fish/monerod.fish b/utils/fish/monerod.fish index f0644190a..c8d2b8c27 100644 --- a/utils/fish/monerod.fish +++ b/utils/fish/monerod.fish @@ -103,10 +103,6 @@ complete -c monerod -l rpc-ssl-allowed-fingerprints -r -d "List of certificate f complete -c monerod -l rpc-ssl-allow-chained -d "Allow user (via --rpc-ssl-certificates) chain certificates" complete -c monerod -l disable-rpc-ban -d "Do not ban hosts on RPC errors" complete -c monerod -l rpc-ssl-allow-any-cert -d "Allow any peer certificate" -complete -c monerod -l rpc-payment-address -r -d "Restrict RPC to clients sending micropayment to this address" -complete -c monerod -l rpc-payment-difficulty -r -d "Restrict RPC to clients sending micropayment at this difficulty. Default: 1000" -complete -c monerod -l rpc-payment-credits -r -d "Restrict RPC to clients sending micropayment, yields that many credits per payment. Default: 100" -complete -c monerod -l rpc-payment-allow-free-loopback -d "Allow free access from the loopback address (ie, the local host)" complete -c monerod -l rpc-max-connections-per-public-ip -d "Max RPC connections per public IP permitted. Default: 3" complete -c monerod -l rpc-max-connections-per-private-ip -d "Max RPC connections per private and localhost IP permitted. Default: 25" complete -c monerod -l rpc-max-connections -d "Max RPC connections permitted. Default: 100" diff --git a/utils/python-rpc/framework/daemon.py b/utils/python-rpc/framework/daemon.py index 71aa0aeb5..adab4204c 100644 --- a/utils/python-rpc/framework/daemon.py +++ b/utils/python-rpc/framework/daemon.py @@ -612,73 +612,3 @@ class Daemon(object): 'id': '0' } return self.rpc.send_json_rpc_request(sync_txpool) - - def rpc_access_info(self, client): - rpc_access_info = { - 'method': 'rpc_access_info', - 'params': { - 'client': client, - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_info) - - def rpc_access_submit_nonce(self, client, nonce, cookie): - rpc_access_submit_nonce = { - 'method': 'rpc_access_submit_nonce', - 'params': { - 'client': client, - 'nonce': nonce, - 'cookie': cookie, - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_submit_nonce) - - def rpc_access_pay(self, client, paying_for, payment): - rpc_access_pay = { - 'method': 'rpc_access_pay', - 'params': { - 'client': client, - 'paying_for': paying_for, - 'payment': payment, - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_pay) - - def rpc_access_tracking(self, clear = False): - rpc_access_tracking = { - 'method': 'rpc_access_tracking', - 'params': { - 'clear': clear, - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_tracking) - - def rpc_access_data(self): - rpc_access_data = { - 'method': 'rpc_access_data', - 'params': { - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_data) - - def rpc_access_account(self, client, delta_balance = 0): - rpc_access_account = { - 'method': 'rpc_access_account', - 'params': { - 'client': client, - 'delta_balance': delta_balance, - }, - 'jsonrpc': '2.0', - 'id': '0' - } - return self.rpc.send_json_rpc_request(rpc_access_account)