Skip to content

Commit

Permalink
daemon, wallet: port pay-for-service to randomx
Browse files Browse the repository at this point in the history
  • Loading branch information
moneromooo-monero committed Sep 2, 2019
1 parent 5c6c356 commit 047ced8
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/cryptonote_core/cryptonote_tx_utils.cpp
Expand Up @@ -680,8 +680,7 @@ namespace cryptonote
return true;
}
blobdata bd = get_block_hashing_blob(b);
const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
if (pow_variant >= 6) {
if (b.major_version >= RX_BLOCK_VERSION) {
uint64_t seed_height;
if (rx_needhash(height, &seed_height)) {
crypto::hash hash;
Expand All @@ -693,6 +692,7 @@ namespace cryptonote
}
rx_slow_hash(bd.data(), bd.size(), res.data, miners);
} else {
const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
}
return true;
Expand Down
43 changes: 25 additions & 18 deletions src/rpc/core_rpc_server.cpp
Expand Up @@ -1525,7 +1525,7 @@ namespace cryptonote
return 0;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::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, block &b, epee::json_rpc::error &error_resp)
bool core_rpc_server::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, block &b, crypto::hash &seed_hash, crypto::hash &next_seed_hash, epee::json_rpc::error &error_resp)
{
b = boost::value_initialized<cryptonote::block>();
if(!m_core.get_block_template(b, prev_block, address, difficulty, height, expected_reward, extra_nonce))
Expand All @@ -1544,6 +1544,18 @@ namespace cryptonote
LOG_ERROR("Failed to get tx pub key in coinbase extra");
return false;
}

seed_hash = next_seed_hash = crypto::null_hash;
if (b.major_version >= RX_BLOCK_VERSION)
{
uint64_t seed_height, next_height;
crypto::rx_seedheights(height, &seed_height, &next_height);
seed_hash = m_core.get_block_id_by_height(seed_height);
if (next_height != seed_height) {
next_seed_hash = m_core.get_block_id_by_height(next_height);
}
}

if (extra_nonce.empty())
{
reserved_offset = 0;
Expand All @@ -1566,18 +1578,6 @@ namespace cryptonote
LOG_ERROR("Failed to calculate offset for ");
return false;
}
if (b.major_version >= RX_BLOCK_VERSION)
{
uint64_t seed_height, next_height;
crypto::hash seed_hash;
crypto::rx_seedheights(res.height, &seed_height, &next_height);
seed_hash = m_core.get_block_id_by_height(seed_height);
res.seed_hash = string_tools::pod_to_hex(seed_hash);
if (next_height != seed_height) {
seed_hash = m_core.get_block_id_by_height(next_height);
res.next_seed_hash = string_tools::pod_to_hex(seed_hash);
}
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1656,7 +1656,8 @@ namespace cryptonote
return false;
}
}
if (!get_block_template(info.address, req.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, b, error_resp))
crypto::hash seed_hash, next_seed_hash;
if (!get_block_template(info.address, req.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, b, seed_hash, next_seed_hash, error_resp))
return false;
res.reserved_offset = reserved_offset;
store_difficulty(wdiff, res.difficulty, res.wide_difficulty, res.difficulty_top64);
Expand All @@ -1665,6 +1666,9 @@ namespace cryptonote
res.prev_hash = string_tools::pod_to_hex(b.prev_id);
res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
res.blockhashing_blob = string_tools::buff_to_hex_nodelimer(hashing_blob);
res.seed_hash = string_tools::pod_to_hex(seed_hash);
if (next_seed_hash != crypto::null_hash)
res.next_seed_hash = string_tools::pod_to_hex(next_seed_hash);
res.status = CORE_RPC_STATUS_OK;
return true;
}
Expand Down Expand Up @@ -2903,23 +2907,26 @@ namespace cryptonote
return false;
}

