Skip to content
Permalink
Browse files

TO SQUASH - handle stale nonces correctly

  • Loading branch information...
moneromooo-monero committed Jul 5, 2019
1 parent 1581175 commit 5c39207ef9538a1f50eb6bb75558fee611cf6b28
Showing with 29 additions and 18 deletions.
  1. +15 −11 src/rpc/core_rpc_server.cpp
  2. +11 −6 src/rpc/rpc_payment.cpp
  3. +3 −1 src/rpc/rpc_payment.h
@@ -2727,23 +2727,27 @@ namespace cryptonote
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))
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;
}

// 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))
if (!stale)
{
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");
// 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);
@@ -139,14 +139,17 @@ namespace cryptonote
bool need_template = top != info.top || now >= info.block_template_update_time + STALE_THRESHOLD;
if (need_template)
{
cryptonote::block new_block;
cryptonote::blobdata extra_nonce("\x42\x42\x42\x42", 4);
if (!get_block_template(extra_nonce, info.block))
if (!get_block_template(extra_nonce, new_block))
return false;
if(!remove_field_from_tx_extra(info.block.miner_tx.extra, typeid(cryptonote::tx_extra_nonce)))
if(!remove_field_from_tx_extra(new_block.miner_tx.extra, typeid(cryptonote::tx_extra_nonce)))
return false;
extra_nonce = cryptonote::blobdata((const char*)&client, 4);
if(!add_extra_nonce_to_tx_extra(info.block.miner_tx.extra, extra_nonce))
if(!add_extra_nonce_to_tx_extra(new_block.miner_tx.extra, extra_nonce))
return false;
info.previous_block = std::move(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;
@@ -166,7 +169,7 @@ namespace cryptonote
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 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)
{
client_info &info = m_client_info[client]; // creates if not found
if (cookie != info.cookie && cookie != info.cookie - 1)
@@ -218,9 +221,10 @@ namespace cryptonote
return false;
}

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(info.block));
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");
@@ -242,8 +246,9 @@ namespace cryptonote
++info.nonces_good;

credits = info.credits;
info.block.nonce = nonce;
block = info.block;
block.nonce = nonce;
stale = is_current;
return true;
}

@@ -43,6 +43,7 @@ namespace cryptonote
struct client_info
{
cryptonote::block block;
cryptonote::block previous_block;
cryptonote::blobdata hashing_blob;
cryptonote::blobdata previous_hashing_blob;
uint32_t cookie;
@@ -67,6 +68,7 @@ namespace cryptonote
inline void serialize(t_archive &a, const unsigned int ver)
{
a & block;
a & previous_block;
a & hashing_blob;
a & previous_hashing_blob;
a & cookie;
@@ -92,7 +94,7 @@ namespace cryptonote
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 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 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);
unsigned int flush_by_age(time_t seconds = 0);

0 comments on commit 5c39207

Please sign in to comment.
You can’t perform that action at this time.