Genoil
8 years ago
50 changed files with 2577 additions and 791 deletions
@ -1,240 +0,0 @@ |
|||
0. Formatting |
|||
|
|||
GOLDEN RULE: Never *ever* use spaces for formatting. |
|||
|
|||
a. Use tabs for indentation! |
|||
- tab stops are every 4 characters. |
|||
- One indentation level -> exactly one byte (i.e. a tab character) in the source file. |
|||
- Never use spaces to line up sequential lines: If you have run-on lines, indent as you would for a block. |
|||
b. Line widths: |
|||
- Don't worry about having lines of code > 80-char wide. |
|||
- Lines of comments should be formatted according to ease of viewing, but simplicity is to be prefered over beauty. |
|||
c. Don't use braces for condition-body one-liners. |
|||
d. Never place condition bodies on same line as condition. |
|||
e. Space between first paren and keyword, but *not* following first paren or preceeding final paren. |
|||
f. No spaces when fewer than intra-expression three parens together; when three or more, space according to clarity. |
|||
g. No spaces for subscripting or unary operators. |
|||
h. No space before ':' but one after it, except in the ternary operator: one on both sides. |
|||
i. Space all other operators. |
|||
j. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. |
|||
|
|||
(WRONG) |
|||
if( a==b[ i ] ) { printf ("Hello\n"); } |
|||
foo->bar(someLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName); |
|||
|
|||
(RIGHT) |
|||
if (a == b[i]) |
|||
printf("Hello\n"); // NOTE spaces used instead of tab here for clarity - first byte should be '\t'. |
|||
foo->bar( |
|||
someLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName, |
|||
anotherLongVariableName |
|||
); |
|||
|
|||
|
|||
|
|||
1. Namespaces; |
|||
|
|||
a. No "using namespace" declarations in header files. |
|||
b. All symbols should be declared in a namespace except for final applications. |
|||
c. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore. |
|||
|
|||
(WRONG) |
|||
#include <cassert> |
|||
using namespace std; |
|||
tuple<float, float> meanAndSigma(vector<float> const& _v); |
|||
|
|||
(CORRECT) |
|||
#include <cassert> |
|||
std::tuple<float, float> meanAndSigma(std::vector<float> const& _v); |
|||
|
|||
|
|||
|
|||
2. Preprocessor; |
|||
|
|||
a. File comment is always at top, and includes: |
|||
- Original author, date. |
|||
- Later maintainers (not contributors - they can be seen through VCS log). |
|||
- Copyright. |
|||
- License (e.g. see COPYING). |
|||
b. Never use #ifdef/#define/#endif file guards. Prefer #pragma once as first line below file comment. |
|||
c. Prefer static const variable to value macros. |
|||
d. Prefer inline constexpr functions to function macros. |
|||
e. Split complex macro on multiple lines with '\'. |
|||
|
|||
|
|||
|
|||
3. Capitalization; |
|||
|
|||
GOLDEN RULE: Preprocessor: ALL_CAPS; C++: camelCase. |
|||
|
|||
a. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions. |
|||
b. The following entities' first alpha is upper case: |
|||
- Type names. |
|||
- Template parameters. |
|||
- Enum members. |
|||
- static const variables that form an external API. |
|||
c. All preprocessor symbols (macros, macro argments) in full uppercase with underscore word separation. |
|||
|
|||
|
|||
All other entities' first alpha is lower case. |
|||
|
|||
|
|||
|
|||
4. Variable prefixes: |
|||
|
|||
a. Leading underscore "_" to parameter names (both normal and template). |
|||
- Exception: "o_parameterName" when it is used exclusively for output. See 6(f). |
|||
- Exception: "io_parameterName" when it is used for both input and output. See 6(f). |
|||
b. Leading "c_" to const variables (unless part of an external API). |
|||
c. Leading "g_" to global (non-const) variables. |
|||
d. Leading "s_" to static (non-const, non-global) variables. |
|||
|
|||
|
|||
|
|||
5. Error reporting: |
|||
|
|||
- Prefer exception to bool/int return type. |
|||
|
|||
|
|||
|
|||
6. Declarations: |
|||
|
|||
a. {Typename} + {qualifiers} + {name}. |
|||
b. Only one per line. |
|||
c. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)). |
|||
d. Favour declarations close to use; don't habitually declare at top of scope ala C. |
|||
e. Always pass non-trivial parameters with a const& suffix. |
|||
f. If a function returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires. |
|||
g. Never use a macro where adequate non-preprocessor C++ can be written. |
|||
h. Make use of auto whenever type is clear or unimportant: |
|||
- Always avoid doubly-stating the type. |
|||
- Use to avoid vast and unimportant type declarations. |
|||
- However, avoid using auto where type is not immediately obvious from the context, and especially not for arithmetic expressions. |
|||
i. Don't pass bools: prefer enumerations instead. |
|||
j. Prefer enum class to straight enum. |
|||
|
|||
|
|||
(WRONG) |
|||
const double d = 0; |
|||
int i, j; |
|||
char *s; |
|||
float meanAndSigma(std::vector<float> _v, float* _sigma, bool _approximate); |
|||
Derived* x(dynamic_cast<Derived*>(base)); |
|||
for (map<ComplexTypeOne, ComplexTypeTwo>::iterator i = l.begin(); i != l.end(); ++l) {} |
|||
|
|||
|
|||
(CORRECT) |
|||
enum class Accuracy |
|||
{ |
|||
Approximate, |
|||
Exact |
|||
}; |
|||
double const d = 0; |
|||
int i; |
|||
int j; |
|||
char* s; |
|||
std::tuple<float, float> meanAndSigma(std::vector<float> const& _v, Accuracy _a); |
|||
auto x = dynamic_cast<Derived*>(base); |
|||
for (auto i = x.begin(); i != x.end(); ++i) {} |
|||
|
|||
|
|||
7. Structs & classes |
|||
|
|||
a. Structs to be used when all members public and no virtual functions. |
|||
- In this case, members should be named naturally and not prefixed with 'm_' |
|||
b. Classes to be used in all other circumstances. |
|||
|
|||
|
|||
|
|||
8. Members: |
|||
|
|||
a. One member per line only. |
|||
b. Private, non-static, non-const fields prefixed with m_. |
|||
c. Avoid public fields, except in structs. |
|||
d. Use override, final and const as much as possible. |
|||
e. No implementations with the class declaration, except: |
|||
- template or force-inline method (though prefer implementation at bottom of header file). |
|||
- one-line implementation (in which case include it in same line as declaration). |
|||
f. For a property 'foo' |
|||
- Member: m_foo; |
|||
- Getter: foo() [ also: for booleans, isFoo() ]; |
|||
- Setter: setFoo(); |
|||
|
|||
|
|||
|
|||
9. Naming |
|||
|
|||
a. Collection conventions: |
|||
- -s means std::vector e.g. using MyTypes = std::vector<MyType> |
|||
- -Set means std::set e.g. using MyTypeSet = std::set<MyType> |
|||
- -Hash means std::unordered_set e.g. using MyTypeHash = std::unordered_set<MyType> |
|||
b. Class conventions: |
|||
- -Face means the interface of some shared concept. (e.g. FooFace might be a pure virtual class.) |
|||
c. Avoid unpronouncable names; |
|||
- If you need to shorten a name favour a pronouncable slice of the original to a scatterred set of consonants. |
|||
- e.g. Manager shortens to Man rather than Mgr. |
|||
d. Avoid prefixes of initials (e.g. DON'T use IMyInterface, CMyImplementation) |
|||
e. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments. |
|||
- A dictionary and thesaurus are your friends. |
|||
- Spell correctly. |
|||
- Think carefully about the class's purpose. |
|||
- Imagine it as an isolated component to try to decontextualise it when considering its name. |
|||
- Don't be trapped into naming it (purely) in terms of its implementation. |
|||
|
|||
|
|||
|
|||
10. Type-definitions |
|||
|
|||
a. Prefer 'using' to 'typedef'. e.g. using ints = std::vector<int>; rather than typedef std::vector<int> ints; |
|||
b. Generally avoid shortening a standard form that already includes all important information: |
|||
- e.g. stick to shared_ptr<X> rather than shortening to ptr<X>. |
|||
c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently. |
|||
- e.g. using Guard = std::lock_guard<std::mutex>; ///< Guard is used throughout the codebase since it's clear in meaning and used commonly. |
|||
d. In general expressions should be roughly as important/semantically meaningful as the space they occupy. |
|||
|
|||
|
|||
11. Commenting |
|||
|
|||
a. Comments should be doxygen-compilable, using @notation rather than \notation. |
|||
b. Document the interface, not the implementation. |
|||
- Documentation should be able to remain completely unchanged, even if the method is reimplemented. |
|||
- Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports). |
|||
- Be careful to scrutinise documentation that extends only to intended purpose and usage. |
|||
- Reject documentation that is simply an English transaction of the implementation. |
|||
|
|||
|
|||
|
|||
12. Include Headers |
|||
|
|||
a. Includes should go in order of lower level (STL -> boost -> libdevcore -> libdevcrypto -> libethcore -> libethereum) to higher level. Lower levels are basically dependencies to the higher levels. For example: |
|||
|
|||
#include <string> |
|||
#include <boost/filesystem.hpp> |
|||
|
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/CommonData.h> |
|||
#include <libdevcore/Exceptions.h> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcrypto/SHA3.h> |
|||
#include <libethereum/Defaults.h> |
|||
|
|||
b. The only exception to the above rule is the top of a .cpp file where its corresponding header should be located. |
|||
|
|||
13. Logging |
|||
|
|||
Logging should be performed at appropriate verbosities depending on the logging message. |
|||
The more likely a message is to repeat (and thus cuase noise) the higher in verbosity it should be. |
|||
Some rules to keep in mind: |
|||
|
|||
- Verbosity == 0 -> Reserved for important stuff that users must see and can understand. |
|||
- Verbosity == 1 -> Reserved for stuff that users don't need to see but can understand. |
|||
- Verbosity >= 2 -> Anything that is or might be displayed more than once every minute |
|||
- Verbosity >= 3 -> Anything that only a developer would understand |
|||
- Verbosity >= 4 -> Anything that is low-level (e.g. peer disconnects, timers being cancelled) |
@ -1,38 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|||
<plist version="1.0"> |
|||
<dict> |
|||
<key>CFBundleDevelopmentRegion</key> |
|||
<string>English</string> |
|||
<key>CFBundleExecutable</key> |
|||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> |
|||
<key>CFBundleGetInfoString</key> |
|||
<string>${MACOSX_BUNDLE_INFO_STRING}</string> |
|||
<key>CFBundleIconFile</key> |
|||
<string>${MACOSX_BUNDLE_ICON_FILE}</string> |
|||
<key>CFBundleIdentifier</key> |
|||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> |
|||
<key>CFBundleInfoDictionaryVersion</key> |
|||
<string>6.0</string> |
|||
<key>CFBundleLongVersionString</key> |
|||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> |
|||
<key>CFBundleName</key> |
|||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> |
|||
<key>CFBundlePackageType</key> |
|||
<string>APPL</string> |
|||
<key>CFBundleShortVersionString</key> |
|||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> |
|||
<key>CFBundleSignature</key> |
|||
<string>????</string> |
|||
<key>CFBundleVersion</key> |
|||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> |
|||
<key>CSResourcesFileMapped</key> |
|||
<true/> |
|||
<key>LSRequiresCarbon</key> |
|||
<true/> |
|||
<key>NSHumanReadableCopyright</key> |
|||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string> |
|||
<key>NSHighResolutionCapable</key> |
|||
<true/> |
|||
</dict> |
|||
</plist> |
@ -1,13 +0,0 @@ |
|||
{ |
|||
"title": "Ethereum", |
|||
"icon": "appdmg_icon.icns", |
|||
"background": "appdmg_background.png", |
|||
"icon-size": 55, |
|||
"contents": [ |
|||
{ "x": 242, "y": 240, "type": "link", "path": "/Applications" }, |
|||
{ "x": 145, "y": 125, "type": "file", "path": "${ETH_ALETHZERO_APP}" }, |
|||
{ "x": 339, "y": 125, "type": "file", "path": "${ETH_MIX_APP}" } |
|||
] |
|||
} |
|||
|
|||
|
@ -1,11 +0,0 @@ |
|||
style=allman |
|||
indent=force-tab=4 |
|||
convert-tabs |
|||
indent-preprocessor |
|||
min-conditional-indent=1 |
|||
pad-oper |
|||
pad-header |
|||
unpad-paren |
|||
align-pointer=type |
|||
keep-one-line-blocks |
|||
close-templates |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 34 KiB |
@ -0,0 +1,71 @@ |
|||
#include "ethash_cuda_miner_kernel_globals.h" |
|||
#include "ethash_cuda_miner_kernel.h" |
|||
|
|||
typedef union { |
|||
uint4 uint4s[4]; |
|||
uint64_t ulongs[8]; |
|||
uint32_t uints[16]; |
|||
} compute_hash_share; |
|||
|
|||
|
|||
__device__ uint64_t compute_hash( |
|||
uint64_t nonce |
|||
) |
|||
{ |
|||
// sha3_512(header .. nonce) |
|||
uint64_t state[25]; |
|||
state[4] = nonce; |
|||
keccak_f1600_init(state); |
|||
|
|||
// Threads work together in this phase in groups of 8. |
|||
const int thread_id = threadIdx.x & (THREADS_PER_HASH - 1); |
|||
const int hash_id = threadIdx.x >> 3; |
|||
|
|||
extern __shared__ compute_hash_share share[]; |
|||
|
|||
for (int i = 0; i < THREADS_PER_HASH; i++) |
|||
{ |
|||
// share init with other threads |
|||
if (i == thread_id) |
|||
copy(share[hash_id].ulongs, state, 8); |
|||
|
|||
__syncthreads(); |
|||
|
|||
uint4 mix = share[hash_id].uint4s[thread_id & 3]; |
|||
__syncthreads(); |
|||
|
|||
uint32_t *share0 = share[hash_id].uints; |
|||
|
|||
// share init0 |
|||
if (thread_id == 0) |
|||
*share0 = mix.x; |
|||
__syncthreads(); |
|||
uint32_t init0 = *share0; |
|||
|
|||
for (uint32_t a = 0; a < ACCESSES; a += 4) |
|||
{ |
|||
int t = bfe(a, 2u, 3u); |
|||
|
|||
for (uint32_t b = 0; b < 4; b++) |
|||
{ |
|||
if (thread_id == t) { |
|||
*share0 = fnv(init0 ^ (a + b), ((uint32_t *)&mix)[b]) % d_dag_size; |
|||
} |
|||
__syncthreads(); |
|||
|
|||
mix = fnv4(mix, d_dag[*share0].uint4s[thread_id]); |
|||
} |
|||
} |
|||
|
|||
share[hash_id].uints[thread_id] = fnv_reduce(mix); |
|||
__syncthreads(); |
|||
|
|||
if (i == thread_id) |
|||
copy(state + 8, share[hash_id].ulongs, 4); |
|||
|
|||
__syncthreads(); |
|||
} |
|||
|
|||
// keccak_256(keccak_512(header..nonce) .. mix); |
|||
return keccak_f1600_final(state); |
|||
} |
@ -1,10 +1,14 @@ |
|||
#ifndef _ETHASH_CUDA_MINER_KERNEL_GLOBALS_H_ |
|||
#define _ETHASH_CUDA_MINER_KERNEL_GLOBALS_H_ |
|||
|
|||
#define SHUFFLE_MIN_VER 300 |
|||
|
|||
//#include "cuda_helper.h"
|
|||
|
|||
__constant__ uint32_t d_dag_size; |
|||
__constant__ hash128_t* d_dag; |
|||
__constant__ uint32_t d_light_size; |
|||
__constant__ hash64_t* d_light; |
|||
__constant__ hash32_t d_header; |
|||
__constant__ uint64_t d_target; |
|||
|
|||
|
@ -0,0 +1,777 @@ |
|||
#include "cuda_helper.h" |
|||
|
|||
__device__ __constant__ uint64_t const keccak_round_constants[24] = { |
|||
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, |
|||
0x8000000080008000ULL, 0x000000000000808BULL, 0x0000000080000001ULL, |
|||
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008AULL, |
|||
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, |
|||
0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, |
|||
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, |
|||
0x000000000000800AULL, 0x800000008000000AULL, 0x8000000080008081ULL, |
|||
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL |
|||
}; |
|||
|
|||
__device__ __forceinline__ |
|||
uint64_t xor5(const uint64_t a, const uint64_t b, const uint64_t c, const uint64_t d, const uint64_t e) { |
|||
return a ^ b ^ c ^ d ^ e; |
|||
} |
|||
__device__ __forceinline__ |
|||
uint64_t xor3(const uint64_t a, const uint64_t b, const uint64_t c) { |
|||
return a ^ b ^ c; |
|||
} |
|||
|
|||
__device__ __forceinline__ |
|||
uint64_t chi(const uint64_t a, const uint64_t b, const uint64_t c) { |
|||
return a ^ (~b) & c; |
|||
} |
|||
|
|||
__device__ __forceinline__ void keccak_f1600_init(uint64_t * s) |
|||
{ |
|||
uint64_t t[5], u, v; |
|||
|
|||
devectorize4(d_header.uint4s[0], s[0], s[1]); |
|||
devectorize4(d_header.uint4s[1], s[2], s[3]); |
|||
|
|||
for (uint32_t i = 5; i < 25; i++) |
|||
{ |
|||
s[i] = 0; |
|||
} |
|||
s[5] = 0x0000000000000001; |
|||
s[8] = 0x8000000000000000; |
|||
|
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = s[0] ^ s[5]; |
|||
t[1] = s[1]; |
|||
t[2] = s[2]; |
|||
t[3] = s[3] ^ s[8]; |
|||
t[4] = s[4]; |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[5] = xor3(s[5], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
s[15] = xor3(s[15], t[4], u); |
|||
s[20] = xor3(s[20], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[1] = xor3(s[1], t[0], u); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[11] = xor3(s[11], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
s[21] = xor3(s[21], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[2] = xor3(s[2], t[1], u); |
|||
s[7] = xor3(s[7], t[1], u); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[17] = xor3(s[17], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[8] = xor3(s[8], t[2], u); |
|||
s[13] = xor3(s[13], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
s[23] = xor3(s[23], t[2], u); |
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[4] = xor3(s[4], t[3], u); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[14] = xor3(s[14], t[3], u); |
|||
s[19] = xor3(s[19], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[22] = ROTL64(s[14], 39); |
|||
s[14] = ROTL64(s[20], 18); |
|||
s[20] = ROTL64(s[2], 62); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[12] = ROTL64(s[13], 25); |
|||
s[13] = ROTL64(s[19], 8); |
|||
s[19] = ROTL64(s[23], 56); |
|||
s[23] = ROTL64(s[15], 41); |
|||
s[15] = ROTL64(s[4], 27); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[24] = ROTL64(s[21], 2); |
|||
s[21] = ROTL64(s[8], 55); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[16] = ROTL64(s[5], 36); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[18] = ROTL64(s[17], 15); |
|||
s[17] = ROTL64(s[11], 10); |
|||
s[11] = ROTL64(s[7], 6); |
|||
s[7] = ROTL64(s[10], 3); |
|||
s[10] = ROTL64(u, 1); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
|
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
|
|||
u = s[5]; v = s[6]; |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
s[8] = chi(s[8], s[9], u); |
|||
s[9] = chi(s[9], u, v); |
|||
|
|||
u = s[10]; v = s[11]; |
|||
s[10] = chi(s[10], s[11], s[12]); |
|||
s[11] = chi(s[11], s[12], s[13]); |
|||
s[12] = chi(s[12], s[13], s[14]); |
|||
s[13] = chi(s[13], s[14], u); |
|||
s[14] = chi(s[14], u, v); |
|||
|
|||
u = s[15]; v = s[16]; |
|||
s[15] = chi(s[15], s[16], s[17]); |
|||
s[16] = chi(s[16], s[17], s[18]); |
|||
s[17] = chi(s[17], s[18], s[19]); |
|||
s[18] = chi(s[18], s[19], u); |
|||
s[19] = chi(s[19], u, v); |
|||
|
|||
u = s[20]; v = s[21]; |
|||
s[20] = chi(s[20], s[21], s[22]); |
|||
s[21] = chi(s[21], s[22], s[23]); |
|||
s[22] = chi(s[22], s[23], s[24]); |
|||
s[23] = chi(s[23], s[24], u); |
|||
s[24] = chi(s[24], u, v); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[0]; |
|||
|
|||
for (int i = 1; i < 23; i++) |
|||
{ |
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor5(s[0] , s[5] , s[10] , s[15] , s[20]); |
|||
t[1] = xor5(s[1] , s[6] , s[11] , s[16] , s[21]); |
|||
t[2] = xor5(s[2] , s[7] , s[12] , s[17] , s[22]); |
|||
t[3] = xor5(s[3] , s[8] , s[13] , s[18] , s[23]); |
|||
t[4] = xor5(s[4] , s[9] , s[14] , s[19] , s[24]); |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[5] = xor3(s[5], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
s[15] = xor3(s[15], t[4], u); |
|||
s[20] = xor3(s[20], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[1] = xor3(s[1], t[0], u); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[11] = xor3(s[11], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
s[21] = xor3(s[21], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[2] = xor3(s[2], t[1], u); |
|||
s[7] = xor3(s[7], t[1], u); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[17] = xor3(s[17], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[8] = xor3(s[8], t[2], u); |
|||
s[13] = xor3(s[13], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
s[23] = xor3(s[23], t[2], u); |
|||
|
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[4] = xor3(s[4], t[3], u); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[14] = xor3(s[14], t[3], u); |
|||
s[19] = xor3(s[19], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[22] = ROTL64(s[14], 39); |
|||
s[14] = ROTL64(s[20], 18); |
|||
s[20] = ROTL64(s[2], 62); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[12] = ROTL64(s[13], 25); |
|||
s[13] = ROTL64(s[19], 8); |
|||
s[19] = ROTL64(s[23], 56); |
|||
s[23] = ROTL64(s[15], 41); |
|||
s[15] = ROTL64(s[4], 27); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[24] = ROTL64(s[21], 2); |
|||
s[21] = ROTL64(s[8], 55); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[16] = ROTL64(s[5], 36); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[18] = ROTL64(s[17], 15); |
|||
s[17] = ROTL64(s[11], 10); |
|||
s[11] = ROTL64(s[7], 6); |
|||
s[7] = ROTL64(s[10], 3); |
|||
s[10] = ROTL64(u, 1); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
|
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
|
|||
u = s[5]; v = s[6]; |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
s[8] = chi(s[8], s[9], u); |
|||
s[9] = chi(s[9], u, v); |
|||
|
|||
u = s[10]; v = s[11]; |
|||
s[10] = chi(s[10], s[11], s[12]); |
|||
s[11] = chi(s[11], s[12], s[13]); |
|||
s[12] = chi(s[12], s[13], s[14]); |
|||
s[13] = chi(s[13], s[14], u); |
|||
s[14] = chi(s[14], u, v); |
|||
|
|||
u = s[15]; v = s[16]; |
|||
s[15] = chi(s[15], s[16], s[17]); |
|||
s[16] = chi(s[16], s[17], s[18]); |
|||
s[17] = chi(s[17], s[18], s[19]); |
|||
s[18] = chi(s[18], s[19], u); |
|||
s[19] = chi(s[19], u, v); |
|||
|
|||
u = s[20]; v = s[21]; |
|||
s[20] = chi(s[20], s[21], s[22]); |
|||
s[21] = chi(s[21], s[22], s[23]); |
|||
s[22] = chi(s[22], s[23], s[24]); |
|||
s[23] = chi(s[23], s[24], u); |
|||
s[24] = chi(s[24], u, v); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[i]; |
|||
} |
|||
|
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor5(s[0], s[5], s[10], s[15], s[20]); |
|||
t[1] = xor5(s[1], s[6], s[11], s[16], s[21]); |
|||
t[2] = xor5(s[2], s[7], s[12], s[17], s[22]); |
|||
t[3] = xor5(s[3], s[8], s[13], s[18], s[23]); |
|||
t[4] = xor5(s[4], s[9], s[14], s[19], s[24]); |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[7] = ROTL64(s[10], 3); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
|
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[23]; |
|||
} |
|||
|
|||
__device__ __forceinline__ uint64_t keccak_f1600_final(uint64_t* s) |
|||
{ |
|||
uint64_t t[5], u, v; |
|||
|
|||
for (uint32_t i = 12; i < 25; i++) |
|||
{ |
|||
s[i] = 0; |
|||
} |
|||
s[12] = 0x0000000000000001; |
|||
s[16] = 0x8000000000000000; |
|||
|
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor3(s[0], s[5], s[10]); |
|||
t[1] = xor3(s[1], s[6], s[11]) ^ s[16]; |
|||
t[2] = xor3(s[2], s[7], s[12]); |
|||
t[3] = s[3] ^ s[8]; |
|||
t[4] = s[4] ^ s[9]; |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[5] = xor3(s[5], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
s[15] = xor3(s[15], t[4], u); |
|||
s[20] = xor3(s[20], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[1] = xor3(s[1], t[0], u); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[11] = xor3(s[11], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
s[21] = xor3(s[21], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[2] = xor3(s[2], t[1], u); |
|||
s[7] = xor3(s[7], t[1], u); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[17] = xor3(s[17], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[8] = xor3(s[8], t[2], u); |
|||
s[13] = xor3(s[13], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
s[23] = xor3(s[23], t[2], u); |
|||
|
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[4] = xor3(s[4], t[3], u); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[14] = xor3(s[14], t[3], u); |
|||
s[19] = xor3(s[19], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[22] = ROTL64(s[14], 39); |
|||
s[14] = ROTL64(s[20], 18); |
|||
s[20] = ROTL64(s[2], 62); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[12] = ROTL64(s[13], 25); |
|||
s[13] = ROTL64(s[19], 8); |
|||
s[19] = ROTL64(s[23], 56); |
|||
s[23] = ROTL64(s[15], 41); |
|||
s[15] = ROTL64(s[4], 27); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[24] = ROTL64(s[21], 2); |
|||
s[21] = ROTL64(s[8], 55); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[16] = ROTL64(s[5], 36); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[18] = ROTL64(s[17], 15); |
|||
s[17] = ROTL64(s[11], 10); |
|||
s[11] = ROTL64(s[7], 6); |
|||
s[7] = ROTL64(s[10], 3); |
|||
s[10] = ROTL64(u, 1); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
|
|||
u = s[5]; v = s[6]; |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
s[8] = chi(s[8], s[9], u); |
|||
s[9] = chi(s[9], u, v); |
|||
|
|||
u = s[10]; v = s[11]; |
|||
s[10] = chi(s[10], s[11], s[12]); |
|||
s[11] = chi(s[11], s[12], s[13]); |
|||
s[12] = chi(s[12], s[13], s[14]); |
|||
s[13] = chi(s[13], s[14], u); |
|||
s[14] = chi(s[14], u, v); |
|||
|
|||
u = s[15]; v = s[16]; |
|||
s[15] = chi(s[15], s[16], s[17]); |
|||
s[16] = chi(s[16], s[17], s[18]); |
|||
s[17] = chi(s[17], s[18], s[19]); |
|||
s[18] = chi(s[18], s[19], u); |
|||
s[19] = chi(s[19], u, v); |
|||
|
|||
u = s[20]; v = s[21]; |
|||
s[20] = chi(s[20], s[21], s[22]); |
|||
s[21] = chi(s[21], s[22], s[23]); |
|||
s[22] = chi(s[22], s[23], s[24]); |
|||
s[23] = chi(s[23], s[24], u); |
|||
s[24] = chi(s[24], u, v); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[0]; |
|||
|
|||
for (int i = 1; i < 23; i++) |
|||
{ |
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor5(s[0], s[5], s[10], s[15], s[20]); |
|||
t[1] = xor5(s[1], s[6], s[11], s[16], s[21]); |
|||
t[2] = xor5(s[2], s[7], s[12], s[17], s[22]); |
|||
t[3] = xor5(s[3], s[8], s[13], s[18], s[23]); |
|||
t[4] = xor5(s[4], s[9], s[14], s[19], s[24]); |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[5] = xor3(s[5], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
s[15] = xor3(s[15], t[4], u); |
|||
s[20] = xor3(s[20], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[1] = xor3(s[1], t[0], u); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[11] = xor3(s[11], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
s[21] = xor3(s[21], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[2] = xor3(s[2], t[1], u); |
|||
s[7] = xor3(s[7], t[1], u); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[17] = xor3(s[17], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[8] = xor3(s[8], t[2], u); |
|||
s[13] = xor3(s[13], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
s[23] = xor3(s[23], t[2], u); |
|||
|
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[4] = xor3(s[4], t[3], u); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[14] = xor3(s[14], t[3], u); |
|||
s[19] = xor3(s[19], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[22] = ROTL64(s[14], 39); |
|||
s[14] = ROTL64(s[20], 18); |
|||
s[20] = ROTL64(s[2], 62); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[12] = ROTL64(s[13], 25); |
|||
s[13] = ROTL64(s[19], 8); |
|||
s[19] = ROTL64(s[23], 56); |
|||
s[23] = ROTL64(s[15], 41); |
|||
s[15] = ROTL64(s[4], 27); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[24] = ROTL64(s[21], 2); |
|||
s[21] = ROTL64(s[8], 55); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[16] = ROTL64(s[5], 36); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[18] = ROTL64(s[17], 15); |
|||
s[17] = ROTL64(s[11], 10); |
|||
s[11] = ROTL64(s[7], 6); |
|||
s[7] = ROTL64(s[10], 3); |
|||
s[10] = ROTL64(u, 1); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
|
|||
u = s[5]; v = s[6]; |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
s[8] = chi(s[8], s[9], u); |
|||
s[9] = chi(s[9], u, v); |
|||
|
|||
u = s[10]; v = s[11]; |
|||
s[10] = chi(s[10], s[11], s[12]); |
|||
s[11] = chi(s[11], s[12], s[13]); |
|||
s[12] = chi(s[12], s[13], s[14]); |
|||
s[13] = chi(s[13], s[14], u); |
|||
s[14] = chi(s[14], u, v); |
|||
|
|||
u = s[15]; v = s[16]; |
|||
s[15] = chi(s[15], s[16], s[17]); |
|||
s[16] = chi(s[16], s[17], s[18]); |
|||
s[17] = chi(s[17], s[18], s[19]); |
|||
s[18] = chi(s[18], s[19], u); |
|||
s[19] = chi(s[19], u, v); |
|||
|
|||
u = s[20]; v = s[21]; |
|||
s[20] = chi(s[20], s[21], s[22]); |
|||
s[21] = chi(s[21], s[22], s[23]); |
|||
s[22] = chi(s[22], s[23], s[24]); |
|||
s[23] = chi(s[23], s[24], u); |
|||
s[24] = chi(s[24], u, v); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[i]; |
|||
} |
|||
|
|||
t[0] = xor5(s[0], s[5], s[10], s[15], s[20]); |
|||
t[1] = xor5(s[1], s[6], s[11], s[16], s[21]); |
|||
t[2] = xor5(s[2], s[7], s[12], s[17], s[22]); |
|||
t[3] = xor5(s[3], s[8], s[13], s[18], s[23]); |
|||
t[4] = xor5(s[4], s[9], s[14], s[19], s[24]); |
|||
|
|||
s[0] = xor3(s[0], t[4], ROTL64(t[1], 1)); |
|||
s[6] = xor3(s[6], t[0], ROTL64(t[2], 1)); |
|||
s[12] = xor3(s[12], t[1], ROTL64(t[3], 1)); |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[2] = ROTL64(s[12], 43); |
|||
|
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
//s[0] ^= vectorize(keccak_round_constants[23]); |
|||
return s[0] ^ keccak_round_constants[23]; |
|||
} |
|||
|
|||
__device__ __forceinline__ void SHA3_512(uint2* s2) { |
|||
|
|||
uint64_t * s = (uint64_t*)s2; //dirty |
|||
|
|||
uint64_t t[5], u, v; |
|||
|
|||
for (uint32_t i = 9; i < 25; i++) |
|||
{ |
|||
s[i] = 0; |
|||
} |
|||
s[8] = 0x8000000000000001; |
|||
|
|||
for (int i = 0; i < 23; i++) |
|||
{ |
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor5(s[0], s[5], s[10], s[15], s[20]); |
|||
t[1] = xor5(s[1], s[6], s[11], s[16], s[21]); |
|||
t[2] = xor5(s[2], s[7], s[12], s[17], s[22]); |
|||
t[3] = xor5(s[3], s[8], s[13], s[18], s[23]); |
|||
t[4] = xor5(s[4], s[9], s[14], s[19], s[24]); |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[5] = xor3(s[5], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
s[15] = xor3(s[15], t[4], u); |
|||
s[20] = xor3(s[20], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[1] = xor3(s[1], t[0], u); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[11] = xor3(s[11], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
s[21] = xor3(s[21], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[2] = xor3(s[2], t[1], u); |
|||
s[7] = xor3(s[7], t[1], u); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[17] = xor3(s[17], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[8] = xor3(s[8], t[2], u); |
|||
s[13] = xor3(s[13], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
s[23] = xor3(s[23], t[2], u); |
|||
|
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[4] = xor3(s[4], t[3], u); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[14] = xor3(s[14], t[3], u); |
|||
s[19] = xor3(s[19], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[22] = ROTL64(s[14], 39); |
|||
s[14] = ROTL64(s[20], 18); |
|||
s[20] = ROTL64(s[2], 62); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[12] = ROTL64(s[13], 25); |
|||
s[13] = ROTL64(s[19], 8); |
|||
s[19] = ROTL64(s[23], 56); |
|||
s[23] = ROTL64(s[15], 41); |
|||
s[15] = ROTL64(s[4], 27); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[24] = ROTL64(s[21], 2); |
|||
s[21] = ROTL64(s[8], 55); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[16] = ROTL64(s[5], 36); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[18] = ROTL64(s[17], 15); |
|||
s[17] = ROTL64(s[11], 10); |
|||
s[11] = ROTL64(s[7], 6); |
|||
s[7] = ROTL64(s[10], 3); |
|||
s[10] = ROTL64(u, 1); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
|
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
|
|||
u = s[5]; v = s[6]; |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
s[8] = chi(s[8], s[9], u); |
|||
s[9] = chi(s[9], u, v); |
|||
|
|||
u = s[10]; v = s[11]; |
|||
s[10] = chi(s[10], s[11], s[12]); |
|||
s[11] = chi(s[11], s[12], s[13]); |
|||
s[12] = chi(s[12], s[13], s[14]); |
|||
s[13] = chi(s[13], s[14], u); |
|||
s[14] = chi(s[14], u, v); |
|||
|
|||
u = s[15]; v = s[16]; |
|||
s[15] = chi(s[15], s[16], s[17]); |
|||
s[16] = chi(s[16], s[17], s[18]); |
|||
s[17] = chi(s[17], s[18], s[19]); |
|||
s[18] = chi(s[18], s[19], u); |
|||
s[19] = chi(s[19], u, v); |
|||
|
|||
u = s[20]; v = s[21]; |
|||
s[20] = chi(s[20], s[21], s[22]); |
|||
s[21] = chi(s[21], s[22], s[23]); |
|||
s[22] = chi(s[22], s[23], s[24]); |
|||
s[23] = chi(s[23], s[24], u); |
|||
s[24] = chi(s[24], u, v); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[i]; |
|||
} |
|||
|
|||
/* theta: c = a[0,i] ^ a[1,i] ^ .. a[4,i] */ |
|||
t[0] = xor5(s[0], s[5], s[10], s[15], s[20]); |
|||
t[1] = xor5(s[1], s[6], s[11], s[16], s[21]); |
|||
t[2] = xor5(s[2], s[7], s[12], s[17], s[22]); |
|||
t[3] = xor5(s[3], s[8], s[13], s[18], s[23]); |
|||
t[4] = xor5(s[4], s[9], s[14], s[19], s[24]); |
|||
|
|||
/* theta: d[i] = c[i+4] ^ rotl(c[i+1],1) */ |
|||
/* theta: a[0,i], a[1,i], .. a[4,i] ^= d[i] */ |
|||
|
|||
u = ROTL64(t[1], 1); |
|||
s[0] = xor3(s[0], t[4], u); |
|||
s[10] = xor3(s[10], t[4], u); |
|||
|
|||
u = ROTL64(t[2], 1); |
|||
s[6] = xor3(s[6], t[0], u); |
|||
s[16] = xor3(s[16], t[0], u); |
|||
|
|||
u = ROTL64(t[3], 1); |
|||
s[12] = xor3(s[12], t[1], u); |
|||
s[22] = xor3(s[22], t[1], u); |
|||
|
|||
u = ROTL64(t[4], 1); |
|||
s[3] = xor3(s[3], t[2], u); |
|||
s[18] = xor3(s[18], t[2], u); |
|||
|
|||
u = ROTL64(t[0], 1); |
|||
s[9] = xor3(s[9], t[3], u); |
|||
s[24] = xor3(s[24], t[3], u); |
|||
|
|||
/* rho pi: b[..] = rotl(a[..], ..) */ |
|||
u = s[1]; |
|||
|
|||
s[1] = ROTL64(s[6], 44); |
|||
s[6] = ROTL64(s[9], 20); |
|||
s[9] = ROTL64(s[22], 61); |
|||
s[2] = ROTL64(s[12], 43); |
|||
s[4] = ROTL64(s[24], 14); |
|||
s[8] = ROTL64(s[16], 45); |
|||
s[5] = ROTL64(s[3], 28); |
|||
s[3] = ROTL64(s[18], 21); |
|||
s[7] = ROTL64(s[10], 3); |
|||
|
|||
/* chi: a[i,j] ^= ~b[i,j+1] & b[i,j+2] */ |
|||
|
|||
u = s[0]; v = s[1]; |
|||
s[0] = chi(s[0], s[1], s[2]); |
|||
s[1] = chi(s[1], s[2], s[3]); |
|||
s[2] = chi(s[2], s[3], s[4]); |
|||
s[3] = chi(s[3], s[4], u); |
|||
s[4] = chi(s[4], u, v); |
|||
s[5] = chi(s[5], s[6], s[7]); |
|||
s[6] = chi(s[6], s[7], s[8]); |
|||
s[7] = chi(s[7], s[8], s[9]); |
|||
|
|||
/* iota: a[0,0] ^= round constant */ |
|||
s[0] ^= keccak_round_constants[23]; |
|||
} |
@ -0,0 +1,19 @@ |
|||
#include "Miner.h" |
|||
#include "EthashAux.h" |
|||
|
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
template <> |
|||
unsigned dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagLoadMode = 0; |
|||
|
|||
template <> |
|||
volatile unsigned dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagLoadIndex = 0; |
|||
|
|||
template <> |
|||
unsigned dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagCreateDevice = 0; |
|||
|
|||
template <> |
|||
volatile void* dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagInHostMemory = NULL; |
|||
|
|||
|
@ -0,0 +1,515 @@ |
|||
|
|||
#include "EthStratumClientV2.h" |
|||
#include <libdevcore/Log.h> |
|||
#include <libethash/endian.h> |
|||
using boost::asio::ip::tcp; |
|||
|
|||
|
|||
static void diffToTarget(uint32_t *target, double diff) |
|||
{ |
|||
uint32_t target2[8]; |
|||
uint64_t m; |
|||
int k; |
|||
|
|||
for (k = 6; k > 0 && diff > 1.0; k--) |
|||
diff /= 4294967296.0; |
|||
m = (uint64_t)(4294901760.0 / diff); |
|||
if (m == 0 && k == 6) |
|||
memset(target2, 0xff, 32); |
|||
else { |
|||
memset(target2, 0, 32); |
|||
target2[k] = (uint32_t)m; |
|||
target2[k + 1] = (uint32_t)(m >> 32); |
|||
} |
|||
|
|||
for (int i = 0; i < 32; i++) |
|||
((uint8_t*)target)[31 - i] = ((uint8_t*)target2)[i]; |
|||
} |
|||
|
|||
|
|||
EthStratumClientV2::EthStratumClientV2(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, int const & protocol, string const & email) |
|||
: Worker("stratum"), |
|||
m_socket(m_io_service) |
|||
{ |
|||
m_minerType = m; |
|||
m_primary.host = host; |
|||
m_primary.port = port; |
|||
m_primary.user = user; |
|||
m_primary.pass = pass; |
|||
|
|||
p_active = &m_primary; |
|||
|
|||
m_authorized = false; |
|||
m_connected = false; |
|||
m_maxRetries = retries; |
|||
m_worktimeout = worktimeout; |
|||
|
|||
m_protocol = protocol; |
|||
m_email = email; |
|||
|
|||
p_farm = f; |
|||
p_worktimer = nullptr; |
|||
startWorking(); |
|||
} |
|||
|
|||
EthStratumClientV2::~EthStratumClientV2() |
|||
{ |
|||
|
|||
} |
|||
|
|||
void EthStratumClientV2::setFailover(string const & host, string const & port) |
|||
{ |
|||
setFailover(host, port, p_active->user, p_active->pass); |
|||
} |
|||
|
|||
void EthStratumClientV2::setFailover(string const & host, string const & port, string const & user, string const & pass) |
|||
{ |
|||
m_failover.host = host; |
|||
m_failover.port = port; |
|||
m_failover.user = user; |
|||
m_failover.pass = pass; |
|||
} |
|||
|
|||
void EthStratumClientV2::workLoop() |
|||
{ |
|||
while (m_running) |
|||
{ |
|||
try { |
|||
if (!m_connected) |
|||
{ |
|||
//m_io_service.run();
|
|||
//boost::thread t(boost::bind(&boost::asio::io_service::run, &m_io_service));
|
|||
connect(); |
|||
|
|||
} |
|||
read_until(m_socket, m_responseBuffer, "\n"); |
|||
std::istream is(&m_responseBuffer); |
|||
std::string response; |
|||
getline(is, response); |
|||
|
|||
if (!response.empty() && response.front() == '{' && response.back() == '}') |
|||
{ |
|||
Json::Value responseObject; |
|||
Json::Reader reader; |
|||
if (reader.parse(response.c_str(), responseObject)) |
|||
{ |
|||
processReponse(responseObject); |
|||
m_response = response; |
|||
} |
|||
else |
|||
{ |
|||
cwarn << "Parse response failed: " << reader.getFormattedErrorMessages(); |
|||
} |
|||
} |
|||
else if (m_protocol != STRATUM_PROTOCOL_ETHPROXY) |
|||
{ |
|||
cwarn << "Discarding incomplete response"; |
|||
} |
|||
} |
|||
catch (std::exception const& _e) { |
|||
cwarn << _e.what(); |
|||
reconnect(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void EthStratumClientV2::connect() |
|||
{ |
|||
cnote << "Connecting to stratum server " << p_active->host + ":" + p_active->port; |
|||
|
|||
tcp::resolver r(m_io_service); |
|||
tcp::resolver::query q(p_active->host, p_active->port); |
|||
tcp::resolver::iterator endpoint_iterator = r.resolve(q); |
|||
tcp::resolver::iterator end; |
|||
|
|||
boost::system::error_code error = boost::asio::error::host_not_found; |
|||
while (error && endpoint_iterator != end) |
|||
{ |
|||
m_socket.close(); |
|||
m_socket.connect(*endpoint_iterator++, error); |
|||
} |
|||
if (error) |
|||
{ |
|||
cerr << "Could not connect to stratum server " << p_active->host + ":" + p_active->port + ", " << error.message(); |
|||
reconnect(); |
|||
} |
|||
else |
|||
{ |
|||
cnote << "Connected!"; |
|||
m_connected = true; |
|||
if (!p_farm->isMining()) |
|||
{ |
|||
cnote << "Starting farm"; |
|||
if (m_minerType == MinerType::CPU) |
|||
p_farm->start("cpu", false); |
|||
else if (m_minerType == MinerType::CL) |
|||
p_farm->start("opencl", false); |
|||
else if (m_minerType == MinerType::CUDA) |
|||
p_farm->start("cuda", false); |
|||
else if (m_minerType == MinerType::Mixed) { |
|||
p_farm->start("cuda", false); |
|||
p_farm->start("opencl", true); |
|||
} |
|||
} |
|||
std::ostream os(&m_requestBuffer); |
|||
|
|||
string user; |
|||
size_t p; |
|||
|
|||
|
|||
switch (m_protocol) { |
|||
case STRATUM_PROTOCOL_STRATUM: |
|||
os << "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": []}\n"; |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHPROXY: |
|||
p = p_active->user.find_first_of("."); |
|||
user = p_active->user.substr(0, p); |
|||
if (p + 1 <= p_active->user.length()) |
|||
m_worker = p_active->user.substr(p + 1); |
|||
else |
|||
m_worker = ""; |
|||
|
|||
if (m_email.empty()) |
|||
{ |
|||
os << "{\"id\": 1, \"worker\":\"" << m_worker << "\", \"method\": \"eth_submitLogin\", \"params\": [\"" << user << "\"]}\n"; |
|||
} |
|||
else |
|||
{ |
|||
os << "{\"id\": 1, \"worker\":\"" << m_worker << "\", \"method\": \"eth_submitLogin\", \"params\": [\"" << user << "\", \"" << m_email << "\"]}\n"; |
|||
} |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHEREUMSTRATUM: |
|||
os << "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": [\"ethminer/" << ETH_PROJECT_VERSION << "\",\"EthereumStratum/1.0.0\"]}\n"; |
|||
break; |
|||
} |
|||
|
|||
write(m_socket, m_requestBuffer); |
|||
} |
|||
} |
|||
|
|||
void EthStratumClientV2::reconnect() |
|||
{ |
|||
if (p_worktimer) { |
|||
p_worktimer->cancel(); |
|||
p_worktimer = nullptr; |
|||
} |
|||
|
|||
//m_io_service.reset();
|
|||
//m_socket.close(); // leads to crashes on Linux
|
|||
m_authorized = false; |
|||
m_connected = false; |
|||
|
|||
if (!m_failover.host.empty()) |
|||
{ |
|||
m_retries++; |
|||
|
|||
if (m_retries > m_maxRetries) |
|||
{ |
|||
if (m_failover.host == "exit") { |
|||
disconnect(); |
|||
return; |
|||
} |
|||
else if (p_active == &m_primary) |
|||
{ |
|||
p_active = &m_failover; |
|||
} |
|||
else { |
|||
p_active = &m_primary; |
|||
} |
|||
m_retries = 0; |
|||
} |
|||
} |
|||
|
|||
cnote << "Reconnecting in 3 seconds..."; |
|||
boost::asio::deadline_timer timer(m_io_service, boost::posix_time::seconds(3)); |
|||
timer.wait(); |
|||
} |
|||
|
|||
void EthStratumClientV2::disconnect() |
|||
{ |
|||
cnote << "Disconnecting"; |
|||
m_connected = false; |
|||
m_running = false; |
|||
if (p_farm->isMining()) |
|||
{ |
|||
cnote << "Stopping farm"; |
|||
p_farm->stop(); |
|||
} |
|||
m_socket.close(); |
|||
//m_io_service.stop();
|
|||
} |
|||
|
|||
void EthStratumClientV2::processExtranonce(std::string& enonce) |
|||
{ |
|||
m_extraNonceHexSize = enonce.length(); |
|||
|
|||
cnote << "Extranonce set to " << enonce; |
|||
|
|||
for (int i = enonce.length(); i < 16; ++i) enonce += "0"; |
|||
m_extraNonce = h64(enonce); |
|||
} |
|||
|
|||
void EthStratumClientV2::processReponse(Json::Value& responseObject) |
|||
{ |
|||
Json::Value error = responseObject.get("error", new Json::Value); |
|||
if (error.isArray()) |
|||
{ |
|||
string msg = error.get(1, "Unknown error").asString(); |
|||
cnote << msg; |
|||
} |
|||
std::ostream os(&m_requestBuffer); |
|||
Json::Value params; |
|||
int id = responseObject.get("id", Json::Value::null).asInt(); |
|||
switch (id) |
|||
{ |
|||
case 1: |
|||
|
|||
if (m_protocol == STRATUM_PROTOCOL_ETHEREUMSTRATUM) |
|||
{ |
|||
m_nextWorkDifficulty = 1; |
|||
params = responseObject.get("result", Json::Value::null); |
|||
if (params.isArray()) |
|||
{ |
|||
std::string enonce = params.get((Json::Value::ArrayIndex)1, "").asString(); |
|||
processExtranonce(enonce); |
|||
} |
|||
|
|||
os << "{\"id\": 2, \"method\": \"mining.extranonce.subscribe\", \"params\": []}\n"; |
|||
} |
|||
if (m_protocol != STRATUM_PROTOCOL_ETHPROXY) |
|||
{ |
|||
cnote << "Subscribed to stratum server"; |
|||
os << "{\"id\": 3, \"method\": \"mining.authorize\", \"params\": [\"" << p_active->user << "\",\"" << p_active->pass << "\"]}\n"; |
|||
write(m_socket, m_requestBuffer); |
|||
} |
|||
else |
|||
{ |
|||
m_authorized = true; |
|||
os << "{\"id\": 5, \"method\": \"eth_getWork\", \"params\": []}\n"; // not strictly required but it does speed up initialization
|
|||
write(m_socket, m_requestBuffer); |
|||
} |
|||
break; |
|||
case 2: |
|||
// nothing to do...
|
|||
break; |
|||
case 3: |
|||
m_authorized = responseObject.get("result", Json::Value::null).asBool(); |
|||
if (!m_authorized) |
|||
{ |
|||
cnote << "Worker not authorized:" << p_active->user; |
|||
disconnect(); |
|||
return; |
|||
} |
|||
cnote << "Authorized worker " << p_active->user; |
|||
break; |
|||
case 4: |
|||
if (responseObject.get("result", false).asBool()) { |
|||
cnote << "B-) Submitted and accepted."; |
|||
p_farm->acceptedSolution(m_stale); |
|||
} |
|||
else { |
|||
cwarn << ":-( Not accepted."; |
|||
p_farm->rejectedSolution(m_stale); |
|||
} |
|||
break; |
|||
default: |
|||
string method, workattr; |
|||
unsigned index; |
|||
if (m_protocol != STRATUM_PROTOCOL_ETHPROXY) |
|||
{ |
|||
method = responseObject.get("method", "").asString(); |
|||
workattr = "params"; |
|||
index = 1; |
|||
} |
|||
else |
|||
{ |
|||
method = "mining.notify"; |
|||
workattr = "result"; |
|||
index = 0; |
|||
} |
|||
|
|||
if (method == "mining.notify") |
|||
{ |
|||
params = responseObject.get(workattr, Json::Value::null); |
|||
if (params.isArray()) |
|||
{ |
|||
string job = params.get((Json::Value::ArrayIndex)0, "").asString(); |
|||
|
|||
if (m_protocol == STRATUM_PROTOCOL_ETHEREUMSTRATUM) |
|||
{ |
|||
string job = params.get((Json::Value::ArrayIndex)0, "").asString(); |
|||
string sSeedHash = params.get((Json::Value::ArrayIndex)1, "").asString(); |
|||
string sHeaderHash = params.get((Json::Value::ArrayIndex)2, "").asString(); |
|||
|
|||
if (sHeaderHash != "" && sSeedHash != "") |
|||
{ |
|||
cnote << "Received new job #" + job; |
|||
|
|||
h256 seedHash = h256(sSeedHash); |
|||
h256 headerHash = h256(sHeaderHash); |
|||
|
|||
m_previous.headerHash = m_current.headerHash; |
|||
m_previous.seedHash = m_current.seedHash; |
|||
m_previous.boundary = m_current.boundary; |
|||
m_previous.startNonce = m_current.startNonce; |
|||
m_previous.exSizeBits = m_previous.exSizeBits; |
|||
m_previousJob = m_job; |
|||
|
|||
m_current.headerHash = h256(sHeaderHash); |
|||
m_current.seedHash = seedHash; |
|||
m_current.boundary = h256(); |
|||
diffToTarget((uint32_t*)m_current.boundary.data(), m_nextWorkDifficulty); |
|||
m_current.startNonce = ethash_swap_u64(*((uint64_t*)m_extraNonce.data())); |
|||
m_current.exSizeBits = m_extraNonceHexSize * 4; |
|||
m_job = job; |
|||
|
|||
p_farm->setWork(m_current); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
string sHeaderHash = params.get((Json::Value::ArrayIndex)index++, "").asString(); |
|||
string sSeedHash = params.get((Json::Value::ArrayIndex)index++, "").asString(); |
|||
string sShareTarget = params.get((Json::Value::ArrayIndex)index++, "").asString(); |
|||
|
|||
// coinmine.pl fix
|
|||
int l = sShareTarget.length(); |
|||
if (l < 66) |
|||
sShareTarget = "0x" + string(66 - l, '0') + sShareTarget.substr(2); |
|||
|
|||
|
|||
if (sHeaderHash != "" && sSeedHash != "" && sShareTarget != "") |
|||
{ |
|||
cnote << "Received new job #" + job.substr(0, 8); |
|||
|
|||
h256 seedHash = h256(sSeedHash); |
|||
h256 headerHash = h256(sHeaderHash); |
|||
|
|||
if (headerHash != m_current.headerHash) |
|||
{ |
|||
//x_current.lock();
|
|||
//if (p_worktimer)
|
|||
// p_worktimer->cancel();
|
|||
|
|||
m_previous.headerHash = m_current.headerHash; |
|||
m_previous.seedHash = m_current.seedHash; |
|||
m_previous.boundary = m_current.boundary; |
|||
m_previousJob = m_job; |
|||
|
|||
m_current.headerHash = h256(sHeaderHash); |
|||
m_current.seedHash = seedHash; |
|||
m_current.boundary = h256(sShareTarget); |
|||
m_job = job; |
|||
|
|||
p_farm->setWork(m_current); |
|||
//x_current.unlock();
|
|||
//p_worktimer = new boost::asio::deadline_timer(m_io_service, boost::posix_time::seconds(m_worktimeout));
|
|||
//p_worktimer->async_wait(boost::bind(&EthStratumClientV2::work_timeout_handler, this, boost::asio::placeholders::error));
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
else if (method == "mining.set_difficulty" && m_protocol == STRATUM_PROTOCOL_ETHEREUMSTRATUM) |
|||
{ |
|||
params = responseObject.get("params", Json::Value::null); |
|||
if (params.isArray()) |
|||
{ |
|||
m_nextWorkDifficulty = params.get((Json::Value::ArrayIndex)0, 1).asDouble(); |
|||
if (m_nextWorkDifficulty <= 0.0001) m_nextWorkDifficulty = 0.0001; |
|||
cnote << "Difficulty set to " << m_nextWorkDifficulty; |
|||
} |
|||
} |
|||
else if (method == "mining.set_extranonce" && m_protocol == STRATUM_PROTOCOL_ETHEREUMSTRATUM) |
|||
{ |
|||
params = responseObject.get("params", Json::Value::null); |
|||
if (params.isArray()) |
|||
{ |
|||
std::string enonce = params.get((Json::Value::ArrayIndex)0, "").asString(); |
|||
processExtranonce(enonce); |
|||
} |
|||
} |
|||
else if (method == "client.get_version") |
|||
{ |
|||
os << "{\"error\": null, \"id\" : " << id << ", \"result\" : \"" << ETH_PROJECT_VERSION << "\"}\n"; |
|||
write(m_socket, m_requestBuffer); |
|||
} |
|||
break; |
|||
} |
|||
|
|||
} |
|||
|
|||
void EthStratumClientV2::work_timeout_handler(const boost::system::error_code& ec) { |
|||
if (!ec) { |
|||
cnote << "No new work received in" << m_worktimeout << "seconds."; |
|||
reconnect(); |
|||
} |
|||
} |
|||
|
|||
bool EthStratumClientV2::submit(EthashProofOfWork::Solution solution) { |
|||
x_current.lock(); |
|||
EthashProofOfWork::WorkPackage tempWork(m_current); |
|||
string temp_job = m_job; |
|||
EthashProofOfWork::WorkPackage tempPreviousWork(m_previous); |
|||
string temp_previous_job = m_previousJob; |
|||
x_current.unlock(); |
|||
|
|||
cnote << "Solution found; Submitting to" << p_active->host << "..."; |
|||
|
|||
string minernonce; |
|||
if (m_protocol != STRATUM_PROTOCOL_ETHEREUMSTRATUM) |
|||
cnote << " Nonce:" << "0x" + solution.nonce.hex(); |
|||
else |
|||
minernonce = solution.nonce.hex().substr(m_extraNonceHexSize, 16 - m_extraNonceHexSize); |
|||
|
|||
|
|||
if (EthashAux::eval(tempWork.seedHash, tempWork.headerHash, solution.nonce).value < tempWork.boundary) |
|||
{ |
|||
string json; |
|||
switch (m_protocol) { |
|||
case STRATUM_PROTOCOL_STRATUM: |
|||
json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + tempWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n"; |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHPROXY: |
|||
json = "{\"id\": 4, \"worker\":\"" + m_worker + "\", \"method\": \"eth_submitWork\", \"params\": [\"0x" + solution.nonce.hex() + "\",\"0x" + tempWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n"; |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHEREUMSTRATUM: |
|||
json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_job + "\",\"" + minernonce + "\"]}\n"; |
|||
break; |
|||
} |
|||
std::ostream os(&m_requestBuffer); |
|||
os << json; |
|||
m_stale = false; |
|||
write(m_socket, m_requestBuffer); |
|||
return true; |
|||
} |
|||
else if (EthashAux::eval(tempPreviousWork.seedHash, tempPreviousWork.headerHash, solution.nonce).value < tempPreviousWork.boundary) |
|||
{ |
|||
string json; |
|||
switch (m_protocol) { |
|||
case STRATUM_PROTOCOL_STRATUM: |
|||
json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_previous_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + tempPreviousWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n"; |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHPROXY: |
|||
json = "{\"id\": 4, \"worker\":\"" + m_worker + "\", \"method\": \"eth_submitWork\", \"params\": [\"0x" + solution.nonce.hex() + "\",\"0x" + tempPreviousWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n"; |
|||
break; |
|||
case STRATUM_PROTOCOL_ETHEREUMSTRATUM: |
|||
json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_previous_job + "\",\"" + minernonce + "\"]}\n"; |
|||
break; |
|||
} std::ostream os(&m_requestBuffer); |
|||
os << json; |
|||
m_stale = true; |
|||
cwarn << "Submitting stale solution."; |
|||
write(m_socket, m_requestBuffer); |
|||
return true; |
|||
} |
|||
else { |
|||
m_stale = false; |
|||
cwarn << "FAILURE: GPU gave incorrect result!"; |
|||
p_farm->failedSolution(); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
@ -0,0 +1,95 @@ |
|||
#include <iostream> |
|||
#include <boost/array.hpp> |
|||
#include <boost/asio.hpp> |
|||
#include <boost/bind.hpp> |
|||
#include <json/json.h> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
#include <libdevcore/Worker.h> |
|||
#include <libethcore/Farm.h> |
|||
#include <libethcore/EthashAux.h> |
|||
#include <libethcore/Miner.h> |
|||
|
|||
#include "BuildInfo.h" |
|||
|
|||
|
|||
using namespace std; |
|||
using namespace boost::asio; |
|||
using boost::asio::ip::tcp; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
class EthStratumClientV2 : public Worker |
|||
{ |
|||
public: |
|||
EthStratumClientV2(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, int const & protocol, string const & email); |
|||
~EthStratumClientV2(); |
|||
|
|||
void setFailover(string const & host, string const & port); |
|||
void setFailover(string const & host, string const & port, string const & user, string const & pass); |
|||
|
|||
bool isRunning() { return m_running; } |
|||
bool isConnected() { return m_connected && m_authorized; } |
|||
h256 currentHeaderHash() { return m_current.headerHash; } |
|||
bool current() { return m_current; } |
|||
unsigned waitState() { return m_waitState; } |
|||
bool submit(EthashProofOfWork::Solution solution); |
|||
void reconnect(); |
|||
private: |
|||
void workLoop() override; |
|||
void connect(); |
|||
|
|||
void disconnect(); |
|||
void work_timeout_handler(const boost::system::error_code& ec); |
|||
|
|||
void processReponse(Json::Value& responseObject); |
|||
|
|||
MinerType m_minerType; |
|||
|
|||
cred_t * p_active; |
|||
cred_t m_primary; |
|||
cred_t m_failover; |
|||
|
|||
string m_worker; // eth-proxy only;
|
|||
|
|||
bool m_authorized; |
|||
bool m_connected; |
|||
bool m_running = true; |
|||
|
|||
int m_retries = 0; |
|||
int m_maxRetries; |
|||
int m_worktimeout = 60; |
|||
|
|||
int m_waitState = MINER_WAIT_STATE_WORK; |
|||
|
|||
string m_response; |
|||
|
|||
GenericFarm<EthashProofOfWork> * p_farm; |
|||
mutex x_current; |
|||
EthashProofOfWork::WorkPackage m_current; |
|||
EthashProofOfWork::WorkPackage m_previous; |
|||
|
|||
bool m_stale = false; |
|||
|
|||
string m_job; |
|||
string m_previousJob; |
|||
EthashAux::FullType m_dag; |
|||
|
|||
boost::asio::io_service m_io_service; |
|||
tcp::socket m_socket; |
|||
|
|||
boost::asio::streambuf m_requestBuffer; |
|||
boost::asio::streambuf m_responseBuffer; |
|||
|
|||
boost::asio::deadline_timer * p_worktimer; |
|||
|
|||
int m_protocol; |
|||
string m_email; |
|||
|
|||
double m_nextWorkDifficulty; |
|||
|
|||
h64 m_extraNonce; |
|||
int m_extraNonceHexSize; |
|||
|
|||
void processExtranonce(std::string& enonce); |
|||
}; |
@ -1,19 +0,0 @@ |
|||
#!/bin/bash |
|||
|
|||
opwd="$PWD" |
|||
br=$(git branch | grep '\*' | sed 's/^..//') |
|||
|
|||
n=cpp-ethereum-src-$(date "+%Y%m%d%H%M%S" --date="1970-01-01 $(git log -1 --date=short --pretty=format:%ct) sec GMT")-$(grep "Version = " libdevcore/Common.cpp | sed 's/^[^"]*"//' | sed 's/".*$//')-$(git rev-parse HEAD | cut -c1-6) |
|||
|
|||
cd /tmp |
|||
git clone "$opwd" $n |
|||
cd $n |
|||
git checkout $br |
|||
rm -f package.sh |
|||
cd .. |
|||
tar c $n | bzip2 -- > $opwd/../${n}.tar.bz2 |
|||
rm -rf $n |
|||
cd $opwd |
|||
|
|||
echo "SHA1(${n}.tar.bz2) = $(shasum $opwd/../${n}.tar.bz2 | cut -d' ' -f 1)" |
|||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue