1
0
Fork 0
forked from lthn/blockchain

Merge branch 'master' into frontend

This commit is contained in:
wildkif 2019-03-04 21:28:37 +02:00
commit 70a64e1cfc
26 changed files with 373 additions and 296 deletions

View file

@ -9,6 +9,7 @@
#include "wild_keccak.h"
#include "include_base_utils.h"
namespace crypto
{
@ -118,16 +119,71 @@ namespace crypto
}
bool generate_scratchpad(const crypto::hash& seed_data, std::vector<crypto::hash>& result_data, uint64_t target_size)
{
//this is very basic implementation, not considered for production (possible to reduce memory by keeping only every x10 item and calc it instead of read)
//TODO: research safe way for scratchpad generation
result_data.resize(target_size);
result_data[0] = crypto::cn_fast_hash(&seed_data, sizeof(seed_data));
//crypto::hash = get_transaction_hash()
for (size_t i = 1; i < target_size; i++)
{
result_data[i] = crypto::cn_fast_hash(&result_data[i - 1], sizeof(result_data[i - 1]));
}
return true;
}
#define WK2_COUNT 0
bool generate_scratchpad2(const crypto::hash& seed_data, std::vector<crypto::hash>& result_data, uint64_t target_size)
{
CHECK_AND_ASSERT_THROW_MES(target_size % 10 == 0, "wrong target_size = " << target_size);
result_data.resize(target_size);
result_data[0] = crypto::cn_fast_hash(&seed_data, sizeof(seed_data));
for (size_t i = 1; i < target_size; i++)
{
result_data[i] = crypto::cn_fast_hash(&result_data[i - 1], sizeof(result_data[i - 1]));
}
return true;
}
bool generate_scratchpad_light(const crypto::hash& seed_data, std::vector<crypto::hash>& result_data, uint64_t target_size)
{
CHECK_AND_ASSERT_THROW_MES(target_size % 10 == 0, "wrong target_size = " << target_size);
result_data.reserve(target_size/10);
result_data.push_back(crypto::cn_fast_hash(&seed_data, sizeof(seed_data)));
crypto::hash prev_hash = result_data[0];
for (size_t i = 1; i < target_size; i++)
{
prev_hash = crypto::cn_fast_hash(&prev_hash, sizeof(prev_hash));
if (!(i % 10))
{
result_data.push_back(prev_hash);
}
}
return true;
}
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad_light)
{
if (!scratchpad_light.size())
return false;
auto light_scr_accessor = [&](uint64_t i)
{
//get index of int64 item in scratchpad from i, where is is random number in whole uint64_t range
uint64_t int64_mod_index = i%(scratchpad_light.size() * 10 * 4);
//get related hash index
uint64_t hash_index = int64_mod_index / 4;
//get_in hash index (from 0 to 3)
uint64_t in_hash_index = int64_mod_index % 4;
//get index of primary hash in scratchpad_light
uint64_t primary_item_index = (hash_index - (hash_index % 10)) / 10;
uint64_t sha_count = hash_index % 10;
crypto::hash res = scratchpad_light[primary_item_index];
for (uint64_t i = 0; i != sha_count; i++)
{
res = cn_fast_hash(&res, sizeof(res));
}
return ((uint64_t*)&res)[in_hash_index];
};
return get_wild_keccak_light(bd, res, light_scr_accessor);
}
}

View file

@ -225,8 +225,10 @@ namespace crypto
inline
bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad, uint64_t sz)
{
uint64_t count_access = 0;
crypto::wild_keccak2_dbl<crypto::regular_f>(reinterpret_cast<const uint8_t*>(bd.data()), bd.size(), reinterpret_cast<uint8_t*>(&res), sizeof(res), [&](crypto::state_t_m& st)
{
++count_access;
if (!sz)
{
return;
@ -248,9 +250,33 @@ namespace crypto
}
st[i] ^= int_array_ptr[ int_array_ptr[ int_array_ptr[st[depend_index] % int64_sz] % int64_sz] % int64_sz];
}
});
return true;
}
template<class t_items_accessor>
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, t_items_accessor cb_get_item)
{
crypto::wild_keccak2_dbl<crypto::regular_f>(reinterpret_cast<const uint8_t*>(bd.data()), bd.size(), reinterpret_cast<uint8_t*>(&res), sizeof(res), [&](crypto::state_t_m& st)
{
for (size_t i = 0; i != sizeof(st) / sizeof(st[0]); i++)
{
size_t depend_index = 0;
if (i == 0)
{
depend_index = sizeof(st) / sizeof(st[0]) - 1;
}
else
{
depend_index = i - 1;
}
st[i] ^= cb_get_item(cb_get_item(cb_get_item(st[depend_index])));
}
});
return true;
}
//------------------------------------------------------------------
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad_light);
//------------------------------------------------------------------
inline
bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad)
@ -281,7 +307,7 @@ namespace crypto
}
//------------------------------------------------------------------
bool generate_scratchpad(const crypto::hash& source_data, std::vector<crypto::hash>& result_data, uint64_t target_size);
bool generate_scratchpad2(const crypto::hash& source_data, std::vector<crypto::hash>& result_data, uint64_t target_size);
bool generate_scratchpad_light(const crypto::hash& seed_data, std::vector<crypto::hash>& result_data, uint64_t target_size);
}

View file

@ -25,7 +25,7 @@ namespace bc_services
, m_core_runtime_config(currency::get_default_core_runtime_config())
, m_last_seen_block_id(currency::null_hash)
, m_deinitialized(false)
, m_disabled(true)
, m_disabled(false)
{}
//------------------------------------------------------------------

View file

@ -67,6 +67,7 @@ namespace bc_services
crypto::hash get_last_seen_block_id();
void set_last_seen_block_id(const crypto::hash& h);
bool clear();
bool set_disabled(bool is_disabled) { m_disabled = is_disabled; return m_disabled; }
bool is_disabled(){ return m_disabled; }
static void init_options(boost::program_options::options_description& desc);
private:

View file

