forked from lthn/blockchain
102 lines
No EOL
4 KiB
C++
102 lines
No EOL
4 KiB
C++
// Copyright (c) 2018-2019 Zano Project
|
|
// Copyright (c) 2018-2019 Hyle Team
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
#include "include_base_utils.h"
|
|
using namespace epee;
|
|
|
|
#include "basic_pow_helpers.h"
|
|
#include "currency_format_utils.h"
|
|
#include "serialization/binary_utils.h"
|
|
#include "serialization/stl_containers.h"
|
|
#include "currency_core/currency_config.h"
|
|
#include "crypto/crypto.h"
|
|
#include "crypto/hash.h"
|
|
#include "common/int-util.h"
|
|
#include "ethereum/libethash/ethash/ethash.hpp"
|
|
#include "ethereum/libethash/ethash/progpow.hpp"
|
|
|
|
namespace currency
|
|
{
|
|
|
|
//--------------------------------------------------------------
|
|
int ethash_custom_log_get_level()
|
|
{
|
|
return epee::log_space::get_set_log_detalisation_level();
|
|
}
|
|
//--------------------------------------------------------------
|
|
void ethash_custom_log(const std::string& m, bool add_callstack)
|
|
{
|
|
std::string msg = epee::log_space::log_singletone::get_prefix_entry() + "[ETHASH]" + m;
|
|
if (add_callstack)
|
|
msg = msg + "callstask: " + epee::misc_utils::get_callstack();
|
|
|
|
epee::log_space::log_singletone::do_log_message(msg, LOG_LEVEL_0, epee::log_space::console_color_default, true, LOG_DEFAULT_TARGET);
|
|
}
|
|
//--------------------------------------------------------------
|
|
void init_ethash_log_if_necessary()
|
|
{
|
|
static bool inited = false;
|
|
if (inited)
|
|
return;
|
|
|
|
ethash::access_custom_log_level_function() = ðash_custom_log_get_level;
|
|
ethash::access_custom_log_function() = ðash_custom_log;
|
|
|
|
inited = true;
|
|
}
|
|
//------------------------------------------------------------------
|
|
int ethash_height_to_epoch(uint64_t height)
|
|
{
|
|
return static_cast<int>(height / ETHASH_EPOCH_LENGTH);
|
|
}
|
|
//--------------------------------------------------------------
|
|
crypto::hash ethash_epoch_to_seed(int epoch)
|
|
{
|
|
auto res_eth = ethash_calculate_epoch_seed(epoch);
|
|
crypto::hash result = currency::null_hash;
|
|
memcpy(&result.data, &res_eth, sizeof(res_eth));
|
|
return result;
|
|
}
|
|
//--------------------------------------------------------------
|
|
crypto::hash get_block_longhash(uint64_t height, const crypto::hash& block_header_hash, uint64_t nonce)
|
|
{
|
|
init_ethash_log_if_necessary();
|
|
int epoch = ethash_height_to_epoch(height);
|
|
std::shared_ptr<ethash::epoch_context_full> p_context = progpow::get_global_epoch_context_full(static_cast<int>(epoch));
|
|
CHECK_AND_ASSERT_THROW_MES(p_context, "progpow::get_global_epoch_context_full returned null");
|
|
auto res_eth = progpow::hash(*p_context, static_cast<int>(height), *(ethash::hash256*)&block_header_hash, nonce);
|
|
crypto::hash result = currency::null_hash;
|
|
memcpy(&result.data, &res_eth.final_hash, sizeof(res_eth.final_hash));
|
|
return result;
|
|
}
|
|
//---------------------------------------------------------------
|
|
crypto::hash get_block_header_mining_hash(const block& b)
|
|
{
|
|
blobdata bd = get_block_hashing_blob(b);
|
|
|
|
access_nonce_in_block_blob(bd) = 0;
|
|
return crypto::cn_fast_hash(bd.data(), bd.size());
|
|
}
|
|
//---------------------------------------------------------------
|
|
void get_block_longhash(const block& b, crypto::hash& res)
|
|
{
|
|
/*
|
|
Since etherium hash has a bit different approach in minig, to adopt our code we made little hack:
|
|
etherium hash calculates from block's hash and(!) nonce, both passed into PoW hash function.
|
|
To achieve the same effect we make blob of data from block in normal way, but then set to zerro nonce
|
|
inside serialized buffer, and then pass this nonce to ethash algo as a second argument, as it expected.
|
|
*/
|
|
crypto::hash bl_hash = get_block_header_mining_hash(b);
|
|
res = get_block_longhash(get_block_height(b), bl_hash, b.nonce);
|
|
}
|
|
//---------------------------------------------------------------
|
|
crypto::hash get_block_longhash(const block& b)
|
|
{
|
|
crypto::hash p = null_hash;
|
|
get_block_longhash(b, p);
|
|
return p;
|
|
}
|
|
} |