crypto::hash top_hash;
crypto::hash top_hash, seed_hash, next_seed_hash;
m_core.get_blockchain_top(res.height, top_hash);
++res.height;
cryptonote::blobdata hashing_blob;
if (!m_rpc_payment->get_info(client, [&](const cryptonote::blobdata &extra_nonce, cryptonote::block &b)->bool{
if (!m_rpc_payment->get_info(client, [&](const cryptonote::blobdata &extra_nonce, cryptonote::block &b, crypto::hash &seed_hash, crypto::hash &next_seed_hash)->bool{
cryptonote::difficulty_type difficulty;
uint64_t height, expected_reward;
size_t reserved_offset;
if (!get_block_template(m_rpc_payment->get_payment_address(), NULL, extra_nonce, reserved_offset, difficulty, height, expected_reward, b, error_resp))
if (!get_block_template(m_rpc_payment->get_payment_address(), NULL, extra_nonce, reserved_offset, difficulty, height, expected_reward, b, seed_hash, next_seed_hash, error_resp))
return false;
return true;
}, hashing_blob, top_hash, res.diff, res.credits_per_hash_found, res.credits, res.cookie))
}, hashing_blob, seed_hash, next_seed_hash, top_hash, res.diff, res.credits_per_hash_found, res.credits, res.cookie))
{
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);
res.seed_hash = string_tools::pod_to_hex(seed_hash);
if (next_seed_hash != crypto::null_hash)
res.next_seed_hash = string_tools::pod_to_hex(next_seed_hash);

res.status = CORE_RPC_STATUS_OK;
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/core_rpc_server.h
Expand Up @@ -265,7 +265,7 @@ namespace cryptonote
enum invoke_http_mode { JON, BIN, JON_RPC };
template <typename COMMAND_TYPE>
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, block &b, epee::json_rpc::error &error_resp);
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, block &b, 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;
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/core_rpc_server_commands_defs.h
Expand Up @@ -2372,6 +2372,8 @@ namespace cryptonote
struct response_t: public rpc_access_response_base
{
std::string hashing_blob;
std::string seed_hash;
std::string next_seed_hash;
uint32_t cookie;
uint64_t diff;
uint64_t credits_per_hash_found;
Expand All @@ -2380,6 +2382,8 @@ namespace cryptonote
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_response_base)
KV_SERIALIZE(hashing_blob)
KV_SERIALIZE(seed_hash)
KV_SERIALIZE(next_seed_hash)
KV_SERIALIZE(cookie)
KV_SERIALIZE(diff)
KV_SERIALIZE(credits_per_hash_found)
Expand Down
29 changes: 25 additions & 4 deletions src/rpc/rpc_payment.cpp
Expand Up @@ -126,16 +126,17 @@ namespace cryptonote
return true;
}

