From cc850cf3c39816009f45754f9c250ee72b598150 Mon Sep 17 00:00:00 2001 From: "crypro.zoidberg" Date: Mon, 25 Mar 2019 01:30:20 +0100 Subject: [PATCH] Inital integration of progpow --- CMakeLists.txt | 2 +- contrib/ethereum/libethash/CMakeLists.txt | 58 +- contrib/ethereum/libethash/bit_manipulation.h | 81 ++ contrib/ethereum/libethash/builtins.h | 43 + contrib/ethereum/libethash/compiler.h | 33 - contrib/ethereum/libethash/data_sizes.h | 812 ------------------ contrib/ethereum/libethash/endian.h | 75 -- contrib/ethereum/libethash/endianness.hpp | 98 +++ .../ethereum/libethash/ethash-internal.hpp | 69 ++ contrib/ethereum/libethash/ethash.cpp | 441 ++++++++++ contrib/ethereum/libethash/ethash.h | 158 ---- contrib/ethereum/libethash/ethash/ethash.h | 93 ++ contrib/ethereum/libethash/ethash/ethash.hpp | 159 ++++ .../ethereum/libethash/ethash/hash_types.h | 46 + .../ethereum/libethash/ethash/hash_types.hpp | 15 + contrib/ethereum/libethash/ethash/keccak.h | 49 ++ contrib/ethereum/libethash/ethash/keccak.hpp | 35 + contrib/ethereum/libethash/ethash/progpow.hpp | 42 + contrib/ethereum/libethash/fnv.h | 39 - contrib/ethereum/libethash/internal.c | 675 --------------- contrib/ethereum/libethash/internal.h | 183 ---- contrib/ethereum/libethash/io.c | 119 --- contrib/ethereum/libethash/io.h | 202 ----- contrib/ethereum/libethash/io_posix.c | 111 --- contrib/ethereum/libethash/io_win32.c | 102 --- contrib/ethereum/libethash/keccak.c | 123 +++ contrib/ethereum/libethash/keccakf1600.c | 255 ++++++ contrib/ethereum/libethash/keccakf800.c | 253 ++++++ contrib/ethereum/libethash/kiss99.hpp | 64 ++ contrib/ethereum/libethash/managed.cpp | 100 +++ contrib/ethereum/libethash/mmap.h | 47 - contrib/ethereum/libethash/mmap_win32.c | 86 -- contrib/ethereum/libethash/primes.c | 43 + contrib/ethereum/libethash/primes.h | 25 + contrib/ethereum/libethash/progpow.cpp | 360 ++++++++ contrib/ethereum/libethash/sha3.c | 151 ---- contrib/ethereum/libethash/sha3.h | 31 - .../ethereum/libethash/support/attributes.h | 33 + contrib/ethereum/libethash/util.c | 41 - contrib/ethereum/libethash/util.h | 47 - contrib/ethereum/libethash/util_win32.c | 38 - src/CMakeLists.txt | 8 +- src/crypto/wild_keccak.cpp | 136 --- src/crypto/wild_keccak.h | 169 ---- src/currency_core/basic_pow_helpers.cpp | 74 ++ src/currency_core/basic_pow_helpers.h | 43 + src/currency_core/blockchain_storage.cpp | 81 +- src/currency_core/blockchain_storage.h | 16 +- src/currency_core/currency_config.h | 6 - src/currency_core/currency_core.cpp | 7 +- src/currency_core/currency_core.h | 4 +- src/currency_core/currency_format_utils.cpp | 34 +- src/currency_core/currency_format_utils.h | 42 - src/currency_core/miner.cpp | 21 +- src/currency_core/miner.h | 31 +- src/currency_core/miner_common.h | 22 - src/currency_core/scratchpad_helper.cpp | 76 -- src/currency_core/scratchpad_helper.h | 53 -- src/rpc/core_rpc_server.cpp | 2 +- src/rpc/mining_protocol_defs.h | 54 -- tests/CMakeLists.txt | 14 +- tests/core_tests/alias_tests.cpp | 15 +- tests/core_tests/block_reward.cpp | 3 +- tests/core_tests/chaingen.cpp | 9 +- tests/core_tests/chaingen.h | 4 - tests/core_tests/chaingen_helpers.h | 22 +- tests/core_tests/checkpoints_tests.cpp | 6 +- tests/core_tests/emission_test.cpp | 11 +- .../escrow_wallet_altchain_test.cpp | 4 +- tests/core_tests/escrow_wallet_tests.cpp | 96 +-- tests/core_tests/misc_tests.cpp | 2 +- tests/core_tests/mixin_attr.cpp | 2 +- tests/core_tests/multisig_wallet_tests.cpp | 32 +- tests/core_tests/offers_test.cpp | 20 +- tests/core_tests/pos_validation.cpp | 6 +- tests/core_tests/tx_validation.cpp | 2 +- tests/core_tests/wallet_rpc_tests.cpp | 4 +- tests/core_tests/wallet_tests.cpp | 38 +- .../core_concurrency_test.cpp | 7 +- tests/performance_tests/keccak_test.h | 404 ++++----- tests/performance_tests/main.cpp | 2 +- tests/unit_tests/pow_hash_test.cpp | 66 +- 82 files changed, 2985 insertions(+), 4100 deletions(-) create mode 100644 contrib/ethereum/libethash/bit_manipulation.h create mode 100644 contrib/ethereum/libethash/builtins.h delete mode 100644 contrib/ethereum/libethash/compiler.h delete mode 100644 contrib/ethereum/libethash/data_sizes.h delete mode 100644 contrib/ethereum/libethash/endian.h create mode 100644 contrib/ethereum/libethash/endianness.hpp create mode 100644 contrib/ethereum/libethash/ethash-internal.hpp create mode 100644 contrib/ethereum/libethash/ethash.cpp delete mode 100644 contrib/ethereum/libethash/ethash.h create mode 100644 contrib/ethereum/libethash/ethash/ethash.h create mode 100644 contrib/ethereum/libethash/ethash/ethash.hpp create mode 100644 contrib/ethereum/libethash/ethash/hash_types.h create mode 100644 contrib/ethereum/libethash/ethash/hash_types.hpp create mode 100644 contrib/ethereum/libethash/ethash/keccak.h create mode 100644 contrib/ethereum/libethash/ethash/keccak.hpp create mode 100644 contrib/ethereum/libethash/ethash/progpow.hpp delete mode 100644 contrib/ethereum/libethash/fnv.h delete mode 100644 contrib/ethereum/libethash/internal.c delete mode 100644 contrib/ethereum/libethash/internal.h delete mode 100644 contrib/ethereum/libethash/io.c delete mode 100644 contrib/ethereum/libethash/io.h delete mode 100644 contrib/ethereum/libethash/io_posix.c delete mode 100644 contrib/ethereum/libethash/io_win32.c create mode 100644 contrib/ethereum/libethash/keccak.c create mode 100644 contrib/ethereum/libethash/keccakf1600.c create mode 100644 contrib/ethereum/libethash/keccakf800.c create mode 100644 contrib/ethereum/libethash/kiss99.hpp create mode 100644 contrib/ethereum/libethash/managed.cpp delete mode 100644 contrib/ethereum/libethash/mmap.h delete mode 100644 contrib/ethereum/libethash/mmap_win32.c create mode 100644 contrib/ethereum/libethash/primes.c create mode 100644 contrib/ethereum/libethash/primes.h create mode 100644 contrib/ethereum/libethash/progpow.cpp delete mode 100644 contrib/ethereum/libethash/sha3.c delete mode 100644 contrib/ethereum/libethash/sha3.h create mode 100644 contrib/ethereum/libethash/support/attributes.h delete mode 100644 contrib/ethereum/libethash/util.c delete mode 100644 contrib/ethereum/libethash/util.h delete mode 100644 contrib/ethereum/libethash/util_win32.c delete mode 100644 src/crypto/wild_keccak.cpp delete mode 100644 src/crypto/wild_keccak.h create mode 100644 src/currency_core/basic_pow_helpers.cpp create mode 100644 src/currency_core/basic_pow_helpers.h delete mode 100644 src/currency_core/scratchpad_helper.cpp delete mode 100644 src/currency_core/scratchpad_helper.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a0376c9..562dde60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,7 +157,7 @@ endif() message(STATUS "Boost: ${Boost_VERSION} from ${Boost_LIBRARY_DIRS}") -include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) +include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/contrib/ethereum/libethash) if(MINGW) set(Boost_LIBRARIES "${Boost_LIBRARIES};ws2_32;mswsock") elseif(NOT MSVC) diff --git a/contrib/ethereum/libethash/CMakeLists.txt b/contrib/ethereum/libethash/CMakeLists.txt index f95048b7..8205079d 100644 --- a/contrib/ethereum/libethash/CMakeLists.txt +++ b/contrib/ethereum/libethash/CMakeLists.txt @@ -1,39 +1,33 @@ -set(LIBRARY ethash) +# ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +# Copyright 2018 Pawel Bylica. +# Licensed under the Apache License, Version 2.0. See the LICENSE file. -if (CPPETHEREUM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") -endif () +# set(include_dir ${PROJECT_SOURCE_DIR}/include) -if (NOT MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") -endif() +add_library( + ethash + bit_manipulation.h + builtins.h + endianness.hpp + ethash/ethash.h + ethash/ethash.hpp + ethash-internal.hpp + ethash.cpp + ethash/hash_types.h + managed.cpp + ethash/keccak.h + ethash/keccak.hpp + keccak.c + keccakf800.c + keccakf1600.c + kiss99.hpp + primes.h + primes.c + ethash/progpow.hpp + progpow.cpp +) -set(FILES util.h - io.c - internal.c - ethash.h - endian.h - compiler.h - fnv.h - data_sizes.h) -if (MSVC) - list(APPEND FILES util_win32.c io_win32.c mmap_win32.c) -else() - list(APPEND FILES io_posix.c) -endif() -# if (NOT CRYPTOPP_FOUND) -# find_package(CryptoPP 5.6.2) -# endif() -list(APPEND FILES sha3.c sha3.h) - -add_library(ethash ${FILES}) - -# if (CRYPTOPP_FOUND) -# TARGET_LINK_LIBRARIES(ethash ${CRYPTOPP_LIBRARIES}) -# endif() - -# install(TARGETS ethash RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) diff --git a/contrib/ethereum/libethash/bit_manipulation.h b/contrib/ethereum/libethash/bit_manipulation.h new file mode 100644 index 00000000..3fa22948 --- /dev/null +++ b/contrib/ethereum/libethash/bit_manipulation.h @@ -0,0 +1,81 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include "builtins.h" +#include "support/attributes.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t rotl32(uint32_t n, unsigned int c) +{ + const unsigned int mask = 31; + + c &= mask; + unsigned int neg_c = (unsigned int)(-(int)c); + return (n << c) | (n >> (neg_c & mask)); +} + +static inline uint32_t rotr32(uint32_t n, unsigned int c) +{ + const unsigned int mask = 31; + + c &= mask; + unsigned int neg_c = (unsigned int)(-(int)c); + return (n >> c) | (n << (neg_c & mask)); +} + +static inline uint32_t clz32(uint32_t x) +{ + return x ? (uint32_t)__builtin_clz(x) : 32; +} + +static inline uint32_t popcount32(uint32_t x) +{ + return (uint32_t)__builtin_popcount(x); +} + +static inline uint32_t mul_hi32(uint32_t x, uint32_t y) +{ + return (uint32_t)(((uint64_t)x * (uint64_t)y) >> 32); +} + + +/** FNV 32-bit prime. */ +static const uint32_t fnv_prime = 0x01000193; + +/** FNV 32-bit offset basis. */ +static const uint32_t fnv_offset_basis = 0x811c9dc5; + +/** + * The implementation of FNV-1 hash. + * + * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1_hash. + */ +NO_SANITIZE("unsigned-integer-overflow") +static inline uint32_t fnv1(uint32_t u, uint32_t v) noexcept +{ + return (u * fnv_prime) ^ v; +} + +/** + * The implementation of FNV-1a hash. + * + * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash. + */ +NO_SANITIZE("unsigned-integer-overflow") +static inline uint32_t fnv1a(uint32_t u, uint32_t v) noexcept +{ + return (u ^ v) * fnv_prime; +} + +#ifdef __cplusplus +} +#endif diff --git a/contrib/ethereum/libethash/builtins.h b/contrib/ethereum/libethash/builtins.h new file mode 100644 index 00000000..6cf6a285 --- /dev/null +++ b/contrib/ethereum/libethash/builtins.h @@ -0,0 +1,43 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +/** + * @file + * Implementation of GCC/clang builtins for MSVC compiler. + */ + +#pragma once + +#ifdef _MSC_VER +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Returns the number of leading 0-bits in `x`, starting at the most significant bit position. + * If `x` is 0, the result is undefined. + */ +static inline int __builtin_clz(unsigned int x) +{ + unsigned long most_significant_bit; + _BitScanReverse(&most_significant_bit, x); + return 31 - (int)most_significant_bit; +} + +/** + * Returns the number of 1-bits in `x`. + */ +static inline int __builtin_popcount(unsigned int x) +{ + return (int)__popcnt(x); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/ethereum/libethash/compiler.h b/contrib/ethereum/libethash/compiler.h deleted file mode 100644 index 9695871c..00000000 --- a/contrib/ethereum/libethash/compiler.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file compiler.h - * @date 2014 - */ -#pragma once - -// Visual Studio doesn't support the inline keyword in C mode -#if defined(_MSC_VER) && !defined(__cplusplus) -#define inline __inline -#endif - -// pretend restrict is a standard keyword -#if defined(_MSC_VER) -#define restrict __restrict -#else -#define restrict __restrict__ -#endif - diff --git a/contrib/ethereum/libethash/data_sizes.h b/contrib/ethereum/libethash/data_sizes.h deleted file mode 100644 index 83cc30bc..00000000 --- a/contrib/ethereum/libethash/data_sizes.h +++ /dev/null @@ -1,812 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software FoundationUUU,either version 3 of the LicenseUUU,or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be usefulU, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If notUUU,see . -*/ - -/** @file data_sizes.h -* @author Matthew Wampler-Doty -* @date 2015 -*/ - -#pragma once - -#include -#include "compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// 2048 Epochs (~20 years) worth of tabulated DAG sizes - -// Generated with the following Mathematica Code: - -// GetCacheSizes[n_] := Module[{ -// CacheSizeBytesInit = 2^24, -// CacheGrowth = 2^17, -// HashBytes = 64, -// j = 0}, -// Reap[ -// While[j < n, -// Module[{i = -// Floor[(CacheSizeBytesInit + CacheGrowth * j) / HashBytes]}, -// While[! PrimeQ[i], i--]; -// Sow[i*HashBytes]; j++]]]][[2]][[1]] - - -static const uint64_t dag_sizes[2048] = { - 1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U, - 1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U, - 1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U, - 1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U, - 1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U, - 1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U, - 1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U, - 1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U, - 1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U, - 1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U, - 1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U, - 1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U, - 1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U, - 1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U, - 1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U, - 1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U, - 1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U, - 1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U, - 1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U, - 1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U, - 1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U, - 1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U, - 1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U, - 2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U, - 2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U, - 2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U, - 2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U, - 2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U, - 2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U, - 2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U, - 2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U, - 2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U, - 2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U, - 2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U, - 2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U, - 2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U, - 2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U, - 2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U, - 2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U, - 2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U, - 2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U, - 2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U, - 2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U, - 2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U, - 2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U, - 2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U, - 3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U, - 3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U, - 3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U, - 3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U, - 3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U, - 3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U, - 3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U, - 3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U, - 3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U, - 3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U, - 3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U, - 3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U, - 3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U, - 3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U, - 3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U, - 3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U, - 3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U, - 3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U, - 3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U, - 3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U, - 3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U, - 3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U, - 3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U, - 3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U, - 4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U, - 4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U, - 4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U, - 4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U, - 4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U, - 4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U, - 4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U, - 4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U, - 4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U, - 4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U, - 4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U, - 4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U, - 4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U, - 4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U, - 4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U, - 4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U, - 4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U, - 4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U, - 4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U, - 4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U, - 4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U, - 4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U, - 4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U, - 4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U, - 5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U, - 5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U, - 5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U, - 5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U, - 5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U, - 5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U, - 5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U, - 5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U, - 5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U, - 5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U, - 5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U, - 5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U, - 5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U, - 5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U, - 5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U, - 5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U, - 5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U, - 5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U, - 5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U, - 5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U, - 5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U, - 5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U, - 5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U, - 5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U, - 6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U, - 6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U, - 6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U, - 6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U, - 6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U, - 6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U, - 6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U, - 6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U, - 6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U, - 6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U, - 6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U, - 6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U, - 6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U, - 6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U, - 6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U, - 6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U, - 6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U, - 6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U, - 6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U, - 6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U, - 6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U, - 6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U, - 6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U, - 6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U, - 7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U, - 7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U, - 7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U, - 7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U, - 7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U, - 7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U, - 7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U, - 7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U, - 7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U, - 7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U, - 7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U, - 7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U, - 7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U, - 7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U, - 7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U, - 7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U, - 7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U, - 7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U, - 7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U, - 7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U, - 7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U, - 7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U, - 7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U, - 7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U, - 8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U, - 8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U, - 8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U, - 8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U, - 8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U, - 8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U, - 8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U, - 8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U, - 8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U, - 8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U, - 8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U, - 8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U, - 8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U, - 8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U, - 8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U, - 8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U, - 8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U, - 8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U, - 8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U, - 8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U, - 8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U, - 8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U, - 8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U, - 9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U, - 9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U, - 9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U, - 9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U, - 9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U, - 9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U, - 9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U, - 9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U, - 9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U, - 9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U, - 9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U, - 9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U, - 9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U, - 9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U, - 9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U, - 9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U, - 9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U, - 9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U, - 9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U, - 9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U, - 9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U, - 9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U, - 9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U, - 9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U, - 10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U, - 10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U, - 10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U, - 10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U, - 10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U, - 10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U, - 10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U, - 10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U, - 10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U, - 10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U, - 10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U, - 10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U, - 10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U, - 10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U, - 10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U, - 10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U, - 10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U, - 10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U, - 10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U, - 10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U, - 10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U, - 10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U, - 10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U, - 10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U, - 11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U, - 11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U, - 11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U, - 11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U, - 11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U, - 11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U, - 11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U, - 11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U, - 11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U, - 11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U, - 11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U, - 11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U, - 11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U, - 11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U, - 11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U, - 11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U, - 11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U, - 11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U, - 11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U, - 11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U, - 11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U, - 11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U, - 11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U, - 11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U, - 12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U, - 12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U, - 12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U, - 12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U, - 12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U, - 12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U, - 12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U, - 12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U, - 12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U, - 12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U, - 12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U, - 12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U, - 12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U, - 12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U, - 12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U, - 12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U, - 12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U, - 12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U, - 12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U, - 12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U, - 12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U, - 12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U, - 12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U, - 12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U, - 13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U, - 13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U, - 13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U, - 13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U, - 13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U, - 13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U, - 13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U, - 13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U, - 13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U, - 13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U, - 13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U, - 13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U, - 13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U, - 13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U, - 13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U, - 13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U, - 13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U, - 13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U, - 13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U, - 13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U, - 13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U, - 13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U, - 13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U, - 13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U, - 14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U, - 14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U, - 14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U, - 14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U, - 14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U, - 14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U, - 14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U, - 14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U, - 14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U, - 14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U, - 14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U, - 14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U, - 14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U, - 14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U, - 14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U, - 14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U, - 14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U, - 14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U, - 14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U, - 14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U, - 14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U, - 14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U, - 14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U, - 14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U, - 15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U, - 15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U, - 15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U, - 15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U, - 15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U, - 15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U, - 15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U, - 15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U, - 15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U, - 15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U, - 15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U, - 15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U, - 15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U, - 15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U, - 15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U, - 15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U, - 15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U, - 15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U, - 15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U, - 15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U, - 15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U, - 15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U, - 15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U, - 16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U, - 16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U, - 16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U, - 16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U, - 16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U, - 16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U, - 16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U, - 16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U, - 16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U, - 16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U, - 16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U, - 16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U, - 16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U, - 16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U, - 16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U, - 16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U, - 16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U, - 16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U, - 16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U, - 16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U, - 16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U, - 16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U, - 16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U, - 16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U, - 17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U, - 17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U, - 17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U, - 17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U, - 17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U, - 17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U, - 17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U, - 17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U, - 17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U, - 17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U, - 17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U, - 17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U, - 17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U, - 17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U, - 17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U, - 17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U, - 17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U, - 17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U, - 17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U, - 17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U, - 17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U, - 17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U, - 17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U, - 17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U, - 18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U, - 18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U, - 18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U, - 18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U, - 18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U, - 18228444544U, 18236833408U, 18245220736U -}; - - -// Generated with the following Mathematica Code: - -// GetCacheSizes[n_] := Module[{ -// DataSetSizeBytesInit = 2^30, -// MixBytes = 128, -// DataSetGrowth = 2^23, -// HashBytes = 64, -// CacheMultiplier = 1024, -// j = 0}, -// Reap[ -// While[j < n, -// Module[{i = Floor[(DataSetSizeBytesInit + DataSetGrowth * j) / (CacheMultiplier * HashBytes)]}, -// While[! PrimeQ[i], i--]; -// Sow[i*HashBytes]; j++]]]][[2]][[1]] - -const uint64_t cache_sizes[2048] = { - 16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U, - 17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U, - 18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U, - 19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U, - 20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U, - 21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U, - 22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U, - 23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U, - 24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U, - 25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U, - 25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U, - 26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U, - 27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U, - 28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U, - 29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U, - 30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U, - 31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U, - 32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U, - 33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U, - 34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U, - 35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U, - 36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U, - 36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U, - 37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U, - 38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U, - 39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U, - 40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U, - 41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U, - 42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U, - 43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U, - 44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U, - 45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U, - 46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U, - 47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U, - 47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U, - 48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U, - 49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U, - 50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U, - 51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U, - 52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U, - 53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U, - 54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U, - 55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U, - 56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U, - 57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U, - 58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U, - 58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U, - 59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U, - 60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U, - 61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U, - 62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U, - 63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U, - 64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U, - 65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U, - 66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U, - 67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U, - 68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U, - 69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U, - 69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U, - 70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U, - 71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U, - 72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U, - 73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U, - 74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U, - 75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U, - 76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U, - 77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U, - 78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U, - 79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U, - 80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U, - 81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U, - 81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U, - 82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U, - 83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U, - 84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U, - 85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U, - 86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U, - 87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U, - 88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U, - 89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U, - 90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U, - 91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U, - 92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U, - 92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U, - 93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U, - 94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U, - 95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U, - 96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U, - 97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U, - 98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U, - 99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U, - 100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U, - 100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U, - 101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U, - 102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U, - 103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U, - 104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U, - 104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U, - 105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U, - 106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U, - 107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U, - 108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U, - 108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U, - 109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U, - 110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U, - 111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U, - 111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U, - 112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U, - 113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U, - 114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U, - 115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U, - 115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U, - 116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U, - 117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U, - 118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U, - 119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U, - 119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U, - 120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U, - 121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U, - 122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U, - 122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U, - 123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U, - 124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U, - 125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U, - 126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U, - 126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U, - 127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U, - 128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U, - 129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U, - 130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U, - 130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U, - 131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U, - 132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U, - 133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U, - 133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U, - 134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U, - 135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U, - 136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U, - 137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U, - 137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U, - 138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U, - 139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U, - 140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U, - 141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U, - 141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U, - 142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U, - 143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U, - 144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U, - 144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U, - 145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U, - 146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U, - 147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U, - 148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U, - 148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U, - 149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U, - 150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U, - 151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U, - 152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U, - 152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U, - 153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U, - 154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U, - 155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U, - 155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U, - 156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U, - 157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U, - 158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U, - 159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U, - 159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U, - 160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U, - 161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U, - 162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U, - 163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U, - 163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U, - 164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U, - 165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U, - 166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U, - 166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U, - 167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U, - 168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U, - 169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U, - 170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U, - 170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U, - 171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U, - 172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U, - 173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U, - 174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U, - 174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U, - 175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U, - 176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U, - 177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U, - 177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U, - 178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U, - 179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U, - 180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U, - 181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U, - 181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U, - 182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U, - 183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U, - 184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U, - 185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U, - 185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U, - 186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U, - 187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U, - 188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U, - 189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U, - 189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U, - 190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U, - 191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U, - 192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U, - 192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U, - 193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U, - 194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U, - 195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U, - 196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U, - 196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U, - 197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U, - 198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U, - 199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U, - 200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U, - 200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U, - 201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U, - 202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U, - 203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U, - 203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U, - 204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U, - 205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U, - 206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U, - 207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U, - 207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U, - 208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U, - 209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U, - 210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U, - 211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U, - 211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U, - 212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U, - 213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U, - 214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U, - 214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U, - 215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U, - 216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U, - 217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U, - 218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U, - 218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U, - 219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U, - 220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U, - 221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U, - 222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U, - 222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U, - 223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U, - 224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U, - 225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U, - 225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U, - 226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U, - 227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U, - 228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U, - 229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U, - 229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U, - 230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U, - 231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U, - 232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U, - 233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U, - 233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U, - 234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U, - 235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U, - 236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U, - 236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U, - 237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U, - 238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U, - 239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U, - 240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U, - 240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U, - 241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U, - 242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U, - 243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U, - 244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U, - 244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U, - 245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U, - 246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U, - 247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U, - 247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U, - 248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U, - 249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U, - 250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U, - 251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U, - 251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U, - 252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U, - 253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U, - 254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U, - 255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U, - 255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U, - 256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U, - 257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U, - 258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U, - 258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U, - 259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U, - 260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U, - 261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U, - 262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U, - 262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U, - 263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U, - 264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U, - 265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U, - 266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U, - 266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U, - 267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U, - 268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U, - 269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U, - 270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U, - 270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U, - 271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U, - 272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U, - 273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U, - 273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U, - 274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U, - 275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U, - 276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U, - 277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U, - 277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U, - 278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U, - 279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U, - 280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U, - 281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U, - 281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U, - 282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U, - 283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U, - 284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U, - 284950208U, 285081536U -}; - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/endian.h b/contrib/ethereum/libethash/endian.h deleted file mode 100644 index 6ca6cc03..00000000 --- a/contrib/ethereum/libethash/endian.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include -#include "compiler.h" - -#if defined(__MINGW32__) || defined(_WIN32) - # define LITTLE_ENDIAN 1234 - # define BYTE_ORDER LITTLE_ENDIAN -#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) - # include -#elif defined(__OpenBSD__) || defined(__SVR4) - # include -#elif defined(__APPLE__) -# include -#elif defined( BSD ) && (BSD >= 199103) - # include -#elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ ) - # define LITTLE_ENDIAN 1234 - # define BYTE_ORDER LITTLE_ENDIAN -#elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ ) - # define BIG_ENDIAN 1234 - # define BYTE_ORDER BIG_ENDIAN -#else -# include -#endif - -#if defined(_WIN32) -#include -#define ethash_swap_u32(input_) _byteswap_ulong(input_) -#define ethash_swap_u64(input_) _byteswap_uint64(input_) -#elif defined(__APPLE__) -#include -#define ethash_swap_u32(input_) OSSwapInt32(input_) -#define ethash_swap_u64(input_) OSSwapInt64(input_) -#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) -#define ethash_swap_u32(input_) bswap32(input_) -#define ethash_swap_u64(input_) bswap64(input_) -#else // posix -#include -#define ethash_swap_u32(input_) __bswap_32(input_) -#define ethash_swap_u64(input_) __bswap_64(input_) -#endif - - -#if LITTLE_ENDIAN == BYTE_ORDER - -#define fix_endian32(dst_ ,src_) dst_ = src_ -#define fix_endian32_same(val_) -#define fix_endian64(dst_, src_) dst_ = src_ -#define fix_endian64_same(val_) -#define fix_endian_arr32(arr_, size_) -#define fix_endian_arr64(arr_, size_) - -#elif BIG_ENDIAN == BYTE_ORDER - -#define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_) -#define fix_endian32_same(val_) val_ = ethash_swap_u32(val_) -#define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_ -#define fix_endian64_same(val_) val_ = ethash_swap_u64(val_) -#define fix_endian_arr32(arr_, size_) \ - do { \ - for (unsigned i_ = 0; i_ < (size_), ++i_) { \ - arr_[i_] = ethash_swap_u32(arr_[i_]); \ - } \ - while (0) -#define fix_endian_arr64(arr_, size_) \ - do { \ - for (unsigned i_ = 0; i_ < (size_), ++i_) { \ - arr_[i_] = ethash_swap_u64(arr_[i_]); \ - } \ - while (0) \ - -#else -# error "endian not supported" -#endif // BYTE_ORDER diff --git a/contrib/ethereum/libethash/endianness.hpp b/contrib/ethereum/libethash/endianness.hpp new file mode 100644 index 00000000..34724778 --- /dev/null +++ b/contrib/ethereum/libethash/endianness.hpp @@ -0,0 +1,98 @@ +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +/// @file +/// This file contains helper functions to handle big-endian architectures. +/// The Ethash algorithm is naturally defined for little-endian architectures +/// so for those the helpers are just no-op empty functions. +/// For big-endian architectures we need 32-bit and 64-bit byte swapping in +/// some places. + +#pragma once + +#include + +#if _WIN32 + +#include + +#define bswap32 _byteswap_ulong +#define bswap64 _byteswap_uint64 + +// On Windows assume little endian. +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __BYTE_ORDER __LITTLE_ENDIAN + +#elif __APPLE__ + +#include + +#define bswap32 __builtin_bswap32 +#define bswap64 __builtin_bswap64 + +#else + +#include + +#define bswap32 __builtin_bswap32 +#define bswap64 __builtin_bswap64 + +#endif + +namespace ethash +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + +struct le +{ + static uint32_t uint32(uint32_t x) noexcept { return x; } + static uint64_t uint64(uint64_t x) noexcept { return x; } + + static const hash1024& uint32s(const hash1024& h) noexcept { return h; } + static const hash512& uint32s(const hash512& h) noexcept { return h; } + static const hash256& uint32s(const hash256& h) noexcept { return h; } +}; + +struct be +{ + static uint64_t uint64(uint64_t x) noexcept { return bswap64(x); } +}; + + +#elif __BYTE_ORDER == __BIG_ENDIAN + +struct le +{ + static uint32_t uint32(uint32_t x) noexcept { return bswap32(x); } + static uint64_t uint64(uint64_t x) noexcept { return bswap64(x); } + + static hash1024 uint32s(hash1024 h) noexcept + { + for (auto& w : h.word32s) + w = uint32(w); + return h; + } + + static hash512 uint32s(hash512 h) noexcept + { + for (auto& w : h.word32s) + w = uint32(w); + return h; + } + + static hash256 uint32s(hash256 h) noexcept + { + for (auto& w : h.word32s) + w = uint32(w); + return h; + } +}; + +struct be +{ + static uint64_t uint64(uint64_t x) noexcept { return x; } +}; + +#endif +} // namespace ethash \ No newline at end of file diff --git a/contrib/ethereum/libethash/ethash-internal.hpp b/contrib/ethereum/libethash/ethash-internal.hpp new file mode 100644 index 00000000..96209bd1 --- /dev/null +++ b/contrib/ethereum/libethash/ethash-internal.hpp @@ -0,0 +1,69 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +/// @file +/// Contains declarations of internal ethash functions to allow them to be +/// unit-tested. + +#pragma once + +#include + +#include "endianness.hpp" + +#include +#include + +extern "C" struct ethash_epoch_context_full : ethash_epoch_context +{ + ethash_hash1024* full_dataset; + + constexpr ethash_epoch_context_full(int epoch_number, int light_cache_num_items, + const ethash_hash512* light_cache, const uint32_t* l1_cache, int full_dataset_num_items, + ethash_hash1024* full_dataset) noexcept + : ethash_epoch_context{epoch_number, light_cache_num_items, light_cache, l1_cache, + full_dataset_num_items}, + full_dataset{full_dataset} + {} +}; + +namespace ethash +{ +inline bool is_less_or_equal(const hash256& a, const hash256& b) noexcept +{ + for (size_t i = 0; i < (sizeof(a) / sizeof(a.word64s[0])); ++i) + { + if (be::uint64(a.word64s[i]) > be::uint64(b.word64s[i])) + return false; + if (be::uint64(a.word64s[i]) < be::uint64(b.word64s[i])) + return true; + } + return true; +} + +inline bool is_equal(const hash256& a, const hash256& b) noexcept +{ + return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0; +} + +void build_light_cache(hash512 cache[], int num_items, const hash256& seed) noexcept; + +hash512 calculate_dataset_item_512(const epoch_context& context, int64_t index) noexcept; +hash1024 calculate_dataset_item_1024(const epoch_context& context, uint32_t index) noexcept; +hash2048 calculate_dataset_item_2048(const epoch_context& context, uint32_t index) noexcept; + +namespace generic +{ +using hash_fn_512 = hash512 (*)(const uint8_t* data, size_t size); +using build_light_cache_fn = void (*)(hash512 cache[], int num_items, const hash256& seed); + +void build_light_cache( + hash_fn_512 hash_fn, hash512 cache[], int num_items, const hash256& seed) noexcept; + +epoch_context_full* create_epoch_context( + build_light_cache_fn build_fn, int epoch_number, bool full) noexcept; + +} // namespace generic + +} // namespace ethash diff --git a/contrib/ethereum/libethash/ethash.cpp b/contrib/ethereum/libethash/ethash.cpp new file mode 100644 index 00000000..f12faab7 --- /dev/null +++ b/contrib/ethereum/libethash/ethash.cpp @@ -0,0 +1,441 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +#include "ethash-internal.hpp" + +#include "bit_manipulation.h" +#include "endianness.hpp" +#include "primes.h" +#include "support/attributes.h" +#include +#include + +#include +#include +#include +#include + +namespace ethash +{ +// Internal constants: +constexpr static int light_cache_init_size = 1 << 24; +constexpr static int light_cache_growth = 1 << 17; +constexpr static int light_cache_rounds = 3; +constexpr static int full_dataset_init_size = 1 << 30; +constexpr static int full_dataset_growth = 1 << 23; +constexpr static int full_dataset_item_parents = 256; + +// Verify constants: +static_assert(sizeof(hash512) == ETHASH_LIGHT_CACHE_ITEM_SIZE, ""); +static_assert(sizeof(hash1024) == ETHASH_FULL_DATASET_ITEM_SIZE, ""); +static_assert(light_cache_item_size == ETHASH_LIGHT_CACHE_ITEM_SIZE, ""); +static_assert(full_dataset_item_size == ETHASH_FULL_DATASET_ITEM_SIZE, ""); + + +namespace +{ +using ::fnv1; + +inline hash512 fnv1(const hash512& u, const hash512& v) noexcept +{ + hash512 r; + for (size_t i = 0; i < sizeof(r) / sizeof(r.word32s[0]); ++i) + r.word32s[i] = fnv1(u.word32s[i], v.word32s[i]); + return r; +} + +inline hash512 bitwise_xor(const hash512& x, const hash512& y) noexcept +{ + hash512 z; + for (size_t i = 0; i < sizeof(z) / sizeof(z.word64s[0]); ++i) + z.word64s[i] = x.word64s[i] ^ y.word64s[i]; + return z; +} +} // namespace + +int find_epoch_number(const hash256& seed) noexcept +{ + static constexpr int num_tries = 30000; // Divisible by 16. + + // Thread-local cache of the last search. + static thread_local int cached_epoch_number = 0; + static thread_local hash256 cached_seed = {}; + + // Load from memory once (memory will be clobbered by keccak256()). + const uint32_t seed_part = seed.word32s[0]; + const int e = cached_epoch_number; + hash256 s = cached_seed; + + if (s.word32s[0] == seed_part) + return e; + + // Try the next seed, will match for sequential epoch access. + s = keccak256(s); + if (s.word32s[0] == seed_part) + { + cached_seed = s; + cached_epoch_number = e + 1; + return e + 1; + } + + // Search for matching seed starting from epoch 0. + s = {}; + for (int i = 0; i < num_tries; ++i) + { + if (s.word32s[0] == seed_part) + { + cached_seed = s; + cached_epoch_number = i; + return i; + } + + s = keccak256(s); + } + + return -1; +} + +namespace generic +{ +void build_light_cache( + hash_fn_512 hash_fn, hash512 cache[], int num_items, const hash256& seed) noexcept +{ + hash512 item = hash_fn(seed.bytes, sizeof(seed)); + cache[0] = item; + for (int i = 1; i < num_items; ++i) + { + item = hash_fn(item.bytes, sizeof(item)); + cache[i] = item; + } + + for (int q = 0; q < light_cache_rounds; ++q) + { + for (int i = 0; i < num_items; ++i) + { + const uint32_t index_limit = static_cast(num_items); + + // Fist index: 4 first bytes of the item as little-endian integer. + const uint32_t t = le::uint32(cache[i].word32s[0]); + const uint32_t v = t % index_limit; + + // Second index. + const uint32_t w = static_cast(num_items + (i - 1)) % index_limit; + + const hash512 x = bitwise_xor(cache[v], cache[w]); + cache[i] = hash_fn(x.bytes, sizeof(x)); + } + } +} + +epoch_context_full* create_epoch_context( + build_light_cache_fn build_fn, int epoch_number, bool full) noexcept +{ + static_assert(sizeof(epoch_context_full) < sizeof(hash512), "epoch_context too big"); + static constexpr size_t context_alloc_size = sizeof(hash512); + + const int light_cache_num_items = calculate_light_cache_num_items(epoch_number); + const int full_dataset_num_items = calculate_full_dataset_num_items(epoch_number); + const size_t light_cache_size = get_light_cache_size(light_cache_num_items); + const size_t full_dataset_size = + full ? static_cast(full_dataset_num_items) * sizeof(hash1024) : + progpow::l1_cache_size; + + const size_t alloc_size = context_alloc_size + light_cache_size + full_dataset_size; + + char* const alloc_data = static_cast(std::calloc(1, alloc_size)); + if (!alloc_data) + return nullptr; // Signal out-of-memory by returning null pointer. + + hash512* const light_cache = reinterpret_cast(alloc_data + context_alloc_size); + const hash256 epoch_seed = calculate_epoch_seed(epoch_number); + build_fn(light_cache, light_cache_num_items, epoch_seed); + + uint32_t* const l1_cache = + reinterpret_cast(alloc_data + context_alloc_size + light_cache_size); + + hash1024* full_dataset = full ? reinterpret_cast(l1_cache) : nullptr; + + epoch_context_full* const context = new (alloc_data) epoch_context_full{ + epoch_number, + light_cache_num_items, + light_cache, + l1_cache, + full_dataset_num_items, + full_dataset, + }; + + auto* full_dataset_2048 = reinterpret_cast(l1_cache); + for (uint32_t i = 0; i < progpow::l1_cache_size / sizeof(full_dataset_2048[0]); ++i) + full_dataset_2048[i] = calculate_dataset_item_2048(*context, i); + return context; +} +} // namespace generic + +void build_light_cache(hash512 cache[], int num_items, const hash256& seed) noexcept +{ + return generic::build_light_cache(keccak512, cache, num_items, seed); +} + +struct item_state +{ + const hash512* const cache; + const int64_t num_cache_items; + const uint32_t seed; + + hash512 mix; + + ALWAYS_INLINE item_state(const epoch_context& context, int64_t index) noexcept + : cache{context.light_cache}, + num_cache_items{context.light_cache_num_items}, + seed{static_cast(index)} + { + mix = cache[index % num_cache_items]; + mix.word32s[0] ^= le::uint32(seed); + mix = le::uint32s(keccak512(mix)); + } + + ALWAYS_INLINE void update(uint32_t round) noexcept + { + static constexpr size_t num_words = sizeof(mix) / sizeof(uint32_t); + const uint32_t t = fnv1(seed ^ round, mix.word32s[round % num_words]); + const int64_t parent_index = t % num_cache_items; + mix = fnv1(mix, le::uint32s(cache[parent_index])); + } + + ALWAYS_INLINE hash512 final() noexcept { return keccak512(le::uint32s(mix)); } +}; + +hash512 calculate_dataset_item_512(const epoch_context& context, int64_t index) noexcept +{ + item_state item0{context, index}; + for (uint32_t j = 0; j < full_dataset_item_parents; ++j) + item0.update(j); + return item0.final(); +} + +/// Calculates a full dataset item +/// +/// This consist of two 512-bit items produced by calculate_dataset_item_partial(). +/// Here the computation is done interleaved for better performance. +hash1024 calculate_dataset_item_1024(const epoch_context& context, uint32_t index) noexcept +{ + item_state item0{context, int64_t(index) * 2}; + item_state item1{context, int64_t(index) * 2 + 1}; + + for (uint32_t j = 0; j < full_dataset_item_parents; ++j) + { + item0.update(j); + item1.update(j); + } + + return hash1024{{item0.final(), item1.final()}}; +} + +hash2048 calculate_dataset_item_2048(const epoch_context& context, uint32_t index) noexcept +{ + item_state item0{context, int64_t(index) * 4}; + item_state item1{context, int64_t(index) * 4 + 1}; + item_state item2{context, int64_t(index) * 4 + 2}; + item_state item3{context, int64_t(index) * 4 + 3}; + + for (uint32_t j = 0; j < full_dataset_item_parents; ++j) + { + item0.update(j); + item1.update(j); + item2.update(j); + item3.update(j); + } + + return hash2048{{item0.final(), item1.final(), item2.final(), item3.final()}}; +} + +namespace +{ +using lookup_fn = hash1024 (*)(const epoch_context&, uint32_t); + +inline hash512 hash_seed(const hash256& header_hash, uint64_t nonce) noexcept +{ + nonce = le::uint64(nonce); + uint8_t init_data[sizeof(header_hash) + sizeof(nonce)]; + std::memcpy(&init_data[0], &header_hash, sizeof(header_hash)); + std::memcpy(&init_data[sizeof(header_hash)], &nonce, sizeof(nonce)); + + return keccak512(init_data, sizeof(init_data)); +} + +inline hash256 hash_final(const hash512& seed, const hash256& mix_hash) +{ + uint8_t final_data[sizeof(seed) + sizeof(mix_hash)]; + std::memcpy(&final_data[0], seed.bytes, sizeof(seed)); + std::memcpy(&final_data[sizeof(seed)], mix_hash.bytes, sizeof(mix_hash)); + return keccak256(final_data, sizeof(final_data)); +} + +inline hash256 hash_kernel( + const epoch_context& context, const hash512& seed, lookup_fn lookup) noexcept +{ + static constexpr size_t num_words = sizeof(hash1024) / sizeof(uint32_t); + const uint32_t index_limit = static_cast(context.full_dataset_num_items); + const uint32_t seed_init = le::uint32(seed.word32s[0]); + + hash1024 mix{{le::uint32s(seed), le::uint32s(seed)}}; + + for (uint32_t i = 0; i < num_dataset_accesses; ++i) + { + const uint32_t p = fnv1(i ^ seed_init, mix.word32s[i % num_words]) % index_limit; + const hash1024 newdata = le::uint32s(lookup(context, p)); + + for (size_t j = 0; j < num_words; ++j) + mix.word32s[j] = fnv1(mix.word32s[j], newdata.word32s[j]); + } + + hash256 mix_hash; + for (size_t i = 0; i < num_words; i += 4) + { + const uint32_t h1 = fnv1(mix.word32s[i], mix.word32s[i + 1]); + const uint32_t h2 = fnv1(h1, mix.word32s[i + 2]); + const uint32_t h3 = fnv1(h2, mix.word32s[i + 3]); + mix_hash.word32s[i / 4] = h3; + } + + return le::uint32s(mix_hash); +} +} // namespace + +result hash(const epoch_context& context, const hash256& header_hash, uint64_t nonce) noexcept +{ + const hash512 seed = hash_seed(header_hash, nonce); + const hash256 mix_hash = hash_kernel(context, seed, calculate_dataset_item_1024); + return {hash_final(seed, mix_hash), mix_hash}; +} + +result hash(const epoch_context_full& context, const hash256& header_hash, uint64_t nonce) noexcept +{ + static const auto lazy_lookup = [](const epoch_context& context, uint32_t index) noexcept + { + auto full_dataset = static_cast(context).full_dataset; + hash1024& item = full_dataset[index]; + if (item.word64s[0] == 0) + { + // TODO: Copy elision here makes it thread-safe? + item = calculate_dataset_item_1024(context, index); + } + + return item; + }; + + const hash512 seed = hash_seed(header_hash, nonce); + const hash256 mix_hash = hash_kernel(context, seed, lazy_lookup); + return {hash_final(seed, mix_hash), mix_hash}; +} + +bool verify_final_hash(const hash256& header_hash, const hash256& mix_hash, uint64_t nonce, + const hash256& boundary) noexcept +{ + const hash512 seed = hash_seed(header_hash, nonce); + return is_less_or_equal(hash_final(seed, mix_hash), boundary); +} + +bool verify(const epoch_context& context, const hash256& header_hash, const hash256& mix_hash, + uint64_t nonce, const hash256& boundary) noexcept +{ + const hash512 seed = hash_seed(header_hash, nonce); + if (!is_less_or_equal(hash_final(seed, mix_hash), boundary)) + return false; + + const hash256 expected_mix_hash = hash_kernel(context, seed, calculate_dataset_item_1024); + return is_equal(expected_mix_hash, mix_hash); +} + +search_result search_light(const epoch_context& context, const hash256& header_hash, + const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept +{ + const uint64_t end_nonce = start_nonce + iterations; + for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce) + { + result r = hash(context, header_hash, nonce); + if (is_less_or_equal(r.final_hash, boundary)) + return {r, nonce}; + } + return {}; +} + +search_result search(const epoch_context_full& context, const hash256& header_hash, + const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept +{ + const uint64_t end_nonce = start_nonce + iterations; + for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce) + { + result r = hash(context, header_hash, nonce); + if (is_less_or_equal(r.final_hash, boundary)) + return {r, nonce}; + } + return {}; +} +} // namespace ethash + +using namespace ethash; + +extern "C" { + +ethash_hash256 ethash_calculate_epoch_seed(int epoch_number) noexcept +{ + ethash_hash256 epoch_seed = {}; + for (int i = 0; i < epoch_number; ++i) + epoch_seed = ethash_keccak256_32(epoch_seed.bytes); + return epoch_seed; +} + +int ethash_calculate_light_cache_num_items(int epoch_number) noexcept +{ + static constexpr int item_size = sizeof(hash512); + static constexpr int num_items_init = light_cache_init_size / item_size; + static constexpr int num_items_growth = light_cache_growth / item_size; + static_assert( + light_cache_init_size % item_size == 0, "light_cache_init_size not multiple of item size"); + static_assert( + light_cache_growth % item_size == 0, "light_cache_growth not multiple of item size"); + + int num_items_upper_bound = num_items_init + epoch_number * num_items_growth; + int num_items = ethash_find_largest_prime(num_items_upper_bound); + return num_items; +} + +int ethash_calculate_full_dataset_num_items(int epoch_number) noexcept +{ + static constexpr int item_size = sizeof(hash1024); + static constexpr int num_items_init = full_dataset_init_size / item_size; + static constexpr int num_items_growth = full_dataset_growth / item_size; + static_assert(full_dataset_init_size % item_size == 0, + "full_dataset_init_size not multiple of item size"); + static_assert( + full_dataset_growth % item_size == 0, "full_dataset_growth not multiple of item size"); + + int num_items_upper_bound = num_items_init + epoch_number * num_items_growth; + int num_items = ethash_find_largest_prime(num_items_upper_bound); + return num_items; +} + +epoch_context* ethash_create_epoch_context(int epoch_number) noexcept +{ + return generic::create_epoch_context(build_light_cache, epoch_number, false); +} + +epoch_context_full* ethash_create_epoch_context_full(int epoch_number) noexcept +{ + return generic::create_epoch_context(build_light_cache, epoch_number, true); +} + +void ethash_destroy_epoch_context_full(epoch_context_full* context) noexcept +{ + ethash_destroy_epoch_context(context); +} + +void ethash_destroy_epoch_context(epoch_context* context) noexcept +{ + context->~epoch_context(); + std::free(context); +} + +} // extern "C" diff --git a/contrib/ethereum/libethash/ethash.h b/contrib/ethereum/libethash/ethash.h deleted file mode 100644 index f54f6348..00000000 --- a/contrib/ethereum/libethash/ethash.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ - -/** @file ethash.h -* @date 2015 -*/ -#pragma once - -#include -#include -#include -#include -#include "compiler.h" - -#define ETHASH_REVISION 23 -#define ETHASH_DATASET_BYTES_INIT 1073741824U // 2**30 -#define ETHASH_DATASET_BYTES_GROWTH 8388608U // 2**23 -#define ETHASH_CACHE_BYTES_INIT 1073741824U // 2**24 -#define ETHASH_CACHE_BYTES_GROWTH 131072U // 2**17 -#define ETHASH_EPOCH_LENGTH 30000U -#define ETHASH_MIX_BYTES 128 -#define ETHASH_HASH_BYTES 64 -#define ETHASH_DATASET_PARENTS 256 -#define ETHASH_CACHE_ROUNDS 3 -#define ETHASH_ACCESSES 64 -#define ETHASH_DAG_MAGIC_NUM_SIZE 8 -#define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE - -#ifdef __cplusplus -extern "C" { -#endif - -/// Type of a seedhash/blockhash e.t.c. -typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t; - -// convenience macro to statically initialize an h256_t -// usage: -// ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... ) -// have to provide all 32 values. If you don't provide all the rest -// will simply be unitialized (not guranteed to be 0) -#define ethash_h256_static_init(...) \ - { {__VA_ARGS__} } - -struct ethash_light; -typedef struct ethash_light* ethash_light_t; -struct ethash_full; -typedef struct ethash_full* ethash_full_t; -typedef int(*ethash_callback_t)(unsigned); - -typedef struct ethash_return_value { - ethash_h256_t result; - ethash_h256_t mix_hash; - bool success; -} ethash_return_value_t; - -/** - * Allocate and initialize a new ethash_light handler - * - * @param block_number The block number for which to create the handler - * @return Newly allocated ethash_light handler or NULL in case of - * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes() - */ -ethash_light_t ethash_light_new(uint64_t block_number); - -/** - * The same as @ref ethash_light_new but with file cache support. The data is read from cache file (if exists) - * or being generated and dumped to the cache file. - * - * @param block_number The block number for which to create the handler - * @param dir_name The directory where a file with cached data is located. - * @return Newly allocated ethash_light handler or NULL in case of error - */ -ethash_light_t ethash_light_filecached(uint64_t block_number, const char* dir_name); - -/** - * Frees a previously allocated ethash_light handler - * @param light The light handler to free - */ -void ethash_light_delete(ethash_light_t light); -/** - * Calculate the light client data - * - * @param light The light client handler - * @param header_hash The header hash to pack into the mix - * @param nonce The nonce to pack into the mix - * @return an object of ethash_return_value_t holding the return values - */ -ethash_return_value_t ethash_light_compute( - ethash_light_t light, - ethash_h256_t const header_hash, - uint64_t nonce -); - -/** - * Allocate and initialize a new ethash_full handler - * - * @param light The light handler containing the cache. - * @param callback A callback function with signature of @ref ethash_callback_t - * It accepts an unsigned with which a progress of DAG calculation - * can be displayed. If all goes well the callback should return 0. - * If a non-zero value is returned then DAG generation will stop. - * Be advised. A progress value of 100 means that DAG creation is - * almost complete and that this function will soon return succesfully. - * It does not mean that the function has already had a succesfull return. - * @return Newly allocated ethash_full handler or NULL in case of - * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data() - */ -ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback); - -/** - * Frees a previously allocated ethash_full handler - * @param full The light handler to free - */ -void ethash_full_delete(ethash_full_t full); -/** - * Calculate the full client data - * - * @param full The full client handler - * @param header_hash The header hash to pack into the mix - * @param nonce The nonce to pack into the mix - * @return An object of ethash_return_value to hold the return value - */ -ethash_return_value_t ethash_full_compute( - ethash_full_t full, - ethash_h256_t const header_hash, - uint64_t nonce -); -/** - * Get a pointer to the full DAG data - */ -void const* ethash_full_dag(ethash_full_t full); -/** - * Get the size of the DAG data - */ -uint64_t ethash_full_dag_size(ethash_full_t full); - -/** - * Calculate the seedhash for a given block number - */ -ethash_h256_t ethash_get_seedhash(uint64_t block_number); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/ethash/ethash.h b/contrib/ethereum/libethash/ethash/ethash.h new file mode 100644 index 00000000..fbcd3c85 --- /dev/null +++ b/contrib/ethereum/libethash/ethash/ethash.h @@ -0,0 +1,93 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include + +#include + +#ifdef __cplusplus +#define NOEXCEPT noexcept +#else +#define NOEXCEPT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETHASH_EPOCH_LENGTH 30000 +#define ETHASH_LIGHT_CACHE_ITEM_SIZE 64 +#define ETHASH_FULL_DATASET_ITEM_SIZE 128 +#define ETHASH_NUM_DATASET_ACCESSES 64 + + +struct ethash_epoch_context +{ + const int epoch_number; + const int light_cache_num_items; + const union ethash_hash512* const light_cache; + const uint32_t* const l1_cache; + const int full_dataset_num_items; +}; + + +struct ethash_epoch_context_full; + + +/** + * Calculates the number of items in the light cache for given epoch. + * + * This function will search for a prime number matching the criteria given + * by the Ethash so the execution time is not constant. It takes ~ 0.01 ms. + * + * @param epoch_number The epoch number. + * @return The number items in the light cache. + */ +int ethash_calculate_light_cache_num_items(int epoch_number) NOEXCEPT; + + +/** + * Calculates the number of items in the full dataset for given epoch. + * + * This function will search for a prime number matching the criteria given + * by the Ethash so the execution time is not constant. It takes ~ 0.05 ms. + * + * @param epoch_number The epoch number. + * @return The number items in the full dataset. + */ +int ethash_calculate_full_dataset_num_items(int epoch_number) NOEXCEPT; + +/** + * Calculates the epoch seed hash. + * @param epoch_number The epoch number. + * @return The epoch seed hash. + */ +union ethash_hash256 ethash_calculate_epoch_seed(int epoch_number) NOEXCEPT; + + +struct ethash_epoch_context* ethash_create_epoch_context(int epoch_number) NOEXCEPT; + +/** + * Creates the epoch context with the full dataset initialized. + * + * The memory for the full dataset is only allocated and marked as "not-generated". + * The items of the full dataset are generated on the fly when hit for the first time. + * + * The memory allocated in the context MUST be freed with ethash_destroy_epoch_context_full(). + * + * @param epoch_number The epoch number. + * @return Pointer to the context or null in case of memory allocation failure. + */ +struct ethash_epoch_context_full* ethash_create_epoch_context_full(int epoch_number) NOEXCEPT; + +void ethash_destroy_epoch_context(struct ethash_epoch_context* context) NOEXCEPT; + +void ethash_destroy_epoch_context_full(struct ethash_epoch_context_full* context) NOEXCEPT; + +#ifdef __cplusplus +} +#endif diff --git a/contrib/ethereum/libethash/ethash/ethash.hpp b/contrib/ethereum/libethash/ethash/ethash.hpp new file mode 100644 index 00000000..532a8e4c --- /dev/null +++ b/contrib/ethereum/libethash/ethash/ethash.hpp @@ -0,0 +1,159 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +/// @file +/// +/// API design decisions: +/// +/// 1. Signed integer type is used whenever the size of the type is not +/// restricted by the Ethash specification. +/// See http://www.aristeia.com/Papers/C++ReportColumns/sep95.pdf. +/// See https://stackoverflow.com/questions/10168079/why-is-size-t-unsigned/. +/// See https://github.com/Microsoft/GSL/issues/171. + +#pragma once + +#include +#include +#include + +#include "ethash/ethash.h" +#include "ethash/hash_types.hpp" + + +namespace ethash +{ +static constexpr int epoch_length = ETHASH_EPOCH_LENGTH; +static constexpr int light_cache_item_size = ETHASH_LIGHT_CACHE_ITEM_SIZE; +static constexpr int full_dataset_item_size = ETHASH_FULL_DATASET_ITEM_SIZE; +static constexpr int num_dataset_accesses = ETHASH_NUM_DATASET_ACCESSES; + +using epoch_context = ethash_epoch_context; +using epoch_context_full = ethash_epoch_context_full; + +/// Constructs a 256-bit hash from an array of bytes. +/// +/// @param bytes A pointer to array of at least 32 bytes. +/// @return The constructed hash. +inline hash256 hash256_from_bytes(const uint8_t bytes[32]) noexcept +{ + hash256 h; + std::memcpy(&h, bytes, sizeof(h)); + return h; +} + +struct result +{ + hash256 final_hash; + hash256 mix_hash; +}; + +struct search_result +{ + bool solution_found = false; + uint64_t nonce = 0; + hash256 final_hash = {}; + hash256 mix_hash = {}; + + search_result() noexcept = default; + + search_result(result res, uint64_t nonce) noexcept + : solution_found(true), nonce(nonce), final_hash(res.final_hash), mix_hash(res.mix_hash) + {} +}; + + +/// Alias for ethash_calculate_light_cache_num_items(). +static constexpr auto calculate_light_cache_num_items = ethash_calculate_light_cache_num_items; + +/// Alias for ethash_calculate_full_dataset_num_items(). +static constexpr auto calculate_full_dataset_num_items = ethash_calculate_full_dataset_num_items; + +/// Alias for ethash_calculate_epoch_seed(). +static constexpr auto calculate_epoch_seed = ethash_calculate_epoch_seed; + + +/// Calculates the epoch number out of the block number. +inline constexpr int get_epoch_number(int block_number) noexcept +{ + return block_number / epoch_length; +} + +/** + * Coverts the number of items of a light cache to size in bytes. + * + * @param num_items The number of items in the light cache. + * @return The size of the light cache in bytes. + */ +inline constexpr size_t get_light_cache_size(int num_items) noexcept +{ + return static_cast(num_items) * light_cache_item_size; +} + +/** + * Coverts the number of items of a full dataset to size in bytes. + * + * @param num_items The number of items in the full dataset. + * @return The size of the full dataset in bytes. + */ +inline constexpr uint64_t get_full_dataset_size(int num_items) noexcept +{ + return static_cast(num_items) * full_dataset_item_size; +} + +/// Owned unique pointer to an epoch context. +using epoch_context_ptr = std::unique_ptr; + +using epoch_context_full_ptr = + std::unique_ptr; + +/// Creates Ethash epoch context. +/// +/// This is a wrapper for ethash_create_epoch_number C function that returns +/// the context as a smart pointer which handles the destruction of the context. +inline epoch_context_ptr create_epoch_context(int epoch_number) noexcept +{ + return {ethash_create_epoch_context(epoch_number), ethash_destroy_epoch_context}; +} + +inline epoch_context_full_ptr create_epoch_context_full(int epoch_number) noexcept +{ + return {ethash_create_epoch_context_full(epoch_number), ethash_destroy_epoch_context_full}; +} + + +result hash(const epoch_context& context, const hash256& header_hash, uint64_t nonce) noexcept; + +result hash(const epoch_context_full& context, const hash256& header_hash, uint64_t nonce) noexcept; + +bool verify_final_hash(const hash256& header_hash, const hash256& mix_hash, uint64_t nonce, + const hash256& boundary) noexcept; + +bool verify(const epoch_context& context, const hash256& header_hash, const hash256& mix_hash, + uint64_t nonce, const hash256& boundary) noexcept; + +search_result search_light(const epoch_context& context, const hash256& header_hash, + const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept; + +search_result search(const epoch_context_full& context, const hash256& header_hash, + const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept; + + +/// Tries to find the epoch number matching the given seed hash. +/// +/// Mining pool protocols (many variants of stratum and "getwork") send out +/// seed hash instead of epoch number to workers. This function tries to recover +/// the epoch number from this seed hash. +/// +/// @param seed Ethash seed hash. +/// @return The epoch number or -1 if not found. +int find_epoch_number(const hash256& seed) noexcept; + + +/// Get global shared epoch context. +const epoch_context& get_global_epoch_context(int epoch_number); + +/// Get global shared epoch context with full dataset initialized. +const epoch_context_full& get_global_epoch_context_full(int epoch_number); +} // namespace ethash diff --git a/contrib/ethereum/libethash/ethash/hash_types.h b/contrib/ethereum/libethash/ethash/hash_types.h new file mode 100644 index 00000000..108e141c --- /dev/null +++ b/contrib/ethereum/libethash/ethash/hash_types.h @@ -0,0 +1,46 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +union ethash_hash256 +{ + uint64_t word64s[4]; + uint32_t word32s[8]; + uint8_t bytes[32]; +}; + +union ethash_hash512 +{ + uint64_t word64s[8]; + uint32_t word32s[16]; + uint8_t bytes[64]; +}; + +union ethash_hash1024 +{ + union ethash_hash512 hash512s[2]; + uint64_t word64s[16]; + uint32_t word32s[32]; + uint8_t bytes[128]; +}; + +union ethash_hash2048 +{ + union ethash_hash512 hash512s[4]; + uint64_t word64s[32]; + uint32_t word32s[64]; + uint8_t bytes[256]; +}; + +#ifdef __cplusplus +} +#endif diff --git a/contrib/ethereum/libethash/ethash/hash_types.hpp b/contrib/ethereum/libethash/ethash/hash_types.hpp new file mode 100644 index 00000000..21027ba2 --- /dev/null +++ b/contrib/ethereum/libethash/ethash/hash_types.hpp @@ -0,0 +1,15 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +#pragma once + +#include "ethash/hash_types.h" + +namespace ethash +{ +using hash256 = ethash_hash256; +using hash512 = ethash_hash512; +using hash1024 = ethash_hash1024; +using hash2048 = ethash_hash2048; +} // namespace ethash diff --git a/contrib/ethereum/libethash/ethash/keccak.h b/contrib/ethereum/libethash/ethash/keccak.h new file mode 100644 index 00000000..e1414b84 --- /dev/null +++ b/contrib/ethereum/libethash/ethash/keccak.h @@ -0,0 +1,49 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include + +#include + +#ifdef __cplusplus +#define NOEXCEPT noexcept +#else +#define NOEXCEPT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The Keccak-f[1600] function. + * + * The implementation of the Keccak-f function with 1600-bit width of the permutation (b). + * The size of the state is also 1600 bit what gives 25 64-bit words. + * + * @param state The state of 25 64-bit words on which the permutation is to be performed. + */ +void ethash_keccakf1600(uint64_t state[25]) NOEXCEPT; + +/** + * The Keccak-f[800] function. + * + * The implementation of the Keccak-f function with 800-bit width of the permutation (b). + * The size of the state is also 800 bit what gives 25 32-bit words. + * + * @param state The state of 25 32-bit words on which the permutation is to be performed. + */ +void ethash_keccakf800(uint32_t state[25]) NOEXCEPT; + +union ethash_hash256 ethash_keccak256(const uint8_t* data, size_t size) NOEXCEPT; +union ethash_hash256 ethash_keccak256_32(const uint8_t data[32]) NOEXCEPT; +union ethash_hash512 ethash_keccak512(const uint8_t* data, size_t size) NOEXCEPT; +union ethash_hash512 ethash_keccak512_64(const uint8_t data[64]) NOEXCEPT; + +#ifdef __cplusplus +} +#endif diff --git a/contrib/ethereum/libethash/ethash/keccak.hpp b/contrib/ethereum/libethash/ethash/keccak.hpp new file mode 100644 index 00000000..9dbc6aaa --- /dev/null +++ b/contrib/ethereum/libethash/ethash/keccak.hpp @@ -0,0 +1,35 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +#pragma once + +#include +#include + +namespace ethash +{ +inline hash256 keccak256(const uint8_t* data, size_t size) noexcept +{ + return ethash_keccak256(data, size); +} + +inline hash256 keccak256(const hash256& input) noexcept +{ + return ethash_keccak256_32(input.bytes); +} + +inline hash512 keccak512(const uint8_t* data, size_t size) noexcept +{ + return ethash_keccak512(data, size); +} + +inline hash512 keccak512(const hash512& input) noexcept +{ + return ethash_keccak512_64(input.bytes); +} + +static constexpr auto keccak256_32 = ethash_keccak256_32; +static constexpr auto keccak512_64 = ethash_keccak512_64; + +} // namespace ethash diff --git a/contrib/ethereum/libethash/ethash/progpow.hpp b/contrib/ethereum/libethash/ethash/progpow.hpp new file mode 100644 index 00000000..8add7d4d --- /dev/null +++ b/contrib/ethereum/libethash/ethash/progpow.hpp @@ -0,0 +1,42 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +/// @file +/// +/// ProgPoW API +/// +/// This file provides the public API for ProgPoW as the Ethash API extension. + +#include + +namespace progpow +{ +using namespace ethash; // Include ethash namespace. + +constexpr int period_length = 50; +constexpr uint32_t num_regs = 32; +constexpr size_t num_lanes = 16; +constexpr int num_cache_accesses = 12; +constexpr int num_math_operations = 20; +constexpr size_t l1_cache_size = 16 * 1024; +constexpr size_t l1_cache_num_items = l1_cache_size / sizeof(uint32_t); + +result hash(const epoch_context& context, int block_number, const hash256& header_hash, + uint64_t nonce) noexcept; + +result hash(const epoch_context_full& context, int block_number, const hash256& header_hash, + uint64_t nonce) noexcept; + +bool verify(const epoch_context& context, int block_number, const hash256& header_hash, + const hash256& mix_hash, uint64_t nonce, const hash256& boundary) noexcept; + +search_result search_light(const epoch_context& context, int block_number, + const hash256& header_hash, const hash256& boundary, uint64_t start_nonce, + size_t iterations) noexcept; + +search_result search(const epoch_context_full& context, int block_number, + const hash256& header_hash, const hash256& boundary, uint64_t start_nonce, + size_t iterations) noexcept; + +} // namespace progpow diff --git a/contrib/ethereum/libethash/fnv.h b/contrib/ethereum/libethash/fnv.h deleted file mode 100644 index d23c4e24..00000000 --- a/contrib/ethereum/libethash/fnv.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file fnv.h -* @author Matthew Wampler-Doty -* @date 2015 -*/ - -#pragma once -#include -#include "compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FNV_PRIME 0x01000193 - -static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y) -{ - return x * FNV_PRIME ^ y; -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/internal.c b/contrib/ethereum/libethash/internal.c deleted file mode 100644 index 8f8aad2e..00000000 --- a/contrib/ethereum/libethash/internal.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file internal.c -* @author Tim Hughes -* @author Matthew Wampler-Doty -* @date 2015 -*/ - -#include -#include -#include -#include -#include -#include "mmap.h" -#include "ethash.h" -#include "fnv.h" -#include "endian.h" -#include "internal.h" -#include "data_sizes.h" -#include "io.h" - -#ifdef WITH_CRYPTOPP - -#include "sha3_cryptopp.h" - -#else -#include "sha3.h" -#endif // WITH_CRYPTOPP - -uint64_t ethash_get_datasize(uint64_t const block_number) -{ - assert(block_number / ETHASH_EPOCH_LENGTH < 2048); - return dag_sizes[block_number / ETHASH_EPOCH_LENGTH]; -} - -uint64_t ethash_get_cachesize(uint64_t const block_number) -{ - assert(block_number / ETHASH_EPOCH_LENGTH < 2048); - return cache_sizes[block_number / ETHASH_EPOCH_LENGTH]; -} - -// Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014) -// https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf -// SeqMemoHash(s, R, N) -static bool ethash_compute_cache_nodes( - node* const nodes, - uint64_t cache_size, - ethash_h256_t const* seed -) -{ - if (cache_size % sizeof(node) != 0) { - return false; - } - uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node)); - - SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32); - - for (uint32_t i = 1; i != num_nodes; ++i) { - SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64); - } - - for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) { - for (uint32_t i = 0; i != num_nodes; i++) { - uint32_t const idx = nodes[i].words[0] % num_nodes; - node data; - data = nodes[(num_nodes - 1 + i) % num_nodes]; - for (uint32_t w = 0; w != NODE_WORDS; ++w) { - data.words[w] ^= nodes[idx].words[w]; - } - SHA3_512(nodes[i].bytes, data.bytes, sizeof(data)); - } - } - - // now perform endian conversion - fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS); - return true; -} - -void ethash_calculate_dag_item( - node* const ret, - uint32_t node_index, - ethash_light_t const light -) -{ - uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node)); - node const* cache_nodes = (node const *) light->cache; - node const* init = &cache_nodes[node_index % num_parent_nodes]; - memcpy(ret, init, sizeof(node)); - ret->words[0] ^= node_index; - SHA3_512(ret->bytes, ret->bytes, sizeof(node)); -#if defined(_M_X64) && ENABLE_SSE - __m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME); - __m128i xmm0 = ret->xmm[0]; - __m128i xmm1 = ret->xmm[1]; - __m128i xmm2 = ret->xmm[2]; - __m128i xmm3 = ret->xmm[3]; -#elif defined(__MIC__) - __m512i const fnv_prime = _mm512_set1_epi32(FNV_PRIME); - __m512i zmm0 = ret->zmm[0]; -#endif - - for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) { - uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes; - node const *parent = &cache_nodes[parent_index]; - -#if defined(_M_X64) && ENABLE_SSE - { - xmm0 = _mm_mullo_epi32(xmm0, fnv_prime); - xmm1 = _mm_mullo_epi32(xmm1, fnv_prime); - xmm2 = _mm_mullo_epi32(xmm2, fnv_prime); - xmm3 = _mm_mullo_epi32(xmm3, fnv_prime); - xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]); - xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]); - xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]); - xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]); - - // have to write to ret as values are used to compute index - ret->xmm[0] = xmm0; - ret->xmm[1] = xmm1; - ret->xmm[2] = xmm2; - ret->xmm[3] = xmm3; - } - #elif defined(__MIC__) - { - zmm0 = _mm512_mullo_epi32(zmm0, fnv_prime); - - // have to write to ret as values are used to compute index - zmm0 = _mm512_xor_si512(zmm0, parent->zmm[0]); - ret->zmm[0] = zmm0; - } - #else - { - for (unsigned w = 0; w != NODE_WORDS; ++w) { - ret->words[w] = fnv_hash(ret->words[w], parent->words[w]); - } - } -#endif - } - SHA3_512(ret->bytes, ret->bytes, sizeof(node)); -} - -bool ethash_compute_full_data( - void* mem, - uint64_t full_size, - ethash_light_t const light, - ethash_callback_t callback -) -{ - if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 || - (full_size % sizeof(node)) != 0) { - return false; - } - uint32_t const max_n = (uint32_t)(full_size / sizeof(node)); - node* full_nodes = mem; - double const progress_change = 1.0f / max_n; - double progress = 0.0f; - // now compute full nodes - for (uint32_t n = 0; n != max_n; ++n) { - if (callback && - n % (max_n / 100) == 0 && - callback((unsigned int)(ceil(progress * 100.0f))) != 0) { - - return false; - } - progress += progress_change; - ethash_calculate_dag_item(&(full_nodes[n]), n, light); - } - return true; -} - -static bool ethash_hash( - ethash_return_value_t* ret, - node const* full_nodes, - ethash_light_t const light, - uint64_t full_size, - ethash_h256_t const header_hash, - uint64_t const nonce -) -{ - if (full_size % MIX_WORDS != 0) { - return false; - } - - // pack hash and nonce together into first 40 bytes of s_mix - assert(sizeof(node) * 8 == 512); - node s_mix[MIX_NODES + 1]; - memcpy(s_mix[0].bytes, &header_hash, 32); - fix_endian64(s_mix[0].double_words[4], nonce); - - // compute sha3-512 hash and replicate across mix - SHA3_512(s_mix->bytes, s_mix->bytes, 40); - fix_endian_arr32(s_mix[0].words, 16); - - node* const mix = s_mix + 1; - for (uint32_t w = 0; w != MIX_WORDS; ++w) { - mix->words[w] = s_mix[0].words[w % NODE_WORDS]; - } - - unsigned const page_size = sizeof(uint32_t) * MIX_WORDS; - unsigned const num_full_pages = (unsigned) (full_size / page_size); - - for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) { - uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages; - - for (unsigned n = 0; n != MIX_NODES; ++n) { - node const* dag_node; - if (full_nodes) { - dag_node = &full_nodes[MIX_NODES * index + n]; - } else { - node tmp_node; - ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light); - dag_node = &tmp_node; - } - -#if defined(_M_X64) && ENABLE_SSE - { - __m128i fnv_prime = _mm_set1_epi32(FNV_PRIME); - __m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]); - __m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]); - __m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]); - __m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]); - mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]); - mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]); - mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]); - mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]); - } - #elif defined(__MIC__) - { - // __m512i implementation via union - // Each vector register (zmm) can store sixteen 32-bit integer numbers - __m512i fnv_prime = _mm512_set1_epi32(FNV_PRIME); - __m512i zmm0 = _mm512_mullo_epi32(fnv_prime, mix[n].zmm[0]); - mix[n].zmm[0] = _mm512_xor_si512(zmm0, dag_node->zmm[0]); - } - #else - { - for (unsigned w = 0; w != NODE_WORDS; ++w) { - mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]); - } - } -#endif - } - - } - -// Workaround for a GCC regression which causes a bogus -Warray-bounds warning. -// The regression was introduced in GCC 4.8.4, fixed in GCC 5.0.0 and backported to GCC 4.9.3 but -// never to the GCC 4.8.x line. -// -// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273 -// -// This regression is affecting Debian Jesse (8.5) builds of cpp-ethereum (GCC 4.9.2) and also -// manifests in the doublethinkco armel v5 cross-builds, which use crosstool-ng and resulting -// in the use of GCC 4.8.4. The Tizen runtime wants an even older GLIBC version - the one from -// GCC 4.6.0! - -#if defined(__GNUC__) && (__GNUC__ < 5) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif // define (__GNUC__) - - // compress mix - for (uint32_t w = 0; w != MIX_WORDS; w += 4) { - uint32_t reduction = mix->words[w + 0]; - reduction = reduction * FNV_PRIME ^ mix->words[w + 1]; - reduction = reduction * FNV_PRIME ^ mix->words[w + 2]; - reduction = reduction * FNV_PRIME ^ mix->words[w + 3]; - mix->words[w / 4] = reduction; - } - -#if defined(__GNUC__) && (__GNUC__ < 5) -#pragma GCC diagnostic pop -#endif // define (__GNUC__) - - fix_endian_arr32(mix->words, MIX_WORDS / 4); - memcpy(&ret->mix_hash, mix->bytes, 32); - // final Keccak hash - SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix) - return true; -} - -void ethash_quick_hash( - ethash_h256_t* return_hash, - ethash_h256_t const* header_hash, - uint64_t const nonce, - ethash_h256_t const* mix_hash -) -{ - uint8_t buf[64 + 32]; - memcpy(buf, header_hash, 32); - fix_endian64_same(nonce); - memcpy(&(buf[32]), &nonce, 8); - SHA3_512(buf, buf, 40); - memcpy(&(buf[64]), mix_hash, 32); - SHA3_256(return_hash, buf, 64 + 32); -} - -ethash_h256_t ethash_get_seedhash(uint64_t block_number) -{ - ethash_h256_t ret; - ethash_h256_reset(&ret); - uint64_t const epochs = block_number / ETHASH_EPOCH_LENGTH; - for (uint32_t i = 0; i < epochs; ++i) - SHA3_256(&ret, (uint8_t*)&ret, 32); - return ret; -} - -bool ethash_quick_check_difficulty( - ethash_h256_t const* header_hash, - uint64_t const nonce, - ethash_h256_t const* mix_hash, - ethash_h256_t const* boundary -) -{ - - ethash_h256_t return_hash; - ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash); - return ethash_check_difficulty(&return_hash, boundary); -} - -ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed) -{ - struct ethash_light *ret; - ret = calloc(sizeof(*ret), 1); - if (!ret) { - return NULL; - } -#if defined(__MIC__) - ret->cache = _mm_malloc((size_t)cache_size, 64); -#else - ret->cache = malloc((size_t)cache_size); -#endif - if (!ret->cache) { - goto fail_free_light; - } - node* nodes = (node*)ret->cache; - if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) { - goto fail_free_cache_mem; - } - ret->cache_size = cache_size; - return ret; - -fail_free_cache_mem: -#if defined(__MIC__) - _mm_free(ret->cache); -#else - free(ret->cache); -#endif -fail_free_light: - free(ret); - return NULL; -} - -ethash_light_t ethash_light_new(uint64_t block_number) -{ - ethash_h256_t seedhash = ethash_get_seedhash(block_number); - ethash_light_t ret; - ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash); - ret->block_number = block_number; - return ret; -} - -ethash_light_t ethash_light_filecached(uint64_t block_number, const char* dir_name) -{ - ethash_h256_t seedhash = ethash_get_seedhash(block_number); - uint64_t size = ethash_get_cachesize(block_number); - ethash_light_t ret = NULL; - uint64_t first_8_bytes_of_seedhash = *(uint64_t*)(&seedhash); - - char filename[256] = { 0 }; - if (snprintf(filename, sizeof filename, "light-B%u-%016" PRIx64, block_number, first_8_bytes_of_seedhash) < 0) - { - ETHASH_CRITICAL("snprintf failed at " __FILE__ ":" __LINE__); - return NULL; - } - - char* fullname = ethash_io_create_filename(dir_name, filename, strlen(filename)); - if (!fullname) - { - ETHASH_CRITICAL("Could not create the light cache pathname at " __FILE__ ":" __LINE__); - return NULL; - } - - FILE* f = ethash_fopen(fullname, "rb+"); - if (f) - { - size_t found_size = 0; - if (!ethash_file_size(f, &found_size)) - { - ETHASH_CRITICAL("Could not query size of file: \"%s\" at " __FILE__ ":" __LINE__, fullname); - fclose(f); - free(fullname); - return NULL; - } - if (found_size != size) - { - ETHASH_CRITICAL("Incorrect file size: %u, expected: %u for \"%s\" at " __FILE__ ":" __LINE__, found_size, size, fullname); - fclose(f); - free(fullname); - return NULL; - } - - // allocate memmory and read the file - ret = calloc(sizeof(*ret), 1); - if (!ret) - { - ETHASH_CRITICAL("calloc failed at " __FILE__ ":" __LINE__); - fclose(f); - free(fullname); - return NULL; - } - - ret->cache_size = size; - ret->block_number = block_number; - ret->cache = malloc(size); - if (!ret->cache) - { - ETHASH_CRITICAL("malloc failed at " __FILE__ ":" __LINE__); - free(ret); - fclose(f); - free(fullname); - return NULL; - } - - size_t bytes_read = fread(ret->cache, 1, size, f); - if (bytes_read != size) - { - ETHASH_CRITICAL("fread failed: %u bytes read, while %u was expected, at " __FILE__ ":" __LINE__, bytes_read, size); - free(ret->cache); - free(ret); - fclose(f); - free(fullname); - return NULL; - } - - fclose(f); - free(fullname); - return ret; - } - - - // file not found, generate light cache - ret = ethash_light_new_internal(size, &seedhash); - ret->block_number = block_number; - - // and dump it to the file (failsafe code here, don't return NULL if smth goes wrong with the file) - f = fopen(fullname, "wb"); - if (f) - { - size_t bytes_written = fwrite(ret->cache, 1, size, f); - if (bytes_written != size) - ETHASH_CRITICAL("fwrite failed: %u bytes written while %u was expected at " __FILE__ ":" __LINE__, bytes_written, size); - fclose(f); - } - else - { - ETHASH_CRITICAL("cannot open file %s for writing, at " __FILE__ ":" __LINE__, fullname); - } - - free(fullname); - return ret; -} - -void ethash_light_delete(ethash_light_t light) -{ - if (light) - { - if (light->cache) { - free(light->cache); - } - free(light); - } -} - -ethash_return_value_t ethash_light_compute_internal( - ethash_light_t light, - uint64_t full_size, - ethash_h256_t const header_hash, - uint64_t nonce -) -{ - ethash_return_value_t ret; - ret.success = true; - if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) { - ret.success = false; - } - return ret; -} - -ethash_return_value_t ethash_light_compute( - ethash_light_t light, - ethash_h256_t const header_hash, - uint64_t nonce -) -{ - uint64_t full_size = ethash_get_datasize(light->block_number); - return ethash_light_compute_internal(light, full_size, header_hash, nonce); -} - -static bool ethash_mmap(struct ethash_full* ret, FILE* f) -{ - int fd; - char* mmapped_data; - errno = 0; - ret->file = f; - if ((fd = ethash_fileno(ret->file)) == -1) { - return false; - } - mmapped_data = mmap( - NULL, - (size_t)ret->file_size + ETHASH_DAG_MAGIC_NUM_SIZE, - PROT_READ | PROT_WRITE, - MAP_SHARED, - fd, - 0 - ); - if (mmapped_data == MAP_FAILED) { - return false; - } - ret->data = (node*)(mmapped_data + ETHASH_DAG_MAGIC_NUM_SIZE); - return true; -} - -ethash_full_t ethash_full_new_internal( - char const* dirname, - ethash_h256_t const seed_hash, - uint64_t full_size, - ethash_light_t const light, - ethash_callback_t callback -) -{ - struct ethash_full* ret; - FILE *f = NULL; - ret = calloc(sizeof(*ret), 1); - if (!ret) { - return NULL; - } - ret->file_size = (size_t)full_size; - switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) { - case ETHASH_IO_FAIL: - // ethash_io_prepare will do all ETHASH_CRITICAL() logging in fail case - goto fail_free_full; - case ETHASH_IO_MEMO_MATCH: - if (!ethash_mmap(ret, f)) { - ETHASH_CRITICAL("mmap failure()"); - goto fail_close_file; - } -#if defined(__MIC__) - node* tmp_nodes = _mm_malloc((size_t)full_size, 64); - //copy all nodes from ret->data - //mmapped_nodes are not aligned properly - uint32_t const countnodes = (uint32_t) ((size_t)ret->file_size / sizeof(node)); - //fprintf(stderr,"ethash_full_new_internal:countnodes:%d",countnodes); - for (uint32_t i = 1; i != countnodes; ++i) { - tmp_nodes[i] = ret->data[i]; - } - ret->data = tmp_nodes; -#endif - return ret; - case ETHASH_IO_MEMO_SIZE_MISMATCH: - // if a DAG of same filename but unexpected size is found, silently force new file creation - if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) { - ETHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size."); - goto fail_free_full; - } - // fallthrough to the mismatch case here, DO NOT go through match - case ETHASH_IO_MEMO_MISMATCH: - if (!ethash_mmap(ret, f)) { - ETHASH_CRITICAL("mmap failure()"); - goto fail_close_file; - } - break; - } - -#if defined(__MIC__) - ret->data = _mm_malloc((size_t)full_size, 64); -#endif - if (!ethash_compute_full_data(ret->data, full_size, light, callback)) { - ETHASH_CRITICAL("Failure at computing DAG data."); - goto fail_free_full_data; - } - - // after the DAG has been filled then we finalize it by writting the magic number at the beginning - if (fseek(f, 0, SEEK_SET) != 0) { - ETHASH_CRITICAL("Could not seek to DAG file start to write magic number."); - goto fail_free_full_data; - } - uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM; - if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { - ETHASH_CRITICAL("Could not write magic number to DAG's beginning."); - goto fail_free_full_data; - } - if (fflush(f) != 0) {// make sure the magic number IS there - ETHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?"); - goto fail_free_full_data; - } - return ret; - -fail_free_full_data: - // could check that munmap(..) == 0 but even if it did not can't really do anything here - munmap(ret->data, (size_t)full_size); -#if defined(__MIC__) - _mm_free(ret->data); -#endif -fail_close_file: - fclose(ret->file); -fail_free_full: - free(ret); - return NULL; -} - -ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback) -{ - char strbuf[256]; - if (!ethash_get_default_dirname(strbuf, 256)) { - return NULL; - } - uint64_t full_size = ethash_get_datasize(light->block_number); - ethash_h256_t seedhash = ethash_get_seedhash(light->block_number); - return ethash_full_new_internal(strbuf, seedhash, full_size, light, callback); -} - -void ethash_full_delete(ethash_full_t full) -{ - // could check that munmap(..) == 0 but even if it did not can't really do anything here - munmap(full->data, (size_t)full->file_size); - if (full->file) { - fclose(full->file); - } - free(full); -} - -ethash_return_value_t ethash_full_compute( - ethash_full_t full, - ethash_h256_t const header_hash, - uint64_t nonce -) -{ - ethash_return_value_t ret; - ret.success = true; - if (!ethash_hash( - &ret, - (node const*)full->data, - NULL, - full->file_size, - header_hash, - nonce)) { - ret.success = false; - } - return ret; -} - -void const* ethash_full_dag(ethash_full_t full) -{ - return full->data; -} - -uint64_t ethash_full_dag_size(ethash_full_t full) -{ - return full->file_size; -} diff --git a/contrib/ethereum/libethash/internal.h b/contrib/ethereum/libethash/internal.h deleted file mode 100644 index 35419c6a..00000000 --- a/contrib/ethereum/libethash/internal.h +++ /dev/null @@ -1,183 +0,0 @@ -#pragma once -#include "compiler.h" -#include "endian.h" -#include "ethash.h" -#include - -#define ENABLE_SSE 0 - -#if defined(_M_X64) && ENABLE_SSE -#include -#elif defined(__MIC__) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// compile time settings -#define NODE_WORDS (64/4) -#define MIX_WORDS (ETHASH_MIX_BYTES/4) -#define MIX_NODES (MIX_WORDS / NODE_WORDS) -#include - -typedef union node { - uint8_t bytes[NODE_WORDS * 4]; - uint32_t words[NODE_WORDS]; - uint64_t double_words[NODE_WORDS / 2]; - -#if defined(_M_X64) && ENABLE_SSE - __m128i xmm[NODE_WORDS/4]; -#elif defined(__MIC__) - __m512i zmm[NODE_WORDS/16]; -#endif - -} node; - -static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i) -{ - return hash->b[i]; -} - -static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v) -{ - hash->b[i] = v; -} - -static inline void ethash_h256_reset(ethash_h256_t* hash) -{ - memset(hash, 0, 32); -} - -// Returns if hash is less than or equal to boundary (2^256/difficulty) -static inline bool ethash_check_difficulty( - ethash_h256_t const* hash, - ethash_h256_t const* boundary -) -{ - // Boundary is big endian - for (int i = 0; i < 32; i++) { - if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) { - continue; - } - return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i); - } - return true; -} - -/** - * Difficulty quick check for POW preverification - * - * @param header_hash The hash of the header - * @param nonce The block's nonce - * @param mix_hash The mix digest hash - * @param boundary The boundary is defined as (2^256 / difficulty) - * @return true for succesful pre-verification and false otherwise - */ -bool ethash_quick_check_difficulty( - ethash_h256_t const* header_hash, - uint64_t const nonce, - ethash_h256_t const* mix_hash, - ethash_h256_t const* boundary -); - -struct ethash_light { - void* cache; - uint64_t cache_size; - uint64_t block_number; -}; - -/** - * Allocate and initialize a new ethash_light handler. Internal version - * - * @param cache_size The size of the cache in bytes - * @param seed Block seedhash to be used during the computation of the - * cache nodes - * @return Newly allocated ethash_light handler or NULL in case of - * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes() - */ -ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed); - -/** - * Calculate the light client data. Internal version. - * - * @param light The light client handler - * @param full_size The size of the full data in bytes. - * @param header_hash The header hash to pack into the mix - * @param nonce The nonce to pack into the mix - * @return The resulting hash. - */ -ethash_return_value_t ethash_light_compute_internal( - ethash_light_t light, - uint64_t full_size, - ethash_h256_t const header_hash, - uint64_t nonce -); - -struct ethash_full { - FILE* file; - uint64_t file_size; - node* data; -}; - -/** - * Allocate and initialize a new ethash_full handler. Internal version. - * - * @param dirname The directory in which to put the DAG file. - * @param seedhash The seed hash of the block. Used in the DAG file naming. - * @param full_size The size of the full data in bytes. - * @param cache A cache object to use that was allocated with @ref ethash_cache_new(). - * Iff this function succeeds the ethash_full_t will take memory - * memory ownership of the cache and free it at deletion. If - * not then the user still has to handle freeing of the cache himself. - * @param callback A callback function with signature of @ref ethash_callback_t - * It accepts an unsigned with which a progress of DAG calculation - * can be displayed. If all goes well the callback should return 0. - * If a non-zero value is returned then DAG generation will stop. - * @return Newly allocated ethash_full handler or NULL in case of - * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data() - */ -ethash_full_t ethash_full_new_internal( - char const* dirname, - ethash_h256_t const seed_hash, - uint64_t full_size, - ethash_light_t const light, - ethash_callback_t callback -); - -void ethash_calculate_dag_item( - node* const ret, - uint32_t node_index, - ethash_light_t const cache -); - -void ethash_quick_hash( - ethash_h256_t* return_hash, - ethash_h256_t const* header_hash, - const uint64_t nonce, - ethash_h256_t const* mix_hash -); - -uint64_t ethash_get_datasize(uint64_t const block_number); -uint64_t ethash_get_cachesize(uint64_t const block_number); - -/** - * Compute the memory data for a full node's memory - * - * @param mem A pointer to an ethash full's memory - * @param full_size The size of the full data in bytes - * @param cache A cache object to use in the calculation - * @param callback The callback function. Check @ref ethash_full_new() for details. - * @return true if all went fine and false for invalid parameters - */ -bool ethash_compute_full_data( - void* mem, - uint64_t full_size, - ethash_light_t const light, - ethash_callback_t callback -); - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/io.c b/contrib/ethereum/libethash/io.c deleted file mode 100644 index f4db477c..00000000 --- a/contrib/ethereum/libethash/io.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file io.c - * @author Lefteris Karapetsas - * @date 2015 - */ -#include "io.h" -#include -#include -#include - -enum ethash_io_rc ethash_io_prepare( - char const* dirname, - ethash_h256_t const seedhash, - FILE** output_file, - uint64_t file_size, - bool force_create -) -{ - char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE]; - enum ethash_io_rc ret = ETHASH_IO_FAIL; - // reset errno before io calls - errno = 0; - - // assert directory exists - if (!ethash_mkdir(dirname)) { - ETHASH_CRITICAL("Could not create the ethash directory"); - goto end; - } - - ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name); - char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name)); - if (!tmpfile) { - ETHASH_CRITICAL("Could not create the full DAG pathname"); - goto end; - } - - FILE *f; - if (!force_create) { - // try to open the file - f = ethash_fopen(tmpfile, "rb+"); - if (f) { - size_t found_size; - if (!ethash_file_size(f, &found_size)) { - fclose(f); - ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile); - goto free_memo; - } - if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) { - fclose(f); - ret = ETHASH_IO_MEMO_SIZE_MISMATCH; - goto free_memo; - } - // compare the magic number, no need to care about endianess since it's local - uint64_t magic_num; - if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { - // I/O error - fclose(f); - ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile); - ret = ETHASH_IO_MEMO_SIZE_MISMATCH; - goto free_memo; - } - if (magic_num != ETHASH_DAG_MAGIC_NUM) { - fclose(f); - ret = ETHASH_IO_MEMO_SIZE_MISMATCH; - goto free_memo; - } - ret = ETHASH_IO_MEMO_MATCH; - goto set_file; - } - } - - // file does not exist, will need to be created - f = ethash_fopen(tmpfile, "wb+"); - if (!f) { - ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile); - goto free_memo; - } - // make sure it's of the proper size - if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) { - fclose(f); - ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile); - goto free_memo; - } - if (fputc('\n', f) == EOF) { - fclose(f); - ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile); - goto free_memo; - } - if (fflush(f) != 0) { - fclose(f); - ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile); - goto free_memo; - } - ret = ETHASH_IO_MEMO_MISMATCH; - goto set_file; - - ret = ETHASH_IO_MEMO_MATCH; -set_file: - *output_file = f; -free_memo: - free(tmpfile); -end: - return ret; -} diff --git a/contrib/ethereum/libethash/io.h b/contrib/ethereum/libethash/io.h deleted file mode 100644 index 7a27089c..00000000 --- a/contrib/ethereum/libethash/io.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file io.h - * @author Lefteris Karapetsas - * @date 2015 - */ -#pragma once -#include -#include -#include -#include -#ifdef __cplusplus -#define __STDC_FORMAT_MACROS 1 -#endif -#include -#include "endian.h" -#include "ethash.h" - -#ifdef __cplusplus -extern "C" { -#endif -// Maximum size for mutable part of DAG file name -// 6 is for "full-R", the suffix of the filename -// 10 is for maximum number of digits of a uint32_t (for REVISION) -// 1 is for - and 16 is for the first 16 hex digits for first 8 bytes of -// the seedhash and last 1 is for the null terminating character -// Reference: https://github.com/ethereum/wiki/wiki/Ethash-DAG -#define DAG_MUTABLE_NAME_MAX_SIZE (6 + 10 + 1 + 16 + 1) -/// Possible return values of @see ethash_io_prepare -enum ethash_io_rc { - ETHASH_IO_FAIL = 0, ///< There has been an IO failure - ETHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong. - ETHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch - ETHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything -}; - -// small hack for windows. I don't feel I should use va_args and forward just -// to have this one function properly cross-platform abstracted -#if defined(_WIN32) && !defined(__GNUC__) -#define snprintf(...) sprintf_s(__VA_ARGS__) -#endif - -/** - * Logs a critical error in important parts of ethash. Should mostly help - * figure out what kind of problem (I/O, memory e.t.c.) causes a NULL - * ethash_full_t - */ -#ifdef ETHASH_PRINT_CRITICAL_OUTPUT -#define ETHASH_CRITICAL(...) \ - do \ - { \ - printf("ETHASH CRITICAL ERROR: "__VA_ARGS__); \ - printf("\n"); \ - fflush(stdout); \ - } while (0) -#else -#define ETHASH_CRITICAL(...) -#endif - -/** - * Prepares io for ethash - * - * Create the DAG directory and the DAG file if they don't exist. - * - * @param[in] dirname A null terminated c-string of the path of the ethash - * data directory. If it does not exist it's created. - * @param[in] seedhash The seedhash of the current block number, used in the - * naming of the file as can be seen from the spec at: - * https://github.com/ethereum/wiki/wiki/Ethash-DAG - * @param[out] output_file If there was no failure then this will point to an open - * file descriptor. User is responsible for closing it. - * In the case of memo match then the file is open on read - * mode, while on the case of mismatch a new file is created - * on write mode - * @param[in] file_size The size that the DAG file should have on disk - * @param[out] force_create If true then there is no check to see if the file - * already exists - * @return For possible return values @see enum ethash_io_rc - */ -enum ethash_io_rc ethash_io_prepare( - char const* dirname, - ethash_h256_t const seedhash, - FILE** output_file, - uint64_t file_size, - bool force_create -); - -/** - * An fopen wrapper for no-warnings crossplatform fopen. - * - * Msvc compiler considers fopen to be insecure and suggests to use their - * alternative. This is a wrapper for this alternative. Another way is to - * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does - * not sound like a good idea. - * - * @param file_name The path to the file to open - * @param mode Opening mode. Check fopen() - * @return The FILE* or NULL in failure - */ -FILE* ethash_fopen(char const* file_name, char const* mode); - -/** - * An strncat wrapper for no-warnings crossplatform strncat. - * - * Msvc compiler considers strncat to be insecure and suggests to use their - * alternative. This is a wrapper for this alternative. Another way is to - * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does - * not sound like a good idea. - * - * @param des Destination buffer - * @param dest_size Maximum size of the destination buffer. This is the - * extra argument for the MSVC secure strncat - * @param src Souce buffer - * @param count Number of bytes to copy from source - * @return If all is well returns the dest buffer. If there is an - * error returns NULL - */ -char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count); - -/** - * A cross-platform mkdir wrapper to create a directory or assert it's there - * - * @param dirname The full path of the directory to create - * @return true if the directory was created or if it already - * existed - */ -bool ethash_mkdir(char const* dirname); - -/** - * Get a file's size - * - * @param[in] f The open file stream whose size to get - * @param[out] size Pass a size_t by reference to contain the file size - * @return true in success and false if there was a failure - */ -bool ethash_file_size(FILE* f, size_t* ret_size); - -/** - * Get a file descriptor number from a FILE stream - * - * @param f The file stream whose fd to get - * @return Platform specific fd handler - */ -int ethash_fileno(FILE* f); - -/** - * Create the filename for the DAG. - * - * @param dirname The directory name in which the DAG file should reside - * If it does not end with a directory separator it is appended. - * @param filename The actual name of the file - * @param filename_length The length of the filename in bytes - * @return A char* containing the full name. User must deallocate. - */ -char* ethash_io_create_filename( - char const* dirname, - char const* filename, - size_t filename_length -); - -/** - * Gets the default directory name for the DAG depending on the system - * - * The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ethash-DAG - * - * @param[out] strbuf A string buffer of sufficient size to keep the - * null termninated string of the directory name - * @param[in] buffsize Size of @a strbuf in bytes - * @return true for success and false otherwise - */ -bool ethash_get_default_dirname(char* strbuf, size_t buffsize); - -static inline bool ethash_io_mutable_name( - uint32_t revision, - ethash_h256_t const* seed_hash, - char* output -) -{ - uint64_t hash = *((uint64_t*)seed_hash); -#if LITTLE_ENDIAN == BYTE_ORDER - hash = ethash_swap_u64(hash); -#endif - return snprintf(output, DAG_MUTABLE_NAME_MAX_SIZE, "full-R%u-%016" PRIx64, revision, hash) >= 0; -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/io_posix.c b/contrib/ethereum/libethash/io_posix.c deleted file mode 100644 index c9a17d84..00000000 --- a/contrib/ethereum/libethash/io_posix.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file io_posix.c - * @author Lefteris Karapetsas - * @date 2015 - */ - -#include "io.h" -#include -#include -#include -#include -#include -#include -#include -#include - -FILE* ethash_fopen(char const* file_name, char const* mode) -{ - return fopen(file_name, mode); -} - -char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count) -{ - return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL; -} - -bool ethash_mkdir(char const* dirname) -{ - int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - return rc != -1 || errno == EEXIST; -} - -int ethash_fileno(FILE *f) -{ - return fileno(f); -} - -char* ethash_io_create_filename( - char const* dirname, - char const* filename, - size_t filename_length -) -{ - size_t dirlen = strlen(dirname); - size_t dest_size = dirlen + filename_length + 1; - if (dirname[dirlen] != '/') { - dest_size += 1; - } - char* name = malloc(dest_size); - if (!name) { - return NULL; - } - - name[0] = '\0'; - ethash_strncat(name, dest_size, dirname, dirlen); - if (dirname[dirlen] != '/') { - ethash_strncat(name, dest_size, "/", 1); - } - ethash_strncat(name, dest_size, filename, filename_length); - return name; -} - -bool ethash_file_size(FILE* f, size_t* ret_size) -{ - struct stat st; - int fd; - if ((fd = fileno(f)) == -1 || fstat(fd, &st) != 0) { - return false; - } - *ret_size = st.st_size; - return true; -} - -bool ethash_get_default_dirname(char* strbuf, size_t buffsize) -{ - static const char dir_suffix[] = ".ethash/"; - strbuf[0] = '\0'; - char* home_dir = getenv("HOME"); - if (!home_dir || strlen(home_dir) == 0) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd) - home_dir = pwd->pw_dir; - } - - size_t len = strlen(home_dir); - if (!ethash_strncat(strbuf, buffsize, home_dir, len)) { - return false; - } - if (home_dir[len] != '/') { - if (!ethash_strncat(strbuf, buffsize, "/", 1)) { - return false; - } - } - return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix)); -} diff --git a/contrib/ethereum/libethash/io_win32.c b/contrib/ethereum/libethash/io_win32.c deleted file mode 100644 index d3719e32..00000000 --- a/contrib/ethereum/libethash/io_win32.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file io_win32.c - * @author Lefteris Karapetsas - * @date 2015 - */ - -#include "io.h" -#include -#include -#include -#include -#include -#include -#include "currency_core/currency_config.h" - -FILE* ethash_fopen(char const* file_name, char const* mode) -{ - FILE* f; - return fopen_s(&f, file_name, mode) == 0 ? f : NULL; -} - -char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count) -{ - return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL; -} - -bool ethash_mkdir(char const* dirname) -{ - int rc = _mkdir(dirname); - return rc != -1 || errno == EEXIST; -} - -int ethash_fileno(FILE* f) -{ - return _fileno(f); -} - -char* ethash_io_create_filename( - char const* dirname, - char const* filename, - size_t filename_length -) -{ - size_t dirlen = strlen(dirname); - size_t dest_size = dirlen + filename_length + 1; - if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') { - dest_size += 1; - } - char* name = malloc(dest_size); - if (!name) { - return NULL; - } - - name[0] = '\0'; - ethash_strncat(name, dest_size, dirname, dirlen); - if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') { - ethash_strncat(name, dest_size, "\\", 1); - } - ethash_strncat(name, dest_size, filename, filename_length); - return name; -} - -bool ethash_file_size(FILE* f, size_t* ret_size) -{ - struct _stat st; - int fd; - if ((fd = _fileno(f)) == -1 || _fstat(fd, &st) != 0) { - return false; - } - *ret_size = st.st_size; - return true; -} - -bool ethash_get_default_dirname(char* strbuf, size_t buffsize) -{ - static const char dir_suffix[] = CURRENCY_NAME_SHORT_BASE"\\"; - strbuf[0] = '\0'; - if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, (CHAR*)strbuf))) { - return false; - } - if (!ethash_strncat(strbuf, buffsize, "\\", 1)) { - return false; - } - - ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix)); - return true; -} diff --git a/contrib/ethereum/libethash/keccak.c b/contrib/ethereum/libethash/keccak.c new file mode 100644 index 00000000..4c0b4caa --- /dev/null +++ b/contrib/ethereum/libethash/keccak.c @@ -0,0 +1,123 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#include + +#include "support/attributes.h" +#include + +#if _WIN32 +/* On Windows assume little endian. */ +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __BYTE_ORDER __LITTLE_ENDIAN +#elif __APPLE__ +#include +#else +#include +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define to_le64(X) X +#else +#define to_le64(X) __builtin_bswap64(X) +#endif + + +/** Loads 64-bit integer from given memory location as little-endian number. */ +static INLINE ALWAYS_INLINE uint64_t load_le(const uint8_t* data) +{ + /* memcpy is the best way of expressing the intention. Every compiler will + optimize is to single load instruction if the target architecture + supports unaligned memory access (GCC and clang even in O0). + This is great trick because we are violating C/C++ memory alignment + restrictions with no performance penalty. */ + uint64_t word; + memcpy(&word, data, sizeof(word)); + return to_le64(word); +} + +static INLINE ALWAYS_INLINE void keccak( + uint64_t* out, size_t bits, const uint8_t* data, size_t size) +{ + static const size_t word_size = sizeof(uint64_t); + const size_t hash_size = bits / 8; + const size_t block_size = (1600 - bits * 2) / 8; + + size_t i; + uint64_t* state_iter; + uint64_t last_word = 0; + uint8_t* last_word_iter = (uint8_t*)&last_word; + + uint64_t state[25] = {0}; + + while (size >= block_size) + { + for (i = 0; i < (block_size / word_size); ++i) + { + state[i] ^= load_le(data); + data += word_size; + } + + ethash_keccakf1600(state); + + size -= block_size; + } + + state_iter = state; + + while (size >= word_size) + { + *state_iter ^= load_le(data); + ++state_iter; + data += word_size; + size -= word_size; + } + + while (size > 0) + { + *last_word_iter = *data; + ++last_word_iter; + ++data; + --size; + } + *last_word_iter = 0x01; + *state_iter ^= to_le64(last_word); + + state[(block_size / word_size) - 1] ^= 0x8000000000000000; + + ethash_keccakf1600(state); + + for (i = 0; i < (hash_size / word_size); ++i) + out[i] = to_le64(state[i]); +} + +union ethash_hash256 ethash_keccak256(const uint8_t* data, size_t size) +{ + union ethash_hash256 hash; + keccak(hash.word64s, 256, data, size); + return hash; +} + +union ethash_hash256 ethash_keccak256_32(const uint8_t data[32]) +{ + union ethash_hash256 hash; + keccak(hash.word64s, 256, data, 32); + return hash; +} + +union ethash_hash512 ethash_keccak512(const uint8_t* data, size_t size) +{ + union ethash_hash512 hash; + keccak(hash.word64s, 512, data, size); + return hash; +} + +union ethash_hash512 ethash_keccak512_64(const uint8_t data[64]) +{ + union ethash_hash512 hash; + keccak(hash.word64s, 512, data, 64); + return hash; +} diff --git a/contrib/ethereum/libethash/keccakf1600.c b/contrib/ethereum/libethash/keccakf1600.c new file mode 100644 index 00000000..271fe76d --- /dev/null +++ b/contrib/ethereum/libethash/keccakf1600.c @@ -0,0 +1,255 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#include + +static uint64_t rol(uint64_t x, unsigned s) +{ + return (x << s) | (x >> (64 - s)); +} + +static const uint64_t round_constants[24] = { + 0x0000000000000001, + 0x0000000000008082, + 0x800000000000808a, + 0x8000000080008000, + 0x000000000000808b, + 0x0000000080000001, + 0x8000000080008081, + 0x8000000000008009, + 0x000000000000008a, + 0x0000000000000088, + 0x0000000080008009, + 0x000000008000000a, + 0x000000008000808b, + 0x800000000000008b, + 0x8000000000008089, + 0x8000000000008003, + 0x8000000000008002, + 0x8000000000000080, + 0x000000000000800a, + 0x800000008000000a, + 0x8000000080008081, + 0x8000000000008080, + 0x0000000080000001, + 0x8000000080008008, +}; + +void ethash_keccakf1600(uint64_t state[25]) +{ + /* The implementation based on the "simple" implementation by Ronny Van Keer. */ + + int round; + + uint64_t Aba, Abe, Abi, Abo, Abu; + uint64_t Aga, Age, Agi, Ago, Agu; + uint64_t Aka, Ake, Aki, Ako, Aku; + uint64_t Ama, Ame, Ami, Amo, Amu; + uint64_t Asa, Ase, Asi, Aso, Asu; + + uint64_t Eba, Ebe, Ebi, Ebo, Ebu; + uint64_t Ega, Ege, Egi, Ego, Egu; + uint64_t Eka, Eke, Eki, Eko, Eku; + uint64_t Ema, Eme, Emi, Emo, Emu; + uint64_t Esa, Ese, Esi, Eso, Esu; + + uint64_t Ba, Be, Bi, Bo, Bu; + + uint64_t Da, De, Di, Do, Du; + + Aba = state[0]; + Abe = state[1]; + Abi = state[2]; + Abo = state[3]; + Abu = state[4]; + Aga = state[5]; + Age = state[6]; + Agi = state[7]; + Ago = state[8]; + Agu = state[9]; + Aka = state[10]; + Ake = state[11]; + Aki = state[12]; + Ako = state[13]; + Aku = state[14]; + Ama = state[15]; + Ame = state[16]; + Ami = state[17]; + Amo = state[18]; + Amu = state[19]; + Asa = state[20]; + Ase = state[21]; + Asi = state[22]; + Aso = state[23]; + Asu = state[24]; + + for (round = 0; round < 24; round += 2) + { + /* Round (round + 0): Axx -> Exx */ + + Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa; + Be = Abe ^ Age ^ Ake ^ Ame ^ Ase; + Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi; + Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso; + Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu; + + Da = Bu ^ rol(Be, 1); + De = Ba ^ rol(Bi, 1); + Di = Be ^ rol(Bo, 1); + Do = Bi ^ rol(Bu, 1); + Du = Bo ^ rol(Ba, 1); + + Ba = Aba ^ Da; + Be = rol(Age ^ De, 44); + Bi = rol(Aki ^ Di, 43); + Bo = rol(Amo ^ Do, 21); + Bu = rol(Asu ^ Du, 14); + Eba = Ba ^ (~Be & Bi) ^ round_constants[round]; + Ebe = Be ^ (~Bi & Bo); + Ebi = Bi ^ (~Bo & Bu); + Ebo = Bo ^ (~Bu & Ba); + Ebu = Bu ^ (~Ba & Be); + + Ba = rol(Abo ^ Do, 28); + Be = rol(Agu ^ Du, 20); + Bi = rol(Aka ^ Da, 3); + Bo = rol(Ame ^ De, 45); + Bu = rol(Asi ^ Di, 61); + Ega = Ba ^ (~Be & Bi); + Ege = Be ^ (~Bi & Bo); + Egi = Bi ^ (~Bo & Bu); + Ego = Bo ^ (~Bu & Ba); + Egu = Bu ^ (~Ba & Be); + + Ba = rol(Abe ^ De, 1); + Be = rol(Agi ^ Di, 6); + Bi = rol(Ako ^ Do, 25); + Bo = rol(Amu ^ Du, 8); + Bu = rol(Asa ^ Da, 18); + Eka = Ba ^ (~Be & Bi); + Eke = Be ^ (~Bi & Bo); + Eki = Bi ^ (~Bo & Bu); + Eko = Bo ^ (~Bu & Ba); + Eku = Bu ^ (~Ba & Be); + + Ba = rol(Abu ^ Du, 27); + Be = rol(Aga ^ Da, 36); + Bi = rol(Ake ^ De, 10); + Bo = rol(Ami ^ Di, 15); + Bu = rol(Aso ^ Do, 56); + Ema = Ba ^ (~Be & Bi); + Eme = Be ^ (~Bi & Bo); + Emi = Bi ^ (~Bo & Bu); + Emo = Bo ^ (~Bu & Ba); + Emu = Bu ^ (~Ba & Be); + + Ba = rol(Abi ^ Di, 62); + Be = rol(Ago ^ Do, 55); + Bi = rol(Aku ^ Du, 39); + Bo = rol(Ama ^ Da, 41); + Bu = rol(Ase ^ De, 2); + Esa = Ba ^ (~Be & Bi); + Ese = Be ^ (~Bi & Bo); + Esi = Bi ^ (~Bo & Bu); + Eso = Bo ^ (~Bu & Ba); + Esu = Bu ^ (~Ba & Be); + + + /* Round (round + 1): Exx -> Axx */ + + Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa; + Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese; + Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi; + Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso; + Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu; + + Da = Bu ^ rol(Be, 1); + De = Ba ^ rol(Bi, 1); + Di = Be ^ rol(Bo, 1); + Do = Bi ^ rol(Bu, 1); + Du = Bo ^ rol(Ba, 1); + + Ba = Eba ^ Da; + Be = rol(Ege ^ De, 44); + Bi = rol(Eki ^ Di, 43); + Bo = rol(Emo ^ Do, 21); + Bu = rol(Esu ^ Du, 14); + Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1]; + Abe = Be ^ (~Bi & Bo); + Abi = Bi ^ (~Bo & Bu); + Abo = Bo ^ (~Bu & Ba); + Abu = Bu ^ (~Ba & Be); + + Ba = rol(Ebo ^ Do, 28); + Be = rol(Egu ^ Du, 20); + Bi = rol(Eka ^ Da, 3); + Bo = rol(Eme ^ De, 45); + Bu = rol(Esi ^ Di, 61); + Aga = Ba ^ (~Be & Bi); + Age = Be ^ (~Bi & Bo); + Agi = Bi ^ (~Bo & Bu); + Ago = Bo ^ (~Bu & Ba); + Agu = Bu ^ (~Ba & Be); + + Ba = rol(Ebe ^ De, 1); + Be = rol(Egi ^ Di, 6); + Bi = rol(Eko ^ Do, 25); + Bo = rol(Emu ^ Du, 8); + Bu = rol(Esa ^ Da, 18); + Aka = Ba ^ (~Be & Bi); + Ake = Be ^ (~Bi & Bo); + Aki = Bi ^ (~Bo & Bu); + Ako = Bo ^ (~Bu & Ba); + Aku = Bu ^ (~Ba & Be); + + Ba = rol(Ebu ^ Du, 27); + Be = rol(Ega ^ Da, 36); + Bi = rol(Eke ^ De, 10); + Bo = rol(Emi ^ Di, 15); + Bu = rol(Eso ^ Do, 56); + Ama = Ba ^ (~Be & Bi); + Ame = Be ^ (~Bi & Bo); + Ami = Bi ^ (~Bo & Bu); + Amo = Bo ^ (~Bu & Ba); + Amu = Bu ^ (~Ba & Be); + + Ba = rol(Ebi ^ Di, 62); + Be = rol(Ego ^ Do, 55); + Bi = rol(Eku ^ Du, 39); + Bo = rol(Ema ^ Da, 41); + Bu = rol(Ese ^ De, 2); + Asa = Ba ^ (~Be & Bi); + Ase = Be ^ (~Bi & Bo); + Asi = Bi ^ (~Bo & Bu); + Aso = Bo ^ (~Bu & Ba); + Asu = Bu ^ (~Ba & Be); + } + + state[0] = Aba; + state[1] = Abe; + state[2] = Abi; + state[3] = Abo; + state[4] = Abu; + state[5] = Aga; + state[6] = Age; + state[7] = Agi; + state[8] = Ago; + state[9] = Agu; + state[10] = Aka; + state[11] = Ake; + state[12] = Aki; + state[13] = Ako; + state[14] = Aku; + state[15] = Ama; + state[16] = Ame; + state[17] = Ami; + state[18] = Amo; + state[19] = Amu; + state[20] = Asa; + state[21] = Ase; + state[22] = Asi; + state[23] = Aso; + state[24] = Asu; +} diff --git a/contrib/ethereum/libethash/keccakf800.c b/contrib/ethereum/libethash/keccakf800.c new file mode 100644 index 00000000..aa7cceef --- /dev/null +++ b/contrib/ethereum/libethash/keccakf800.c @@ -0,0 +1,253 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#include + +static uint32_t rol(uint32_t x, unsigned s) +{ + return (x << s) | (x >> (32 - s)); +} + +static const uint32_t round_constants[22] = { + 0x00000001, + 0x00008082, + 0x0000808A, + 0x80008000, + 0x0000808B, + 0x80000001, + 0x80008081, + 0x00008009, + 0x0000008A, + 0x00000088, + 0x80008009, + 0x8000000A, + 0x8000808B, + 0x0000008B, + 0x00008089, + 0x00008003, + 0x00008002, + 0x00000080, + 0x0000800A, + 0x8000000A, + 0x80008081, + 0x00008080, +}; + +void ethash_keccakf800(uint32_t state[25]) +{ + /* The implementation directly translated from ethash_keccakf1600. */ + + int round; + + uint32_t Aba, Abe, Abi, Abo, Abu; + uint32_t Aga, Age, Agi, Ago, Agu; + uint32_t Aka, Ake, Aki, Ako, Aku; + uint32_t Ama, Ame, Ami, Amo, Amu; + uint32_t Asa, Ase, Asi, Aso, Asu; + + uint32_t Eba, Ebe, Ebi, Ebo, Ebu; + uint32_t Ega, Ege, Egi, Ego, Egu; + uint32_t Eka, Eke, Eki, Eko, Eku; + uint32_t Ema, Eme, Emi, Emo, Emu; + uint32_t Esa, Ese, Esi, Eso, Esu; + + uint32_t Ba, Be, Bi, Bo, Bu; + + uint32_t Da, De, Di, Do, Du; + + Aba = state[0]; + Abe = state[1]; + Abi = state[2]; + Abo = state[3]; + Abu = state[4]; + Aga = state[5]; + Age = state[6]; + Agi = state[7]; + Ago = state[8]; + Agu = state[9]; + Aka = state[10]; + Ake = state[11]; + Aki = state[12]; + Ako = state[13]; + Aku = state[14]; + Ama = state[15]; + Ame = state[16]; + Ami = state[17]; + Amo = state[18]; + Amu = state[19]; + Asa = state[20]; + Ase = state[21]; + Asi = state[22]; + Aso = state[23]; + Asu = state[24]; + + for (round = 0; round < 22; round += 2) + { + /* Round (round + 0): Axx -> Exx */ + + Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa; + Be = Abe ^ Age ^ Ake ^ Ame ^ Ase; + Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi; + Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso; + Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu; + + Da = Bu ^ rol(Be, 1); + De = Ba ^ rol(Bi, 1); + Di = Be ^ rol(Bo, 1); + Do = Bi ^ rol(Bu, 1); + Du = Bo ^ rol(Ba, 1); + + Ba = Aba ^ Da; + Be = rol(Age ^ De, 12); + Bi = rol(Aki ^ Di, 11); + Bo = rol(Amo ^ Do, 21); + Bu = rol(Asu ^ Du, 14); + Eba = Ba ^ (~Be & Bi) ^ round_constants[round]; + Ebe = Be ^ (~Bi & Bo); + Ebi = Bi ^ (~Bo & Bu); + Ebo = Bo ^ (~Bu & Ba); + Ebu = Bu ^ (~Ba & Be); + + Ba = rol(Abo ^ Do, 28); + Be = rol(Agu ^ Du, 20); + Bi = rol(Aka ^ Da, 3); + Bo = rol(Ame ^ De, 13); + Bu = rol(Asi ^ Di, 29); + Ega = Ba ^ (~Be & Bi); + Ege = Be ^ (~Bi & Bo); + Egi = Bi ^ (~Bo & Bu); + Ego = Bo ^ (~Bu & Ba); + Egu = Bu ^ (~Ba & Be); + + Ba = rol(Abe ^ De, 1); + Be = rol(Agi ^ Di, 6); + Bi = rol(Ako ^ Do, 25); + Bo = rol(Amu ^ Du, 8); + Bu = rol(Asa ^ Da, 18); + Eka = Ba ^ (~Be & Bi); + Eke = Be ^ (~Bi & Bo); + Eki = Bi ^ (~Bo & Bu); + Eko = Bo ^ (~Bu & Ba); + Eku = Bu ^ (~Ba & Be); + + Ba = rol(Abu ^ Du, 27); + Be = rol(Aga ^ Da, 4); + Bi = rol(Ake ^ De, 10); + Bo = rol(Ami ^ Di, 15); + Bu = rol(Aso ^ Do, 24); + Ema = Ba ^ (~Be & Bi); + Eme = Be ^ (~Bi & Bo); + Emi = Bi ^ (~Bo & Bu); + Emo = Bo ^ (~Bu & Ba); + Emu = Bu ^ (~Ba & Be); + + Ba = rol(Abi ^ Di, 30); + Be = rol(Ago ^ Do, 23); + Bi = rol(Aku ^ Du, 7); + Bo = rol(Ama ^ Da, 9); + Bu = rol(Ase ^ De, 2); + Esa = Ba ^ (~Be & Bi); + Ese = Be ^ (~Bi & Bo); + Esi = Bi ^ (~Bo & Bu); + Eso = Bo ^ (~Bu & Ba); + Esu = Bu ^ (~Ba & Be); + + + /* Round (round + 1): Exx -> Axx */ + + Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa; + Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese; + Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi; + Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso; + Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu; + + Da = Bu ^ rol(Be, 1); + De = Ba ^ rol(Bi, 1); + Di = Be ^ rol(Bo, 1); + Do = Bi ^ rol(Bu, 1); + Du = Bo ^ rol(Ba, 1); + + Ba = Eba ^ Da; + Be = rol(Ege ^ De, 12); + Bi = rol(Eki ^ Di, 11); + Bo = rol(Emo ^ Do, 21); + Bu = rol(Esu ^ Du, 14); + Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1]; + Abe = Be ^ (~Bi & Bo); + Abi = Bi ^ (~Bo & Bu); + Abo = Bo ^ (~Bu & Ba); + Abu = Bu ^ (~Ba & Be); + + Ba = rol(Ebo ^ Do, 28); + Be = rol(Egu ^ Du, 20); + Bi = rol(Eka ^ Da, 3); + Bo = rol(Eme ^ De, 13); + Bu = rol(Esi ^ Di, 29); + Aga = Ba ^ (~Be & Bi); + Age = Be ^ (~Bi & Bo); + Agi = Bi ^ (~Bo & Bu); + Ago = Bo ^ (~Bu & Ba); + Agu = Bu ^ (~Ba & Be); + + Ba = rol(Ebe ^ De, 1); + Be = rol(Egi ^ Di, 6); + Bi = rol(Eko ^ Do, 25); + Bo = rol(Emu ^ Du, 8); + Bu = rol(Esa ^ Da, 18); + Aka = Ba ^ (~Be & Bi); + Ake = Be ^ (~Bi & Bo); + Aki = Bi ^ (~Bo & Bu); + Ako = Bo ^ (~Bu & Ba); + Aku = Bu ^ (~Ba & Be); + + Ba = rol(Ebu ^ Du, 27); + Be = rol(Ega ^ Da, 4); + Bi = rol(Eke ^ De, 10); + Bo = rol(Emi ^ Di, 15); + Bu = rol(Eso ^ Do, 24); + Ama = Ba ^ (~Be & Bi); + Ame = Be ^ (~Bi & Bo); + Ami = Bi ^ (~Bo & Bu); + Amo = Bo ^ (~Bu & Ba); + Amu = Bu ^ (~Ba & Be); + + Ba = rol(Ebi ^ Di, 30); + Be = rol(Ego ^ Do, 23); + Bi = rol(Eku ^ Du, 7); + Bo = rol(Ema ^ Da, 9); + Bu = rol(Ese ^ De, 2); + Asa = Ba ^ (~Be & Bi); + Ase = Be ^ (~Bi & Bo); + Asi = Bi ^ (~Bo & Bu); + Aso = Bo ^ (~Bu & Ba); + Asu = Bu ^ (~Ba & Be); + } + + state[0] = Aba; + state[1] = Abe; + state[2] = Abi; + state[3] = Abo; + state[4] = Abu; + state[5] = Aga; + state[6] = Age; + state[7] = Agi; + state[8] = Ago; + state[9] = Agu; + state[10] = Aka; + state[11] = Ake; + state[12] = Aki; + state[13] = Ako; + state[14] = Aku; + state[15] = Ama; + state[16] = Ame; + state[17] = Ami; + state[18] = Amo; + state[19] = Amu; + state[20] = Asa; + state[21] = Ase; + state[22] = Asi; + state[23] = Aso; + state[24] = Asu; +} diff --git a/contrib/ethereum/libethash/kiss99.hpp b/contrib/ethereum/libethash/kiss99.hpp new file mode 100644 index 00000000..8550b82e --- /dev/null +++ b/contrib/ethereum/libethash/kiss99.hpp @@ -0,0 +1,64 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include "support/attributes.h" +#include + +/** + * KISS PRNG by the spec from 1999. + * + * The implementation of KISS pseudo-random number generator + * by the specification published on 21 Jan 1999 in + * http://www.cse.yorku.ca/~oz/marsaglia-rng.html. + * The KISS is not versioned so here we are using `kiss99` prefix to indicate + * the version from 1999. + * + * The specification uses `unsigned long` type with the intention for 32-bit + * values. Because in GCC/clang for 64-bit architectures `unsigned long` is + * 64-bit size type, here the explicit `uint32_t` type is used. + * + * @defgroup kiss99 KISS99 + * @{ + */ + +/** + * The KISS generator. + */ +class kiss99 +{ + uint32_t z = 362436069; + uint32_t w = 521288629; + uint32_t jsr = 123456789; + uint32_t jcong = 380116160; + +public: + /** Creates KISS generator state with default values provided by the specification. */ + kiss99() noexcept = default; + + /** Creates KISS generator state with provided init values.*/ + kiss99(uint32_t z, uint32_t w, uint32_t jsr, uint32_t jcong) noexcept + : z{z}, w{w}, jsr{jsr}, jcong{jcong} + {} + + /** Generates next number from the KISS generator. */ + NO_SANITIZE("unsigned-integer-overflow") + uint32_t operator()() noexcept + { + z = 36969 * (z & 0xffff) + (z >> 16); + w = 18000 * (w & 0xffff) + (w >> 16); + + jcong = 69069 * jcong + 1234567; + + jsr ^= (jsr << 17); + jsr ^= (jsr >> 13); + jsr ^= (jsr << 5); + + return (((z << 16) + w) ^ jcong) + jsr; + } +}; + +/** @} */ diff --git a/contrib/ethereum/libethash/managed.cpp b/contrib/ethereum/libethash/managed.cpp new file mode 100644 index 00000000..900da7e7 --- /dev/null +++ b/contrib/ethereum/libethash/managed.cpp @@ -0,0 +1,100 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +#include "ethash-internal.hpp" + +#include +#include + +#if !defined(__has_cpp_attribute) +#define __has_cpp_attribute(x) 0 +#endif + +#if __has_cpp_attribute(gnu::noinline) +#define ATTRIBUTE_NOINLINE [[gnu::noinline]] +#elif _MSC_VER +#define ATTRIBUTE_NOINLINE __declspec(noinline) +#else +#define ATTRIBUTE_NOINLINE +#endif + +namespace ethash +{ +namespace +{ +std::mutex shared_context_mutex; +std::shared_ptr shared_context; +thread_local std::shared_ptr thread_local_context; + +std::mutex shared_context_full_mutex; +std::shared_ptr shared_context_full; +thread_local std::shared_ptr thread_local_context_full; + +/// Update thread local epoch context. +/// +/// This function is on the slow path. It's separated to allow inlining the fast +/// path. +/// +/// @todo: Redesign to guarantee deallocation before new allocation. +ATTRIBUTE_NOINLINE +void update_local_context(int epoch_number) +{ + // Release the shared pointer of the obsoleted context. + thread_local_context.reset(); + + // Local context invalid, check the shared context. + std::lock_guard lock{shared_context_mutex}; + + if (!shared_context || shared_context->epoch_number != epoch_number) + { + // Release the shared pointer of the obsoleted context. + shared_context.reset(); + + // Build new context. + shared_context = create_epoch_context(epoch_number); + } + + thread_local_context = shared_context; +} + +ATTRIBUTE_NOINLINE +void update_local_context_full(int epoch_number) +{ + // Release the shared pointer of the obsoleted context. + thread_local_context_full.reset(); + + // Local context invalid, check the shared context. + std::lock_guard lock{shared_context_full_mutex}; + + if (!shared_context_full || shared_context_full->epoch_number != epoch_number) + { + // Release the shared pointer of the obsoleted context. + shared_context_full.reset(); + + // Build new context. + shared_context_full = create_epoch_context_full(epoch_number); + } + + thread_local_context_full = shared_context_full; +} +} // namespace + +const epoch_context& get_global_epoch_context(int epoch_number) +{ + // Check if local context matches epoch number. + if (!thread_local_context || thread_local_context->epoch_number != epoch_number) + update_local_context(epoch_number); + + return *thread_local_context; +} + +const epoch_context_full& get_global_epoch_context_full(int epoch_number) +{ + // Check if local context matches epoch number. + if (!thread_local_context_full || thread_local_context_full->epoch_number != epoch_number) + update_local_context_full(epoch_number); + + return *thread_local_context_full; +} +} // namespace ethash diff --git a/contrib/ethereum/libethash/mmap.h b/contrib/ethereum/libethash/mmap.h deleted file mode 100644 index 1e226e83..00000000 --- a/contrib/ethereum/libethash/mmap.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file mmap.h - * @author Lefteris Karapetsas - * @date 2015 - */ -#pragma once -#if defined(__MINGW32__) || defined(_WIN32) -#include - -#define PROT_READ 0x1 -#define PROT_WRITE 0x2 -/* This flag is only available in WinXP+ */ -#ifdef FILE_MAP_EXECUTE -#define PROT_EXEC 0x4 -#else -#define PROT_EXEC 0x0 -#define FILE_MAP_EXECUTE 0 -#endif - -#define MAP_SHARED 0x01 -#define MAP_PRIVATE 0x02 -#define MAP_ANONYMOUS 0x20 -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FAILED ((void *) -1) - -void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset); -void munmap(void* addr, size_t length); -#else // posix, yay! ^_^ -#include -#endif - - diff --git a/contrib/ethereum/libethash/mmap_win32.c b/contrib/ethereum/libethash/mmap_win32.c deleted file mode 100644 index e1f061a1..00000000 --- a/contrib/ethereum/libethash/mmap_win32.c +++ /dev/null @@ -1,86 +0,0 @@ -/* mmap() replacement for Windows - * - * Author: Mike Frysinger - * Placed into the public domain - */ - -/* References: - * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx - * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx - * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx - * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx - */ - -#include -#include -#include "mmap.h" - -#ifdef __USE_FILE_OFFSET64 -# define DWORD_HI(x) (x >> 32) -# define DWORD_LO(x) ((x) & 0xffffffff) -#else -# define DWORD_HI(x) (0) -# define DWORD_LO(x) (x) -#endif - -void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset) -{ - DWORD flProtect; - DWORD dwDesiredAccess; - if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) - return MAP_FAILED; - if (fd == -1) { - if (!(flags & MAP_ANON) || offset) - return MAP_FAILED; - } else if (flags & MAP_ANON) - return MAP_FAILED; - - - if (prot & PROT_WRITE) { - if (prot & PROT_EXEC) - flProtect = PAGE_EXECUTE_READWRITE; - else - flProtect = PAGE_READWRITE; - } else if (prot & PROT_EXEC) { - if (prot & PROT_READ) - flProtect = PAGE_EXECUTE_READ; - else if (prot & PROT_EXEC) - flProtect = PAGE_EXECUTE; - } else - flProtect = PAGE_READONLY; - - off_t end = length + offset; - HANDLE mmap_fd, h; - if (fd == -1) - mmap_fd = INVALID_HANDLE_VALUE; - else - mmap_fd = (HANDLE)_get_osfhandle(fd); - h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL); - if (h == NULL) - return MAP_FAILED; - - - if (prot & PROT_WRITE) - dwDesiredAccess = FILE_MAP_WRITE; - else - dwDesiredAccess = FILE_MAP_READ; - if (prot & PROT_EXEC) - dwDesiredAccess |= FILE_MAP_EXECUTE; - if (flags & MAP_PRIVATE) - dwDesiredAccess |= FILE_MAP_COPY; - void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length); - if (ret == NULL) { - ret = MAP_FAILED; - } - // since we are handling the file ourselves with fd, close the Windows Handle here - CloseHandle(h); - return ret; -} - -void munmap(void* addr, size_t length) -{ - UnmapViewOfFile(addr); -} - -#undef DWORD_HI -#undef DWORD_LO diff --git a/contrib/ethereum/libethash/primes.c b/contrib/ethereum/libethash/primes.c new file mode 100644 index 00000000..2d58874b --- /dev/null +++ b/contrib/ethereum/libethash/primes.c @@ -0,0 +1,43 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#include "primes.h" + +/** Checks if the number is prime. Requires the number to be > 2 and odd. */ +static int is_odd_prime(int number) +{ + int d; + + /* Check factors up to sqrt(number). + To avoid computing sqrt, compare d*d <= number with 64-bit precision. */ + for (d = 3; (int64_t)d * (int64_t)d <= (int64_t)number; d += 2) + { + if (number % d == 0) + return 0; + } + + return 1; +} + +int ethash_find_largest_prime(int upper_bound) +{ + int n = upper_bound; + + if (n < 2) + return 0; + + if (n == 2) + return 2; + + /* If even number, skip it. */ + if (n % 2 == 0) + --n; + + /* Test descending odd numbers. */ + while (!is_odd_prime(n)) + n -= 2; + + return n; +} diff --git a/contrib/ethereum/libethash/primes.h b/contrib/ethereum/libethash/primes.h new file mode 100644 index 00000000..cf923b01 --- /dev/null +++ b/contrib/ethereum/libethash/primes.h @@ -0,0 +1,25 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Finds the largest prime number not greater than the provided upper bound. + * + * @param upper_bound The upper bound. SHOULD be greater than 1. + * @return The largest prime number `p` such `p <= upper_bound`. + * In case `upper_bound <= 1`, returns 0. + */ +int ethash_find_largest_prime(int upper_bound) NOEXCEPT; + +#ifdef __cplusplus +} +#endif diff --git a/contrib/ethereum/libethash/progpow.cpp b/contrib/ethereum/libethash/progpow.cpp new file mode 100644 index 00000000..e311f37e --- /dev/null +++ b/contrib/ethereum/libethash/progpow.cpp @@ -0,0 +1,360 @@ +// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. +// Copyright 2018 Pawel Bylica. +// Licensed under the Apache License, Version 2.0. See the LICENSE file. + +#include + +#include "bit_manipulation.h" +#include "endianness.hpp" +#include "ethash-internal.hpp" +#include "kiss99.hpp" +#include + +#include + +namespace progpow +{ +namespace +{ +/// A variant of Keccak hash function for ProgPoW. +/// +/// This Keccak hash function uses 800-bit permutation (Keccak-f[800]) with 576 bitrate. +/// It take exactly 576 bits of input (split across 3 arguments) and adds no padding. +/// +/// @param header_hash The 256-bit header hash. +/// @param nonce The 64-bit nonce. +/// @param mix_hash Additional 256-bits of data. +/// @return The 256-bit output of the hash function. +hash256 keccak_progpow_256( + const hash256& header_hash, uint64_t nonce, const hash256& mix_hash) noexcept +{ + static constexpr size_t num_words = + sizeof(header_hash.word32s) / sizeof(header_hash.word32s[0]); + + uint32_t state[25] = {}; + + size_t i; + for (i = 0; i < num_words; ++i) + state[i] = le::uint32(header_hash.word32s[i]); + + state[i++] = static_cast(nonce); + state[i++] = static_cast(nonce >> 32); + + for (uint32_t mix_word : mix_hash.word32s) + state[i++] = le::uint32(mix_word); + + ethash_keccakf800(state); + + hash256 output; + for (i = 0; i < num_words; ++i) + output.word32s[i] = le::uint32(state[i]); + return output; +} + +/// The same as keccak_progpow_256() but uses null mix +/// and returns top 64 bits of the output being a big-endian prefix of the 256-bit hash. +inline uint64_t keccak_progpow_64(const hash256& header_hash, uint64_t nonce) noexcept +{ + const hash256 h = keccak_progpow_256(header_hash, nonce, {}); + return be::uint64(h.word64s[0]); +} + + +/// ProgPoW mix RNG state. +/// +/// Encapsulates the state of the random number generator used in computing ProgPoW mix. +/// This includes the state of the KISS99 RNG and the precomputed random permutation of the +/// sequence of mix item indexes. +class mix_rng_state +{ +public: + inline explicit mix_rng_state(uint64_t seed) noexcept; + + uint32_t next_dst() noexcept { return dst_seq[(dst_counter++) % num_regs]; } + uint32_t next_src() noexcept { return src_seq[(src_counter++) % num_regs]; } + + kiss99 rng; + +private: + size_t dst_counter = 0; + std::array dst_seq; + size_t src_counter = 0; + std::array src_seq; +}; + +mix_rng_state::mix_rng_state(uint64_t seed) noexcept +{ + const auto seed_lo = static_cast(seed); + const auto seed_hi = static_cast(seed >> 32); + + const auto z = fnv1a(fnv_offset_basis, seed_lo); + const auto w = fnv1a(z, seed_hi); + const auto jsr = fnv1a(w, seed_lo); + const auto jcong = fnv1a(jsr, seed_hi); + + rng = kiss99{z, w, jsr, jcong}; + + // Create random permutations of mix destinations / sources. + // Uses Fisher–Yates shuffle. + for (uint32_t i = 0; i < num_regs; ++i) + { + dst_seq[i] = i; + src_seq[i] = i; + } + + for (uint32_t i = num_regs; i > 1; --i) + { + std::swap(dst_seq[i - 1], dst_seq[rng() % i]); + std::swap(src_seq[i - 1], src_seq[rng() % i]); + } +} + + +NO_SANITIZE("unsigned-integer-overflow") +inline uint32_t random_math(uint32_t a, uint32_t b, uint32_t selector) noexcept +{ + switch (selector % 11) + { + default: + case 0: + return a + b; + case 1: + return a * b; + case 2: + return mul_hi32(a, b); + case 3: + return std::min(a, b); + case 4: + return rotl32(a, b); + case 5: + return rotr32(a, b); + case 6: + return a & b; + case 7: + return a | b; + case 8: + return a ^ b; + case 9: + return clz32(a) + clz32(b); + case 10: + return popcount32(a) + popcount32(b); + } +} + +/// Merge data from `b` and `a`. +/// Assuming `a` has high entropy, only do ops that retain entropy even if `b` +/// has low entropy (i.e. do not do `a & b`). +NO_SANITIZE("unsigned-integer-overflow") +inline void random_merge(uint32_t& a, uint32_t b, uint32_t selector) noexcept +{ + const auto x = (selector >> 16) % 31 + 1; // Additional non-zero selector from higher bits. + switch (selector % 4) + { + case 0: + a = (a * 33) + b; + break; + case 1: + a = (a ^ b) * 33; + break; + case 2: + a = rotl32(a, x) ^ b; + break; + case 3: + a = rotr32(a, x) ^ b; + break; + } +} + +using lookup_fn = hash2048 (*)(const epoch_context&, uint32_t); + +using mix_array = std::array, num_lanes>; + +void round( + const epoch_context& context, uint32_t r, mix_array& mix, mix_rng_state state, lookup_fn lookup) +{ + const uint32_t num_items = static_cast(context.full_dataset_num_items / 2); + const uint32_t item_index = mix[r % num_lanes][0] % num_items; + const hash2048 item = lookup(context, item_index); + + constexpr size_t num_words_per_lane = sizeof(item) / (sizeof(uint32_t) * num_lanes); + constexpr int max_operations = + num_cache_accesses > num_math_operations ? num_cache_accesses : num_math_operations; + + // Process lanes. + for (int i = 0; i < max_operations; ++i) + { + if (i < num_cache_accesses) // Random access to cached memory. + { + const auto src = state.next_src(); + const auto dst = state.next_dst(); + const auto sel = state.rng(); + + for (size_t l = 0; l < num_lanes; ++l) + { + const size_t offset = mix[l][src] % l1_cache_num_items; + random_merge(mix[l][dst], le::uint32(context.l1_cache[offset]), sel); + } + } + if (i < num_math_operations) // Random math. + { + // Generate 2 unique source indexes. + const auto src_rnd = state.rng() % (num_regs * (num_regs - 1)); + const auto src1 = src_rnd % num_regs; // O <= src1 < num_regs + auto src2 = src_rnd / num_regs; // 0 <= src2 < num_regs - 1 + if (src2 >= src1) + ++src2; + + const auto sel1 = state.rng(); + const auto dst = state.next_dst(); + const auto sel2 = state.rng(); + + for (size_t l = 0; l < num_lanes; ++l) + { + const uint32_t data = random_math(mix[l][src1], mix[l][src2], sel1); + random_merge(mix[l][dst], data, sel2); + } + } + } + + // DAG access pattern. + uint32_t dsts[num_words_per_lane]; + uint32_t sels[num_words_per_lane]; + for (size_t i = 0; i < num_words_per_lane; ++i) + { + dsts[i] = i == 0 ? 0 : state.next_dst(); + sels[i] = state.rng(); + } + + // DAG access. + for (size_t l = 0; l < num_lanes; ++l) + { + const auto offset = ((l ^ r) % num_lanes) * num_words_per_lane; + for (size_t i = 0; i < num_words_per_lane; ++i) + { + const auto word = le::uint32(item.word32s[offset + i]); + random_merge(mix[l][dsts[i]], word, sels[i]); + } + } +} + +mix_array init_mix(uint64_t seed) +{ + const uint32_t z = fnv1a(fnv_offset_basis, static_cast(seed)); + const uint32_t w = fnv1a(z, static_cast(seed >> 32)); + + mix_array mix; + for (uint32_t l = 0; l < mix.size(); ++l) + { + const uint32_t jsr = fnv1a(w, l); + const uint32_t jcong = fnv1a(jsr, l); + kiss99 rng{z, w, jsr, jcong}; + + for (auto& row : mix[l]) + row = rng(); + } + return mix; +} + +hash256 hash_mix( + const epoch_context& context, int block_number, uint64_t seed, lookup_fn lookup) noexcept +{ + auto mix = init_mix(seed); + mix_rng_state state{uint64_t(block_number / period_length)}; + + for (uint32_t i = 0; i < 64; ++i) + round(context, i, mix, state, lookup); + + // Reduce mix data to a single per-lane result. + uint32_t lane_hash[num_lanes]; + for (size_t l = 0; l < num_lanes; ++l) + { + lane_hash[l] = fnv_offset_basis; + for (uint32_t i = 0; i < num_regs; ++i) + lane_hash[l] = fnv1a(lane_hash[l], mix[l][i]); + } + + // Reduce all lanes to a single 256-bit result. + static constexpr size_t num_words = sizeof(hash256) / sizeof(uint32_t); + hash256 mix_hash; + for (uint32_t& w : mix_hash.word32s) + w = fnv_offset_basis; + for (size_t l = 0; l < num_lanes; ++l) + mix_hash.word32s[l % num_words] = fnv1a(mix_hash.word32s[l % num_words], lane_hash[l]); + return le::uint32s(mix_hash); +} +} // namespace + +result hash(const epoch_context& context, int block_number, const hash256& header_hash, + uint64_t nonce) noexcept +{ + const uint64_t seed = keccak_progpow_64(header_hash, nonce); + const hash256 mix_hash = hash_mix(context, block_number, seed, calculate_dataset_item_2048); + const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash); + return {final_hash, mix_hash}; +} + +result hash(const epoch_context_full& context, int block_number, const hash256& header_hash, + uint64_t nonce) noexcept +{ + static const auto lazy_lookup = [](const epoch_context& context, uint32_t index) noexcept + { + auto* full_dataset_1024 = static_cast(context).full_dataset; + auto* full_dataset_2048 = reinterpret_cast(full_dataset_1024); + hash2048& item = full_dataset_2048[index]; + if (item.word64s[0] == 0) + { + // TODO: Copy elision here makes it thread-safe? + item = calculate_dataset_item_2048(context, index); + } + + return item; + }; + + const uint64_t seed = keccak_progpow_64(header_hash, nonce); + const hash256 mix_hash = hash_mix(context, block_number, seed, lazy_lookup); + const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash); + return {final_hash, mix_hash}; +} + +bool verify(const epoch_context& context, int block_number, const hash256& header_hash, + const hash256& mix_hash, uint64_t nonce, const hash256& boundary) noexcept +{ + const uint64_t seed = keccak_progpow_64(header_hash, nonce); + const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash); + if (!is_less_or_equal(final_hash, boundary)) + return false; + + const hash256 expected_mix_hash = + hash_mix(context, block_number, seed, calculate_dataset_item_2048); + return is_equal(expected_mix_hash, mix_hash); +} + +search_result search_light(const epoch_context& context, int block_number, + const hash256& header_hash, const hash256& boundary, uint64_t start_nonce, + size_t iterations) noexcept +{ + const uint64_t end_nonce = start_nonce + iterations; + for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce) + { + result r = hash(context, block_number, header_hash, nonce); + if (is_less_or_equal(r.final_hash, boundary)) + return {r, nonce}; + } + return {}; +} + +search_result search(const epoch_context_full& context, int block_number, + const hash256& header_hash, const hash256& boundary, uint64_t start_nonce, + size_t iterations) noexcept +{ + const uint64_t end_nonce = start_nonce + iterations; + for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce) + { + result r = hash(context, block_number, header_hash, nonce); + if (is_less_or_equal(r.final_hash, boundary)) + return {r, nonce}; + } + return {}; +} + +} // namespace progpow diff --git a/contrib/ethereum/libethash/sha3.c b/contrib/ethereum/libethash/sha3.c deleted file mode 100644 index e72fe101..00000000 --- a/contrib/ethereum/libethash/sha3.c +++ /dev/null @@ -1,151 +0,0 @@ -/** libkeccak-tiny -* -* A single-file implementation of SHA-3 and SHAKE. -* -* Implementor: David Leon Gil -* License: CC0, attribution kindly requested. Blame taken too, -* but not liability. -*/ -#include "sha3.h" - -#include -#include -#include -#include - -/******** The Keccak-f[1600] permutation ********/ - -/*** Constants. ***/ -static const uint8_t rho[24] = \ - { 1, 3, 6, 10, 15, 21, - 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, - 62, 18, 39, 61, 20, 44}; -static const uint8_t pi[24] = \ - {10, 7, 11, 17, 18, 3, - 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, - 20, 14, 22, 9, 6, 1}; -static const uint64_t RC[24] = \ - {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, - 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, - 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; - -/*** Helper macros to unroll the permutation. ***/ -#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) -#define REPEAT6(e) e e e e e e -#define REPEAT24(e) REPEAT6(e e e e) -#define REPEAT5(e) e e e e e -#define FOR5(v, s, e) \ - v = 0; \ - REPEAT5(e; v += s;) - -/*** Keccak-f[1600] ***/ -static inline void keccakf(void* state) { - uint64_t* a = (uint64_t*)state; - uint64_t b[5] = {0}; - uint64_t t = 0; - uint8_t x, y; - - for (int i = 0; i < 24; i++) { - // Theta - FOR5(x, 1, - b[x] = 0; - FOR5(y, 5, - b[x] ^= a[x + y]; )) - FOR5(x, 1, - FOR5(y, 5, - a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) - // Rho and pi - t = a[1]; - x = 0; - REPEAT24(b[0] = a[pi[x]]; - a[pi[x]] = rol(t, rho[x]); - t = b[0]; - x++; ) - // Chi - FOR5(y, - 5, - FOR5(x, 1, - b[x] = a[y + x];) - FOR5(x, 1, - a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) - // Iota - a[0] ^= RC[i]; - } -} - -/******** The FIPS202-defined functions. ********/ - -/*** Some helper macros. ***/ - -#define _(S) do { S } while (0) -#define FOR(i, ST, L, S) \ - _(for (size_t i = 0; i < L; i += ST) { S; }) -#define mkapply_ds(NAME, S) \ - static inline void NAME(uint8_t* dst, \ - const uint8_t* src, \ - size_t len) { \ - FOR(i, 1, len, S); \ - } -#define mkapply_sd(NAME, S) \ - static inline void NAME(const uint8_t* src, \ - uint8_t* dst, \ - size_t len) { \ - FOR(i, 1, len, S); \ - } - -mkapply_ds(xorin, dst[i] ^= src[i]) // xorin -mkapply_sd(setout, dst[i] = src[i]) // setout - -#define P keccakf -#define Plen 200 - -// Fold P*F over the full blocks of an input. -#define foldP(I, L, F) \ - while (L >= rate) { \ - F(a, I, rate); \ - P(a); \ - I += rate; \ - L -= rate; \ - } - -/** The sponge-based hash construction. **/ -static inline int hash(uint8_t* out, size_t outlen, - const uint8_t* in, size_t inlen, - size_t rate, uint8_t delim) { - if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { - return -1; - } - uint8_t a[Plen] = {0}; - // Absorb input. - foldP(in, inlen, xorin); - // Xor in the DS and pad frame. - a[inlen] ^= delim; - a[rate - 1] ^= 0x80; - // Xor in the last block. - xorin(a, in, inlen); - // Apply P - P(a); - // Squeeze output. - foldP(out, outlen, setout); - setout(a, out, outlen); - memset(a, 0, 200); - return 0; -} - -#define defsha3(bits) \ - int sha3_##bits(uint8_t* out, size_t outlen, \ - const uint8_t* in, size_t inlen) { \ - if (outlen > (bits/8)) { \ - return -1; \ - } \ - return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ - } - -/*** FIPS202 SHA3 FOFs ***/ -defsha3(256) -defsha3(512) diff --git a/contrib/ethereum/libethash/sha3.h b/contrib/ethereum/libethash/sha3.h deleted file mode 100644 index a3800629..00000000 --- a/contrib/ethereum/libethash/sha3.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "compiler.h" -#include -#include - -struct ethash_h256; - -#define decsha3(bits) \ - int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t); - -decsha3(256) -decsha3(512) - -static inline void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t const size) -{ - sha3_256((uint8_t*)ret, 32, data, size); -} - -static inline void SHA3_512(uint8_t* ret, uint8_t const* data, size_t const size) -{ - sha3_512(ret, 64, data, size); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/support/attributes.h b/contrib/ethereum/libethash/support/attributes.h new file mode 100644 index 00000000..bb62b8d4 --- /dev/null +++ b/contrib/ethereum/libethash/support/attributes.h @@ -0,0 +1,33 @@ +/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. + * Copyright 2018 Pawel Bylica. + * Licensed under the Apache License, Version 2.0. See the LICENSE file. + */ + +#pragma once + +/** inline */ +#if _MSC_VER || __STDC_VERSION__ +#define INLINE inline +#else +#define INLINE +#endif + +/** [[always_inline]] */ +#if _MSC_VER +#define ALWAYS_INLINE __forceinline +#elif defined(__has_attribute) && __STDC_VERSION__ +#if __has_attribute(always_inline) +#define ALWAYS_INLINE __attribute__((always_inline)) +#endif +#endif +#if !defined(ALWAYS_INLINE) +#define ALWAYS_INLINE +#endif + +/** [[no_sanitize()]] */ +#if __clang__ +#define NO_SANITIZE(sanitizer) \ + __attribute__((no_sanitize(sanitizer))) +#else +#define NO_SANITIZE(sanitizer) +#endif diff --git a/contrib/ethereum/libethash/util.c b/contrib/ethereum/libethash/util.c deleted file mode 100644 index fbf268b7..00000000 --- a/contrib/ethereum/libethash/util.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file util.c - * @author Tim Hughes - * @date 2015 - */ -#include -#include -#include "util.h" - -#ifdef _MSC_VER - -// foward declare without all of Windows.h -__declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString); - -void debugf(const char *str, ...) -{ - va_list args; - va_start(args, str); - - char buf[1<<16]; - _vsnprintf_s(buf, sizeof(buf), sizeof(buf), str, args); - buf[sizeof(buf)-1] = '\0'; - OutputDebugStringA(buf); -} - -#endif diff --git a/contrib/ethereum/libethash/util.h b/contrib/ethereum/libethash/util.h deleted file mode 100644 index c5fc6e55..00000000 --- a/contrib/ethereum/libethash/util.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - This file is part of ethash. - - ethash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ethash. If not, see . -*/ -/** @file util.h - * @author Tim Hughes - * @date 2015 - */ -#pragma once -#include -#include "compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _MSC_VER -void debugf(char const* str, ...); -#else -#define debugf printf -#endif - -static inline uint32_t min_u32(uint32_t a, uint32_t b) -{ - return a < b ? a : b; -} - -static inline uint32_t clamp_u32(uint32_t x, uint32_t min_, uint32_t max_) -{ - return x < min_ ? min_ : (x > max_ ? max_ : x); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/ethereum/libethash/util_win32.c b/contrib/ethereum/libethash/util_win32.c deleted file mode 100644 index 268e6db0..00000000 --- a/contrib/ethereum/libethash/util_win32.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file util.c - * @author Tim Hughes - * @date 2015 - */ -#include -#include -#include "util.h" - - -// foward declare without all of Windows.h -__declspec(dllimport) void __stdcall OutputDebugStringA(char const* lpOutputString); - -void debugf(char const* str, ...) -{ - va_list args; - va_start(args, str); - - char buf[1<<16]; - _vsnprintf_s(buf, sizeof(buf), sizeof(buf), str, args); - buf[sizeof(buf)-1] = '\0'; - OutputDebugStringA(buf); -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac57925c..e374d773 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -114,19 +114,19 @@ target_link_libraries(currency_core lmdb) add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL}) add_dependencies(daemon version) -target_link_libraries(daemon rpc currency_core crypto common upnpc-static zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(daemon rpc currency_core crypto common upnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) ENABLE_SHARED_PCH(DAEMON) ENABLE_SHARED_PCH_EXECUTABLE(daemon) add_executable(connectivity_tool ${CONN_TOOL}) add_dependencies(connectivity_tool version) -target_link_libraries(connectivity_tool currency_core crypto common zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(connectivity_tool currency_core crypto common zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) ENABLE_SHARED_PCH(CONN_TOOL) ENABLE_SHARED_PCH_EXECUTABLE(connectivity_tool) add_executable(simplewallet ${SIMPLEWALLET}) add_dependencies(simplewallet version) -target_link_libraries(simplewallet wallet rpc currency_core crypto common zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(simplewallet wallet rpc currency_core crypto common zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) ENABLE_SHARED_PCH(SIMPLEWALLET) ENABLE_SHARED_PCH_EXECUTABLE(simplewallet) @@ -150,7 +150,7 @@ if(BUILD_GUI) QT5_USE_MODULES(Zano WebEngineWidgets WebChannel) find_package(Qt5PrintSupport REQUIRED) - target_link_libraries(Zano wallet rpc currency_core crypto common zlibstatic Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + target_link_libraries(Zano wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) if(APPLE) target_link_libraries(Zano ${COCOA_LIBRARY}) diff --git a/src/crypto/wild_keccak.cpp b/src/crypto/wild_keccak.cpp deleted file mode 100644 index fa49c539..00000000 --- a/src/crypto/wild_keccak.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// keccak.c -// 19-Nov-11 Markku-Juhani O. Saarinen -// A baseline Keccak (3rd round) implementation. - -// Memory-hard extension of keccak for PoW -// Copyright (c) 2014 The Boolberry developers -// Copyright (c) 2019 The Hyle Team -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include "wild_keccak.h" -#include "include_base_utils.h" -namespace crypto -{ - - const uint64_t keccakf_rndc[24] = - { - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, - 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, - 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, - 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, - 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, - 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 - }; - - const int keccakf_rotc[24] = - { - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 - }; - - const int keccakf_piln[24] = - { - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 - }; - - // update the state with given number of rounds - void regular_f::keccakf(uint64_t st[25], int rounds) - { - int i, j, round; - uint64_t t, bc[5]; - - for (round = 0; round < rounds; round++) { - - // Theta - for (i = 0; i < 5; i++) - bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; - - for (i = 0; i < 5; i++) { - t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); - for (j = 0; j < 25; j += 5) - st[j + i] ^= t; - } - - // Rho Pi - t = st[1]; - for (i = 0; i < 24; i++) { - j = keccakf_piln[i]; - bc[0] = st[j]; - st[j] = ROTL64(t, keccakf_rotc[i]); - t = bc[0]; - } - - // Chi - for (j = 0; j < 25; j += 5) { - for (i = 0; i < 5; i++) - bc[i] = st[j + i]; - for (i = 0; i < 5; i++) - st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; - } - - // Iota - st[0] ^= keccakf_rndc[round]; - } - } - - bool generate_scratchpad(const crypto::hash& seed_data, std::vector& result_data, uint64_t 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 deleted file mode 100644 index dc842b02..00000000 --- a/src/crypto/wild_keccak.h +++ /dev/null @@ -1,169 +0,0 @@ -// keccak.h -// 19-Nov-11 Markku-Juhani O. Saarinen - -// Copyright (c) 2014 The Boolberry developers -// Copyright (c) 2019 The Hyle Team -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#pragma once - -#include -#include -#include "crypto.h" - -extern "C" { -//#include "crypto/alt/KeccakNISTInterface.h" - } - -#ifndef KECCAK_ROUNDS -#define KECCAK_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - - -#define KK_MIXIN_SIZE 24 - -namespace crypto -{ - typedef uint64_t state_t_m[25]; - typedef uint64_t mixin_t[KK_MIXIN_SIZE]; - - template - int wild_keccak2(const uint8_t *in, size_t inlen, uint8_t *md, size_t mdlen, callback_t cb) - { - state_t_m st; - uint8_t temp[144]; - uint64_t rsiz, rsizw; - - rsiz = sizeof(state_t_m) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; - rsizw = rsiz / 8; - memset(&st[0], 0, 25 * sizeof(st[0])); - - - for (; inlen >= rsiz; inlen -= rsiz, in += rsiz) - { - for (size_t i = 0; i < rsizw; i++) - st[i] ^= ((uint64_t *)in)[i]; - - for (int keccak_round = 0; keccak_round != KECCAK_ROUNDS; keccak_round++) - { - f_traits::keccakf(st, keccak_round); - cb(st); - } - } - - // last block and padding - memcpy(temp, in, inlen); - temp[inlen++] = 1; - memset(temp + inlen, 0, rsiz - inlen); - temp[rsiz - 1] |= 0x80; - - for (size_t i = 0; i < rsizw; i++) - st[i] ^= ((uint64_t *)temp)[i]; - - for (int keccak_round = 0; keccak_round != KECCAK_ROUNDS; keccak_round++) - { - f_traits::keccakf(st, keccak_round); - cb(st); - } - - memcpy(md, st, mdlen); - - return 0; - } - - template - int wild_keccak2_dbl(const uint8_t *in, size_t inlen, uint8_t *md, size_t mdlen, callback_t cb) - { - //Satoshi's classic - wild_keccak2(in, inlen, md, mdlen, cb); - wild_keccak2(md, mdlen, md, mdlen, cb); - return 0; - } - - class regular_f - { - public: - static void keccakf(uint64_t st[25], int rounds); - }; - - - - //------------------------------------------------------------------ - inline - bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const uint64_t* int_array_ptr_scratch, uint64_t int64_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 (!int64_sz) - { - return; - } - - 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] ^= int_array_ptr_scratch[int_array_ptr_scratch[int_array_ptr_scratch[st[depend_index] % int64_sz] % int64_sz] % int64_sz]; - } - }); - return true; - } - //------------------------------------------------------------------ - inline - bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector& scratchpad, uint64_t sz) - { - - const uint64_t* int_array_ptr = (const uint64_t*)&scratchpad[0]; - size_t int64_sz = sz * 4; - return get_wild_keccak2(bd, res, int_array_ptr, int64_sz); - } - //------------------------------------------------------------------ - 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) - { - return get_wild_keccak2(bd, res, scratchpad, scratchpad.size()); - } - //------------------------------------------------------------------ - bool generate_scratchpad(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/basic_pow_helpers.cpp b/src/currency_core/basic_pow_helpers.cpp new file mode 100644 index 00000000..95ed6dfd --- /dev/null +++ b/src/currency_core/basic_pow_helpers.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2018-2019 Zano Project +// Copyright (c) 2018-2019 Hyle Team +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#include "include_base_utils.h" +using namespace epee; + +#include "basic_pow_helpers.h" +#include "currency_format_utils.h" +#include "serialization/binary_utils.h" +#include "serialization/stl_containers.h" +#include "currency_core/currency_config.h" +#include "crypto/crypto.h" +#include "crypto/hash.h" +#include "common/int-util.h" +#include "ethereum/libethash/ethash/ethash.hpp" +#include "ethereum/libethash/ethash/progpow.hpp" + +namespace currency +{ + + //-------------------------------------------------------------- + //global object +// crypto::ethash::cache_manager cache; +// void ethash_set_use_dag(bool use_dag) +// { +// cache.set_use_dag(use_dag); +// } +// //------------------------------------------------------------------ +// const uint8_t* ethash_get_dag(uint64_t epoch, uint64_t& dag_size) +// { +// return cache.get_dag(epoch, dag_size); +// } + //------------------------------------------------------------------ + int ethash_height_to_epoch(uint64_t height) + { + return height / ETHASH_EPOCH_LENGTH; + } + //-------------------------------------------------------------- + crypto::hash get_block_longhash(uint64_t height, const crypto::hash& block_long_ash, uint64_t nonce) + { + int epoch = ethash_height_to_epoch(height); + const auto& context = progpow::get_global_epoch_context_full(static_cast(epoch)); + auto res_eth = progpow::hash(context, height, *(ethash::hash256*)&block_long_ash, nonce); + crypto::hash result = currency::null_hash; + memcpy(&result.data, &res_eth.final_hash, sizeof(res_eth.final_hash)); + return result; + } + //--------------------------------------------------------------- + void get_block_longhash(const block& b, crypto::hash& res) + { + /* + Since etherium hash has a bit different approach in minig, to adopt our code we made little hack: + etherium hash calculates from block's hash and(!) nonce, both passed into PoW hash function. + To achieve the same effect we make blob of data from block in normal way, but then set to zerro nonce + inside serialized buffer, and then pass this nonce to ethash algo as a second argument, as it expected. + */ + blobdata bd = get_block_hashing_blob(b); + + access_nonce_in_block_blob(bd) = 0; + crypto::hash bl_hash = crypto::cn_fast_hash(bd.data(), bd.size()); + + res = get_block_longhash(get_block_height(b), bl_hash, b.nonce); + } + //--------------------------------------------------------------- + crypto::hash get_block_longhash(const block& b) + { + crypto::hash p = null_hash; + get_block_longhash(b, p); + return p; + } +} \ No newline at end of file diff --git a/src/currency_core/basic_pow_helpers.h b/src/currency_core/basic_pow_helpers.h new file mode 100644 index 00000000..5cbde053 --- /dev/null +++ b/src/currency_core/basic_pow_helpers.h @@ -0,0 +1,43 @@ +// Copyright (c) 2014-2018 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include +#include +#include + +#include "account.h" +#include "include_base_utils.h" + +#include "currency_format_utils_abstract.h" +#include "common/crypto_stream_operators.h" +#include "currency_protocol/currency_protocol_defs.h" +#include "crypto/crypto.h" +#include "crypto/hash.h" +#include "difficulty.h" +//#include "offers_services_helpers.h" +#include "rpc/core_rpc_server_commands_defs.h" +#include "bc_payments_id_service.h" +#include "bc_attachments_helpers_basic.h" +#include "blockchain_storage_basic.h" + +#define CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET 1 + +namespace currency +{ + crypto::hash get_block_longhash(uint64_t h, const crypto::hash& block_long_ash, uint64_t nonce); + void get_block_longhash(const block& b, crypto::hash& res); + crypto::hash get_block_longhash(const block& b); + + inline uint64_t& access_nonce_in_block_blob(blobdata& bd) + { + return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); + } + + inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd) + { + return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); + } +} \ No newline at end of file diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 7c2d6cb5..19b29ebb 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -31,6 +31,7 @@ #include "miner_common.h" #include "storages/portable_storage_template_helper.h" #include "common/db_backend_lmdb.h" +#include "basic_pow_helpers.h" #include "version.h" #undef LOG_DEFAULT_CHANNEL @@ -99,9 +100,7 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(std::share m_current_fee_median(0), 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_height(0) + m_deinit_is_done(false) { @@ -291,9 +290,6 @@ 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); @@ -1112,16 +1108,16 @@ uint64_t blockchain_storage::get_current_comulative_blocksize_limit() const return m_db_current_block_cumul_sz_limit; } //------------------------------------------------------------------ -bool blockchain_storage::create_block_template(block& b, crypto::hash& seed, +bool blockchain_storage::create_block_template(block& b, const account_public_address& miner_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) const { - return create_block_template(b, seed, miner_address, miner_address, diffic, height, ex_nonce, false, pos_entry()); + return create_block_template(b, miner_address, miner_address, diffic, height, ex_nonce, false, pos_entry()); } //------------------------------------------------------------------ -bool blockchain_storage::create_block_template(block& b, crypto::hash& seed, +bool blockchain_storage::create_block_template(block& b, const account_public_address& miner_address, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, @@ -1131,7 +1127,6 @@ bool blockchain_storage::create_block_template(block& b, crypto::hash& seed, const pos_entry& pe, fill_block_template_func_t custom_fill_block_template_func /* = nullptr */) const { - seed = m_current_scratchpad_seed; size_t median_size; uint64_t already_generated_coins; CRITICAL_REGION_BEGIN(m_read_lock); @@ -1456,10 +1451,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: } else { - crypto::hash seed = null_hash; - get_seed_for_scratchpad_alt_chain(abei.height, seed, alt_chain); - - proof_of_work = m_scratchpad.get_pow_hash(abei.bl, seed); + proof_of_work = get_block_longhash(abei.bl); if (!check_hash(proof_of_work, current_diff)) { @@ -1613,7 +1605,7 @@ bool blockchain_storage::pre_validate_relayed_block(block& bl, block_verificatio } else { - proof_hash = m_scratchpad.get_pow_hash(bl, m_current_scratchpad_seed); //get_block_longhash(bl); + proof_hash = get_block_longhash(bl); //get_block_longhash(bl); if (!check_hash(proof_hash, current_diffic)) { @@ -1738,9 +1730,6 @@ bool blockchain_storage::get_main_block_rpc_details(uint64_t i, block_rpc_extend CRITICAL_REGION_LOCAL(m_read_lock); auto core_bei_ptr = m_db_blocks[i]; crypto::hash id = get_block_hash(core_bei_ptr->bl); - crypto::hash pow_seed = null_hash; - get_seed_for_scratchpad(i, pow_seed); - bei.pow_seed = epee::string_tools::pod_to_hex(pow_seed); bei.is_orphan = false; bei.total_fee = 0; bei.total_txs_size = 0; @@ -2763,7 +2752,6 @@ bool blockchain_storage::pop_transaction_from_global_index(const transaction& tx CHECK_AND_ASSERT_MES(back_item->tx_id == tx_id, false, "transactions outs global index consistency broken: tx id missmatch"); CHECK_AND_ASSERT_MES(back_item->out_no == i, false, "transactions outs global index consistency broken: in transaction index missmatch"); m_db_outputs.pop_back_item(ot.amount); - //do not let to exist empty m_outputs entries - this will broke scratchpad selector //if (!it->second.size()) // m_db_outputs.erase(it); } @@ -4301,18 +4289,13 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt } else { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++ - //precaution(do we really need this check?) - check_scratchpad(); - //++++++++++++++++++++++++++++++++++++++++++++++++++++++ - proof_hash = m_scratchpad.get_pow_hash(bl, m_current_scratchpad_seed); + proof_hash = get_block_longhash(bl); if (!check_hash(proof_hash, current_diffic)) { LOG_ERROR("Block with id: " << id << ENDL << "PoW hash: " << proof_hash << ENDL - << "PoW seed: " << m_current_scratchpad_seed << ENDL << "unexpected difficulty: " << current_diffic); bvc.m_verification_failed = true; return false; @@ -4575,28 +4558,16 @@ void blockchain_storage::on_block_added(const block_extended_info& bei, const cr { update_next_comulative_size_limit(); m_timestamps_median_cache.clear(); - check_scratchpad(); m_tx_pool.on_blockchain_inc(bei.height, id); TIME_MEASURE_START_PD(raise_block_core_event); rise_core_event(CORE_EVENT_BLOCK_ADDED, void_struct()); TIME_MEASURE_FINISH_PD(raise_block_core_event); } -//------------------------------------------------------------------ - bool blockchain_storage::check_scratchpad() -{ - 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; -} //------------------------------------------------------------------ void blockchain_storage::on_block_removed(const block_extended_info& bei) { m_tx_pool.on_blockchain_dec(m_db_blocks.size() - 1, get_top_block_id()); m_timestamps_median_cache.clear(); - check_scratchpad(); LOG_PRINT_L2("block at height " << bei.height << " was removed from the blockchain"); } //------------------------------------------------------------------ @@ -5330,42 +5301,6 @@ bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx return false; } //------------------------------------------------------------------ -bool blockchain_storage::get_seed_for_scratchpad(uint64_t height, crypto::hash& seed)const -{ - CRITICAL_REGION_LOCAL(m_read_lock); - LOG_PRINT_MAGENTA("Get seed for scratchpad [main_chain] on height " << height, LOG_LEVEL_0); - return get_seed_for_scratchpad_cb(height, seed, [&](uint64_t index) -> crypto::hash - { - return get_block_hash(m_db_blocks[index]->bl); - }); -} -//------------------------------------------------------------------ -bool blockchain_storage::get_seed_for_scratchpad_alt_chain(uint64_t height, crypto::hash& seed, const alt_chain_type& alt_chain)const -{ - CRITICAL_REGION_LOCAL(m_read_lock); - //alt_chain: front -> mainchain, back -> alternative head - uint64_t connection_to_main_chain = height; - if (alt_chain.size()) - connection_to_main_chain = alt_chain.front()->second.height; - - return get_seed_for_scratchpad_cb(height, seed, [&](uint64_t index) -> crypto::hash - { - if (index < connection_to_main_chain) - { - //addressed to main chain - return get_block_hash(m_db_blocks[index]->bl); - } - else - { - //addressed to alt chain - uint64_t offset = index - connection_to_main_chain; - CHECK_AND_ASSERT_THROW_MES(offset < alt_chain.size(), "Internal error: failed to validate offset(" << offset << ") < alt_chain.size()("<< alt_chain.size() <<")"); - CHECK_AND_ASSERT_THROW_MES(alt_chain[offset]->second.height == index, "Internal error: failed to validate offset(" << offset << ") < alt_chain.size()(" << alt_chain.size() << ")"); - return get_block_hash(alt_chain[offset]->second.bl); - } - }); -} -//------------------------------------------------------------------ bool blockchain_storage::get_transaction_from_pool_or_db(const crypto::hash& tx_id, std::shared_ptr& tx_ptr, uint64_t min_allowed_block_height /* = 0 */) const { tx_ptr.reset(new transaction()); diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 5312a4c2..adfddb91 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -39,7 +39,7 @@ #include "dispatch_core_events.h" #include "bc_attachments_service_manager.h" #include "common/median_db_cache.h" -#include "scratchpad_helper.h" + MARK_AS_POD_C11(crypto::key_image); @@ -231,8 +231,8 @@ namespace currency wide_difficulty_type get_cached_next_difficulty(bool pos) const; typedef bool fill_block_template_func_t(block &bl, bool pos, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee, uint64_t height); - bool create_block_template(block& b, crypto::hash& seed, const account_public_address& miner_address, const account_public_address& stakeholder_address, wide_difficulty_type& di, uint64_t& height, const blobdata& ex_nonce, bool pos, const pos_entry& pe, fill_block_template_func_t custom_fill_block_template_func = nullptr) const; - bool create_block_template(block& b, crypto::hash& seed, const account_public_address& miner_address, wide_difficulty_type& di, uint64_t& height, const blobdata& ex_nonce) const; + bool create_block_template(block& b, const account_public_address& miner_address, const account_public_address& stakeholder_address, wide_difficulty_type& di, uint64_t& height, const blobdata& ex_nonce, bool pos, const pos_entry& pe, fill_block_template_func_t custom_fill_block_template_func = nullptr) const; + bool create_block_template(block& b, const account_public_address& miner_address, wide_difficulty_type& di, uint64_t& height, const blobdata& ex_nonce) const; bool have_block(const crypto::hash& id) const; size_t get_total_transactions()const; @@ -510,10 +510,7 @@ namespace currency //work like a cache to avoid mutable uint64_t m_current_fee_median; mutable uint64_t m_current_fee_median_effective_index; - bool m_is_reorganize_in_process; - 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; + bool m_is_reorganize_in_process; mutable std::atomic m_deinit_is_done; @@ -542,10 +539,6 @@ namespace currency bool validate_alt_block_txs(const block& b, const crypto::hash& id, std::set& collected_keyimages, alt_block_extended_info& abei, const alt_chain_type& alt_chain, uint64_t split_height, uint64_t& ki_lookup_time_total) const; bool update_alt_out_indexes_for_tx_in_block(const transaction& tx, alt_block_extended_info& abei)const; bool get_transaction_from_pool_or_db(const crypto::hash& tx_id, std::shared_ptr& tx_ptr, uint64_t min_allowed_block_height = 0) const; - bool get_seed_for_scratchpad(uint64_t height, crypto::hash& seed)const ; - bool get_seed_for_scratchpad_alt_chain(uint64_t height, crypto::hash& seed, const alt_chain_type& alt_chain) const ; - - bool check_scratchpad(); bool prevalidate_miner_transaction(const block& b, uint64_t height, bool pos)const; bool validate_transaction(const block& b, uint64_t height, const transaction& tx)const; @@ -572,7 +565,6 @@ namespace currency uint64_t get_adjusted_time()const; bool complete_timestamps_vector(uint64_t start_height, std::vector& timestamps); bool update_next_comulative_size_limit(); - //bool get_block_for_scratchpad_alt(uint64_t connection_height, uint64_t block_index, std::list& alt_chain, block & b); bool process_blockchain_tx_extra(const transaction& tx); bool unprocess_blockchain_tx_extra(const transaction& tx); bool process_blockchain_tx_attachments(const transaction& tx, uint64_t h, const crypto::hash& bl_id, uint64_t timestamp); diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 71608c76..f829b6df 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -46,12 +46,6 @@ #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 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 -#define CURRENCY_SCRATCHPAD_GENESIS_SEED "4c98962ddce32c7763bb9326933a4692975ca29a76349ae7a139faa3430cc5ab" - #define TX_DEFAULT_FEE ((uint64_t)100000) // pow(10, 5) #define TX_MINIMUM_FEE ((uint64_t)100000) // pow(10, 5) diff --git a/src/currency_core/currency_core.cpp b/src/currency_core/currency_core.cpp index 555df8ae..c4b785f4 100644 --- a/src/currency_core/currency_core.cpp +++ b/src/currency_core/currency_core.cpp @@ -401,14 +401,9 @@ namespace currency return m_mempool.add_tx(tx, tx_hash, blob_size, tvc, kept_by_block); } //----------------------------------------------------------------------------------------------- - bool core::get_block_template(block& b, crypto::hash& seed, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos, const pos_entry& pe) - { - return m_blockchain_storage.create_block_template(b, seed, adr, stakeholder_address, diffic, height, ex_nonce, pos, pe); - } bool core::get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos, const pos_entry& pe) { - crypto::hash seed_subst = currency::null_hash; - return m_blockchain_storage.create_block_template(b, seed_subst, adr, stakeholder_address, diffic, height, ex_nonce, pos, pe); + return m_blockchain_storage.create_block_template(b, adr, stakeholder_address, diffic, height, ex_nonce, pos, pe); } //----------------------------------------------------------------------------------------------- bool core::find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const diff --git a/src/currency_core/currency_core.h b/src/currency_core/currency_core.h index 1f178268..84b2e821 100644 --- a/src/currency_core/currency_core.h +++ b/src/currency_core/currency_core.h @@ -51,9 +51,7 @@ namespace currency //-------------------- i_miner_handler ----------------------- virtual bool handle_block_found(const block& b, block_verification_context* p_verification_result = nullptr); - virtual bool get_block_template(block& b, crypto::hash& seed, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()); - - bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()); + virtual bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()); miner& get_miner(){ return m_miner; } static void init_options(boost::program_options::options_description& desc); diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 20cb55ce..c1663dc8 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1664,24 +1664,7 @@ namespace currency } return true; } -// //-------------------------------------------------------------- -// crypto::hash get_block_longhash(uint64_t height, const crypto::hash& block_long_ash, uint64_t nonce) -// { -// //TODO: add wild keccak 2 -// return null_hash;//TODO; -// } -// //--------------------------------------------------------------- -// void get_block_longhash(const block& b, crypto::hash& res) -// { -// //TODO: add wild keccak 2 -// } -// //--------------------------------------------------------------- -// crypto::hash get_block_longhash(const block& b) -// { -// crypto::hash p = null_hash; -// get_block_longhash(b, p); -// return p; -// } + //--------------------------------------------------------------- uint64_t get_alias_coast_from_fee(const std::string& alias, uint64_t median_fee) { @@ -2405,21 +2388,6 @@ namespace currency return CURRENCY_TESTNET_CONST_REWARD; } //----------------------------------------------------------------------------------------------- - uint64_t get_scratchpad_last_update_rebuild_height(uint64_t h) - { - return h - (h%CURRENCY_SCRATCHPAD_REBUILD_INTERVAL); - } - //----------------------------------------------------------------------------------------------- - uint64_t get_scratchpad_size_for_height(uint64_t h) - { - 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) { uint64_t base_reward = get_base_block_reward(is_pos, already_generated_coins, height); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 263e258c..a984233f 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -295,11 +295,6 @@ namespace currency bool parse_amount(uint64_t& amount, const std::string& str_amount); - -// crypto::hash get_block_longhash(uint64_t h, const crypto::hash& block_long_ash, uint64_t nonce); -// void get_block_longhash(const block& b, crypto::hash& res); -// crypto::hash get_block_longhash(const block& b); - bool unserialize_block_complete_entry(const COMMAND_RPC_GET_BLOCKS_FAST::response& serialized, COMMAND_RPC_GET_BLOCKS_DIRECT::response& unserialized); @@ -389,8 +384,6 @@ namespace currency size_t get_max_tx_size(); 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); uint64_t get_base_block_reward(bool is_pos, uint64_t already_generated_coins, uint64_t height); - uint64_t get_scratchpad_last_update_rebuild_height(uint64_t h); - uint64_t get_scratchpad_size_for_height(uint64_t h); bool is_payment_id_size_ok(const std::string& payment_id); std::string get_account_address_as_str(const account_public_address& addr); std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const std::string& payment_id); @@ -520,41 +513,6 @@ namespace currency } return false; } - //--------------------------------------------------------------- - template - bool get_seed_for_scratchpad_cb(uint64_t height, crypto::hash& seed, block_chain_accessor_t cb) - { - //CHECK_AND_ASSERT_THROW_MES(m_db_blocks.size() > height, "Internal error: m_db_blocks.size()=" << m_db_blocks.size() << " > height=" << height); - uint64_t last_upd_h = get_scratchpad_last_update_rebuild_height(height); - std::vector seed_data; - if (last_upd_h == 0) - { - crypto::hash genesis_seed = null_hash; - bool r = epee::string_tools::hex_to_pod(CURRENCY_SCRATCHPAD_GENESIS_SEED, genesis_seed); - CHECK_AND_ASSERT_THROW_MES(r, "Unable to parse CURRENCY_SCRATCHPAD_GENESIS_SEED " << CURRENCY_SCRATCHPAD_GENESIS_SEED); - LOG_PRINT_MAGENTA("[SCRATCHPAD] GENESIS SEED SELECTED: " << genesis_seed, LOG_LEVEL_0); - seed = genesis_seed; - return true; - } - uint64_t low_bound_window = 0; - CHECK_AND_ASSERT_THROW_MES(last_upd_h >= CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW, "Internal error: last_upd_h(" << last_upd_h << ") < CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW(" << CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW << ")"); - low_bound_window = last_upd_h - CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW; - - crypto::hash selector_id = cb(last_upd_h - CURRENCY_SCRATCHPAD_BASE_INDEX_ID_OFFSET); - - const uint64_t* pselectors = (const uint64_t*)&selector_id; - std::stringstream ss; - for (size_t i = 0; i != 4; i++) - { - seed_data.push_back(cb(low_bound_window + pselectors[i] % CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW)); - ss << "[" << std::setw(8) << std::hex << pselectors[i] << "->" << low_bound_window + pselectors[i] % CURRENCY_SCRATCHPAD_SEED_BLOCKS_WINDOW << "]" << seed_data.back() << ENDL; - } - seed = crypto::cn_fast_hash(&seed_data[0], sizeof(seed_data[0]) * seed_data.size()); - - LOG_PRINT_MAGENTA("[SCRATCHPAD] SEED SELECTED: h = " << last_upd_h << ", selector: " << selector_id << ENDL << ss.str() << "SEED: " << seed, LOG_LEVEL_0); - - return true; - } //--------------------------------------------------------------- // 62387455827 -> 455827 + 7000000 + 80000000 + 300000000 + 2000000000 + 60000000000, where 455827 <= dust_threshold diff --git a/src/currency_core/miner.cpp b/src/currency_core/miner.cpp index 1a451d83..ad73b771 100644 --- a/src/currency_core/miner.cpp +++ b/src/currency_core/miner.cpp @@ -20,6 +20,7 @@ #include "string_coding.h" #include "version.h" #include "storages/portable_storage_template_helper.h" +#include "basic_pow_helpers.h" using namespace epee; @@ -64,16 +65,14 @@ namespace currency stop(); } //----------------------------------------------------------------------------------------------------- - bool miner::set_block_template(const block& bl, const wide_difficulty_type& di, uint64_t height, const crypto::hash& seed) + bool miner::set_block_template(const block& bl, const wide_difficulty_type& di, uint64_t height) { CRITICAL_REGION_LOCAL(m_template_lock); m_template = bl; m_diffic = di; m_height = height; - m_seed = seed; ++m_template_no; m_starter_nonce = crypto::rand(); - m_scratchpad.generate(m_seed, height); return true; } //----------------------------------------------------------------------------------------------------- @@ -96,13 +95,12 @@ namespace currency { extra_nonce += std::string("|") + m_extra_messages[m_config.current_extra_message_index]; } - crypto::hash seed = null_hash; - if(!m_phandler->get_block_template(bl, seed, m_mine_address, m_mine_address, di, height, extra_nonce)) + if(!m_phandler->get_block_template(bl, m_mine_address, m_mine_address, di, height, extra_nonce)) { LOG_ERROR("Failed to get_block_template()"); return false; } - set_block_template(bl, di, height, seed); + set_block_template(bl, di, height); return true; } //----------------------------------------------------------------------------------------------------- @@ -309,8 +307,8 @@ namespace currency wide_difficulty_type local_diff = 0; uint32_t local_template_ver = 0; blobdata local_blob_data; - crypto::hash local_seed = null_hash; uint64_t local_height = 0; + crypto::hash local_blob_data_hash = null_hash; //uint64_t local_template_height = 0; block b; @@ -327,14 +325,15 @@ namespace currency { CRITICAL_REGION_BEGIN(m_template_lock); b = m_template; + b.nonce = 0; local_diff = m_diffic; - local_seed = m_seed; local_height = m_height; CRITICAL_REGION_END(); //local_template_height = get_block_height(b); local_template_ver = m_template_no; nonce = m_starter_nonce + th_local_index; local_blob_data = get_block_hashing_blob(b); + local_blob_data_hash = crypto::cn_fast_hash(local_blob_data.data(), local_blob_data.size()); } if(!local_template_ver)//no any set_block_template call @@ -343,9 +342,9 @@ namespace currency epee::misc_utils::sleep_no_w(1000); continue; } - b.nonce = nonce; - access_nonce_in_block_blob(local_blob_data) = b.nonce; - crypto::hash h = m_scratchpad.get_pow_hash_from_blob(local_blob_data, local_height, local_seed); + //b.nonce = nonce; + //access_nonce_in_block_blob(local_blob_data) = b.nonce; + crypto::hash h = get_block_longhash(local_height, local_blob_data_hash, nonce); if(check_hash(h, local_diff)) { diff --git a/src/currency_core/miner.h b/src/currency_core/miner.h index 21799172..1e9d030e 100644 --- a/src/currency_core/miner.h +++ b/src/currency_core/miner.h @@ -14,26 +14,17 @@ #include "difficulty.h" #include "math_helper.h" #include "blockchain_storage.h" +#include "basic_pow_helpers.h" + -#define CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET 1 namespace currency { - inline uint64_t& access_nonce_in_block_blob(blobdata& bd) - { - return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); - } - - inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd) - { - return *reinterpret_cast(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]); - } - struct i_miner_handler { virtual bool handle_block_found(const block& b, block_verification_context* p_verification_result = nullptr) = 0; - virtual bool get_block_template(block& b, crypto::hash& seed, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()) = 0; + virtual bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry()) = 0; protected: ~i_miner_handler(){}; }; @@ -63,17 +54,17 @@ namespace currency void do_print_hashrate(bool do_hr); inline - static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height, const crypto::hash& seed, scratchpad_keeper& sk) + static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height) { + bl.nonce = 0; blobdata bd = get_block_hashing_blob(bl); - uint64_t& nonce_ref = access_nonce_in_block_blob(bd); - nonce_ref = 0; + crypto::hash bd_hash = crypto::cn_fast_hash(bd.data(), bd.size()); + //uint64_t& nonce_ref = access_nonce_in_block_blob(bd); + //nonce_ref = 0; for(; bl.nonce != std::numeric_limits::max(); bl.nonce++) { - nonce_ref = bl.nonce; - - crypto::hash h = sk.get_pow_hash_from_blob(bd, height, seed); + crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce); if(check_hash(h, diffic)) { LOG_PRINT_L0("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << "(diff:" << diffic << "), ts: " << bl.timestamp); @@ -84,7 +75,7 @@ namespace currency } private: - bool set_block_template(const block& bl, const wide_difficulty_type& diffic, uint64_t height, const crypto::hash& seed); + bool set_block_template(const block& bl, const wide_difficulty_type& diffic, uint64_t height); bool worker_thread(); bool request_block_template(); void merge_hr(); @@ -106,8 +97,6 @@ namespace currency std::atomic m_starter_nonce; wide_difficulty_type m_diffic; std::atomic m_height; - scratchpad_keeper m_scratchpad; - crypto::hash m_seed; volatile uint32_t m_thread_index; volatile uint32_t m_threads_total; std::atomic m_pausers_count; diff --git a/src/currency_core/miner_common.h b/src/currency_core/miner_common.h index 4c49e173..9c6db391 100644 --- a/src/currency_core/miner_common.h +++ b/src/currency_core/miner_common.h @@ -6,25 +6,3 @@ #pragma once -#define SCRATCHPAD_DEFAULT_FILENAME "scratchpad.bin" -#define WILD_KECCAK_ADDENDUMS_ARRAY_SIZE 10 - -#pragma pack (push, 1) - -struct export_scratchpad_hi -{ - crypto::hash prevhash; - uint64_t height; -}; -struct export_addendums_array_entry -{ - export_scratchpad_hi prev_hi; - uint64_t add_size; -}; -struct export_scratchpad_file_header -{ - export_scratchpad_hi current_hi; - export_addendums_array_entry add_arr[WILD_KECCAK_ADDENDUMS_ARRAY_SIZE]; - uint64_t scratchpad_size; -}; -#pragma pack(pop) diff --git a/src/currency_core/scratchpad_helper.cpp b/src/currency_core/scratchpad_helper.cpp deleted file mode 100644 index b52e967a..00000000 --- a/src/currency_core/scratchpad_helper.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2018-2019 Zano Project - -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include "scratchpad_helper.h" -#include "currency_format_utils.h" - - - -namespace currency -{ - scratchpad_keeper::scratchpad_keeper():m_seed(null_hash) - { - - } - //------------------------------------------------------------------------------------ - bool scratchpad_keeper::generate(const crypto::hash& scr_seed, uint64_t height) - { - bool r = false; - CRITICAL_REGION_BEGIN(m_lock); - r = crypto::generate_scratchpad(scr_seed, m_scratchpad, get_scratchpad_size_for_height(height)); - if (r) - m_seed = scr_seed; - CRITICAL_REGION_END(); - return r; - } - //------------------------------------------------------------------------------------ - 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; - if (scr_seed != m_seed || get_scratchpad_size_for_height(height) != this->size()) - { - bool r = generate(scr_seed, height); - CHECK_AND_ASSERT_THROW_MES(r, "Unable to generate scratchpad"); - } - CHECK_AND_ASSERT_THROW_MES(get_scratchpad_size_for_height(height) == this->size(), "Fatal error on hash calculation: scratchpad_size=" << m_scratchpad.size() << " at height=" << height << ", scr_seed=" << scr_seed << ", m_seed=" << m_seed); - CHECK_AND_ASSERT_THROW_MES(scr_seed == m_seed, "Fatal error on hash calculation: scratchpad_seed missmatch scr_seed=" << scr_seed << ", m_seed=" << m_seed); - - bool res = get_wild_keccak2(bd, res_hash, m_scratchpad); - CHECK_AND_ASSERT_THROW_MES(res, "Fatal error on hash calculation: scratchpad_size=" << m_scratchpad.size()); - return res_hash; - } - //------------------------------------------------------------------------------------ - - //------------------------------------------------------------------------------------ - 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> 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 deleted file mode 100644 index 515acd56..00000000 --- a/src/currency_core/scratchpad_helper.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2014-2018 Zano Project -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#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 -{ - 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_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& seed); - uint64_t size(); - private: - scratchpad_keeper(const scratchpad_keeper&) {} - crypto::hash m_seed; - std::vector m_scratchpad; - 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/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 4ba2bbf3..bf9c8994 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -783,7 +783,7 @@ namespace currency //pe.keyimage key image will be set in the wallet //pe.wallet_index is not included in serialization map, TODO: refactoring here - if (!m_core.get_block_template(b, res.seed, miner_address, stakeholder_address, dt, res.height, req.extra_text, req.pos_block, pe)) + if (!m_core.get_block_template(b, miner_address, stakeholder_address, dt, res.height, req.extra_text, req.pos_block, pe)) { error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.message = "Internal error: failed to create block template"; diff --git a/src/rpc/mining_protocol_defs.h b/src/rpc/mining_protocol_defs.h index 14665583..4a2c0f23 100644 --- a/src/rpc/mining_protocol_defs.h +++ b/src/rpc/mining_protocol_defs.h @@ -120,34 +120,6 @@ namespace mining }; }; - struct COMMAND_RPC_GET_FULLSCRATCHPAD - { - RPC_METHOD_NAME("getfullscratchpad"); - - struct request - { - std::string id; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(id) - END_KV_SERIALIZE_MAP() - }; - - struct response - { - height_info hi; - std::string scratchpad_hex; - std::string status; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hi) - KV_SERIALIZE(scratchpad_hex) - KV_SERIALIZE(status) - END_KV_SERIALIZE_MAP() - }; - }; - - struct COMMAND_RPC_SUBMITSHARE { RPC_METHOD_NAME("submit"); @@ -177,31 +149,5 @@ namespace mining }; }; - - struct COMMAND_RPC_STORE_SCRATCHPAD - { - RPC_METHOD_NAME("store_scratchpad"); - - struct request - { - std::string local_file_path; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(local_file_path) - END_KV_SERIALIZE_MAP() - }; - - struct response - { - std::string status; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - END_KV_SERIALIZE_MAP() - }; - }; - - - } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe608853..99d17fd8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,13 +29,13 @@ add_executable(net_load_tests_srv net_load_tests/srv.cpp) add_dependencies(coretests version) -target_link_libraries(coretests currency_core common crypto wallet rpc zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(difficulty-tests currency_core ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(functional_tests wallet currency_core crypto common rpc zlibstatic upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(hash-tests crypto) -target_link_libraries(hash-target-tests crypto currency_core ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(performance_tests currency_core common crypto zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -target_link_libraries(unit_tests wallet currency_core crypto common gtest_main zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(coretests currency_core common crypto wallet rpc zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(difficulty-tests currency_core ${CMAKE_THREAD_LIBS_INIT} ethash ${Boost_LIBRARIES}) +target_link_libraries(functional_tests wallet currency_core crypto common rpc zlibstatic ethash upnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(hash-tests crypto ethash) +target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(performance_tests currency_core common crypto zlibstatic ethash${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +target_link_libraries(unit_tests wallet currency_core crypto common gtest_main zlibstatic ethash${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/tests/core_tests/alias_tests.cpp b/tests/core_tests/alias_tests.cpp index 8996b88f..498287ac 100644 --- a/tests/core_tests/alias_tests.cpp +++ b/tests/core_tests/alias_tests.cpp @@ -381,8 +381,7 @@ bool gen_alias_tests::check_too_many_aliases_registration(currency::core& c, siz wide_difficulty_type diff; uint64_t height; blobdata extra = AUTO_VAL_INIT(extra); - crypto::hash seed = currency::null_hash; - bool r = c.get_block_template(b, seed, ai.m_address, ai.m_address, diff, height, extra); + bool r = c.get_block_template(b, ai.m_address, ai.m_address, diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); CHECK_AND_ASSERT_MES(b.tx_hashes.empty(), false, "block template has some txs, expected--none"); @@ -413,7 +412,7 @@ bool gen_alias_tests::check_too_many_aliases_registration(currency::core& c, siz CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == total_alias_to_gen, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count() << ", expected: " << total_alias_to_gen); // complete block template and try to process it - r = miner::find_nonce_for_given_block(b, diff, height, seed, m_scratchpad_keeper); + r = miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -1289,12 +1288,11 @@ bool gen_alias_switch_and_check_block_template::add_block_from_template(currency currency::block b; wide_difficulty_type diff; uint64_t height; - crypto::hash seed = currency::null_hash; blobdata extra = AUTO_VAL_INIT(extra); - bool r = c.get_block_template(b, seed, acc.get_public_address(), acc.get_public_address(), diff, height, extra); + bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); - r = miner::find_nonce_for_given_block(b, diff, height, seed, m_scratchpad_keeper); + r = miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -1409,12 +1407,11 @@ bool gen_alias_too_many_regs_in_block_template::add_block_from_template(currency currency::block b; wide_difficulty_type diff; uint64_t height; - crypto::hash seed = currency::null_hash; blobdata extra = AUTO_VAL_INIT(extra); - bool r = c.get_block_template(b, seed, acc.get_public_address(), acc.get_public_address(), diff, height, extra); + bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); - r = miner::find_nonce_for_given_block(b, diff, height, seed, m_scratchpad_keeper); + r = miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); diff --git a/tests/core_tests/block_reward.cpp b/tests/core_tests/block_reward.cpp index 3fdf7d3b..a7d01fd8 100644 --- a/tests/core_tests/block_reward.cpp +++ b/tests/core_tests/block_reward.cpp @@ -87,8 +87,7 @@ bool block_template_against_txs_size::c1(currency::core& c, size_t ev_index, con wide_difficulty_type diff = 0; uint64_t height = 0; g_block_txs_total_size = txs_total_size; // passing an argument to custom_fill_block_template_func via global variable (not perfect but works well) - crypto::hash seed = currency::null_hash; - r = bcs.create_block_template(b, seed, miner_addr, miner_addr, diff, height, ex_nonce, is_pos != 0, pe, &custom_fill_block_template_func); + r = bcs.create_block_template(b, miner_addr, miner_addr, diff, height, ex_nonce, is_pos != 0, pe, &custom_fill_block_template_func); CHECK_AND_ASSERT_MES(r, false, "create_block_template failed, txs_total_size = " << txs_total_size); CHECK_AND_ASSERT_MES(height == top_block_height + 1, false, "Incorrect height: " << height << ", expected: " << top_block_height + 1 << ", txs_total_size = " << txs_total_size); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 97c420db..944ffd77 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -693,15 +693,8 @@ bool test_generator::find_nounce(currency::block& blk, std::vector crypto::hash - { - return currency::get_block_hash(blocks[index]->b); - }); - - return miner::find_nonce_for_given_block(blk, dif, height, seed, m_scratchpad); + return miner::find_nonce_for_given_block(blk, dif, height); } bool test_generator::construct_genesis_block(currency::block& blk, const currency::account_base& miner_acc, uint64_t timestamp) diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 321e9882..c91d0cea 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -14,7 +14,6 @@ #include "wallet/wallet2.h" #include "test_core_time.h" #include "chaingen_helpers.h" -#include "currency_core/scratchpad_helper.h" #define TESTS_DEFAULT_FEE ((uint64_t)TX_DEFAULT_FEE) #define MK_TEST_COINS(amount) (static_cast(amount) * TESTS_DEFAULT_FEE) @@ -306,7 +305,6 @@ protected: uint64_t height; crypto::hash hash; }; - currency::scratchpad_keeper m_scratchpad_keeper; size_t m_invalid_block_index; size_t m_invalid_tx_index; size_t m_orphan_block_index; @@ -507,7 +505,6 @@ private: std::unordered_map m_blocks_info; static test_gentime_settings m_test_gentime_settings; static test_gentime_settings m_test_gentime_settings_default; - mutable currency::scratchpad_keeper m_scratchpad; }; extern const crypto::signature invalid_signature; // invalid non-null signature for test purpose @@ -872,7 +869,6 @@ namespace crypto { return o << "account: " << std::endl << " addr: " << get_account_address_as_str(acc.get_public_address()) << std::endl << - " seed: " << epee::string_tools::buff_to_hex_nodelimer(acc.get_restore_data()) << std::endl << " spend secret key: " << acc.get_keys().m_spend_secret_key << std::endl << " spend public key: " << acc.get_public_address().m_spend_public_key << std::endl << " view secret key: " << acc.get_keys().m_view_secret_key << std::endl << diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h index 69216e7d..00b193dd 100644 --- a/tests/core_tests/chaingen_helpers.h +++ b/tests/core_tests/chaingen_helpers.h @@ -11,14 +11,13 @@ // chaingen-independent helpers that may be used outside of core_tests (for ex. in functional_tests) -inline bool mine_next_pow_block_in_playtime(currency::scratchpad_keeper& scr_keeper, const currency::account_public_address& miner_addr, currency::core& c, currency::block* output = nullptr) +inline bool mine_next_pow_block_in_playtime(const currency::account_public_address& miner_addr, currency::core& c, currency::block* output = nullptr) { currency::block b = AUTO_VAL_INIT(b); currency::wide_difficulty_type diff; uint64_t height; currency::blobdata extra = AUTO_VAL_INIT(extra); - crypto::hash seed = currency::null_hash; - bool r = c.get_block_template(b, seed, miner_addr, miner_addr, diff, height, extra); + bool r = c.get_block_template(b, miner_addr, miner_addr, diff, height, extra); CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); // adjust block's timestamp to keep difficulty low @@ -28,7 +27,7 @@ inline bool mine_next_pow_block_in_playtime(currency::scratchpad_keeper& scr_kee // keep global time up with blocks' timestamps test_core_time::adjust(b.timestamp); - r = currency::miner::find_nonce_for_given_block(b, diff, height, seed, scr_keeper); + r = currency::miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -41,7 +40,7 @@ inline bool mine_next_pow_block_in_playtime(currency::scratchpad_keeper& scr_kee return true; } -inline bool mine_next_pow_block_in_playtime_with_given_txs(currency::scratchpad_keeper& scr_keeper, const currency::account_public_address& miner_addr, currency::core& c, const std::vector& txs, const crypto::hash& prev_id, uint64_t height, currency::block* output = nullptr) +inline bool mine_next_pow_block_in_playtime_with_given_txs(const currency::account_public_address& miner_addr, currency::core& c, const std::vector& txs, const crypto::hash& prev_id, uint64_t height, currency::block* output = nullptr) { struct loc_helper { @@ -73,12 +72,11 @@ inline bool mine_next_pow_block_in_playtime_with_given_txs(currency::scratchpad_ uint64_t height_from_template = 0; currency::blobdata extra = AUTO_VAL_INIT(extra); currency::pos_entry pe = AUTO_VAL_INIT(pe); - crypto::hash seed; bool r = false; { CRITICAL_REGION_LOCAL(s_locker); loc_helper::txs_accessor() = &txs; - r = c.get_blockchain_storage().create_block_template(b, seed, miner_addr, miner_addr, diff, height_from_template, extra, false, pe, loc_helper::fill_block_template_func); + r = c.get_blockchain_storage().create_block_template(b, miner_addr, miner_addr, diff, height_from_template, extra, false, pe, loc_helper::fill_block_template_func); } CHECK_AND_ASSERT_MES(r, false, "get_block_template failed"); @@ -106,7 +104,7 @@ inline bool mine_next_pow_block_in_playtime_with_given_txs(currency::scratchpad_ height = height_from_template; } - r = currency::miner::find_nonce_for_given_block(b, diff, height, seed, scr_keeper); + r = currency::miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); @@ -119,15 +117,15 @@ inline bool mine_next_pow_block_in_playtime_with_given_txs(currency::scratchpad_ return true; } -inline bool mine_next_pow_block_in_playtime_with_given_txs(currency::scratchpad_keeper& scr_keeper, const currency::account_public_address& miner_addr, currency::core& c, const std::vector& txs, currency::block* output = nullptr) +inline bool mine_next_pow_block_in_playtime_with_given_txs(const currency::account_public_address& miner_addr, currency::core& c, const std::vector& txs, currency::block* output = nullptr) { - return mine_next_pow_block_in_playtime_with_given_txs(scr_keeper, miner_addr, c, txs, currency::null_hash, SIZE_MAX, output); + return mine_next_pow_block_in_playtime_with_given_txs(miner_addr, c, txs, currency::null_hash, SIZE_MAX, output); } -inline bool mine_next_pow_blocks_in_playtime(currency::scratchpad_keeper& scr_keeper, const currency::account_public_address& miner_addr, currency::core& c, size_t blocks_count) +inline bool mine_next_pow_blocks_in_playtime(const currency::account_public_address& miner_addr, currency::core& c, size_t blocks_count) { for (size_t i = 0; i != blocks_count; i++) - if (!mine_next_pow_block_in_playtime(scr_keeper, miner_addr, c)) + if (!mine_next_pow_block_in_playtime(miner_addr, c)) return false; return true; diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index a2688df7..acfae956 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -683,19 +683,19 @@ bool gen_no_attchments_in_coinbase::c1(currency::core& c, size_t ev_index, const test_core_time::adjust(blk_0r.timestamp + DIFFICULTY_TOTAL_TARGET); block blk_a; - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_miner_acc.get_public_address(), c, &blk_a); + r = mine_next_pow_block_in_playtime(m_miner_acc.get_public_address(), c, &blk_a); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); test_core_time::adjust(blk_a.timestamp + DIFFICULTY_TOTAL_TARGET); block blk_b; - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_miner_acc.get_public_address(), c, &blk_b); + r = mine_next_pow_block_in_playtime(m_miner_acc.get_public_address(), c, &blk_b); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); test_core_time::adjust(blk_b.timestamp + DIFFICULTY_TOTAL_TARGET); block blk_c; - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_miner_acc.get_public_address(), c, &blk_c); + r = mine_next_pow_block_in_playtime(m_miner_acc.get_public_address(), c, &blk_c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // make sure the checkpoint zone is successfully left behind diff --git a/tests/core_tests/emission_test.cpp b/tests/core_tests/emission_test.cpp index 590524f7..33de91e6 100644 --- a/tests/core_tests/emission_test.cpp +++ b/tests/core_tests/emission_test.cpp @@ -66,10 +66,9 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector& events) bool escrow_altchain_meta_impl::mine_next_block_with_tx(currency::core& c, const currency::transaction& tx) { block b = AUTO_VAL_INIT(b); - bool r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx }), m_last_block_hash, m_last_block_height + 1, &b); + bool r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx }), m_last_block_hash, m_last_block_height + 1, &b); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); m_last_block_hash = get_block_hash(b); m_last_block_height = get_block_height(b); @@ -95,7 +95,7 @@ bool escrow_altchain_meta_impl::mine_next_block_with_tx(currency::core& c, const bool escrow_altchain_meta_impl::mine_next_block_with_no_tx(currency::core& c) { block b = AUTO_VAL_INIT(b); - bool r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector(), m_last_block_hash, m_last_block_height + 1, &b); + bool r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector(), m_last_block_hash, m_last_block_height + 1, &b); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); m_last_block_hash = get_block_hash(b); m_last_block_height = get_block_height(b); diff --git a/tests/core_tests/escrow_wallet_tests.cpp b/tests/core_tests/escrow_wallet_tests.cpp index f0d02778..a0045d0d 100644 --- a/tests/core_tests/escrow_wallet_tests.cpp +++ b/tests/core_tests/escrow_wallet_tests.cpp @@ -80,7 +80,7 @@ bool escrow_wallet_test::prepare_proposal_accepted_test(currency::core& c, const miner_wlt->transfer(AMOUNT_TO_TRANSFER_ESCROW + TX_DEFAULT_FEE * 2, accunt_seller.get_public_address()); LOG_PRINT_MAGENTA("Transaction sent to seller_account: " << AMOUNT_TO_TRANSFER_ESCROW + TX_DEFAULT_FEE * 2, LOG_LEVEL_0); - bool r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + bool r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); @@ -121,7 +121,7 @@ bool escrow_wallet_test::prepare_proposal_accepted_test(currency::core& c, const LOG_PRINT_MAGENTA("Escrow proposal sent bseller_account: escrow_proposal_tx id: " << currency::get_transaction_hash(escrow_proposal_tx) << ", multisig_id: " << multisig_id, LOG_LEVEL_0); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, 2); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, 2); wallet_buyer->refresh(); wallet_seller->refresh(); @@ -147,7 +147,7 @@ bool escrow_wallet_test::prepare_proposal_accepted_test(currency::core& c, const //---------------------- wallet_seller->accept_proposal(multisig_id, TX_DEFAULT_FEE); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); wallet_buyer->refresh(); wallet_seller->refresh(); @@ -197,7 +197,7 @@ bool escrow_wallet_test::exec_test_with_specific_release_type(currency::core& c, tools::wallet2::escrow_contracts_container contracts_buyer, contracts_seller; wallet_buyer->finish_contract(multisig_id, release_instruction); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, 2); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, 2); wallet_buyer->refresh(); wallet_seller->refresh(); wallet_buyer->get_contracts(contracts_buyer); @@ -230,11 +230,11 @@ bool escrow_wallet_test::exec_test_with_cancel_release_type(currency::core& c, c wallet_miner = init_playtime_test_wallet(events, c, m_mining_accunt); wallet_miner->refresh(); wallet_miner->transfer(TX_DEFAULT_FEE, wallet_buyer->get_account().get_public_address()); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, 10); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, 10); wallet_buyer->refresh(); tools::wallet2::escrow_contracts_container contracts_buyer, contracts_seller; wallet_buyer->request_cancel_contract(multisig_id, TX_DEFAULT_FEE, 60 * 60); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, 2); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, 2); wallet_buyer->refresh(); wallet_seller->refresh(); wallet_buyer->get_contracts(contracts_buyer); @@ -252,7 +252,7 @@ bool escrow_wallet_test::exec_test_with_cancel_release_type(currency::core& c, c //cancel contract wallet_seller->accept_cancel_contract(multisig_id); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, 2); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, 2); wallet_buyer->refresh(); wallet_seller->refresh(); wallet_buyer->get_contracts(contracts_buyer); @@ -396,7 +396,7 @@ bool escrow_w_and_fake_outputs::c1(currency::core& c, size_t ev_index, const std CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -406,7 +406,7 @@ bool escrow_w_and_fake_outputs::c1(currency::core& c, size_t ev_index, const std CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -416,7 +416,7 @@ bool escrow_w_and_fake_outputs::c1(currency::core& c, size_t ev_index, const std CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -441,7 +441,7 @@ bool escrow_w_and_fake_outputs::c1(currency::core& c, size_t ev_index, const std CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -651,7 +651,7 @@ bool escrow_incorrect_proposal::check_normal_proposal(currency::core& c, size_t alice_wlt->accept_proposal(contract_id, TX_DEFAULT_FEE); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -661,7 +661,7 @@ bool escrow_incorrect_proposal::check_normal_proposal(currency::core& c, size_t miner_wlt->finish_contract(contract_id, BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -788,7 +788,7 @@ bool escrow_proposal_expiration::c1(currency::core& c, size_t ev_index, const st CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); // mine a block with proposal transport tx - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -797,7 +797,7 @@ bool escrow_proposal_expiration::c1(currency::core& c, size_t ev_index, const st CHECK_AND_ASSERT_MES(refresh_wallet_and_check_contract_state("Bob", bob_wlt, tools::wallet_rpc::escrow_contract_details::proposal_sent, ms_id, 1), false, ""); // mine few block to shift the timestamp median far enough - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); // check Alice's balance @@ -866,7 +866,7 @@ bool escrow_proposal_expiration::c2(currency::core& c, size_t ev_index, const st // mine a few blocks with no txs for (size_t i = 0; i < TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW + 1; ++i) { - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); } @@ -896,7 +896,7 @@ bool escrow_proposal_expiration::c2(currency::core& c, size_t ev_index, const st CHECK_AND_ASSERT_MES(r, false, "Bob tried to accept an expired proposal, but wallet exception was not caught"); // mine a block with proposal transport tx - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // check it has left tx pool @@ -1022,7 +1022,7 @@ bool escrow_proposal_and_accept_expiration::c1(currency::core& c, size_t ev_inde // mine a few blocks with no txs for (size_t i = 0; i < TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW + 1; ++i) { - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); } @@ -1057,7 +1057,7 @@ bool escrow_proposal_and_accept_expiration::c1(currency::core& c, size_t ev_inde CHECK_AND_ASSERT_MES(r, false, "Bob tried to accept an expired proposal, but wallet exception was not caught"); LOG_PRINT_CYAN("%%%%% mine a block with proposal transport tx", LOG_LEVEL_0); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // check it has left tx pool @@ -1336,7 +1336,7 @@ bool escrow_incorrect_proposal_acceptance::check_normal_acceptance(currency::cor CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1673,7 +1673,7 @@ bool escrow_custom_test::do_custom_test(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(check_wallet_balance_blocked_for_escrow(*alice_wlt.get(), "Alice", cd.cpd.amount_a_pledge + cd.cpd.amount_to_pay), false, ""); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1712,7 +1712,7 @@ bool escrow_custom_test::do_custom_test(currency::core& c, size_t ev_index, cons false, ""); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1751,7 +1751,7 @@ bool escrow_custom_test::do_custom_test(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", bob_expected_balance, 0, INVALID_BALANCE_VAL, 0, 0), false, ""); // should not change CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1795,7 +1795,7 @@ bool escrow_custom_test::do_custom_test(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", bob_expected_balance, 0, INVALID_BALANCE_VAL, cd.is_release_normal() ? cd.cpd.amount_b_pledge + cd.cpd.amount_to_pay : 0, cd.is_release_normal() ? 0 : ms_amount - cd.b_release_fee), false, ""); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1842,7 +1842,7 @@ bool escrow_custom_test::do_custom_test(currency::core& c, size_t ev_index, cons CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "Bob", bob_expected_balance, 0, INVALID_BALANCE_VAL, bob_expected_aw_in_balance, 0), false, ""); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -2096,7 +2096,7 @@ bool escrow_incorrect_cancel_proposal::check_normal_cancel_proposal(currency::co bob_wlt->accept_cancel_contract(ms_id); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -2273,7 +2273,7 @@ bool escrow_proposal_not_enough_money::c1(currency::core& c, size_t ev_index, co CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "Alice", MK_TEST_COINS(30), 0, MK_TEST_COINS(30), 0, 0), false, ""); // mine few blocks to make sure there's no problem - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, 5); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, 5); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); // and check balance again @@ -2359,7 +2359,7 @@ bool escrow_cancellation_and_tx_order::c1(currency::core& c, size_t ev_index, co // mine a block, containing escrow proposal tx CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2377,7 +2377,7 @@ bool escrow_cancellation_and_tx_order::c1(currency::core& c, size_t ev_index, co // mine a block containing contract acceptance CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2437,8 +2437,8 @@ bool escrow_cancellation_and_tx_order::c1(currency::core& c, size_t ev_index, co CHECK_AND_ASSERT_MES(contracts.begin()->second.state == tools::wallet_rpc::escrow_contract_details::contract_released_cancelled, false, "Bob has invalid contract state: " << tools::wallet_rpc::get_escrow_contract_state_name(contracts.begin()->second.state)); // mine a block containing only cancel_request_acceptance_tx (this should trigger contracts' states swtiching into contract_released_cancelled) - LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, cancel_request_acceptance_tx)", LOG_LEVEL_0); - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({cancel_request_acceptance_tx})); + LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime_with_given_txs(cancel_request_acceptance_tx)", LOG_LEVEL_0); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({cancel_request_acceptance_tx})); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2458,8 +2458,8 @@ bool escrow_cancellation_and_tx_order::c1(currency::core& c, size_t ev_index, co // mine a block containing only cancel_request_tx (this SHOULD NOT trigger contracts' states swtiching into contract_cancel_proposal_sent or anything) - LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, cancel_request_tx)", LOG_LEVEL_0); - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({cancel_request_tx})); + LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime_with_given_txs(cancel_request_tx)", LOG_LEVEL_0); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({cancel_request_tx})); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2563,7 +2563,7 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in // mine a block, containing escrow proposal tx CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2584,7 +2584,7 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in // mine a block containing contract acceptance CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2621,7 +2621,7 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in // mine a few blocks with no txs to shift expiration median for(size_t i = 0; i < 7; ++i) { - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); } // cancellation request is still in the pool @@ -2649,8 +2649,8 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in CHECK_AND_ASSERT_MES(refresh_wallet_and_check_1_contract_state("Bob", bob_wlt, tools::wallet_rpc::escrow_contract_details::contract_accepted, 7), false, ""); // mine a block containing cancel_request_tx (already expired) -- should be okay - LOG_PRINT_GREEN("\n\n\n" "mine_next_pow_block_in_playtime(m_scratchpad_keeper, ) -- including expires contract cancellation request" "\n\n", LOG_LEVEL_0); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + LOG_PRINT_GREEN("\n\n\n" "mine_next_pow_block_in_playtime() -- including expires contract cancellation request" "\n\n", LOG_LEVEL_0); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2684,8 +2684,8 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in CHECK_AND_ASSERT_MES(refresh_wallet_and_check_1_contract_state("Bob", bob_wlt, tools::wallet_rpc::escrow_contract_details::contract_cancel_proposal_sent, 0), false, ""); // mine a block containing cancel_request_tx - LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime(m_scratchpad_keeper, )", LOG_LEVEL_0); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime()", LOG_LEVEL_0); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2694,8 +2694,8 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in CHECK_AND_ASSERT_MES(refresh_wallet_and_check_1_contract_state("Bob", bob_wlt, tools::wallet_rpc::escrow_contract_details::contract_cancel_proposal_sent, 1), false, ""); // mine one more block (it's necessary for triggering expiration checks in wallets and shifting an expiration ts median) - LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime(m_scratchpad_keeper, )", LOG_LEVEL_0); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, 7); + LOG_PRINT_GREEN("\n" "mine_next_pow_block_in_playtime()", LOG_LEVEL_0); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, 7); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2810,7 +2810,7 @@ bool escrow_cancellation_acceptance_expiration::c1(currency::core& c, size_t ev_ // mine a block, containing escrow proposal tx CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2825,7 +2825,7 @@ bool escrow_cancellation_acceptance_expiration::c1(currency::core& c, size_t ev_ // mine a block containing contract acceptance CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2838,7 +2838,7 @@ bool escrow_cancellation_acceptance_expiration::c1(currency::core& c, size_t ev_ // confirm cancellation request in blockchain CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); + CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); // contract state in wallets should be cancel_proposal_sent for both parties @@ -2862,7 +2862,7 @@ bool escrow_cancellation_acceptance_expiration::c1(currency::core& c, size_t ev_ // mine a few blocks with no txs to shift expiration median, cancellation acceptance is still in the pool for(size_t i = 0; i < 7; ++i) { - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); } CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -2886,7 +2886,7 @@ bool escrow_cancellation_acceptance_expiration::c1(currency::core& c, size_t ev_ CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); // mine a block with cancel_accept_tx (already expired). It should be rejected - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ cancel_accept_tx })); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ cancel_accept_tx })); CHECK_AND_ASSERT_MES(!r, false, "mine_next_pow_block_in_playtime_with_given_txs should have been failed as block contains expired tx"); // no changes with contract state expected @@ -2968,6 +2968,6 @@ bool escrow_proposal_acceptance_in_alt_chain::generate(std::vector& events) { - //mine_next_pow_block_in_playtime(m_scratchpad_keeper, ) + //mine_next_pow_block_in_playtime() return true; } diff --git a/tests/core_tests/misc_tests.cpp b/tests/core_tests/misc_tests.cpp index 80c800ca..ac4feddd 100644 --- a/tests/core_tests/misc_tests.cpp +++ b/tests/core_tests/misc_tests.cpp @@ -347,7 +347,7 @@ bool block_template_vs_invalid_txs_from_pool::check_block_template(currency::cor bool r = false; currency::block b = AUTO_VAL_INIT(b); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, addr, c, &b); + r = mine_next_pow_block_in_playtime(addr, c, &b); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); return true; diff --git a/tests/core_tests/mixin_attr.cpp b/tests/core_tests/mixin_attr.cpp index 3d68039b..ac4fec15 100644 --- a/tests/core_tests/mixin_attr.cpp +++ b/tests/core_tests/mixin_attr.cpp @@ -289,7 +289,7 @@ bool mix_in_spent_outs::c1(currency::core& c, size_t ev_index, const std::vector CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of txs in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are txs in the pool"); diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index 73bd4162..663b24c8 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -160,7 +160,7 @@ bool multisig_wallet_test::c1(currency::core& c, size_t ev_index, const std::vec transaction result_tx = AUTO_VAL_INIT(result_tx); miner_wlt->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx); - bool r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + bool r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); //findout multisig out intex @@ -175,7 +175,7 @@ bool multisig_wallet_test::c1(currency::core& c, size_t ev_index, const std::vec crypto::hash multisig_id = get_multisig_out_id(result_tx, i); CHECK_AND_ASSERT_MES(multisig_id != null_hash, false, "Multisig failed: failed to get get_multisig_out_id"); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); std::shared_ptr wallet_a = init_playtime_test_wallet(events, c, m_accunt_a); @@ -208,7 +208,7 @@ bool multisig_wallet_test::c1(currency::core& c, size_t ev_index, const std::vec tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); wallet_a->refresh(); @@ -300,7 +300,7 @@ bool multisig_wallet_test_many_dst::c1(currency::core& c, size_t ev_index, const CHECK_AND_ASSERT_MES(it != result_tx.vout.end(), false, "Can't find output txout_multisig"); size_t multisig_index = it - result_tx.vout.begin(); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); std::shared_ptr w = init_playtime_test_wallet(events, c, addresses[0]); @@ -317,7 +317,7 @@ bool multisig_wallet_test_many_dst::c1(currency::core& c, size_t ev_index, const transfer_multisig(*w.get(), owner_keys, get_multisig_out_id(result_tx, multisig_index), std::vector({ de2 }), 0, TESTS_DEFAULT_FEE, std::vector(), std::vector(), tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); TMP_LOG_RESTORE; - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]); @@ -428,7 +428,7 @@ bool multisig_wallet_heterogenous_dst::c1(currency::core& c, size_t ev_index, co // Mine a block and make sure tx was put into it CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -487,7 +487,7 @@ bool multisig_wallet_heterogenous_dst::c1(currency::core& c, size_t ev_index, co 0, TX_DEFAULT_FEE, std::vector(), std::vector(), tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // Once Bob refreshes his wallet he should see that Alice has already spent they shared multisig @@ -549,7 +549,7 @@ bool multisig_wallet_heterogenous_dst::c1(currency::core& c, size_t ev_index, co 0, TX_DEFAULT_FEE, std::vector(), std::vector(), tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are txs in the pool."); @@ -584,7 +584,7 @@ bool multisig_wallet_heterogenous_dst::c1(currency::core& c, size_t ev_index, co CHECK_AND_ASSERT_MES(caught, false, "Dan was able to make multisig tx for alreadly spent output"); // Miner mines the next PoW block, confirming Alice's transaction. - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are txs in the pool."); @@ -689,7 +689,7 @@ bool multisig_wallet_same_dst_addr::c1(currency::core& c, size_t ev_index, const // mine the next PoW and make sure everythig is allright CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of tx in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are transactions in the pool"); @@ -707,7 +707,7 @@ bool multisig_wallet_same_dst_addr::c1(currency::core& c, size_t ev_index, const 0, TX_DEFAULT_FEE, empty_extra, empty_attachment, tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of tx in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are transactions in the pool"); @@ -778,7 +778,7 @@ bool multisig_wallet_ms_to_ms::c1(currency::core& c, size_t ev_index, const std: // mine the next PoW and make sure everythig is allright CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of tx in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are transactions in the pool"); @@ -802,7 +802,7 @@ bool multisig_wallet_ms_to_ms::c1(currency::core& c, size_t ev_index, const std: // check the pool and mine a block CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of tx in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are transactions in the pool"); @@ -818,7 +818,7 @@ bool multisig_wallet_ms_to_ms::c1(currency::core& c, size_t ev_index, const std: 0, TX_DEFAULT_FEE, empty_extra, empty_attachment, tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect number of tx in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "There are transactions in the pool"); @@ -2490,14 +2490,14 @@ bool multisig_unconfirmed_transfer_and_multiple_scan_pool_calls::c1(currency::co transaction key_to_ms_tx = AUTO_VAL_INIT(key_to_ms_tx); miner_wlt->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, tools::detail::digit_split_strategy, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), key_to_ms_tx); - bool r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, miner_acc.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + bool r = mine_next_pow_blocks_in_playtime(miner_acc.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); size_t ms_out_idx = get_multisig_out_index(key_to_ms_tx.vout); crypto::hash multisig_id = get_multisig_out_id(key_to_ms_tx, ms_out_idx); CHECK_AND_ASSERT_MES(multisig_id != null_hash, false, "Multisig failed: failed to get get_multisig_out_id"); - //r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, miner_acc.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + //r = mine_next_pow_blocks_in_playtime(miner_acc.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); //CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, alice_acc); diff --git a/tests/core_tests/offers_test.cpp b/tests/core_tests/offers_test.cpp index 8a24e711..ca72b906 100644 --- a/tests/core_tests/offers_test.cpp +++ b/tests/core_tests/offers_test.cpp @@ -567,7 +567,7 @@ bool offers_handling_on_chain_switching::c1(currency::core& c, size_t ev_index, uint64_t blk_1r_height = c.get_current_blockchain_size() - 2; crypto::hash blk_1r_id = c.get_block_id_by_height(blk_1r_height); block blk_2a = AUTO_VAL_INIT(blk_2a); - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector(), blk_1r_id, blk_1r_height + 1, &blk_2a); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector(), blk_1r_id, blk_1r_height + 1, &blk_2a); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -577,7 +577,7 @@ bool offers_handling_on_chain_switching::c1(currency::core& c, size_t ev_index, // mine second alt block (include offer tx) -- this should trigger chain switching block blk_3a = AUTO_VAL_INIT(blk_3a); - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({tx_1}), get_block_hash(blk_2a), blk_1r_height + 2, &blk_3a); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({tx_1}), get_block_hash(blk_2a), blk_1r_height + 2, &blk_3a); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); @@ -673,7 +673,7 @@ bool offer_removing_and_selected_output::check_offers(currency::core& c, size_t crypto::hash create_offer_tx_id = get_transaction_hash(create_offer_tx); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); + CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); refresh_wallet_and_check_balance("offer's put into the blockchain", "Alice", alice_wlt, alice_start_balance - od.fee, true, 1); @@ -699,7 +699,7 @@ bool offer_removing_and_selected_output::check_offers(currency::core& c, size_t // add it to the blockchain CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); + CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c), false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); // Alice's banace should not change @@ -937,7 +937,7 @@ bool offers_updating_hack::update_foreign_offer(currency::core& c, size_t ev_ind // put in a block 'tx', leave Alice's tx in the pool CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx })), false, "mine_next_pow_block_in_playtime failed"); + CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx })), false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); LOG_PRINT_L0(ENDL << c.get_tx_pool().print_pool(true)); @@ -1005,7 +1005,7 @@ bool offers_updating_hack::delete_foreign_offer(currency::core& c, size_t ev_ind // put in a block 'tx', leave Alice's tx in the pool CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); - CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx_c })), false, "mine_next_pow_block_in_playtime failed"); + CHECK_AND_ASSERT_MES(mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector({ tx_c })), false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); LOG_PRINT_L0(ENDL << c.get_tx_pool().print_pool(true)); @@ -1264,7 +1264,7 @@ bool offer_lifecycle_via_tx_pool::c1(currency::core& c, size_t ev_index, const s CATCH_ENTRY2(false); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, some_addr, c); + r = mine_next_pow_block_in_playtime(some_addr, c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); @@ -1280,7 +1280,7 @@ bool offer_lifecycle_via_tx_pool::c1(currency::core& c, size_t ev_index, const s CATCH_ENTRY2(false); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, some_addr, c); + r = mine_next_pow_block_in_playtime(some_addr, c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); @@ -1297,7 +1297,7 @@ bool offer_lifecycle_via_tx_pool::c1(currency::core& c, size_t ev_index, const s CATCH_ENTRY2(false); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, some_addr, c); + r = mine_next_pow_block_in_playtime(some_addr, c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); @@ -1313,7 +1313,7 @@ bool offer_lifecycle_via_tx_pool::c1(currency::core& c, size_t ev_index, const s CATCH_ENTRY2(false); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, some_addr, c); + r = mine_next_pow_block_in_playtime(some_addr, c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Invalid tx pool count: " << c.get_pool_transactions_count() << ENDL << "tx pool:" << ENDL << c.get_tx_pool().print_pool(true)); diff --git a/tests/core_tests/pos_validation.cpp b/tests/core_tests/pos_validation.cpp index a137fc8f..7d8af42a 100644 --- a/tests/core_tests/pos_validation.cpp +++ b/tests/core_tests/pos_validation.cpp @@ -495,7 +495,7 @@ bool pos_wallet_minting_same_amount_diff_outs::prepare_wallets_0(currency::core& r = populate_wallet_with_stake_coins(w.w, alice_wlt, w.pos_entries_count, m_wallet_stake_amount, pos_amounts); CHECK_AND_ASSERT_MES(r, false, "populate_wallet_with_stake_coins failed"); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, alice_wlt->get_account().get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE + 1); // to preventing run out of the money for Alice + r = mine_next_pow_blocks_in_playtime(alice_wlt->get_account().get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE + 1); // to preventing run out of the money for Alice CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); c.get_blockchain_storage().get_top_block(b); uint64_t ts = b.timestamp; @@ -552,7 +552,7 @@ bool pos_wallet_minting_same_amount_diff_outs::prepare_wallets_1(currency::core& r = populate_wallet_with_stake_coins(w.w, alice_wlt, w.pos_entries_count, m_wallet_stake_amount, pos_amounts); CHECK_AND_ASSERT_MES(r, false, "populate_wallet_with_stake_coins failed"); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, alice_wlt->get_account().get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE + 1); // to preventing run out of the money for Alice + r = mine_next_pow_blocks_in_playtime(alice_wlt->get_account().get_public_address(), c, WALLET_DEFAULT_TX_SPENDABLE_AGE + 1); // to preventing run out of the money for Alice CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); c.get_blockchain_storage().get_top_block(b); uint64_t ts = b.timestamp; @@ -662,7 +662,7 @@ bool pos_wallet_minting_same_amount_diff_outs::c1(currency::core& c, size_t ev_i ts = ideal_next_pow_block_ts; // "wait" until ideal_next_pow_block_ts if it was not already happened (fast forward but don't wayback the time) test_core_time::adjust(ts); size_t tx_count_before = c.get_pool_transactions_count(); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(tx_count_before == 0 || c.get_pool_transactions_count() < tx_count_before, false, "invalid number of txs in tx pool: " << c.get_pool_transactions_count() << ", was: " << tx_count_before); last_pow_block_ts = ts; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 5062d752..b8af35f7 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -1309,7 +1309,7 @@ bool tx_expiration_time_and_block_template::c1(currency::core& c, size_t ev_inde CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect tx count in the pool: " << c.get_pool_transactions_count()); account_public_address addr = AUTO_VAL_INIT(addr); - bool r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, addr, c); + bool r = mine_next_pow_block_in_playtime(addr, c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // tx MAY stay in the pool, check it as forced condition (may change in future) diff --git a/tests/core_tests/wallet_rpc_tests.cpp b/tests/core_tests/wallet_rpc_tests.cpp index 34293b18..c4ee2e51 100644 --- a/tests/core_tests/wallet_rpc_tests.cpp +++ b/tests/core_tests/wallet_rpc_tests.cpp @@ -137,7 +137,7 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count()); @@ -171,7 +171,7 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind CHECK_AND_ASSERT_MES(r, false, "RPC call failed, code: " << je.code << ", msg: " << je.message); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count()); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index 71427959..0cbc7551 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -1179,7 +1179,7 @@ bool gen_wallet_oversized_payment_id::c1(currency::core& c, size_t ev_index, con CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Tx pool has incorrect number of txs: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count()); @@ -1215,7 +1215,7 @@ bool gen_wallet_oversized_payment_id::c1(currency::core& c, size_t ev_index, con CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Tx pool has incorrect number of txs: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count()); @@ -1769,7 +1769,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_ CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - bool r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + bool r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -1790,7 +1790,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_ CHECK_AND_ASSERT_MES(l->m_result, false, "Wrong wti received via callback"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 2, false, "Incorrect blockchain size"); @@ -1803,7 +1803,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_ alice_wlt->request_alias_update(ai, res_tx, TX_DEFAULT_FEE, 0); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 3, false, "Incorrect blockchain size"); @@ -2072,7 +2072,7 @@ bool gen_wallet_offers_basic::c1(currency::core& c, size_t ev_index, const std:: CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool"); - bool r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + bool r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -2123,7 +2123,7 @@ bool gen_wallet_offers_basic::c1(currency::core& c, size_t ev_index, const std:: CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -2154,7 +2154,7 @@ bool gen_wallet_offers_basic::c1(currency::core& c, size_t ev_index, const std:: CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool"); @@ -2274,7 +2274,7 @@ bool gen_wallet_offers_size_limit::c1(currency::core& c, size_t ev_index, const log_space::get_set_log_detalisation_level(true, log_level); // restore CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); miner_wlt->refresh(blocks_fetched, received_money, atomic_false); CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect numbers of blocks fetched"); @@ -2373,7 +2373,7 @@ bool gen_wallet_dust_to_account::c1(currency::core& c, size_t ev_index, const st CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - bool r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + bool r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); miner_wlt->refresh(blocks_fetched, received_money, atomic_false); @@ -2473,7 +2473,7 @@ bool gen_wallet_selecting_pos_entries::c1(currency::core& c, size_t ev_index, co CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3 + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE - 1, false, "Incorrect current blockchain height"); // this block should unlock the money and PoS-entries should become available - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); alice_wlt->refresh(blocks_fetched, received_money, atomic_false); CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect number of blocks fetched"); @@ -2497,7 +2497,7 @@ bool gen_wallet_selecting_pos_entries::c1(currency::core& c, size_t ev_index, co alice_wlt->transfer(dst, 0, 0, TX_DEFAULT_FEE, std::vector(), std::vector()); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); alice_wlt->refresh(blocks_fetched, received_money, atomic_false); CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect number of blocks fetched"); @@ -2571,7 +2571,7 @@ bool gen_wallet_spending_coinstake_after_minting::c1(currency::core& c, size_t e CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool"); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); alice_wlt->refresh(blocks_fetched, received_money, atomic_false); CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect number of blocks fetched"); @@ -2878,7 +2878,7 @@ bool mined_balance_wallet_test::c1(currency::core& c, size_t ev_index, const std std::list blocks; size_t n = CURRENCY_MINED_MONEY_UNLOCK_WINDOW; - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, n); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, n); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); r = bcs.get_blocks(bcs.get_current_blockchain_size() - n, n, blocks); CHECK_AND_ASSERT_MES(r, false, "get_blocks failed"); @@ -2994,11 +2994,11 @@ bool wallet_outputs_with_same_key_image::c1(currency::core& c, size_t ev_index, bool r = refresh_wallet_and_check_balance("before tx_1 and tx_2 added", "Alice", alice_wlt, MK_TEST_COINS(3) * 2, true, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2, 0); CHECK_AND_ASSERT_MES(r, false, ""); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "there are txs in the pool!"); - r = mine_next_pow_blocks_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed"); // only one tx_1 output is counted as the tx_2 output has the very same key image @@ -3017,7 +3017,7 @@ bool wallet_outputs_with_same_key_image::c1(currency::core& c, size_t ev_index, } CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "wrong tx count in the pool: " << c.get_pool_transactions_count()); - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "there are txs in the pool!"); @@ -3097,7 +3097,7 @@ bool wallet_unconfirmed_tx_expiration::c1(currency::core& c, size_t ev_index, co // mine a few block with no tx, so Alice's tx is expired in the pool for (size_t i = 0; i < 5; ++i) { - r = mine_next_pow_block_in_playtime_with_given_txs(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); + r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector()); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed"); } @@ -3114,7 +3114,7 @@ bool wallet_unconfirmed_tx_expiration::c1(currency::core& c, size_t ev_index, co CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Invalid txs count in the pool: " << c.get_pool_transactions_count()); // mine one more block to trigger wallet's on_idle() and outdated tx clearing - r = mine_next_pow_block_in_playtime(m_scratchpad_keeper, m_accounts[MINER_ACC_IDX].get_public_address(), c); + r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c); CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed"); // make sure all Alice's money are unlocked and no coins were actually spent diff --git a/tests/functional_tests/core_concurrency_test.cpp b/tests/functional_tests/core_concurrency_test.cpp index 11594763..23bb8885 100644 --- a/tests/functional_tests/core_concurrency_test.cpp +++ b/tests/functional_tests/core_concurrency_test.cpp @@ -101,17 +101,14 @@ bool generate_events(currency::core& c, cct_events_t& events, const cct_wallets_ const currency::account_public_address& miner_addr = wallets[random_in_range(0, wallets.size() - 1)]->get_account().get_public_address(); currency::block b = AUTO_VAL_INIT(b); - currency::scratchpad_keeper sk; - crypto::hash seed = currency::null_hash; - sk.generate(seed, height); if (is_in_main_chain) { blobdata ex_nonce; wide_difficulty_type diff = 0; if (prev_block.height != 0) test_core_time::adjust(prev_block.bl.timestamp + DIFFICULTY_POW_TARGET); - r = bcs.create_block_template(b, seed, miner_addr, diff, height, ex_nonce); + r = bcs.create_block_template(b, miner_addr, diff, height, ex_nonce); CHECK_AND_ASSERT_MES(r, false, "create_block_template failed"); } else @@ -145,7 +142,7 @@ bool generate_events(currency::core& c, cct_events_t& events, const cct_wallets_ test_core_time::adjust(b.timestamp); currency::wide_difficulty_type diff = 0; - r = currency::miner::find_nonce_for_given_block(b, diff, height, seed, sk); + r = currency::miner::find_nonce_for_given_block(b, diff, height); CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed"); currency::block_verification_context bvc = AUTO_VAL_INIT(bvc); diff --git a/tests/performance_tests/keccak_test.h b/tests/performance_tests/keccak_test.h index 3553ec1a..e6579cb2 100644 --- a/tests/performance_tests/keccak_test.h +++ b/tests/performance_tests/keccak_test.h @@ -4,126 +4,92 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once - -#include "crypto/crypto.h" -#include "currency_core/currency_basic.h" -#include "profile_tools.h" - -extern "C" { -#include "crypto/keccak.h" -//#include "crypto/alt/KeccakNISTInterface.h" -} - - -#include "crypto/wild_keccak.h" -//#include "crypto/wild_keccak2.h" -#include "../core_tests/random_helper.h" -#include "crypto/hash.h" - - - - -#define TEST_BUFF_LEN 200 - -class test_keccak_base -{ -public: - static const size_t loop_count = 100000; - - bool init() - { - currency::block b; - m_buff = currency::get_block_hashing_blob(b); - m_buff.append(32 * 4, 0); - return true; - } - - bool pretest() - { - ++m_buff[0]; - if (!m_buff[0]) - ++m_buff[0]; - return true; - } -protected: - std::string m_buff; -}; - -// class test_keccak : public test_keccak_base +// +// #include "crypto/crypto.h" +// #include "currency_core/currency_basic.h" +// #include "profile_tools.h" +// +// extern "C" { +// #include "crypto/keccak.h" +// //#include "crypto/alt/KeccakNISTInterface.h" +// } +// +// +// #include "crypto/wild_keccak.h" +// //#include "crypto/wild_keccak2.h" +// #include "../core_tests/random_helper.h" +// #include "crypto/hash.h" +// +// +// +// +// #define TEST_BUFF_LEN 200 +// +// class test_keccak_base +// { +// public: +// static const size_t loop_count = 100000; +// +// bool init() +// { +// currency::block b; +// m_buff = currency::get_block_hashing_blob(b); +// m_buff.append(32 * 4, 0); +// return true; +// } +// +// bool pretest() +// { +// ++m_buff[0]; +// if (!m_buff[0]) +// ++m_buff[0]; +// return true; +// } +// protected: +// std::string m_buff; +// }; +// +// // class test_keccak : public test_keccak_base +// // { +// // public: +// // bool test() +// // { +// // pretest(); +// // crypto::hash h; +// // keccak(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); +// // LOG_PRINT_L4(h); +// // return true; +// // } +// // }; +// +// +// class test_keccak_generic : public test_keccak_base // { // public: // bool test() // { // pretest(); // crypto::hash h; -// keccak(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); +// crypto::keccak_generic(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); // LOG_PRINT_L4(h); // return true; // } // }; - - -class test_keccak_generic : public test_keccak_base -{ -public: - bool test() - { - pretest(); - crypto::hash h; - crypto::keccak_generic(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); - LOG_PRINT_L4(h); - return true; - } -}; - -class test_keccak_generic_with_mul : public test_keccak_base -{ -public: - bool test() - { - pretest(); - crypto::hash h; - crypto::keccak_generic(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); - return true; - } -}; - -template -class test_wild_keccak : public test_keccak_base -{ -public: - bool init() - { - m_scratchpad_vec.resize(scratchpad_size / sizeof(crypto::hash)); - for (auto& h : m_scratchpad_vec) - h = crypto::rand(); - - return test_keccak_base::init(); - } - - bool test() - { - pretest(); - - crypto::hash h; - crypto::wild_keccak_dbl(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h), [&](crypto::state_t_m& st, crypto::mixin_t& mix) - { -#define SCR_I(i) m_scratchpad_vec[st[i]%m_scratchpad_vec.size()] - for (size_t i = 0; i != 6; i++) - { - OPT_XOR_4_RES(SCR_I(i * 4), SCR_I(i * 4 + 1), SCR_I(i * 4 + 2), SCR_I(i * 4 + 3), *(crypto::hash*)&mix[i * 4]); - } - }); - - return true; - } -protected: - std::vector m_scratchpad_vec; -}; - +// +// class test_keccak_generic_with_mul : public test_keccak_base +// { +// public: +// bool test() +// { +// pretest(); +// crypto::hash h; +// crypto::keccak_generic(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h)); +// return true; +// } +// }; // // template -// class test_wild_keccak2 : public test_keccak_base +// class test_wild_keccak : public test_keccak_base // { // public: // bool init() @@ -139,102 +105,136 @@ protected: // { // pretest(); // -// crypto::hash h2; -// crypto::wild_keccak_dbl_opt(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h2), sizeof(h2), (const UINT64*)&m_scratchpad_vec[0], m_scratchpad_vec.size() * 4); -// LOG_PRINT_L4("HASH:" << h2); +// crypto::hash h; +// crypto::wild_keccak_dbl(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h), sizeof(h), [&](crypto::state_t_m& st, crypto::mixin_t& mix) +// { +// #define SCR_I(i) m_scratchpad_vec[st[i]%m_scratchpad_vec.size()] +// for (size_t i = 0; i != 6; i++) +// { +// OPT_XOR_4_RES(SCR_I(i * 4), SCR_I(i * 4 + 1), SCR_I(i * 4 + 2), SCR_I(i * 4 + 3), *(crypto::hash*)&mix[i * 4]); +// } +// }); +// // return true; // } // protected: // std::vector m_scratchpad_vec; // }; - -#ifdef _DEBUG - #define max_measere_scratchpad 100000 -#else - #define max_measere_scratchpad 50000000 -#endif -#define measere_rounds 10000 - -void generate_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_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) << "w2\t" << -// 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"; - - for (size_t j = 0; j != scratchpad_vec.size(); j++) - scratchpad_vec[j] = crypto::rand(); - - 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; - - uint64_t ticks_b = epee::misc_utils::get_tick_count(); - for (size_t r = 0; r != measere_rounds; r++) - { - *(size_t*)(&has_str[1]) = r; - crypto::get_wild_keccak(has_str, res_h, 1, scratchpad_vec, i); - } - - //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::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++) - { - crypto::get_wild_keccak2(has_str, res_h, scratchpad_vec, i); - } - - 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_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); -} +// +// // +// // template +// // class test_wild_keccak2 : public test_keccak_base +// // { +// // public: +// // bool init() +// // { +// // m_scratchpad_vec.resize(scratchpad_size / sizeof(crypto::hash)); +// // for (auto& h : m_scratchpad_vec) +// // h = crypto::rand(); +// // +// // return test_keccak_base::init(); +// // } +// // +// // bool test() +// // { +// // pretest(); +// // +// // crypto::hash h2; +// // crypto::wild_keccak_dbl_opt(reinterpret_cast(&m_buff[0]), m_buff.size(), reinterpret_cast(&h2), sizeof(h2), (const UINT64*)&m_scratchpad_vec[0], m_scratchpad_vec.size() * 4); +// // LOG_PRINT_L4("HASH:" << h2); +// // return true; +// // } +// // protected: +// // std::vector m_scratchpad_vec; +// // }; +// +// #ifdef _DEBUG +// #define max_measere_scratchpad 100000 +// #else +// #define max_measere_scratchpad 50000000 +// #endif +// #define measere_rounds 10000 +// +// void generate_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_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) << "w2\t" << +// // 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"; +// +// for (size_t j = 0; j != scratchpad_vec.size(); j++) +// scratchpad_vec[j] = crypto::rand(); +// +// 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; +// +// uint64_t ticks_b = epee::misc_utils::get_tick_count(); +// for (size_t r = 0; r != measere_rounds; r++) +// { +// *(size_t*)(&has_str[1]) = r; +// crypto::get_wild_keccak(has_str, res_h, 1, scratchpad_vec, i); +// } +// +// //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::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++) +// { +// crypto::get_wild_keccak2(has_str, res_h, scratchpad_vec, i); +// } +// +// 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_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 c6b88c64..37591d6a 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -38,7 +38,7 @@ int main(int argc, char** argv) //generate_scratchpad(); //generate_light_scratchpad(); //measure_keccak_over_scratchpad(); - test_scratchpad_against_light_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 523aeed1..f74c1ad9 100644 --- a/tests/unit_tests/pow_hash_test.cpp +++ b/tests/unit_tests/pow_hash_test.cpp @@ -10,42 +10,42 @@ #include "crypto/crypto.h" #include "currency_core/currency_basic.h" #include "profile_tools.h" -#include "crypto/wild_keccak.h" +//#include "crypto/wild_keccak.h" #include "currency_core/currency_format_utils.h" using namespace currency; - -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); - - 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) - { - LOG_ERROR("Hash missmatch"); - return false; - } - return true; -} - -TEST(pow_tests, test_full_against_light) -{ - bool res = test_scratchpad_against_light_scratchpad(); - ASSERT_TRUE(res); -} +// +// 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); +// +// 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) +// { +// LOG_ERROR("Hash missmatch"); +// return false; +// } +// return true; +// } +// +// TEST(pow_tests, test_full_against_light) +// { +// bool res = test_scratchpad_against_light_scratchpad(); +// ASSERT_TRUE(res); +// }