forked from lthn/blockchain
Merge branch 'master' into frontend
This commit is contained in:
commit
6246eccc1b
78 changed files with 4836 additions and 1158 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@ Building
|
|||
|
||||
Recommended OS version: Ubuntu 17.04 LTS.
|
||||
|
||||
1. `$ sudo apt install git g++ cmake unzip libicu-dev mesa-common-dev libglu1-mesa-dev qt5-default qtwebengine5-dev`
|
||||
1. For server version: \
|
||||
`$ sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git libboost-all-dev screen`\
|
||||
For GUI version:\
|
||||
`$ sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git libboost-all-dev screen mesa-common-dev libglu1-mesa-dev qt5-default qtwebengine5-dev`
|
||||
|
||||
2. `$ cd zano/ && make -j$(nproc) gui`
|
||||
3. Look for the binaries, including the `Zano` GUI, in the build directory
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Build test executables")
|
|||
add_subdirectory(miniupnpc)
|
||||
add_subdirectory(zlib)
|
||||
add_subdirectory(db)
|
||||
|
||||
add_subdirectory(ethereum)
|
||||
|
||||
|
||||
set_property(TARGET upnpc-static PROPERTY FOLDER "contrib")
|
||||
|
|
@ -13,6 +13,7 @@ set_property(TARGET lmdb PROPERTY FOLDER "contrib")
|
|||
|
||||
|
||||
|
||||
|
||||
if(MSVC)
|
||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
else()
|
||||
|
|
|
|||
10
contrib/ethereum/CMakeLists.txt
Normal file
10
contrib/ethereum/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
add_subdirectory(libethash)
|
||||
|
||||
set_property(TARGET ethash PROPERTY FOLDER "contrib")
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(ethash PRIVATE /wd4477 /wd4267)
|
||||
else()
|
||||
target_compile_options(ethash PRIVATE -Wno-format -Wno-aggregate-return -Wno-empty-body)
|
||||
endif()
|
||||
|
||||
33
contrib/ethereum/libethash/CMakeLists.txt
Normal file
33
contrib/ethereum/libethash/CMakeLists.txt
Normal file
|
|
@ -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.
|
||||
|
||||
# set(include_dir ${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
81
contrib/ethereum/libethash/bit_manipulation.h
Normal file
81
contrib/ethereum/libethash/bit_manipulation.h
Normal file
|
|
@ -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 <stdint.h>
|
||||
|
||||
#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
|
||||
43
contrib/ethereum/libethash/builtins.h
Normal file
43
contrib/ethereum/libethash/builtins.h
Normal file
|
|
@ -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 <intrin.h>
|
||||
|
||||
#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
|
||||
98
contrib/ethereum/libethash/endianness.hpp
Normal file
98
contrib/ethereum/libethash/endianness.hpp
Normal file
|
|
@ -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 <ethash/ethash.hpp>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#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 <machine/endian.h>
|
||||
|
||||
#define bswap32 __builtin_bswap32
|
||||
#define bswap64 __builtin_bswap64
|
||||
|
||||
#else
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#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
|
||||
69
contrib/ethereum/libethash/ethash-internal.hpp
Normal file
69
contrib/ethereum/libethash/ethash-internal.hpp
Normal file
|
|
@ -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 <ethash/ethash.hpp>
|
||||
|
||||
#include "endianness.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
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
|
||||
441
contrib/ethereum/libethash/ethash.cpp
Normal file
441
contrib/ethereum/libethash/ethash.cpp
Normal file
|
|
@ -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 <ethash/keccak.hpp>
|
||||
#include <ethash/progpow.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
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<uint32_t>(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<uint32_t>(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<size_t>(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<char*>(std::calloc(1, alloc_size));
|
||||
if (!alloc_data)
|
||||
return nullptr; // Signal out-of-memory by returning null pointer.
|
||||
|
||||
hash512* const light_cache = reinterpret_cast<hash512*>(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<uint32_t*>(alloc_data + context_alloc_size + light_cache_size);
|
||||
|
||||
hash1024* full_dataset = full ? reinterpret_cast<hash1024*>(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<hash2048*>(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<uint32_t>(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<uint32_t>(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<const epoch_context_full&>(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"
|
||||
99
contrib/ethereum/libethash/ethash/ethash.h
Normal file
99
contrib/ethereum/libethash/ethash/ethash.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/* 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>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NOEXCEPT noexcept
|
||||
#else
|
||||
#define NOEXCEPT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The Ethash algorithm revision implemented as specified in the Ethash spec
|
||||
* https://github.com/ethereum/wiki/wiki/Ethash.
|
||||
*/
|
||||
#define ETHASH_REVISION "23"
|
||||
|
||||
#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
|
||||
160
contrib/ethereum/libethash/ethash/ethash.hpp
Normal file
160
contrib/ethereum/libethash/ethash/ethash.hpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
// 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 <ethash/ethash.h>
|
||||
#include <ethash/hash_types.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
namespace ethash
|
||||
{
|
||||
constexpr auto revision = ETHASH_REVISION;
|
||||
|
||||
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<size_t>(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<uint64_t>(num_items) * full_dataset_item_size;
|
||||
}
|
||||
|
||||
/// Owned unique pointer to an epoch context.
|
||||
using epoch_context_ptr = std::unique_ptr<epoch_context, decltype(ðash_destroy_epoch_context)>;
|
||||
|
||||
using epoch_context_full_ptr =
|
||||
std::unique_ptr<epoch_context_full, decltype(ðash_destroy_epoch_context_full)>;
|
||||
|
||||
/// 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
|
||||
46
contrib/ethereum/libethash/ethash/hash_types.h
Normal file
46
contrib/ethereum/libethash/ethash/hash_types.h
Normal file
|
|
@ -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 <stdint.h>
|
||||
|
||||
#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
|
||||
15
contrib/ethereum/libethash/ethash/hash_types.hpp
Normal file
15
contrib/ethereum/libethash/ethash/hash_types.hpp
Normal file
|
|
@ -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
|
||||
49
contrib/ethereum/libethash/ethash/keccak.h
Normal file
49
contrib/ethereum/libethash/ethash/keccak.h
Normal file
|
|
@ -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 <ethash/hash_types.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
35
contrib/ethereum/libethash/ethash/keccak.hpp
Normal file
35
contrib/ethereum/libethash/ethash/keccak.hpp
Normal file
|
|
@ -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 <ethash/keccak.h>
|
||||
#include <ethash/hash_types.hpp>
|
||||
|
||||
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
|
||||
47
contrib/ethereum/libethash/ethash/progpow.hpp
Normal file
47
contrib/ethereum/libethash/ethash/progpow.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// 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 <ethash/ethash.hpp>
|
||||
|
||||
namespace progpow
|
||||
{
|
||||
using namespace ethash; // Include ethash namespace.
|
||||
|
||||
|
||||
/// The ProgPoW algorithm revision implemented as specified in the spec
|
||||
/// https://github.com/ifdefelse/ProgPOW#change-history.
|
||||
constexpr auto revision = "0.9.2";
|
||||
|
||||
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
|
||||
18
contrib/ethereum/libethash/ethash/version.h
Normal file
18
contrib/ethereum/libethash/ethash/version.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
|
||||
* Copyright 2019 Pawel Bylica.
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/** The ethash library version. */
|
||||
#define ETHASH_VERSION "0.4.3"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace ethash
|
||||
{
|
||||
/// The ethash library version.
|
||||
constexpr auto version = ETHASH_VERSION;
|
||||
|
||||
} // namespace ethash
|
||||
#endif
|
||||
123
contrib/ethereum/libethash/keccak.c
Normal file
123
contrib/ethereum/libethash/keccak.c
Normal file
|
|
@ -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 <ethash/keccak.h>
|
||||
|
||||
#include "support/attributes.h"
|
||||
#include <string.h>
|
||||
|
||||
#if _WIN32
|
||||
/* On Windows assume little endian. */
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#elif __APPLE__
|
||||
#include <machine/endian.h>
|
||||
#else
|
||||
#include <endian.h>
|
||||
#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;
|
||||
}
|
||||
255
contrib/ethereum/libethash/keccakf1600.c
Normal file
255
contrib/ethereum/libethash/keccakf1600.c
Normal file
|
|
@ -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 <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
253
contrib/ethereum/libethash/keccakf800.c
Normal file
253
contrib/ethereum/libethash/keccakf800.c
Normal file
|
|
@ -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 <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
64
contrib/ethereum/libethash/kiss99.hpp
Normal file
64
contrib/ethereum/libethash/kiss99.hpp
Normal file
|
|
@ -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 <stdint.h>
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
/** @} */
|
||||
100
contrib/ethereum/libethash/managed.cpp
Normal file
100
contrib/ethereum/libethash/managed.cpp
Normal file
|
|
@ -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 <memory>
|
||||
#include <mutex>
|
||||
|
||||
#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<epoch_context> shared_context;
|
||||
thread_local std::shared_ptr<epoch_context> thread_local_context;
|
||||
|
||||
std::mutex shared_context_full_mutex;
|
||||
std::shared_ptr<epoch_context_full> shared_context_full;
|
||||
thread_local std::shared_ptr<epoch_context_full> 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<std::mutex> 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<std::mutex> 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
|
||||
43
contrib/ethereum/libethash/primes.c
Normal file
43
contrib/ethereum/libethash/primes.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
25
contrib/ethereum/libethash/primes.h
Normal file
25
contrib/ethereum/libethash/primes.h
Normal file
|
|
@ -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 <ethash/ethash.h>
|
||||
|
||||
#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
|
||||
360
contrib/ethereum/libethash/progpow.cpp
Normal file
360
contrib/ethereum/libethash/progpow.cpp
Normal file
|
|
@ -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 <ethash/progpow.hpp>
|
||||
|
||||
#include "bit_manipulation.h"
|
||||
#include "endianness.hpp"
|
||||
#include "ethash-internal.hpp"
|
||||
#include "kiss99.hpp"
|
||||
#include <ethash/keccak.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
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<uint32_t>(nonce);
|
||||
state[i++] = static_cast<uint32_t>(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<uint32_t, num_regs> dst_seq;
|
||||
size_t src_counter = 0;
|
||||
std::array<uint32_t, num_regs> src_seq;
|
||||
};
|
||||
|
||||
mix_rng_state::mix_rng_state(uint64_t seed) noexcept
|
||||
{
|
||||
const auto seed_lo = static_cast<uint32_t>(seed);
|
||||
const auto seed_hi = static_cast<uint32_t>(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<std::array<uint32_t, num_regs>, 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<uint32_t>(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<uint32_t>(seed));
|
||||
const uint32_t w = fnv1a(z, static_cast<uint32_t>(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<const epoch_context_full&>(context).full_dataset;
|
||||
auto* full_dataset_2048 = reinterpret_cast<hash2048*>(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
|
||||
33
contrib/ethereum/libethash/support/attributes.h
Normal file
33
contrib/ethereum/libethash/support/attributes.h
Normal file
|
|
@ -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
|
||||
|
|
@ -49,6 +49,7 @@ file(GLOB_RECURSE DAEMON daemon/*)
|
|||
|
||||
file(GLOB_RECURSE P2P p2p/*)
|
||||
file(GLOB_RECURSE RPC rpc/*)
|
||||
file(GLOB_RECURSE STRATUM stratum/*)
|
||||
file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
|
||||
file(GLOB_RECURSE CONN_TOOL connectivity_tool/*)
|
||||
file(GLOB_RECURSE WALLET wallet/*)
|
||||
|
|
@ -73,6 +74,7 @@ source_group(currency_protocol FILES ${CURRENCY_PROTOCOL})
|
|||
source_group(daemon FILES ${DAEMON})
|
||||
source_group(p2p FILES ${P2P})
|
||||
source_group(rpc FILES ${RPC})
|
||||
source_group(stratum FILES ${STRATUM})
|
||||
source_group(simplewallet FILES ${SIMPLEWALLET})
|
||||
source_group(connectivity-tool FILES ${CONN_TOOL})
|
||||
source_group(wallet FILES ${WALLET})
|
||||
|
|
@ -106,6 +108,10 @@ add_library(rpc ${RPC})
|
|||
add_dependencies(rpc version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(RPC)
|
||||
|
||||
add_library(stratum ${STRATUM})
|
||||
add_dependencies(stratum version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(STRATUM)
|
||||
|
||||
add_library(wallet ${WALLET})
|
||||
add_dependencies(wallet version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(WALLET)
|
||||
|
|
@ -114,23 +120,23 @@ 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 stratum 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)
|
||||
|
||||
set_property(TARGET common crypto currency_core rpc wallet PROPERTY FOLDER "libs")
|
||||
set_property(TARGET common crypto currency_core rpc stratum wallet PROPERTY FOLDER "libs")
|
||||
set_property(TARGET daemon simplewallet connectivity_tool PROPERTY FOLDER "prog")
|
||||
set_property(TARGET daemon PROPERTY OUTPUT_NAME "zanod")
|
||||
|
||||
|
|
@ -150,7 +156,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})
|
||||
|
|
|
|||
|
|
@ -1,136 +0,0 @@
|
|||
// keccak.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
// 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<crypto::hash>& 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<crypto::hash>& result_data, uint64_t target_size)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(target_size % 10 == 0, "wrong target_size = " << target_size);
|
||||
result_data.reserve(target_size/10);
|
||||
result_data.push_back(crypto::cn_fast_hash(&seed_data, sizeof(seed_data)));
|
||||
crypto::hash prev_hash = result_data[0];
|
||||
for (size_t i = 1; i < target_size; i++)
|
||||
{
|
||||
prev_hash = crypto::cn_fast_hash(&prev_hash, sizeof(prev_hash));
|
||||
if (!(i % 10))
|
||||
{
|
||||
result_data.push_back(prev_hash);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad_light)
|
||||
{
|
||||
if (!scratchpad_light.size())
|
||||
return false;
|
||||
auto light_scr_accessor = [&](uint64_t i)
|
||||
{
|
||||
//get index of int64 item in scratchpad from i, where is is random number in whole uint64_t range
|
||||
uint64_t int64_mod_index = i%(scratchpad_light.size() * 10 * 4);
|
||||
//get related hash index
|
||||
uint64_t hash_index = int64_mod_index / 4;
|
||||
//get_in hash index (from 0 to 3)
|
||||
uint64_t in_hash_index = int64_mod_index % 4;
|
||||
|
||||
//get index of primary hash in scratchpad_light
|
||||
uint64_t primary_item_index = (hash_index - (hash_index % 10)) / 10;
|
||||
uint64_t sha_count = hash_index % 10;
|
||||
crypto::hash res = scratchpad_light[primary_item_index];
|
||||
for (uint64_t i = 0; i != sha_count; i++)
|
||||
{
|
||||
res = cn_fast_hash(&res, sizeof(res));
|
||||
}
|
||||
return ((uint64_t*)&res)[in_hash_index];
|
||||
};
|
||||
return get_wild_keccak_light(bd, res, light_scr_accessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
// keccak.h
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
// 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 <stdint.h>
|
||||
#include <string.h>
|
||||
#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<class f_traits, class callback_t>
|
||||
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<class f_traits, class callback_t>
|
||||
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<f_traits>(in, inlen, md, mdlen, cb);
|
||||
wild_keccak2<f_traits>(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<crypto::regular_f>(reinterpret_cast<const uint8_t*>(bd.data()), bd.size(), reinterpret_cast<uint8_t*>(&res), sizeof(res), [&](crypto::state_t_m& st)
|
||||
{
|
||||
++count_access;
|
||||
if (!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<crypto::hash>& 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<class t_items_accessor>
|
||||
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, t_items_accessor cb_get_item)
|
||||
{
|
||||
crypto::wild_keccak2_dbl<crypto::regular_f>(reinterpret_cast<const uint8_t*>(bd.data()), bd.size(), reinterpret_cast<uint8_t*>(&res), sizeof(res), [&](crypto::state_t_m& st)
|
||||
{
|
||||
for (size_t i = 0; i != sizeof(st) / sizeof(st[0]); i++)
|
||||
{
|
||||
size_t depend_index = 0;
|
||||
if (i == 0)
|
||||
{
|
||||
depend_index = sizeof(st) / sizeof(st[0]) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
depend_index = i - 1;
|
||||
}
|
||||
st[i] ^= cb_get_item(cb_get_item(cb_get_item(st[depend_index])));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool get_wild_keccak_light(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad_light);
|
||||
//------------------------------------------------------------------
|
||||
inline
|
||||
bool get_wild_keccak2(const std::string& bd, crypto::hash& res, const std::vector<crypto::hash>& scratchpad)
|
||||
{
|
||||
return get_wild_keccak2(bd, res, scratchpad, scratchpad.size());
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool generate_scratchpad(const crypto::hash& source_data, std::vector<crypto::hash>& result_data, uint64_t target_size);
|
||||
bool generate_scratchpad_light(const crypto::hash& seed_data, std::vector<crypto::hash>& result_data, uint64_t target_size);
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ namespace currency
|
|||
//cut the last timestamp word from restore_dats
|
||||
std::list<std::string> words;
|
||||
boost::split(words, restore_data_, boost::is_space());
|
||||
CHECK_AND_ASSERT_THROW_MES(words.size() == BRAINWALLET_DEFAULT_WORDS_COUNT, "Words count missmatch: " << words.size());
|
||||
CHECK_AND_ASSERT_MES(words.size() == BRAINWALLET_DEFAULT_WORDS_COUNT, false, "Words count missmatch: " << words.size());
|
||||
|
||||
std::string timestamp_word = words.back();
|
||||
words.erase(--words.end());
|
||||
|
|
|
|||
74
src/currency_core/basic_pow_helpers.cpp
Normal file
74
src/currency_core/basic_pow_helpers.cpp
Normal file
|
|
@ -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<int>(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;
|
||||
}
|
||||
}
|
||||
44
src/currency_core/basic_pow_helpers.h
Normal file
44
src/currency_core/basic_pow_helpers.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// 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 <typeindex>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
#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
|
||||
{
|
||||
int ethash_height_to_epoch(uint64_t height);
|
||||
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<uint64_t*>(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]);
|
||||
}
|
||||
|
||||
inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd)
|
||||
{
|
||||
return *reinterpret_cast<const uint64_t*>(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<transaction>& tx_ptr, uint64_t min_allowed_block_height /* = 0 */) const
|
||||
{
|
||||
tx_ptr.reset(new transaction());
|
||||
|
|
|
|||
|
|
@ -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<bool> m_deinit_is_done;
|
||||
|
||||
|
||||
|
|
@ -542,10 +539,6 @@ namespace currency
|
|||
bool validate_alt_block_txs(const block& b, const crypto::hash& id, std::set<crypto::key_image>& 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<transaction>& 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<uint64_t>& timestamps);
|
||||
bool update_next_comulative_size_limit();
|
||||
//bool get_block_for_scratchpad_alt(uint64_t connection_height, uint64_t block_index, std::list<blockchain_storage::blocks_ext_by_hash::iterator>& 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);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#define CURRENCY_FORMATION_VERSION 76
|
||||
#define CURRENCY_FORMATION_VERSION 78
|
||||
|
||||
|
||||
#define CURRENCY_MAX_BLOCK_NUMBER 500000000
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1212,7 +1212,7 @@ namespace currency
|
|||
//---------------------------------------------------------------
|
||||
std::string get_word_from_timstamp(uint64_t timestamp)
|
||||
{
|
||||
uint64_t date_offset = timestamp ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
|
||||
uint64_t date_offset = timestamp > WALLET_BRAIN_DATE_OFFSET ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
|
||||
uint64_t weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM;
|
||||
CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits<uint32_t>::max(), "internal error: unable to converto to uint32, val = " << weeks_count);
|
||||
uint32_t weeks_count_32 = static_cast<uint32_t>(weeks_count);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<class block_chain_accessor_t>
|
||||
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<crypto::hash> 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
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ namespace currency {
|
|||
return false;
|
||||
// usual slow check
|
||||
boost::multiprecision::uint512_t hashVal = 0;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{ // highest word is zero
|
||||
hashVal |= swap64le(((const uint64_t *)&h)[3 - i]);
|
||||
hashVal << 64;
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
hashVal <<= 64;
|
||||
hashVal |= swap64le(((const uint64_t *) &h)[3-i]);
|
||||
}
|
||||
return (hashVal * difficulty > max256bit);
|
||||
return (hashVal * difficulty <= max256bit);
|
||||
}
|
||||
|
||||
uint64_t difficulty_to_boundary(wide_difficulty_type difficulty)
|
||||
|
|
|
|||
|
|
@ -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<uint32_t>();
|
||||
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,14 +342,15 @@ 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))
|
||||
{
|
||||
b.nonce = nonce;
|
||||
++m_config.current_extra_message_index;
|
||||
LOG_PRINT_GREEN("Found block for difficulty: " << local_diff, LOG_LEVEL_0);
|
||||
LOG_PRINT_GREEN("Found block for difficulty: " << local_diff << ", height: " << local_height << ", PoW hash: " << h << ", local_blob_data_hash: " << local_blob_data_hash << ", nonce: " << std::hex << nonce, LOG_LEVEL_0);
|
||||
if(!m_phandler->handle_block_found(b))
|
||||
{
|
||||
--m_config.current_extra_message_index;
|
||||
|
|
|
|||
|
|
@ -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<uint64_t*>(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]);
|
||||
}
|
||||
|
||||
inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd)
|
||||
{
|
||||
return *reinterpret_cast<const uint64_t*>(&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<uint64_t>::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<uint32_t> m_starter_nonce;
|
||||
wide_difficulty_type m_diffic;
|
||||
std::atomic<uint64_t> m_height;
|
||||
scratchpad_keeper m_scratchpad;
|
||||
crypto::hash m_seed;
|
||||
volatile uint32_t m_thread_index;
|
||||
volatile uint32_t m_threads_total;
|
||||
std::atomic<int32_t> m_pausers_count;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<std::vector<crypto::hash>> pscr_light;
|
||||
if (!m_scratchpad_pools.get(seed, pscr_light))
|
||||
{
|
||||
LOG_PRINT_MAGENTA("Generating scratchpad light for " << seed << "["<< height <<"]", LOG_LEVEL_0);
|
||||
pscr_light.reset(new std::vector<crypto::hash>());
|
||||
bool r = crypto::generate_scratchpad_light(seed, *pscr_light, currency::get_scratchpad_size_for_height(height));
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to generate_scratchpad_light");
|
||||
m_scratchpad_pools.set(seed, pscr_light);
|
||||
LOG_PRINT_MAGENTA("Generated ok", LOG_LEVEL_0);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(pscr_light->size()*10 == currency::get_scratchpad_size_for_height(height),
|
||||
"Wrong size of cached scratchpad = " << pscr_light->size() << ", expected " << currency::get_scratchpad_size_for_height(height) << " for height " << height);
|
||||
crypto::hash res = currency::null_hash;
|
||||
bool r = crypto::get_wild_keccak_light(bd, res, *pscr_light);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to get_wild_keccak_light");
|
||||
return res;
|
||||
}
|
||||
//------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
|
@ -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 t_parent>
|
||||
class scratchpad_keeper_base
|
||||
{
|
||||
public:
|
||||
crypto::hash get_pow_hash(const block& b, const crypto::hash& scr_seed)
|
||||
{
|
||||
blobdata bl = get_block_hashing_blob(b);
|
||||
return static_cast<t_parent*>(this)->get_pow_hash_from_blob(bl, get_block_height(b), scr_seed);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class scratchpad_keeper: public scratchpad_keeper_base<scratchpad_keeper>
|
||||
{
|
||||
public:
|
||||
scratchpad_keeper();
|
||||
bool generate(const crypto::hash& seed, uint64_t height);
|
||||
crypto::hash get_pow_hash_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<crypto::hash> m_scratchpad;
|
||||
std::recursive_mutex m_lock;
|
||||
};
|
||||
|
||||
|
||||
class scratchpad_light_pool : public scratchpad_keeper_base<scratchpad_light_pool>
|
||||
{
|
||||
public:
|
||||
scratchpad_light_pool() {}
|
||||
crypto::hash get_pow_hash_from_blob(const blobdata& bd, uint64_t height, const crypto::hash& seed);
|
||||
private:
|
||||
//map of seed to
|
||||
epee::misc_utils::cache_base<false, crypto::hash, std::shared_ptr<std::vector<crypto::hash>>, 4> m_scratchpad_pools;
|
||||
std::recursive_mutex m_lock;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ using namespace epee;
|
|||
#include "currency_core/checkpoints_create.h"
|
||||
#include "currency_core/currency_core.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
#include "stratum/stratum_server.h"
|
||||
#include "currency_protocol/currency_protocol_handler.h"
|
||||
#include "daemon_commands_handler.h"
|
||||
#include "common/miniupnp_helper.h"
|
||||
|
|
@ -85,6 +86,7 @@ int main(int argc, char* argv[])
|
|||
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >::init_options(desc_cmd_sett);
|
||||
currency::miner::init_options(desc_cmd_sett);
|
||||
bc_services::bc_offers_service::init_options(desc_cmd_sett);
|
||||
currency::stratum_server::init_options(desc_cmd_sett);
|
||||
|
||||
|
||||
po::options_description desc_options("Allowed options");
|
||||
|
|
@ -146,8 +148,8 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// stratum server is enabled if any of its options present
|
||||
bool stratum_enabled = currency::stratum_server::should_start(vm);
|
||||
LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0);
|
||||
|
||||
//create objects and link them
|
||||
|
|
@ -162,6 +164,9 @@ int main(int argc, char* argv[])
|
|||
daemon_cmmands_handler dch(p2psrv, rpc_server);
|
||||
tools::miniupnp_helper upnp_helper;
|
||||
//ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
|
||||
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
|
||||
if (stratum_enabled)
|
||||
stratum_server_ptr = std::make_shared<currency::stratum_server>(&ccore);
|
||||
|
||||
if (command_line::get_arg(vm, command_line::arg_show_rpc_autodoc))
|
||||
{
|
||||
|
|
@ -206,6 +211,15 @@ int main(int argc, char* argv[])
|
|||
res = ccore.init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
|
||||
LOG_PRINT_L0("Core initialized OK");
|
||||
|
||||
if (stratum_enabled)
|
||||
{
|
||||
LOG_PRINT_L0("Initializing stratum server...");
|
||||
res = stratum_server_ptr->init(vm);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize stratum server.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto& bcs = ccore.get_blockchain_storage();
|
||||
if (!offers_service.is_disabled() && bcs.get_current_blockchain_size() > 1 && bcs.get_top_block_id() != offers_service.get_last_seen_block_id())
|
||||
|
|
@ -231,16 +245,35 @@ int main(int argc, char* argv[])
|
|||
CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core rpc server.");
|
||||
LOG_PRINT_L0("Core rpc server started ok");
|
||||
|
||||
//start stratum only after core got initialized
|
||||
if (stratum_enabled)
|
||||
{
|
||||
LOG_PRINT_L0("Starting stratum server...");
|
||||
res = stratum_server_ptr->run(false);
|
||||
CHECK_AND_ASSERT_MES(res, 1, "Failed to start stratum server.");
|
||||
LOG_PRINT_L0("Stratum server started ok");
|
||||
}
|
||||
|
||||
tools::signal_handler::install([&dch, &p2psrv] {
|
||||
tools::signal_handler::install([&dch, &p2psrv, &stratum_server_ptr] {
|
||||
dch.stop_handling();
|
||||
p2psrv.send_stop_signal();
|
||||
if (stratum_server_ptr)
|
||||
stratum_server_ptr->send_stop_signal();
|
||||
});
|
||||
|
||||
LOG_PRINT_L0("Starting p2p net loop...");
|
||||
p2psrv.run();
|
||||
LOG_PRINT_L0("p2p net loop stopped");
|
||||
|
||||
//stop components
|
||||
if (stratum_enabled)
|
||||
{
|
||||
LOG_PRINT_L0("Stopping stratum server...");
|
||||
stratum_server_ptr->send_stop_signal();
|
||||
stratum_server_ptr->timed_wait_server_stop(1000);
|
||||
LOG_PRINT_L0("Stratum server stopped");
|
||||
}
|
||||
|
||||
LOG_PRINT_L0("Stopping core rpc server...");
|
||||
rpc_server.send_stop_signal();
|
||||
rpc_server.timed_wait_server_stop(5000);
|
||||
|
|
@ -253,6 +286,9 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_L0("Deinitializing market...");
|
||||
(static_cast<currency::i_bc_service&>(offers_service)).deinit();
|
||||
|
||||
LOG_PRINT_L0("Deinitializing stratum server ...");
|
||||
stratum_server_ptr.reset();
|
||||
|
||||
LOG_PRINT_L0("Deinitializing rpc server ...");
|
||||
rpc_server.deinit();
|
||||
LOG_PRINT_L0("Deinitializing currency_protocol...");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
248
src/stratum/stratum_helpers.h
Normal file
248
src/stratum/stratum_helpers.h
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor 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 <string>
|
||||
#include "epee/include/misc_language.h"
|
||||
#include "epee/include/storages/parserse_base_utils.h"
|
||||
#include "epee/include/storages/portable_storage.h"
|
||||
#include "ethereum/libethash/ethash/ethash.h"
|
||||
#include "ethereum/libethash/ethash/keccak.h"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
|
||||
namespace stratum
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Small helper for extracting separate JSON-RPC requests from input buffer.
|
||||
// TODO: currently it does not handle curly brackets within strings to make things simplier
|
||||
struct json_helper
|
||||
{
|
||||
void feed(const std::string& s)
|
||||
{
|
||||
feed(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
void feed(const char* str, size_t size)
|
||||
{
|
||||
m_buffer.append(str, size);
|
||||
|
||||
int b_count = 0;
|
||||
for(size_t i = 0; i < m_buffer.size(); )
|
||||
{
|
||||
char c = m_buffer[i];
|
||||
if (c == '{')
|
||||
++b_count;
|
||||
else if (c == '}')
|
||||
{
|
||||
if (--b_count == 0)
|
||||
{
|
||||
m_objects.push_back(m_buffer.substr(0, i + 1));
|
||||
m_buffer.erase(0, i + 1);
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
bool has_objects() const
|
||||
{
|
||||
return !m_objects.empty();
|
||||
}
|
||||
|
||||
bool pop_object(std::string &destination)
|
||||
{
|
||||
if (m_objects.empty())
|
||||
return false;
|
||||
|
||||
destination = m_objects.front();
|
||||
m_objects.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string m_buffer;
|
||||
std::list<std::string> m_objects;
|
||||
};
|
||||
|
||||
template<class t_value>
|
||||
bool ps_get_value_noexcept(epee::serialization::portable_storage& ps, const std::string& value_name, t_value& val, epee::serialization::portable_storage::hsection hparent_section)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ps.get_value(value_name, val, hparent_section);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string trim_0x(const std::string& s)
|
||||
{
|
||||
if (s.length() >= 2 && s[0] == '0' && s[1] == 'x')
|
||||
return s.substr(2);
|
||||
return s;
|
||||
}
|
||||
|
||||
constexpr char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
constexpr char hexmap_backward[] =
|
||||
{ //0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 0
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 1
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 2
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 20, 20, 20, 20, 20, // 3
|
||||
20, 10, 11, 12, 13, 14, 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 4
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 5
|
||||
20, 10, 11, 12, 13, 14, 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 6
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 7
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 8
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 9
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // A
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // B
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // C
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // D
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // E
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 // F
|
||||
};
|
||||
|
||||
template<class pod_t>
|
||||
std::string pod_to_net_format(const pod_t &h)
|
||||
{
|
||||
const char* data = reinterpret_cast<const char*>(&h);
|
||||
size_t len = sizeof h;
|
||||
|
||||
std::string s(len * 2, ' ');
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
s[2 * i] = hexmap[(data[i] & 0xF0) >> 4];
|
||||
s[2 * i + 1] = hexmap[(data[i] & 0x0F)];
|
||||
}
|
||||
|
||||
return "0x" + s;
|
||||
}
|
||||
|
||||
template<class pod_t>
|
||||
std::string pod_to_net_format_reverse(const pod_t &h)
|
||||
{
|
||||
const char* data = reinterpret_cast<const char*>(&h);
|
||||
size_t len = sizeof h;
|
||||
|
||||
std::string s(len * 2, ' ');
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
s[2 * i] = hexmap[(data[len - i - 1] & 0xF0) >> 4]; // reverse bytes order in data
|
||||
s[2 * i + 1] = hexmap[(data[len - i - 1] & 0x0F)];
|
||||
}
|
||||
|
||||
return "0x" + s;
|
||||
}
|
||||
template<class pod_t>
|
||||
bool pod_from_net_format(const std::string& str, pod_t& result, bool assume_following_zeroes = false)
|
||||
{
|
||||
std::string s = trim_0x(str);
|
||||
if (s.size() != sizeof(pod_t) * 2)
|
||||
{
|
||||
if (!assume_following_zeroes || s.size() > sizeof(pod_t) * 2)
|
||||
return false; // invalid string length
|
||||
s.insert(s.size() - 1, sizeof(pod_t) * 2 - s.size(), '0'); // add zeroes at the end
|
||||
}
|
||||
|
||||
const unsigned char* hex_str = reinterpret_cast<const unsigned char*>(s.c_str());
|
||||
char* pod_data = reinterpret_cast<char*>(&result);
|
||||
|
||||
for (size_t i = 0; i < sizeof(pod_t); ++i)
|
||||
{
|
||||
char a = hexmap_backward[hex_str[2 * i + 1]];
|
||||
char b = hexmap_backward[hex_str[2 * i + 0]];
|
||||
if (a > 15 || b > 15)
|
||||
return false; // invalid character
|
||||
pod_data[i] = a | (b << 4);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class pod_t>
|
||||
bool pod_from_net_format_reverse(const std::string& str, pod_t& result, bool assume_leading_zeroes = false)
|
||||
{
|
||||
std::string s = trim_0x(str);
|
||||
if (s.size() != sizeof(pod_t) * 2)
|
||||
{
|
||||
if (!assume_leading_zeroes || s.size() > sizeof(pod_t) * 2)
|
||||
return false; // invalid string length
|
||||
s.insert(0, sizeof(pod_t) * 2 - s.size(), '0'); // add zeroes at the beginning
|
||||
}
|
||||
|
||||
const unsigned char* hex_str = reinterpret_cast<const unsigned char*>(s.c_str());
|
||||
char* pod_data = reinterpret_cast<char*>(&result);
|
||||
|
||||
for (size_t i = 0; i < sizeof(pod_t); ++i)
|
||||
{
|
||||
char a = hexmap_backward[hex_str[2 * i + 1]];
|
||||
char b = hexmap_backward[hex_str[2 * i + 0]];
|
||||
if (a > 15 || b > 15)
|
||||
return false; // invalid character
|
||||
pod_data[sizeof(pod_t) - i - 1] = a | (b << 4); // reverse byte order
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t epoch_by_seedhash(const ethash_hash256& seed_hash)
|
||||
{
|
||||
ethash_hash256 epoch_seed = {};
|
||||
for (uint32_t i = 0; i < 2016; ++i) // 2016 epoches will be enough until 2038
|
||||
{
|
||||
if (memcmp(&seed_hash, &epoch_seed, sizeof seed_hash) == 0)
|
||||
return i;
|
||||
epoch_seed = ethash_keccak256_32(epoch_seed.bytes);
|
||||
}
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// http://www.jsonrpc.org/specification
|
||||
// 'id' -- an identifier established by the Client that MUST contain a String, Number, or NULL value if included.
|
||||
// The Server MUST reply with the same value in the Response object if included.
|
||||
struct jsonrpc_id_null_t {};
|
||||
typedef boost::variant<int64_t, std::string, jsonrpc_id_null_t> jsonrpc_id_t;
|
||||
|
||||
std::string jsonrpc_id_to_value_str(const jsonrpc_id_t& id)
|
||||
{
|
||||
if (id.type() == typeid(int64_t))
|
||||
return boost::to_string(boost::get<int64_t>(id));
|
||||
if (id.type() == typeid(std::string))
|
||||
return '"' + boost::to_string(boost::get<std::string>(id)) + '"';
|
||||
return "null";
|
||||
}
|
||||
|
||||
namespace details
|
||||
{
|
||||
struct jsonrpc_id_visitor : public boost::static_visitor<>
|
||||
{
|
||||
explicit jsonrpc_id_visitor(jsonrpc_id_t &value) : m_value(value) {}
|
||||
void operator()(const uint64_t id) { m_value = id; }
|
||||
void operator()(const int64_t id) { m_value = id; }
|
||||
void operator()(const std::string& id) { m_value = id; }
|
||||
template<typename T>
|
||||
void operator()(const T&) { /* nothing */ }
|
||||
|
||||
jsonrpc_id_t &m_value;
|
||||
};
|
||||
}
|
||||
|
||||
bool read_jsonrpc_id(epee::serialization::portable_storage& ps, jsonrpc_id_t& result)
|
||||
{
|
||||
epee::serialization::storage_entry se;
|
||||
if (!ps.get_value("id", se, nullptr))
|
||||
return false;
|
||||
|
||||
details::jsonrpc_id_visitor vis(result);
|
||||
boost::apply_visitor(vis, se);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace stratum
|
||||
|
||||
inline std::ostream &operator <<(std::ostream &o, const ethash_hash256 &v) { return print256(o, v); }
|
||||
1207
src/stratum/stratum_server.cpp
Normal file
1207
src/stratum/stratum_server.cpp
Normal file
File diff suppressed because it is too large
Load diff
42
src/stratum/stratum_server.h
Normal file
42
src/stratum/stratum_server.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2018-2019 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor 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 <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "stratum"
|
||||
|
||||
namespace currency
|
||||
{
|
||||
class core;
|
||||
struct stratum_server_impl;
|
||||
|
||||
class stratum_server
|
||||
{
|
||||
public:
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
static bool should_start(const boost::program_options::variables_map& vm);
|
||||
|
||||
stratum_server(core* c);
|
||||
~stratum_server();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool run(bool wait = true);
|
||||
bool deinit();
|
||||
bool timed_wait_server_stop(uint64_t ms);
|
||||
bool send_stop_signal();
|
||||
|
||||
private:
|
||||
size_t m_threads_count;
|
||||
|
||||
stratum_server_impl* m_impl;
|
||||
core* m_p_core;
|
||||
};
|
||||
}
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL NULL
|
||||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "1.0"
|
||||
#define PROJECT_VERSION_BUILD_NO 9
|
||||
#define PROJECT_VERSION_BUILD_NO 12
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -693,15 +693,8 @@ bool test_generator::find_nounce(currency::block& blk, std::vector<const block_i
|
|||
{
|
||||
if(height != blocks.size())
|
||||
throw std::runtime_error("wrong height in find_nounce");
|
||||
|
||||
crypto::hash seed = currency::null_hash;
|
||||
currency::get_seed_for_scratchpad_cb(height, seed, [&](uint64_t index) -> 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)
|
||||
|
|
|
|||
|
|
@ -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<uint64_t>(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<crypto::hash, block_info> 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 <<
|
||||
|
|
|
|||
|
|
@ -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<currency::transaction>& 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<currency::transaction>& 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<currency::transaction>& 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<currency::transaction>& 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;
|
||||
|
|
|
|||
|
|
@ -628,7 +628,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
|
|||
crc.pos_minimum_heigh = 1;
|
||||
c.get_blockchain_storage().set_core_runtime_config(crc);
|
||||
|
||||
m_checkpoints.add_checkpoint(12, "4ba98ca9d92e99e28a30bd5395a305213be2fc18372bbf94ef216ba017640e56");
|
||||
m_checkpoints.add_checkpoint(12, "b28d40aa02b30d1f0e807147151b5073dc8dc930414cbbdbde11a9502f9c6936");
|
||||
c.set_checkpoints(currency::checkpoints(m_checkpoints));
|
||||
|
||||
return true;
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -66,10 +66,9 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector<tes
|
|||
currency::block b = AUTO_VAL_INIT(b);
|
||||
blobdata extra = AUTO_VAL_INIT(extra);
|
||||
uint64_t height_from_template = 0;
|
||||
crypto::hash seed = currency::null_hash;
|
||||
r = c.get_block_template(b, seed, m_miner_acc.get_public_address(), m_miner_acc.get_public_address(), difficulty, height_from_template, extra);
|
||||
r = c.get_block_template(b, m_miner_acc.get_public_address(), m_miner_acc.get_public_address(), difficulty, height_from_template, extra);
|
||||
CHECK_AND_ASSERT_MES(r || height_from_template != height, false, "get_block_template failed");
|
||||
r = miner::find_nonce_for_given_block(b, difficulty, height, seed, m_scratchpad_keeper);
|
||||
r = miner::find_nonce_for_given_block(b, difficulty, height);
|
||||
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
|
||||
c.handle_incoming_block(t_serializable_object_to_blob(b), bvc);
|
||||
CHECK_AND_NO_ASSERT_MES(!bvc.m_verification_failed && !bvc.m_marked_as_orphaned && !bvc.m_already_exists, false, "block verification context check failed");
|
||||
|
|
@ -241,7 +240,7 @@ bool pos_emission_test::c1(currency::core& c, size_t ev_index, const std::vector
|
|||
if (ts < ideal_next_pow_block_ts)
|
||||
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);
|
||||
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, "invalid number of txs in tx pool: " << c.get_pool_transactions_count());
|
||||
|
||||
|
|
@ -355,7 +354,7 @@ bool pos_emission_test::c2(currency::core& c, size_t ev_index, const std::vector
|
|||
if (ts < ideal_next_pow_block_ts)
|
||||
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);
|
||||
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, "invalid number of txs in tx pool: " << c.get_pool_transactions_count());
|
||||
|
||||
|
|
@ -501,7 +500,7 @@ bool pos_emission_test::c3(currency::core& c, size_t ev_index, const std::vector
|
|||
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);
|
||||
//uint64_t pow_blocks_interval = ts - last_pow_block_ts;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ bool escrow_altchain_meta_impl::generate(std::vector<test_event_entry>& 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<transaction>({ 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<transaction>({ 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<transaction>(), 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<transaction>(), 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);
|
||||
|
|
|
|||
|
|
@ -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<transaction>());
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>());
|
||||
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<transaction>());
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>());
|
||||
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<transaction>({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<transaction>({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<transaction>({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<transaction>({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<transaction>());
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>());
|
||||
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<transaction>());
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>());
|
||||
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<transaction>({ cancel_accept_tx }));
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>({ 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<test_event_en
|
|||
bool escrow_proposal_acceptance_in_alt_chain::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
//mine_next_pow_block_in_playtime(m_scratchpad_keeper, )
|
||||
//mine_next_pow_block_in_playtime()
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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<tools::wallet2> 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<tools::wallet2> 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<tx_destination_entry>({ de2 }), 0, TESTS_DEFAULT_FEE, std::vector<currency::extra_v>(), std::vector<currency::attachment_v>(), 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<tools::wallet2> 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<currency::extra_v>(), std::vector<currency::attachment_v>(), 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<currency::extra_v>(), std::vector<currency::attachment_v>(), 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");
|
||||
|
||||
|
|
@ -1625,7 +1625,7 @@ multisig_and_checkpoints::multisig_and_checkpoints()
|
|||
bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
currency::checkpoints checkpoints;
|
||||
checkpoints.add_checkpoint(15, "816f96e8a0e259491ed7e03ef0f2eea69762276152f4990d71f657b1e37d8764");
|
||||
checkpoints.add_checkpoint(15, "b9adef016fc8de02ad6d0db526e536a3c2211ee23a2d906f56989465c3e38602");
|
||||
c.set_checkpoints(std::move(checkpoints));
|
||||
|
||||
return true;
|
||||
|
|
@ -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<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, alice_acc);
|
||||
|
|
|
|||
|
|
@ -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<transaction>(), 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<transaction>(), 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<transaction>({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<transaction>({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<transaction>({ 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<transaction>({ 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<transaction>({ 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<transaction>({ 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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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<extra_v>(), std::vector<attachment_v>());
|
||||
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<currency::block> 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<transaction>());
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>());
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&h), sizeof(h));
|
||||
// crypto::keccak_generic<crypto::regular_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<crypto::regular_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<crypto::mul_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&h), sizeof(h));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<int scratchpad_size>
|
||||
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<crypto::hash>();
|
||||
|
||||
return test_keccak_base::init();
|
||||
}
|
||||
|
||||
bool test()
|
||||
{
|
||||
pretest();
|
||||
|
||||
crypto::hash h;
|
||||
crypto::wild_keccak_dbl<crypto::mul_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<crypto::hash> m_scratchpad_vec;
|
||||
};
|
||||
|
||||
//
|
||||
// class test_keccak_generic_with_mul : public test_keccak_base
|
||||
// {
|
||||
// public:
|
||||
// bool test()
|
||||
// {
|
||||
// pretest();
|
||||
// crypto::hash h;
|
||||
// crypto::keccak_generic<crypto::mul_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&h), sizeof(h));
|
||||
// return true;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// template<int scratchpad_size>
|
||||
// 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<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<crypto::mul_f>(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&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<crypto::hash> 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<crypto::hash> scratchpad;
|
||||
size_t count = 500000000 / 32;
|
||||
TIME_MEASURE_START_MS(gen_time);
|
||||
LOG_PRINT_L0("Generating....");
|
||||
crypto::generate_scratchpad2(seed, scratchpad, count);
|
||||
TIME_MEASURE_FINISH_MS(gen_time);
|
||||
LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
}
|
||||
|
||||
void generate_light_scratchpad()
|
||||
{
|
||||
crypto::hash seed = crypto::cn_fast_hash("sdssdsffdss", 10);
|
||||
std::vector<crypto::hash> scratchpad;
|
||||
size_t count = 500000000 / 32;
|
||||
TIME_MEASURE_START_MS(gen_time);
|
||||
LOG_PRINT_L0("Generating....");
|
||||
crypto::generate_scratchpad_light(seed, scratchpad, count);
|
||||
TIME_MEASURE_FINISH_MS(gen_time);
|
||||
LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
}
|
||||
|
||||
|
||||
void measure_keccak_over_scratchpad(uint64_t start_scratchpad_size, uint64_t step_size)
|
||||
{
|
||||
// std::cout << std::setw(20) << std::left << "sz\t" <<
|
||||
//std::setw(10) << "original\t" <<
|
||||
// std::setw(10) << "original opt\t" <<
|
||||
// std::setw(10) << "w2\t" <<
|
||||
// std::setw(10) << "w2_opt" << ENDL;
|
||||
|
||||
std::vector<crypto::hash> scratchpad_vec;
|
||||
scratchpad_vec.resize(max_measere_scratchpad);
|
||||
std::string has_str = "Keccak is a family of sponge functions. The sponge function is a generalization of the concept of cryptographic hash function with infinite output and can perform quasi all symmetric cryptographic functions, from hashing to pseudo-random number generation to authenticated encryption";
|
||||
|
||||
for (size_t j = 0; j != scratchpad_vec.size(); j++)
|
||||
scratchpad_vec[j] = crypto::rand<crypto::hash>();
|
||||
|
||||
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<int scratchpad_size>
|
||||
// // 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<crypto::hash>();
|
||||
// //
|
||||
// // return test_keccak_base::init();
|
||||
// // }
|
||||
// //
|
||||
// // bool test()
|
||||
// // {
|
||||
// // pretest();
|
||||
// //
|
||||
// // crypto::hash h2;
|
||||
// // crypto::wild_keccak_dbl_opt(reinterpret_cast<const uint8_t*>(&m_buff[0]), m_buff.size(), reinterpret_cast<uint8_t*>(&h2), sizeof(h2), (const UINT64*)&m_scratchpad_vec[0], m_scratchpad_vec.size() * 4);
|
||||
// // LOG_PRINT_L4("HASH:" << h2);
|
||||
// // return true;
|
||||
// // }
|
||||
// // protected:
|
||||
// // std::vector<crypto::hash> 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<crypto::hash> scratchpad;
|
||||
// size_t count = 500000000 / 32;
|
||||
// TIME_MEASURE_START_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generating....");
|
||||
// crypto::generate_scratchpad2(seed, scratchpad, count);
|
||||
// TIME_MEASURE_FINISH_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
// }
|
||||
//
|
||||
// void generate_light_scratchpad()
|
||||
// {
|
||||
// crypto::hash seed = crypto::cn_fast_hash("sdssdsffdss", 10);
|
||||
// std::vector<crypto::hash> scratchpad;
|
||||
// size_t count = 500000000 / 32;
|
||||
// TIME_MEASURE_START_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generating....");
|
||||
// crypto::generate_scratchpad_light(seed, scratchpad, count);
|
||||
// TIME_MEASURE_FINISH_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generated scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// void measure_keccak_over_scratchpad(uint64_t start_scratchpad_size, uint64_t step_size)
|
||||
// {
|
||||
// // std::cout << std::setw(20) << std::left << "sz\t" <<
|
||||
// //std::setw(10) << "original\t" <<
|
||||
// // std::setw(10) << "original opt\t" <<
|
||||
// // std::setw(10) << "w2\t" <<
|
||||
// // std::setw(10) << "w2_opt" << ENDL;
|
||||
//
|
||||
// std::vector<crypto::hash> scratchpad_vec;
|
||||
// scratchpad_vec.resize(max_measere_scratchpad);
|
||||
// std::string has_str = "Keccak is a family of sponge functions. The sponge function is a generalization of the concept of cryptographic hash function with infinite output and can perform quasi all symmetric cryptographic functions, from hashing to pseudo-random number generation to authenticated encryption";
|
||||
//
|
||||
// for (size_t j = 0; j != scratchpad_vec.size(); j++)
|
||||
// scratchpad_vec[j] = crypto::rand<crypto::hash>();
|
||||
//
|
||||
// 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);
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<crypto::hash> scratchpad;
|
||||
size_t count = 400;
|
||||
TIME_MEASURE_START_MS(gen_time);
|
||||
LOG_PRINT_L0("Generating full ....");
|
||||
crypto::generate_scratchpad2(seed, scratchpad, count);
|
||||
TIME_MEASURE_FINISH_MS(gen_time);
|
||||
LOG_PRINT_L0("Generated full scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
std::vector<crypto::hash> scratchpad_light;
|
||||
crypto::generate_scratchpad_light(seed, scratchpad_light, count);
|
||||
|
||||
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<crypto::hash> scratchpad;
|
||||
// size_t count = 400;
|
||||
// TIME_MEASURE_START_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generating full ....");
|
||||
// crypto::generate_scratchpad2(seed, scratchpad, count);
|
||||
// TIME_MEASURE_FINISH_MS(gen_time);
|
||||
// LOG_PRINT_L0("Generated full scratchpad " << (scratchpad.size() * 32) / (1024 * 1024) << "MB in " << gen_time << "ms");
|
||||
// std::vector<crypto::hash> scratchpad_light;
|
||||
// crypto::generate_scratchpad_light(seed, scratchpad_light, count);
|
||||
//
|
||||
// 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);
|
||||
// }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2015_64
|
||||
cd build_msvc2015_64
|
||||
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015_64 -D BUILD_GUI=TRUE -D USE_OPENCL=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.0" -G "Visual Studio 14 2015 Win64" -T host=x64 ".."
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.0" -G "Visual Studio 14 2015 Win64" -T host=x64 ".."
|
||||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2017_64
|
||||
cd build_msvc2017_64
|
||||
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D USE_OPENCL=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
Loading…
Add table
Reference in a new issue