bool rpc_payment::get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&)> &get_block_template, cryptonote::blobdata &hashing_blob, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie)
bool rpc_payment::get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&, crypto::hash&, crypto::hash&)> &get_block_template, cryptonote::blobdata &hashing_blob, crypto::hash &seed_hash, crypto::hash &next_seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie)
{
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;
crypto::hash new_seed_hash, new_next_seed_hash;
cryptonote::blobdata extra_nonce("\x42\x42\x42\x42", 4);
if (!get_block_template(extra_nonce, new_block))
if (!get_block_template(extra_nonce, new_block, new_seed_hash, new_next_seed_hash))
return false;
if(!remove_field_from_tx_extra(new_block.miner_tx.extra, typeid(cryptonote::tx_extra_nonce)))
return false;
Expand All @@ -152,6 +153,10 @@ namespace cryptonote
hashing_blob = get_block_hashing_blob(info.block);
info.previous_hashing_blob = info.hashing_blob;
info.hashing_blob = hashing_blob;
info.previous_seed_hash = info.seed_hash;
info.seed_hash = new_seed_hash;
info.previous_next_seed_hash = info.next_seed_hash;
info.next_seed_hash = new_next_seed_hash;
info.previous_top = info.top;
std::swap(info.previous_payments, info.payments);
info.payments.clear();
Expand All @@ -161,6 +166,8 @@ namespace cryptonote
info.top = top;
info.update_time = now;
hashing_blob = info.hashing_blob;
seed_hash = info.seed_hash;
next_seed_hash = info.next_seed_hash;
diff = m_diff;
credits_per_hash_found = m_credits_per_hash_found;
credits = info.credits;
Expand Down Expand Up @@ -221,8 +228,22 @@ namespace cryptonote

block = is_current ? info.block : info.previous_block;
*(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(nonce);
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));
const uint8_t major_version = hashing_blob[0];
if (major_version >= RX_BLOCK_VERSION)
{
const int miners = 1;
uint64_t seed_height;
if (crypto::rx_needhash(cryptonote::get_block_height(block), &seed_height))
{
crypto::rx_seedhash(seed_height, is_current ? info.seed_hash.data : info.previous_seed_hash.data, miners);
}
crypto::rx_slow_hash(hashing_blob.data(), hashing_blob.size(), hash.data, miners);
}
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");
Expand Down
10 changes: 9 additions & 1 deletion src/rpc/rpc_payment.h
Expand Up @@ -46,6 +46,10 @@ namespace cryptonote
cryptonote::block previous_block;
cryptonote::blobdata hashing_blob;
cryptonote::blobdata previous_hashing_blob;
crypto::hash previous_seed_hash;
crypto::hash seed_hash;
crypto::hash previous_next_seed_hash;
crypto::hash next_seed_hash;
uint32_t cookie;
crypto::hash top;
crypto::hash previous_top;
Expand All @@ -71,6 +75,10 @@ namespace cryptonote
a & previous_block;
a & hashing_blob;
a & previous_hashing_blob;
a & seed_hash;
a & previous_seed_hash;
a & next_seed_hash;
a & previous_next_seed_hash;
a & cookie;
a & top;
a & previous_top;
Expand All @@ -93,7 +101,7 @@ namespace cryptonote
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<bool(const cryptonote::blobdata&, cryptonote::block&)> &get_block_template, cryptonote::blobdata &hashing_blob, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie);
bool get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&, crypto::hash&, crypto::hash&)> &get_block_template, cryptonote::blobdata &hashing_blob, crypto::hash &seed_hash, crypto::hash &next_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<bool(const crypto::public_key &client, const client_info &info)> &f) const;
Expand Down
9 changes: 6 additions & 3 deletions src/simplewallet/simplewallet.cpp
Expand Up @@ -1952,11 +1952,12 @@ bool simple_wallet::rpc_payment_info(const std::vector<std::string> &args)
uint64_t credits, diff, credits_per_hash_found, height;
uint32_t cookie;
std::string hashing_blob;
crypto::hash seed_hash, next_seed_hash;
crypto::public_key pkey;
crypto::secret_key_to_public_key(m_wallet->get_rpc_client_secret_key(), pkey);
message_writer() << tr("RPC client ID: ") << pkey;
message_writer() << tr("RPC client secret key: ") << m_wallet->get_rpc_client_secret_key();
if (!m_wallet->get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, cookie))
if (!m_wallet->get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, seed_hash, next_seed_hash, cookie))
{
fail_msg_writer() << tr("Failed to query daemon");
return true;
Expand Down Expand Up @@ -2339,7 +2340,8 @@ bool simple_wallet::start_mining_for_rpc(const std::vector<std::string> &args)
uint64_t credits, diff, credits_per_hash_found, height;
uint32_t cookie;
std::string hashing_blob;
if (!m_wallet->get_rpc_payment_info(true, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, cookie))
crypto::hash seed_hash, next_seed_hash;
if (!m_wallet->get_rpc_payment_info(true, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, seed_hash, next_seed_hash, cookie))
{
fail_msg_writer() << tr("Failed to query daemon");
return true;
Expand Down Expand Up @@ -5189,7 +5191,8 @@ bool simple_wallet::check_daemon_rpc_prices(const std::string &daemon_url, uint3
uint64_t credits, diff, credits_per_hash_found, height;
uint32_t cookie;
cryptonote::blobdata hashing_blob;
if (m_wallet->get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, cookie) && payment_required)
crypto::hash seed_hash, next_seed_hash;
if (m_wallet->get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, seed_hash, next_seed_hash, cookie) && payment_required)
{
actual_cph = RPC_CREDITS_PER_HASH_SCALE * (credits_per_hash_found / (float)diff);
return true;
Expand Down
20 changes: 19 additions & 1 deletion src/wallet/node_rpc_proxy.cpp
Expand Up @@ -74,6 +74,8 @@ void NodeRPCProxy::invalidate()
m_block_weight_limit = 0;
m_get_info_time = 0;
m_rpc_payment_info_time = 0;
m_rpc_payment_seed_hash = crypto::null_hash;
m_rpc_payment_next_seed_hash = crypto::null_hash;
}

boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version)
Expand Down Expand Up @@ -254,7 +256,7 @@ boost::optional<std::string> NodeRPCProxy::get_fee_quantization_mask(uint64_t &f
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &blob, uint64_t &height, uint32_t &cookie)
boost::optional<std::string> NodeRPCProxy::get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &blob, uint64_t &height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie)
{
const time_t now = time(NULL);
if (m_rpc_payment_state.stale || now >= m_rpc_payment_info_time + 5*60 || (mining && now >= m_rpc_payment_info_time + 10)) // re-cache every 10 seconds if mining, 5 minutes otherwise
Expand All @@ -280,6 +282,20 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_payment_info(bool mining, boo
MERROR("Invalid hashing blob: " << resp_t.hashing_blob);
return boost::optional<std::string>("Invalid hashing blob");
}
if (!epee::string_tools::hex_to_pod(resp_t.seed_hash, m_rpc_payment_seed_hash))
{
MERROR("Invalid seed_hash: " << resp_t.seed_hash);
return boost::optional<std::string>("Invalid seed hash");
}
if (resp_t.next_seed_hash.empty())
{
m_rpc_payment_next_seed_hash = crypto::null_hash;
}
else if (!epee::string_tools::hex_to_pod(resp_t.next_seed_hash, m_rpc_payment_next_seed_hash))
{
MERROR("Invalid next_seed_hash: " << resp_t.next_seed_hash);
return boost::optional<std::string>("Invalid next seed hash");
}
m_rpc_payment_info_time = now;
}

