Skip to content

Commit

Permalink
Protect stake transactions processor from error during transactions p…
Browse files Browse the repository at this point in the history
…arsing
  • Loading branch information
LenyKholodov committed Mar 11, 2019
1 parent 065d683 commit 3d92859
Showing 1 changed file with 58 additions and 47 deletions.
105 changes: 58 additions & 47 deletions src/cryptonote_core/stake_transaction_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,65 +134,76 @@ void StakeTransactionProcessor::process_block_stake_transaction(uint64_t block_i

for (const crypto::hash& tx_hash : block.tx_hashes)
{
const transaction& tx = db.get_tx(tx_hash);
try
{
const transaction& tx = db.get_tx(tx_hash);

if (!get_graft_stake_tx_extra_from_extra(tx, stake_tx.supernode_public_id, stake_tx.supernode_public_address, stake_tx.supernode_signature, stake_tx.tx_secret_key))
continue;
if (!get_graft_stake_tx_extra_from_extra(tx, stake_tx.supernode_public_id, stake_tx.supernode_public_address, stake_tx.supernode_signature, stake_tx.tx_secret_key))
continue;

crypto::public_key W;
if (!epee::string_tools::hex_to_pod(stake_tx.supernode_public_id, W) || !check_key(W))
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash
<< " because of invalid supernode public identifier '" << stake_tx.supernode_public_id << "'");
continue;
}
crypto::public_key W;
if (!epee::string_tools::hex_to_pod(stake_tx.supernode_public_id, W) || !check_key(W))
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash
<< " because of invalid supernode public identifier '" << stake_tx.supernode_public_id << "'");
continue;
}

std::string supernode_public_address_str = cryptonote::get_account_address_as_str(m_blockchain.testnet(), stake_tx.supernode_public_address);
std::string data = supernode_public_address_str + ":" + stake_tx.supernode_public_id;
crypto::hash hash;
crypto::cn_fast_hash(data.data(), data.size(), hash);
std::string supernode_public_address_str = cryptonote::get_account_address_as_str(m_blockchain.testnet(), stake_tx.supernode_public_address);
std::string data = supernode_public_address_str + ":" + stake_tx.supernode_public_id;
crypto::hash hash;
crypto::cn_fast_hash(data.data(), data.size(), hash);

if (!crypto::check_signature(hash, W, stake_tx.supernode_signature))
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because of invalid supernode signature (mismatch)");
continue;
}
if (!crypto::check_signature(hash, W, stake_tx.supernode_signature))
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because of invalid supernode signature (mismatch)");
continue;
}

uint64_t unlock_time = tx.unlock_time - block_index;
uint64_t unlock_time = tx.unlock_time - block_index;

if (unlock_time < config::graft::STAKE_MIN_UNLOCK_TIME)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because unlock time " << unlock_time << " is less than minimum allowed " << config::graft::STAKE_MIN_UNLOCK_TIME);
continue;
}
if (unlock_time < config::graft::STAKE_MIN_UNLOCK_TIME)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because unlock time " << unlock_time << " is less than minimum allowed " << config::graft::STAKE_MIN_UNLOCK_TIME);
continue;
}

if (unlock_time > config::graft::STAKE_MAX_UNLOCK_TIME)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because unlock time " << unlock_time << " is greater than maximum allowed " << config::graft::STAKE_MAX_UNLOCK_TIME);
continue;
}
if (unlock_time > config::graft::STAKE_MAX_UNLOCK_TIME)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because unlock time " << unlock_time << " is greater than maximum allowed " << config::graft::STAKE_MAX_UNLOCK_TIME);
continue;
}

uint64_t amount = get_transaction_amount(tx, stake_tx.supernode_public_address, stake_tx.tx_secret_key);
uint64_t amount = get_transaction_amount(tx, stake_tx.supernode_public_address, stake_tx.tx_secret_key);

if (!amount)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because of error at parsing amount");
continue;
}
if (!amount)
{
MCLOG(el::Level::Warning, "global", "Ignore stake transaction at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id << "'"
<< " because of error at parsing amount");
continue;
}

stake_tx.amount = amount;
stake_tx.block_height = block_index;
stake_tx.hash = tx_hash;
stake_tx.unlock_time = unlock_time;
stake_tx.amount = amount;
stake_tx.block_height = block_index;
stake_tx.hash = tx_hash;
stake_tx.unlock_time = unlock_time;

m_storage->add_tx(stake_tx);
m_storage->add_tx(stake_tx);

MCLOG(el::Level::Info, "global", "New stake transaction found at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id
<< "', amount=" << amount / double(COIN));
MCLOG(el::Level::Info, "global", "New stake transaction found at block #" << block_index << ", tx_hash=" << tx_hash << ", supernode_public_id '" << stake_tx.supernode_public_id
<< "', amount=" << amount / double(COIN));
}
catch (std::exception& e)
{
MCLOG(el::Level::Warning, "global", "Ignore transaction at block #" << block_index << ", tx_hash=" << tx_hash << " because of error at parsing: " << e.what());
}
catch (...)
{
MCLOG(el::Level::Warning, "global", "Ignore transaction at block #" << block_index << ", tx_hash=" << tx_hash << " because of unknown error at parsing");
}
}

//update supernode stakes
Expand Down

0 comments on commit 3d92859

Please sign in to comment.