diff --git a/src/crypto/wild_keccak.cpp b/src/crypto/wild_keccak.cpp index 89ffb258..c34216ee 100644 --- a/src/crypto/wild_keccak.cpp +++ b/src/crypto/wild_keccak.cpp @@ -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& 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& 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& 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& 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); + } } diff --git a/src/crypto/wild_keccak.h b/src/crypto/wild_keccak.h index f9fd7e32..cfef801f 100644 --- a/src/crypto/wild_keccak.h +++ b/src/crypto/wild_keccak.h @@ -225,8 +225,10 @@ namespace crypto inline bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector& scratchpad, uint64_t sz) { + uint64_t count_access = 0; crypto::wild_keccak2_dbl(reinterpret_cast(bd.data()), bd.size(), reinterpret_cast(&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 + bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, t_items_accessor cb_get_item) + { + crypto::wild_keccak2_dbl(reinterpret_cast(bd.data()), bd.size(), reinterpret_cast(&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& scratchpad_light); //------------------------------------------------------------------ inline bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector& scratchpad) @@ -281,7 +307,7 @@ namespace crypto } //------------------------------------------------------------------ bool generate_scratchpad(const crypto::hash& source_data, std::vector& result_data, uint64_t target_size); - - + bool generate_scratchpad2(const crypto::hash& source_data, std::vector& result_data, uint64_t target_size); + bool generate_scratchpad_light(const crypto::hash& seed_data, std::vector& result_data, uint64_t target_size); } diff --git a/src/currency_core/bc_offers_service.cpp b/src/currency_core/bc_offers_service.cpp index deaa471c..44e1de3e 100644 --- a/src/currency_core/bc_offers_service.cpp +++ b/src/currency_core/bc_offers_service.cpp @@ -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) {} //------------------------------------------------------------------ diff --git a/src/currency_core/bc_offers_service.h b/src/currency_core/bc_offers_service.h index 634aa6f1..1d7c6429 100644 --- a/src/currency_core/bc_offers_service.h +++ b/src/currency_core/bc_offers_service.h @@ -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: diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 13d7d90c..7c2d6cb5 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -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; } diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 31ce5b67..5312a4c2 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -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 m_deinit_is_done; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index ccae4dae..3f6684aa 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -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 diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index ad612fe8..20cb55ce 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -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) diff --git a/src/currency_core/difficulty.cpp b/src/currency_core/difficulty.cpp index ca48c338..518b59dd 100644 --- a/src/currency_core/difficulty.cpp +++ b/src/currency_core/difficulty.cpp @@ -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::max()); const boost::multiprecision::uint256_t max128bit(std::numeric_limits::max()); const boost::multiprecision::uint512_t max256bit(std::numeric_limits::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(); 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::max(); nominal_hash = nominal_hash / difficulty; @@ -145,7 +145,7 @@ namespace currency { difficulty_type next_difficulty_old(vector timestamps, vector 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& timestamps, vector& 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& timestamps_sorted, vector& 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 next_difficulty(vector& timestamps, vector& 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()); - 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(); + return summ / devider; } } diff --git a/src/currency_core/miner.cpp b/src/currency_core/miner.cpp index 56e4b53f..1a451d83 100644 --- a/src/currency_core/miner.cpp +++ b/src/currency_core/miner.cpp @@ -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)) { diff --git a/src/currency_core/miner.h b/src/currency_core/miner.h index 5e8727e9..21799172 100644 --- a/src/currency_core/miner.h +++ b/src/currency_core/miner.h @@ -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); diff --git a/src/currency_core/scratchpad_helper.cpp b/src/currency_core/scratchpad_helper.cpp index b220c8e3..b52e967a 100644 --- a/src/currency_core/scratchpad_helper.cpp +++ b/src/currency_core/scratchpad_helper.cpp @@ -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(); } -} \ No newline at end of file + //------------------------------------------------------------------------------------ + 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> 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()); + 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; + } + //------------------------------------------------------------------------------------ +} + diff --git a/src/currency_core/scratchpad_helper.h b/src/currency_core/scratchpad_helper.h index 0ecf73ce..515acd56 100644 --- a/src/currency_core/scratchpad_helper.h +++ b/src/currency_core/scratchpad_helper.h @@ -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 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(this)->get_pow_hash_from_blob(bl, get_block_height(b), scr_seed); + } + }; + + + class scratchpad_keeper: public scratchpad_keeper_base { 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 + { + 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>, 4> m_scratchpad_pools; + std::recursive_mutex m_lock; + }; + } \ No newline at end of file diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 632bb62d..6adef318 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -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 cprotocol(ccore, NULL ); nodetool::node_server > p2psrv(cprotocol); diff --git a/src/gui/qt-daemon/application/daemon_backend.cpp b/src/gui/qt-daemon/application/daemon_backend.cpp index baa26fce..b518be67 100644 --- a/src/gui/qt-daemon/application/daemon_backend.cpp +++ b/src/gui/qt-daemon/application/daemon_backend.cpp @@ -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 arg_alloc_win_console = {"alloc-win-console", "Allocates debug console with GUI", false}; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 01c07dac..77429e54 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -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(); + 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) { diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 7b6e78e1..3ceb9dbc 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -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() }; diff --git a/src/version.h.in b/src/version.h.in index 6b74aed1..974320d3 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -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 "]" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 725dd33a..fe608853 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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() diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index 9179efb8..a2688df7 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -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; diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index 6a767414..73bd4162 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -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& events) { currency::checkpoints checkpoints; - checkpoints.add_checkpoint(15, "697d829dd0898fd8c766f5cfc9c174ba353d0c0ebf48def8edec0e2f2e355781"); + checkpoints.add_checkpoint(15, "816f96e8a0e259491ed7e03ef0f2eea69762276152f4990d71f657b1e37d8764"); c.set_checkpoints(std::move(checkpoints)); return true; diff --git a/tests/db_tests/CMakeLists.txt b/tests/db_tests/CMakeLists.txt index 2333a149..50d0e9df 100644 --- a/tests/db_tests/CMakeLists.txt +++ b/tests/db_tests/CMakeLists.txt @@ -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}) diff --git a/tests/functional_tests/difficulty_analysis.cpp b/tests/functional_tests/difficulty_analysis.cpp index 9dfef6f2..b784a88b 100644 --- a/tests/functional_tests/difficulty_analysis.cpp +++ b/tests/functional_tests/difficulty_analysis.cpp @@ -100,14 +100,14 @@ currency::wide_difficulty_type bbr_next_difficulty(std::vector& 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()); std::vector 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& timestamps, std::vector& 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"); diff --git a/tests/performance_tests/keccak_test.h b/tests/performance_tests/keccak_test.h index 14d0bdf3..3553ec1a 100644 --- a/tests/performance_tests/keccak_test.h +++ b/tests/performance_tests/keccak_test.h @@ -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 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 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 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 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); +} diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 49728abb..c6b88c64 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -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); diff --git a/tests/unit_tests/pow_hash_test.cpp b/tests/unit_tests/pow_hash_test.cpp index a3a6876e..523aeed1 100644 --- a/tests/unit_tests/pow_hash_test.cpp +++ b/tests/unit_tests/pow_hash_test.cpp @@ -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 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 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& 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& 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 -bool check_hash(hash_cb hcb) -{ - for(size_t i = 0; i < sizeof(expected_results)/sizeof(expected_results[0]); i++) - { - std::vector 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& scratchpad){ - - return get_block_longhash(blob); - }); - ASSERT_TRUE(r); - - r = check_hash([](const std::string& blob, std::vector& scratchpad){ - - return get_block_longhash(blob); - }); - ASSERT_TRUE(r); + bool res = test_scratchpad_against_light_scratchpad(); + ASSERT_TRUE(res); } -*/ \ No newline at end of file