Expand All @@ -289,6 +305,8 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_payment_info(bool mining, boo
credits_per_hash_found = m_rpc_payment_credits_per_hash_found;
blob = m_rpc_payment_blob;
height = m_rpc_payment_height;
seed_hash = m_rpc_payment_seed_hash;
next_seed_hash = m_rpc_payment_next_seed_hash;
cookie = m_rpc_payment_cookie;
return boost::optional<std::string>();
}
Expand Down
4 changes: 3 additions & 1 deletion src/wallet/node_rpc_proxy.h
Expand Up @@ -55,7 +55,7 @@ class NodeRPCProxy
boost::optional<std::string> get_earliest_height(uint8_t version, uint64_t &earliest_height);
boost::optional<std::string> get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee);
boost::optional<std::string> get_fee_quantization_mask(uint64_t &fee_quantization_mask);
boost::optional<std::string> get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &blob, uint64_t &height, uint32_t &cookie);
boost::optional<std::string> get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &blob, uint64_t &height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);

private:
template<typename T> void handle_payment_changes(const T &res, std::true_type) {
Expand Down Expand Up @@ -93,6 +93,8 @@ class NodeRPCProxy
uint64_t m_rpc_payment_credits_per_hash_found;
cryptonote::blobdata m_rpc_payment_blob;
uint64_t m_rpc_payment_height;
crypto::hash m_rpc_payment_seed_hash;
crypto::hash m_rpc_payment_next_seed_hash;
uint32_t m_rpc_payment_cookie;
};

Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet2.h
Expand Up @@ -1247,7 +1247,7 @@ namespace tools

bool is_unattended() const { return m_unattended; }

bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, uint32_t &cookie);
bool get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &hashing_blob, uint64_t &height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);
bool daemon_requires_payment();
bool make_rpc_payment(uint32_t nonce, uint32_t cookie, uint64_t &credits, uint64_t &balance);
bool search_for_rpc_payment(uint64_t credits_target, const std::function<bool(uint64_t, uint64_t)> &startfunc, const std::function<bool(unsigned)> &contfunc, const std::function<bool(uint64_t)> &foundfunc = NULL, const std::function<void(const std::string&)> &errorfunc = NULL);
Expand Down

0 comments on commit 047ced8

Please sign in to comment.