@ -100,7 +100,8 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(std::share
m_current_fee_median_effective_index(0),
m_is_reorganize_in_process(false),
m_deinit_is_done(false),
m_current_scratchpad_seed(currency::null_hash)
m_current_scratchpad_seed(currency::null_hash),
m_current_scratchpad_seed_height(0)
{
@ -291,6 +292,7 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
initialize_db_solo_options_values();
get_seed_for_scratchpad(m_db_blocks.size(), m_current_scratchpad_seed);
m_current_scratchpad_seed_height = m_db_blocks.size();
m_services_mgr.init(config_folder, vm);
@ -4582,9 +4584,10 @@ void blockchain_storage::on_block_added(const block_extended_info& bei, const cr
//------------------------------------------------------------------
bool blockchain_storage::check_scratchpad()
{
if (get_scratchpad_size_for_height(m_db_blocks.size()) != m_scratchpad.size())
if(get_scratchpad_last_update_rebuild_height(m_db_blocks.size()) != m_current_scratchpad_seed_height)
{
get_seed_for_scratchpad(m_db_blocks.size(), m_current_scratchpad_seed);
m_current_scratchpad_seed_height = get_scratchpad_last_update_rebuild_height(m_db_blocks.size());
}
return true;
}

View file

@ -511,8 +511,9 @@ namespace currency
mutable uint64_t m_current_fee_median;
mutable uint64_t m_current_fee_median_effective_index;
bool m_is_reorganize_in_process;
mutable scratchpad_keeper m_scratchpad;
mutable scratchpad_light_pool m_scratchpad; //TODO: optimization for using full scratchpad in mainchain
crypto::hash m_current_scratchpad_seed;
uint64_t m_current_scratchpad_seed_height;
mutable std::atomic<bool> m_deinit_is_done;

View file

@ -8,7 +8,7 @@
#pragma once
#define CURRENCY_FORMATION_VERSION 75
#define CURRENCY_FORMATION_VERSION 76
#define CURRENCY_MAX_BLOCK_NUMBER 500000000
@ -47,8 +47,7 @@
#define BASE_REWARD_DUST_THRESHOLD ((uint64_t)1000000) // pow(10, 6) - change this will cause hard-fork!
#define DEFAULT_DUST_THRESHOLD ((uint64_t)0)//((uint64_t)100000) // pow(10, 5)
//#define CURRENCY_SCRATCHPAD_BASE_SIZE 16777216 //count in crypto::hash, to get size in bytes x32
#define CURRENCY_SCRATCHPAD_BASE_SIZE 167 //count in crypto::hash, to get size in bytes x32
#define CURRENCY_SCRATCHPAD_BASE_SIZE 16777210 //count in crypto::hash, to get size in bytes x32
#define CURRENCY_SCRATCHPAD_REBUILD_INTERVAL 720 //once a day if block goes once in 2 minute
#define CURRENCY_SCRATCHPAD_BASE_INDEX_ID_OFFSET 20 //offset down from last rebuild height to block id, that used for indexing seed blocks in CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW
#define CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW 700 //window for addressing seed block ids

View file

@ -2412,8 +2412,12 @@ namespace currency
//-----------------------------------------------------------------------------------------------
uint64_t get_scratchpad_size_for_height(uint64_t h)
{
//let's have ~256MB/year if block interval is 2 minutes
return CURRENCY_SCRATCHPAD_BASE_SIZE + get_scratchpad_last_update_rebuild_height(h)*32;
if (h < CURRENCY_BLOCKS_PER_DAY * 7)
{
return 100;
}
//let's have ~250MB/year if block interval is 2 minutes
return CURRENCY_SCRATCHPAD_BASE_SIZE + get_scratchpad_last_update_rebuild_height(h)*30;
}
//-----------------------------------------------------------------------------------------------
bool get_block_reward(bool is_pos, size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward, uint64_t height)

View file

@ -40,9 +40,9 @@ namespace currency {
static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) {
typedef unsigned __int128 uint128_t;
uint128_t res = (uint128_t) a * (uint128_t) b;
low = (uint64_t) res;
high = (uint64_t) (res >> 64);
uint128_t res = (uint128_t)a * (uint128_t)b;
low = (uint64_t)res;
high = (uint64_t)(res >> 64);
}
#endif
@ -52,21 +52,21 @@ namespace currency {
}
static inline bool cadc(uint64_t a, uint64_t b, bool c) {
return a + b < a || (c && a + b == (uint64_t) -1);
return a + b < a || (c && a + b == (uint64_t)-1);
}
bool check_hash_old(const crypto::hash &hash, difficulty_type difficulty) {
uint64_t low, high, top, cur;
// First check the highest word, this will most likely fail for a random hash.
mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, top, high);
mul(swap64le(((const uint64_t *)&hash)[3]), difficulty, top, high);
if (high != 0) {
return false;
}
mul(swap64le(((const uint64_t *) &hash)[0]), difficulty, low, cur);
mul(swap64le(((const uint64_t *) &hash)[1]), difficulty, low, high);
mul(swap64le(((const uint64_t *)&hash)[0]), difficulty, low, cur);
mul(swap64le(((const uint64_t *)&hash)[1]), difficulty, low, high);
bool carry = cadd(cur, low);
cur = high;
mul(swap64le(((const uint64_t *) &hash)[2]), difficulty, low, high);
mul(swap64le(((const uint64_t *)&hash)[2]), difficulty, low, high);
carry = cadc(cur, low, carry);
carry = cadc(high, top, carry);
return !carry;
@ -81,14 +81,14 @@ namespace currency {
const wide_difficulty_type max64bit(std::numeric_limits<std::uint64_t>::max());
const boost::multiprecision::uint256_t max128bit(std::numeric_limits<boost::multiprecision::uint128_t>::max());
const boost::multiprecision::uint512_t max256bit(std::numeric_limits<boost::multiprecision::uint256_t>::max());
bool check_hash(const crypto::hash &hash_, wide_difficulty_type difficulty)
bool check_hash(const crypto::hash &hash_, wide_difficulty_type difficulty)
{
//revert byte order
crypto::hash h = {};
for (size_t i = 0; i != sizeof(h); i++)
{
*(((char*)&h) + (sizeof(h)-(i + 1))) = *(((char*)&hash_) +i );
*(((char*)&h) + (sizeof(h) - (i + 1))) = *(((char*)&hash_) + i);
}
PROFILE_FUNC("check_hash");
@ -97,26 +97,26 @@ namespace currency {
std::uint64_t dl = difficulty.convert_to<std::uint64_t>();
uint64_t low, high, top, cur;
// First check the highest word, this will most likely fail for a random hash.
mul(swap64le(((const uint64_t *) &h)[3]), dl, top, high);
if (high != 0)
mul(swap64le(((const uint64_t *)&h)[3]), dl, top, high);
if (high != 0)
return false;
mul(swap64le(((const uint64_t *) &h)[0]), dl, low, cur);
mul(swap64le(((const uint64_t *) &h)[1]), dl, low, high);
mul(swap64le(((const uint64_t *)&h)[0]), dl, low, cur);
mul(swap64le(((const uint64_t *)&h)[1]), dl, low, high);
bool carry = cadd(cur, low);
cur = high;
mul(swap64le(((const uint64_t *) &h)[2]), dl, low, high);
mul(swap64le(((const uint64_t *)&h)[2]), dl, low, high);
carry = cadc(cur, low, carry);
carry = cadc(high, top, carry);
return !carry;
}
// fast check
if (((const uint64_t *) &h)[3] > 0)
if (((const uint64_t *)&h)[3] > 0)
return false;
// usual slow check
boost::multiprecision::uint512_t hashVal = 0;
for(int i = 1; i < 4; i++)
for (int i = 1; i < 4; i++)
{ // highest word is zero
hashVal |= swap64le(((const uint64_t *) &h)[3 - i]);
hashVal |= swap64le(((const uint64_t *)&h)[3 - i]);
hashVal << 64;
}
return (hashVal * difficulty > max256bit);
@ -130,7 +130,7 @@ namespace currency {
return res;
}
void difficulty_to_boundary_long(wide_difficulty_type difficulty, crypto::hash& result)
void difficulty_to_boundary_long(wide_difficulty_type difficulty, crypto::hash& result)
{
boost::multiprecision::uint256_t nominal_hash = std::numeric_limits<boost::multiprecision::uint256_t>::max();
nominal_hash = nominal_hash / difficulty;
@ -145,7 +145,7 @@ namespace currency {
difficulty_type next_difficulty_old(vector<uint64_t> timestamps, vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
//cutoff DIFFICULTY_LAG
if(timestamps.size() > DIFFICULTY_WINDOW)
if (timestamps.size() > DIFFICULTY_WINDOW)
{
timestamps.resize(DIFFICULTY_WINDOW);
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
@ -165,7 +165,8 @@ namespace currency {
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
} else {
}
else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
}
@ -184,11 +185,62 @@ namespace currency {
return (low + time_span - 1) / time_span;
}
wide_difficulty_type next_difficulty(vector<uint64_t>& timestamps, vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds)
void get_cut_location_from_len(size_t length, size_t& cut_begin, size_t& cut_end, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
{
if (length <= REDEF_DIFFICULTY_WINDOW)
{
cut_begin = 0;
cut_end = length;
}
else
{
cut_begin = REDEF_DIFFICULTY_WINDOW - REDEF_DIFFICULTY_CUT_LAST + 1;
cut_end = cut_begin + (REDEF_DIFFICULTY_WINDOW - (REDEF_DIFFICULTY_CUT_OLD + REDEF_DIFFICULTY_CUT_LAST));
}
}
void get_adjustment_zone(size_t length, size_t& cut_begin, size_t& cut_end, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
{
//cutoff DIFFICULTY_LAG
if (length <= REDEF_DIFFICULTY_WINDOW - (REDEF_DIFFICULTY_CUT_OLD + REDEF_DIFFICULTY_CUT_LAST))
{
cut_begin = 0;
cut_end = length;
}
else
{
cut_begin = REDEF_DIFFICULTY_CUT_LAST;
cut_end = cut_begin + (REDEF_DIFFICULTY_WINDOW - (REDEF_DIFFICULTY_CUT_OLD + REDEF_DIFFICULTY_CUT_LAST));
if (cut_end > length)
cut_end = length;
}
CHECK_AND_ASSERT_THROW_MES(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length, "validation in next_difficulty is failed");
}
wide_difficulty_type get_adjustment_for_zone(vector<uint64_t>& timestamps_sorted, vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
{
size_t length = timestamps_sorted.size();
size_t cut_begin = 0;
size_t cut_end = 0;
get_adjustment_zone(length, cut_begin, cut_end, REDEF_DIFFICULTY_WINDOW, REDEF_DIFFICULTY_CUT_OLD, REDEF_DIFFICULTY_CUT_LAST);
uint64_t time_span = timestamps_sorted[cut_begin] - timestamps_sorted[cut_end - 1];
if (time_span == 0)
{
time_span = 1;
}
wide_difficulty_type total_work = cumulative_difficulties[cut_begin] - cumulative_difficulties[cut_end - 1];
boost::multiprecision::uint256_t res = (boost::multiprecision::uint256_t(total_work) * target_seconds + time_span - 1) / time_span;
if (res > max128bit)
return 0; // to behave like previous implementation, may be better return max128bit?
return res.convert_to<wide_difficulty_type>();
}
wide_difficulty_type next_difficulty(vector<uint64_t>& timestamps, vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds)
{
// timestamps - first is latest, back - is oldest timestamps
//cutoff DIFFICULTY_LAG
if(timestamps.size() > DIFFICULTY_WINDOW)
if (timestamps.size() > DIFFICULTY_WINDOW)
{
timestamps.resize(DIFFICULTY_WINDOW);
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
@ -197,30 +249,32 @@ namespace currency {
size_t length = timestamps.size();
CHECK_AND_ASSERT_MES(length == cumulative_difficulties.size(), 0, "Check \"length == cumulative_difficulties.size()\" failed");
if (length <= 1) {
if (length <= 1)
{
return DIFFICULTY_STARTER;
}
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
CHECK_AND_ASSERT_MES(length <= DIFFICULTY_WINDOW, 0, "length <= DIFFICULTY_WINDOW check failed, length=" << length);
sort(timestamps.begin(), timestamps.end(), std::greater<uint64_t>());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
} else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
wide_difficulty_type dif_slow = get_adjustment_for_zone(timestamps, cumulative_difficulties, target_seconds, DIFFICULTY_WINDOW, DIFFICULTY_CUT/2, DIFFICULTY_CUT/2);
wide_difficulty_type dif_medium = get_adjustment_for_zone(timestamps, cumulative_difficulties, target_seconds, DIFFICULTY_WINDOW/3, DIFFICULTY_CUT / 8, DIFFICULTY_CUT / 12);
wide_difficulty_type dif_fast = get_adjustment_for_zone(timestamps, cumulative_difficulties, target_seconds, DIFFICULTY_WINDOW/18, DIFFICULTY_CUT / 10, 2);
uint64_t devider = 1;
wide_difficulty_type summ = dif_slow;
if (dif_medium != 0)
{
summ += dif_medium;
++devider;
}
CHECK_AND_ASSERT_THROW_MES(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length, "validation in next_difficulty is failed");
uint64_t time_span = timestamps[cut_begin] - timestamps[cut_end - 1];
if (time_span == 0) {
time_span = 1;
if (dif_fast != 0)
{
summ += dif_fast;
++devider;
}
wide_difficulty_type total_work = cumulative_difficulties[cut_begin] - cumulative_difficulties[cut_end - 1];
boost::multiprecision::uint256_t res = (boost::multiprecision::uint256_t(total_work) * target_seconds + time_span - 1) / time_span;
if(res > max128bit)
return 0; // to behave like previous implementation, may be better return max128bit?
return res.convert_to<wide_difficulty_type>();
return summ / devider;
}
}

View file

@ -345,7 +345,7 @@ namespace currency
}
b.nonce = nonce;
access_nonce_in_block_blob(local_blob_data) = b.nonce;
crypto::hash h = m_scratchpad.get_pow_hash(local_blob_data, local_height, local_seed);
crypto::hash h = m_scratchpad.get_pow_hash_from_blob(local_blob_data, local_height, local_seed);
if(check_hash(h, local_diff))
{

View file

@ -73,7 +73,7 @@ namespace currency
{
nonce_ref = bl.nonce;
crypto::hash h = sk.get_pow_hash(bd, height, seed);
crypto::hash h = sk.get_pow_hash_from_blob(bd, height, seed);
if(check_hash(h, diffic))
{
LOG_PRINT_L0("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << "(diff:" << diffic << "), ts: " << bl.timestamp);

View file

@ -15,6 +15,7 @@ namespace currency
{
}
//------------------------------------------------------------------------------------
bool scratchpad_keeper::generate(const crypto::hash& scr_seed, uint64_t height)
{
bool r = false;
@ -25,7 +26,8 @@ namespace currency
CRITICAL_REGION_END();
return r;
}
crypto::hash scratchpad_keeper::get_pow_hash(const blobdata& bd, uint64_t height, const crypto::hash& scr_seed)
//------------------------------------------------------------------------------------
crypto::hash scratchpad_keeper::get_pow_hash_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& scr_seed)
{
CRITICAL_REGION_LOCAL(m_lock);
crypto::hash res_hash = null_hash;
@ -41,13 +43,34 @@ namespace currency
CHECK_AND_ASSERT_THROW_MES(res, "Fatal error on hash calculation: scratchpad_size=" << m_scratchpad.size());
return res_hash;
}
crypto::hash scratchpad_keeper::get_pow_hash(const block& b, const crypto::hash& scr_seed)
{
blobdata bl = get_block_hashing_blob(b);
return get_pow_hash(bl, get_block_height(b), scr_seed);
}
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
uint64_t scratchpad_keeper::size()
{
return m_scratchpad.size();
}
}
//------------------------------------------------------------------------------------
crypto::hash scratchpad_light_pool::get_pow_hash_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& seed)
{
CRITICAL_REGION_LOCAL(m_lock);
std::shared_ptr<std::vector<crypto::hash>> pscr_light;
if (!m_scratchpad_pools.get(seed, pscr_light))
{
LOG_PRINT_MAGENTA("Generating scratchpad light for " << seed << "["<< height <<"]", LOG_LEVEL_0);
pscr_light.reset(new std::vector<crypto::hash>());
bool r = crypto::generate_scratchpad_light(seed, *pscr_light, currency::get_scratchpad_size_for_height(height));
CHECK_AND_ASSERT_THROW_MES(r, "Failed to generate_scratchpad_light");
m_scratchpad_pools.set(seed, pscr_light);
LOG_PRINT_MAGENTA("Generated ok", LOG_LEVEL_0);
}
CHECK_AND_ASSERT_THROW_MES(pscr_light->size()*10 == currency::get_scratchpad_size_for_height(height),
"Wrong size of cached scratchpad = " << pscr_light->size() << ", expected " << currency::get_scratchpad_size_for_height(height) << " for height " << height);
crypto::hash res = currency::null_hash;
bool r = crypto::get_wild_keccak_light(bd, res, *pscr_light);
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_wild_keccak_light");
return res;
}
//------------------------------------------------------------------------------------
}

View file

@ -6,16 +6,30 @@
#include "crypto/wild_keccak.h"
#include "currency_protocol/blobdatatype.h"
#include "currency_core/currency_basic.h"
#include "cache_helper.h"
#include "currency_core/currency_format_utils.h"
#include "currency_core/currency_format_utils_blocks.h"
namespace currency
{
class scratchpad_keeper
template<class t_parent>
class scratchpad_keeper_base
{
public:
crypto::hash get_pow_hash(const block& b, const crypto::hash& scr_seed)
{
blobdata bl = get_block_hashing_blob(b);
return static_cast<t_parent*>(this)->get_pow_hash_from_blob(bl, get_block_height(b), scr_seed);
}
};
class scratchpad_keeper: public scratchpad_keeper_base<scratchpad_keeper>
{
public:
scratchpad_keeper();
bool generate(const crypto::hash& seed, uint64_t height);
crypto::hash get_pow_hash(const blobdata& bd, uint64_t height, const crypto::hash& seed);
crypto::hash get_pow_hash(const block& b, const crypto::hash& seed);
crypto::hash get_pow_hash_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& seed);
uint64_t size();
private:
scratchpad_keeper(const scratchpad_keeper&) {}
@ -24,4 +38,16 @@ namespace currency
std::recursive_mutex m_lock;
};
class scratchpad_light_pool : public scratchpad_keeper_base<scratchpad_light_pool>
{
public:
scratchpad_light_pool() {}
crypto::hash get_pow_hash_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& seed);
private:
//map of seed to
epee::misc_utils::cache_base<false, crypto::hash, std::shared_ptr<std::vector<crypto::hash>>, 4> m_scratchpad_pools;
std::recursive_mutex m_lock;
};
}

View file

@ -152,6 +152,7 @@ int main(int argc, char* argv[])
//create objects and link them
bc_services::bc_offers_service offers_service(nullptr);
offers_service.set_disabled(true);
currency::core ccore(NULL);
currency::t_currency_protocol_handler<currency::core> cprotocol(ccore, NULL );
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > p2psrv(cprotocol);

View file

@ -42,7 +42,8 @@ daemon_backend::daemon_backend():m_pview(&m_view_stub),
m_remote_node_mode(false),
m_is_pos_allowed(false)
{
m_ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&m_offers_service);
m_offers_service.set_disabled(true);
//m_ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&m_offers_service);
}
const command_line::arg_descriptor<bool> arg_alloc_win_console = {"alloc-win-console", "Allocates debug console with GUI", false};

View file

@ -156,6 +156,8 @@ namespace currency
m_core.get_blockchain_storage().get_top_block(b);
res.last_block_total_reward = currency::get_reward_from_miner_tx(b.miner_tx);
res.pos_diff_total_coins_rate = (pos_diff / (res.total_coins - PREMINE_AMOUNT + 1)).convert_to<uint64_t>();
res.last_block_timestamp = b.timestamp;
res.last_block_hash = string_tools::pod_to_hex(get_block_hash(b));
}
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_POS_BLOCK_TS_SHIFT_VS_ACTUAL)
{

View file

@ -660,6 +660,8 @@ namespace currency
uint64_t tx_count_in_last_block;
uint64_t default_fee;
uint64_t minimum_fee;
uint64_t last_block_timestamp;
std::string last_block_hash;
//market
uint64_t offers_count;
@ -708,6 +710,8 @@ namespace currency
KV_SERIALIZE(tx_count_in_last_block)
KV_SERIALIZE(default_fee)
KV_SERIALIZE(minimum_fee)
KV_SERIALIZE(last_block_timestamp)
KV_SERIALIZE(last_block_hash)
KV_SERIALIZE(offers_count)
END_KV_SERIALIZE_MAP()
};

View file

@ -2,6 +2,6 @@
#define BUILD_COMMIT_ID "@VERSION@"
#define PROJECT_VERSION "1.0"
#define PROJECT_VERSION_BUILD_NO 8
#define PROJECT_VERSION_BUILD_NO 9
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"

View file

@ -62,11 +62,9 @@ add_test(coretests coretests)
# set PCH for core_tests
if(MSVC)
if(MSVC AND USE_PCH)
set_property(TARGET coretests APPEND_STRING PROPERTY COMPILE_FLAGS " /Yuchaingen.h /Zm1000")
set_property(SOURCE "core_tests/chaingen.cpp" APPEND_STRING PROPERTY COMPILE_FLAGS " /Ycchaingen.h /Zm1000")
if(USE_PCH) # see also src/CMakeLists.txt for details
set_property(TARGET coretests difficulty-tests functional_tests hash-target-tests performance_tests unit_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../src/$(ConfigurationName)/stdafx.obj")
set_property(TARGET db_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../../src/$(ConfigurationName)/stdafx.obj")
endif()
set_property(TARGET coretests difficulty-tests functional_tests hash-target-tests performance_tests unit_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../src/$(ConfigurationName)/stdafx.obj")
set_property(TARGET db_tests APPEND_STRING PROPERTY LINK_FLAGS "$(MSBuildProjectDirectory)/../../src/$(ConfigurationName)/stdafx.obj")
endif()

View file

@ -597,7 +597,7 @@ gen_no_attchments_in_coinbase::gen_no_attchments_in_coinbase()
// NOTE: This test is made deterministic to be able to correctly set up checkpoint.
random_state_test_restorer::reset_random(); // random generator's state was previously stored, will be restore on dtor (see also m_random_state_test_restorer)
bool r = m_miner_acc.restore_keys_from_braindata("confusion reason crash guess dude scatter rabbit view story protect trickle gather");
bool r = m_miner_acc.restore_keys_from_braindata("battle harsh arrow gain best doubt nose raw protect salty apart tell distant final yeah stubborn true stop shoulder breathe throne problem everyone stranger only");
CHECK_AND_ASSERT_THROW_MES(r, "gen_no_attchments_in_coinbase: Can't restore account from braindata");
REGISTER_CALLBACK_METHOD(gen_no_attchments_in_coinbase, c1);
@ -628,7 +628,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
crc.pos_minimum_heigh = 1;
c.get_blockchain_storage().set_core_runtime_config(crc);
m_checkpoints.add_checkpoint(12, "d34f992c250cad590b474bf0096273fb9beb0d5540a258b46bbbe6e99632fc1a");
m_checkpoints.add_checkpoint(12, "4ba98ca9d92e99e28a30bd5395a305213be2fc18372bbf94ef216ba017640e56");
c.set_checkpoints(currency::checkpoints(m_checkpoints));
return true;

View file

@ -1625,7 +1625,7 @@ multisig_and_checkpoints::multisig_and_checkpoints()
bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
currency::checkpoints checkpoints;
checkpoints.add_checkpoint(15, "697d829dd0898fd8c766f5cfc9c174ba353d0c0ebf48def8edec0e2f2e355781");
checkpoints.add_checkpoint(15, "816f96e8a0e259491ed7e03ef0f2eea69762276152f4990d71f657b1e37d8764");
c.set_checkpoints(std::move(checkpoints));
return true;

View file

@ -1,3 +1,3 @@
add_executable(db_tests db_tests.cpp)
target_link_libraries(db_tests crypto common lmdb zlib ${Boost_LIBRARIES})
target_link_libraries(db_tests crypto common lmdb zlibstatic ${Boost_LIBRARIES})

View file

@ -100,14 +100,14 @@ currency::wide_difficulty_type bbr_next_difficulty(std::vector<uint64_t>& timest
void get_cut_location_from_len(size_t length, size_t& cut_begin, size_t& cut_end, size_t REDEF_DIFFICULTY_WINDOW, size_t REDEF_DIFFICULTY_CUT_OLD, size_t REDEF_DIFFICULTY_CUT_LAST)
{
if (length <= REDEF_DIFFICULTY_WINDOW)
if (length <= REDEF_DIFFICULTY_WINDOW - (REDEF_DIFFICULTY_CUT_OLD+ REDEF_DIFFICULTY_CUT_LAST))
{
cut_begin = 0;
cut_end = length;
}
else
{
cut_begin = REDEF_DIFFICULTY_WINDOW - REDEF_DIFFICULTY_CUT_LAST + 1;
cut_begin = REDEF_DIFFICULTY_CUT_LAST;
cut_end = cut_begin + (REDEF_DIFFICULTY_WINDOW - (REDEF_DIFFICULTY_CUT_OLD + REDEF_DIFFICULTY_CUT_LAST));
}
}
@ -154,7 +154,7 @@ currency::wide_difficulty_type bbr_next_difficulty_composit(std::vector<uint64_t
sort(timestamps.begin(), timestamps.end(), std::greater<uint64_t>());
std::vector<uint64_t> timestamps_local = timestamps;
currency::wide_difficulty_type dif = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, REDEF_DIFFICULTY_WINDOW, REDEF_DIFFICULTY_CUT_OLD, REDEF_DIFFICULTY_CUT_LAST);
currency::wide_difficulty_type dif2 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 200, 5, 5);
currency::wide_difficulty_type dif2 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 240, 5, 5);
currency::wide_difficulty_type dif3 = bbr_next_difficulty_configurable(timestamps_local, cumulative_difficulties, target_seconds, 40, 1, 1);
return (dif3 + dif2 + dif) / 3;
}
@ -300,10 +300,19 @@ void run_emulation(const std::string& path)
}); \
current_index+=2;
#define PERFORME_SIMULATION_FOR_FUNCTION_NO_WINDOW(func_name) \
perform_simulation_for_function(timestamp_to_hashrate, current_index, blocks, result_blocks, \
[&](std::vector<uint64_t>& timestamps, std::vector<currency::wide_difficulty_type>& cumulative_difficulties, size_t target_seconds) \
{ \
return func_name(timestamps, cumulative_difficulties, target_seconds); \
}); \
current_index+=2;
PERFORME_SIMULATION_FOR_FUNCTION(bbr_next_difficulty_configurable, BBR_DIFFICULTY_WINDOW, BBR_DIFFICULTY_CUT, BBR_DIFFICULTY_CUT);
PERFORME_SIMULATION_FOR_FUNCTION(bbr_next_difficulty_configurable, 500, 60, 60);
PERFORME_SIMULATION_FOR_FUNCTION(bbr_next_difficulty_configurable, 300, 60, 60);
PERFORME_SIMULATION_FOR_FUNCTION(bbr_next_difficulty_composit, 720, 60, 60);
PERFORME_SIMULATION_FOR_FUNCTION_NO_WINDOW(currency::next_difficulty);
print_blocks(result_blocks, path + "result.txt");
LOG_PRINT_L0("Done");

View file

@ -7,7 +7,7 @@
#include "crypto/crypto.h"
#include "currency_core/currency_basic.h"
#include "profile_tools.h"
extern "C" {
#include "crypto/keccak.h"
@ -18,7 +18,7 @@ extern "C" {
#include "crypto/wild_keccak.h"
//#include "crypto/wild_keccak2.h"
#include "../core_tests/random_helper.h"
#include "crypto/hash.h"
@ -151,59 +151,57 @@ protected:
#ifdef _DEBUG
#define max_measere_scratchpad 100000
#else
#define max_measere_scratchpad 10000000
#define max_measere_scratchpad 50000000
#endif
#define measere_rounds 10000
void measure_keccak_over_scratchpad()
void generate_scratchpad()
{
std::cout << std::setw(20) << std::left << "sz\t" <<
crypto::hash seed = crypto::cn_fast_hash("sdssdsffdss", 10);
std::vector<crypto::hash> scratchpad;
size_t count = 500000000 / 32;
TIME_MEASURE_START_MS(gen_time);
LOG_PRINT_L0("Generating....");
crypto::generate_scratchpad2(seed, scratchpad, count);
TIME_MEASURE_FINISH_MS(gen_time);
LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
}
void generate_light_scratchpad()
{
crypto::hash seed = crypto::cn_fast_hash("sdssdsffdss", 10);
std::vector<crypto::hash> scratchpad;
size_t count = 500000000 / 32;
TIME_MEASURE_START_MS(gen_time);
LOG_PRINT_L0("Generating....");
crypto::generate_scratchpad_light(seed, scratchpad, count);
TIME_MEASURE_FINISH_MS(gen_time);
LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
}
void measure_keccak_over_scratchpad(uint64_t start_scratchpad_size, uint64_t step_size)
{
// std::cout << std::setw(20) << std::left << "sz\t" <<
//std::setw(10) << "original\t" <<
std::setw(10) << "original opt\t" <<
// std::setw(10) << "original opt\t" <<
// std::setw(10) << "w2\t" <<
std::setw(10) << "w2_opt" << ENDL;
// std::setw(10) << "w2_opt" << ENDL;
std::vector<crypto::hash> scratchpad_vec;
scratchpad_vec.resize(max_measere_scratchpad);
std::string has_str = "Keccak is a family of sponge functions. The sponge function is a generalization of the concept of cryptographic hash function with infinite output and can perform quasi all symmetric cryptographic functions, from hashing to pseudo-random number generation to authenticated encryption";
//static const uint64_t my_own_random_seed = 4669201609102990671;
//random_state_test_restorer::reset_random(my_own_random_seed); // random seeded, entering deterministic mode...
//uint64_t size_original = scratchpad_vec.size();
//scratchpad_vec.resize(i / sizeof(crypto::hash));
for (size_t j = 0; j != scratchpad_vec.size(); j++)
scratchpad_vec[j] = crypto::rand<crypto::hash>();
crypto::hash res_to_test = { 0 };
crypto::hash res_etalon = { 0 };
OPT_XOR_4_RES(scratchpad_vec[0], scratchpad_vec[1], scratchpad_vec[2], scratchpad_vec[3], res_to_test);
OPT_XOR_4_RES(scratchpad_vec[0], scratchpad_vec[1], scratchpad_vec[2], scratchpad_vec[3], res_etalon);
//
// crypto::hash res_h1 = currency::null_hash;
// res_h1 = crypto::get_wild_keccak2_over_scratchpad(has_str, 1, scratchpad_vec, 1000);
//
// crypto::hash res_h2 = currency::null_hash;
// crypto::get_wild_keccak2(has_str, res_h2, 1, scratchpad_vec, 1000);
// if (res_h2 != res_h1)
// {
// return;
// }
for (uint64_t i = 1000; i < max_measere_scratchpad; i += 100000)
for (uint64_t i = start_scratchpad_size; i < max_measere_scratchpad; i += i/10)
{
crypto::hash res_h = currency::null_hash;
uint64_t ticks_a = epee::misc_utils::get_tick_count();
*(uint64_t*)(&has_str[8]) = i;
//original keccak
// for (size_t r = 0; r != measere_rounds; r++)
// {
// *(size_t*)(&has_str[0]) = r;
// res_h = crypto::get_blob_longhash(has_str, 1, scratchpad_vec, i);
// }
//original keccak opt
uint64_t ticks_b = epee::misc_utils::get_tick_count();
for (size_t r = 0; r != measere_rounds; r++)
{
@ -213,11 +211,11 @@ void measure_keccak_over_scratchpad()
//wild keccak 2
uint64_t ticks_c = epee::misc_utils::get_tick_count();
// for (size_t r = 0; r != measere_rounds; r++)
// {
// *(size_t*)(&has_str[1]) = r;
// res_h = crypto::get_wild_keccak2_over_scratchpad(has_str, 1, scratchpad_vec, i);
// }
for (size_t r = 0; r != measere_rounds; r++)
{
*(size_t*)(&has_str[1]) = r;
res_h = crypto::cn_fast_hash(has_str.data(), has_str.size());
}
//wild keccak 2 opt
uint64_t ticks_d = epee::misc_utils::get_tick_count();
for (size_t r = 0; r != measere_rounds; r++)
@ -228,8 +226,15 @@ void measure_keccak_over_scratchpad()
uint64_t ticks_e = epee::misc_utils::get_tick_count();
std::cout << std::setw(20) << std::left << i * sizeof(crypto::hash) << "\t" <<
//std::setw(10) << ticks_b - ticks_a << "\t" <<
std::setw(10) << ticks_c - ticks_b << "\t" <<
//std::setw(10) << ticks_d - ticks_c << "\t" <<
//std::setw(10) << ticks_c - ticks_b << "\t" <<
std::setw(10) << ticks_d - ticks_c << "\t" <<
std::setw(10) << ticks_e - ticks_d << ENDL;
}
}
void measure_keccak_over_scratchpad()
{
//measure_keccak_over_scratchpad(100/32, 100/32);
//measure_keccak_over_scratchpad(10, max_measere_scratchpad / 10);
measure_keccak_over_scratchpad(max_measere_scratchpad/10, 0);
}

View file

@ -35,8 +35,10 @@ int main(int argc, char** argv)
performance_timer timer;
timer.start();
measure_keccak_over_scratchpad();
//generate_scratchpad();
//generate_light_scratchpad();
//measure_keccak_over_scratchpad();
test_scratchpad_against_light_scratchpad();
/*
TEST_PERFORMANCE2(test_construct_tx, 1, 1);
TEST_PERFORMANCE2(test_construct_tx, 1, 2);

View file

@ -2,188 +2,50 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
/*
DISCLAIMER:
Due to hash change (Wild Keccak -> x11 -> Ethash) this test should be completely rewritten.
Also consider using this function:
crypto::hash get_block_longhash(const blobdata& bd)
{
crypto::hash result = null_hash;
block b = AUTO_VAL_INIT(b);
if (parse_and_validate_block_from_blob(bd, b))
{
blobdata local_bd = bd;
access_nonce_in_block_blob(local_bd) = 0;
crypto::hash bl_hash = crypto::cn_fast_hash(local_bd.data(), local_bd.size());
result = get_block_longhash(get_block_height(b), bl_hash, b.nonce);
}
return result;
}
#include "gtest/gtest.h"
#include "crypto/crypto.h"
#include "currency_core/currency_basic.h"
#include "profile_tools.h"
#include "crypto/wild_keccak.h"
#include "currency_core/currency_format_utils.h"
using namespace currency;
const char* test_hashes[51] = {
"0069fbf4c58a4d48ef3134f277c7a711da33fc030fdbf4a6a9eee372616c0f57",
"2ea7ddcbc819ad4fe96def105335773a19e83b8ee04272c63ec034425fbbcccd",
"995cd314592747e673487a8eab8bd8a97bc32c078cc2b975b73cae2c031af7c3",
"8daba3abaeaf44848d4800c44b237638e2ac1650ac58917e34ede513825696ff",
"95d5d7e08e2cc6d81211342b43f7a6ccdd0f05248bd59d5390bcc6c5cea89aae",
"7949d3d906bb66871bca78ef0e4b56f999e000fff987a58b90efef5073b6b27c",
"87ce7ee6527a533c5ac900b0b28d88996ad965d18a8182329e187cfaa96e1272",
"cd6385547b7f64cd2e09455d0b540334d542302600a8f08c7ccd265759a4b324",
"4ba77c0da65bee3088eaca598bfe63a71c257850a16535f3e2e2518cef306aed",
"794372f55692df868c4ca53ff879aa7dddbb290f3fe4a19297ddf4d5e08fe6ad",
"d16e207f9fdb2e61d738cd4318a6024cba9512d56b1624b76d03e5453fb88818",
"39a7669648a0f54f0a1bc311267a0cc124ceee34bfbd6a60a8d43ba5437e8a4f",
"0e6d1192662c71b65201a27d35f1da933e7070c42186f104c9ae1c231ea09f8a",
"9b8cfe7c7acef37ff11b3e9bdfd69c998c63a42adf42b569ab111ef1cfa12afe",
"f83187e1e7c6c3f4d0f7ab964da16f39a78a47dc8ce0aa8df55abc689283f3ed",
"7e2fd86fb9de617bba76a9382772a7aa4369d626c5e127f9699fc464ea1f21b2",
"9a53eb68c7e8b1a4177029014350dea2b7023aae777d5a2509cedb946e794ccb",
"127442cf4d970764cd903b0620c613ffdf92ad43aef9054edf54647ee8ee9a79",
"d7fc147f5a5ddf4f8131c2721498f2bd10a36a50d79bd7f7b1c03e765c4fe16a",
"a7b3729a2a4a9c393e342003edf265aa88a704ff4a659f3ef5326a666f73ebe3",
"3574f8e0c1dd85b704d2dbd9dddc5e9007bb9903e5654f921acd2e1e7be8d6ea",
"a5037e77c4d2c789e32b22e74366c32ee0697c5b4f958d98e3743a704ffc977a",
"d417520014ada3ec182b5cc1ce05ab29b204b1e3545ebee44136eb15801ec042",
"7c17de8607cdcb7776671803504f1f78015df93ee8ae9c1e269ec5dc228e0f31",
"c4679efc2fc306fcb1f3ea7c509ee87daa3b66e54696e63ca4a58235e15f72fc",
"4de02c7066962e6f31c1a686d241d067498d2d326ae69b6588baf49fd62b927d",
"035c335ce07a60387e835858f690376c87993585f4e26964cf33623a90decf2d",
"14ccc27cfb8f2d643cdb775c0afbed38bd30cbe64087bfb12a2a8ee5d185f16a",
"4e19d5a360b3c3de7364d8b7fa53f1c0d051ddc993b32f8356a2123020bc4d94",
"e10e90853db58de03423c5c9f02751c002b11db0baef5428612fc3f2e71fd52b",
"e5f91c2a5a6b33652d2af2d473e07996a26aadf9c545be361555191ef4d8b101",
"2f595481d3fc0d8636d73b95b1b94ea50aeb956a4eeeb06d45d3d8691de5984c",
"5f53e64b1a06be5b2b7b597f462a0ac079cb4a05243b560165688c90867580f2",
"3254d508fe51c42526045048bee5cd29516477180ea8522f1f3b0cc249d98959",
"df364e5c4c10083b8d19639ea04cb23c8268fef04c6601f8fbff284cca4a6e64",
"1a15e83c9bc8bd6ca38e05f2e3318eb50deaa1b4f0d44316d0a16ac608fcf8ec",
"1e4614f61d7c78480fbac8d79863b05ac7c47fd7856489796b10aada9b472b87",
"1ea359c55bef9fa54fc0a89dcdab63281f93ffd0d373d7f29d96ba4f9df0f560",
"f4f58ce5f6afba27075b0d1566a2534cd12a1d546792c50acc0506ebfaf6e5b6",
"4b8feee88ff37929cab4c2aa50334b4908f6b0019da75a4cbb00d759737b0b97",
"07c6c8f4303e456b7f350ffc19a14c0daa303ef38cbf8ed729d0a65cc0d0fe31",
"2cc3c3c065689c1e2639e76aa75d7c7a2356045038bd8e39492f9b5752356b0c",
"ab6c1c109b0ca67f75a54a8b353f817b0704b8dc70ffc7d97eaa45616348f4eb",
"53e23a7291704817fc8a84cf332ef99aa5388cf6cd0d3ca59f2483ff57703849",
"408a8c0141abbdef767669a1624f2d49b24cc277a11d042e318cc64fd41001dd",
"3daf24a36a87fd5c2eda7cf4d58da3eafc3cc26e2a343d97a02a12ecf76eb0a1",
"0c53057b47dac5a7539ec806148fe6534186af5325b0f35014f1abfb4fcf0be1",
"b5404f47ddb58667422ef37a1fa9611565b0c6d4ce07b106ef43832e5a57988d",
"4ae02032ed82d1aed440b4351bd4f0baf54e3c18b853b48f60aea2556d0b1e2b",
"5a017e9303c9d18efaf8716445a3786d81126030f2803646db01d424161461e1",
"83325584cdca2a153a26fb3f5b7a9cc89171bb62c1db85bdba7e113c773f5f41"
};
bool test_scratchpad_against_light_scratchpad()
{
crypto::hash seed = crypto::cn_fast_hash("sdssdsffdss", 10);
std::vector<crypto::hash> scratchpad;
size_t count = 400;
TIME_MEASURE_START_MS(gen_time);
LOG_PRINT_L0("Generating full ....");
crypto::generate_scratchpad2(seed, scratchpad, count);
TIME_MEASURE_FINISH_MS(gen_time);
LOG_PRINT_L0("Generated full scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
std::vector<crypto::hash> scratchpad_light;
crypto::generate_scratchpad_light(seed, scratchpad_light, count);
const char* test_srings[] = {
"",
"President Obama is ready to use American air power in targeted and precise military action",
"Roy Hodgson insisted last night that he would not quit despite admitting that England's World Cup dream was all but over",
};
struct hash_result
{
size_t scratch_size;
size_t string_no;
const char* expected_hash;
};
hash_result expected_results[] =
std::string hashing_str = "dsfssfadfada";
crypto::hash full_h = currency::null_hash;
crypto::hash light_h = currency::null_hash;
crypto::get_wild_keccak2(hashing_str, full_h, scratchpad);
crypto::get_wild_keccak_light(hashing_str, light_h, scratchpad_light);
if (full_h != light_h)
{
{1,0,"b2767f554a15e3471c854118f62c2cc0959ccd6c67a70e75f80f85f548a715bb"},
{10,0,"7071b26139d8469916adba2ada612adc7c767344564907e977bb7466d7cc69ab"},
{100,0,"3fd77bcacf0c579618a9b5f054223692a5cf56926f95a1a5df4a57e044100a20"},
{1000,0,"5a7fc927e8eff077557cc4ad6a4691d4036548ba3131374a543d685e94ea1ea0"},
{10000,0,"d672d0d532fcd0e3a6796975a1ee976f0eae0572d531c5eb45fe0c178099f48f"},
{100000,0,"c7cadb46cbb5575d5bd01d9a8272e427a0f5bc5df69e400c93f5595da78c52d1"},
{1,1,"1a7656a4f0403c3cd2ef7a1471bd5d7a18c7965921e1d03ad12209cca6302cb9"},
{10,1,"94a747ddb33cb6d3908a1e47930903dfd06c365020db0a176b4b5609a37a19f3"},
{100,1,"bcabc30513f4f2b7ff907e86d0fed06894b11a3b11e3e273c26e08f7b5f0666f"},
{1000,1,"03e2ede9f00079404457c385375122e9a0e6f10216f62f70d789cc9ab4491694"},
{10000,1,"ed9594fc45b5161af4d16293449c042ad2508f0c86ef6f42352ec72ae6d94a0a"},
{100000,1,"6650ca0ad0132f85ae757f9a5e41efb638fde7efe2bf2a7e113a7d3d6bd8189d"},
{1,2,"b1d3119e86600023f18aa1e633059de545c835dff2392457e6cac92f1a0da5be"},
{10,2,"fdb1ff6b103d056fe3d68de3deabf0e568cbca56ab5b3b46197a078d5fc2a83b"},
{100,2,"f9acedad2cdca5d5fe2eb0da62d651bb5a8f7dfc9becc4ba9530d71f531effba"},
{1000,2,"4f319beb818183d51cb203c9fa26cd250c67bf3e1fec62995d122dbf8df7292b"},
{10000,2,"e5d95f8465af6e41f132e6e3a625d8b4e6f41c30a85808137b1ae07635bd7804"},
{100000,2,"8ea12900e89a9002080605f06d85b6aab3c584cef761886f450c163ee65168f3"}
};
bool add_hash_str_to_hash_vector(const std::string& str, std::vector<crypto::hash>& scratchpad)
{
crypto::hash h = null_hash;
bool r = epee::string_tools::parse_tpod_from_hex_string(str, h);
CHECK_AND_ASSERT_THROW_MES(r, "wrong hash str");
scratchpad.push_back(h);
return true;
}
void get_scratchpad(size_t hashes_count, std::vector<crypto::hash>& scratchpad)
{
scratchpad.reserve(hashes_count);
size_t count_text_hashes = (sizeof(test_hashes)/sizeof(test_hashes[0]));
for(size_t i = 0; i != hashes_count;i++)
if(i < count_text_hashes)
{
add_hash_str_to_hash_vector(test_hashes[i], scratchpad);
}else
{
scratchpad.push_back(scratchpad[i%count_text_hashes]);
}
}
template<typename hash_cb>
bool check_hash(hash_cb hcb)
{
for(size_t i = 0; i < sizeof(expected_results)/sizeof(expected_results[0]); i++)
{
std::vector<crypto::hash> scratchpad;
get_scratchpad(expected_results[i].scratch_size, scratchpad);
crypto::hash h_expected = null_hash;
bool r = epee::string_tools::parse_tpod_from_hex_string(expected_results[i].expected_hash, h_expected);
CHECK_AND_ASSERT_THROW_MES(r, "wrong expected hash");
crypto::hash res = hcb(test_srings[expected_results[i].string_no], scratchpad);
CHECK_AND_ASSERT_MES(res == h_expected, false, "wrong pow_hash: " << res << ", expected: " );
LOG_ERROR("Hash missmatch");
return false;
}
return true;
}
TEST(pow_tests, test_reference_func)
TEST(pow_tests, test_full_against_light)
{
bool r = check_hash([](const std::string& blob, std::vector<crypto::hash>& scratchpad){
return get_block_longhash(blob);
});
ASSERT_TRUE(r);
r = check_hash([](const std::string& blob, std::vector<crypto::hash>& scratchpad){
return get_block_longhash(blob);
});
ASSERT_TRUE(r);
bool res = test_scratchpad_against_light_scratchpad();
ASSERT_TRUE(res);
}
*/