Compare commits
26 Commits
Author | SHA1 | Date |
---|---|---|
Duke | 54a38abafe | 4 months ago |
Duke | 3166f1359d | 4 months ago |
Duke | ee6341e277 | 4 months ago |
Duke | 23af9a4bf8 | 4 months ago |
Duke | 5c17dbd207 | 4 months ago |
Duke | 6663118e2a | 4 months ago |
Duke | 1a49819e44 | 4 months ago |
Duke | b853cb92a1 | 4 months ago |
Duke | 470eacc6bd | 4 months ago |
Duke | 0864cb0550 | 4 months ago |
Duke | 04b122a067 | 4 months ago |
Duke | b70370123e | 4 months ago |
Duke | 323d2134a1 | 4 months ago |
Duke | 3f6c9ec651 | 4 months ago |
Duke | 22e0cfcb17 | 5 months ago |
Duke | d386a0439e | 5 months ago |
Duke | 0ce00a29ed | 5 months ago |
Duke | aaea1a418b | 5 months ago |
Duke | dd45fed774 | 5 months ago |
Duke | e05e9b6fce | 5 months ago |
Duke | 61e801539d | 5 months ago |
Duke | 8f3e62bd65 | 5 months ago |
Duke | a9cbc8fa09 | 7 months ago |
Duke | f335fb539f | 9 months ago |
Duke | b40a6f6d34 | 9 months ago |
Duke | f89cd61fce | 9 months ago |
14 changed files with 778 additions and 8 deletions
@ -0,0 +1,32 @@ |
|||||
|
# Prerequisites |
||||
|
*.d |
||||
|
|
||||
|
# Compiled Object files |
||||
|
*.slo |
||||
|
*.lo |
||||
|
*.o |
||||
|
*.obj |
||||
|
|
||||
|
# Precompiled Headers |
||||
|
*.gch |
||||
|
*.pch |
||||
|
|
||||
|
# Compiled Dynamic libraries |
||||
|
*.so |
||||
|
*.dylib |
||||
|
*.dll |
||||
|
|
||||
|
# Fortran module files |
||||
|
*.mod |
||||
|
*.smod |
||||
|
|
||||
|
# Compiled Static libraries |
||||
|
*.lai |
||||
|
*.la |
||||
|
*.a |
||||
|
*.lib |
||||
|
|
||||
|
# Executables |
||||
|
*.exe |
||||
|
*.out |
||||
|
*.app |
@ -0,0 +1,99 @@ |
|||||
|
# define the name of application
|
||||
|
APPNAME := lxrhash |
||||
|
|
||||
|
# define the cpp compiler to use
|
||||
|
CXX := g++ |
||||
|
|
||||
|
# define the FLAGS
|
||||
|
FLAGS := -Wall |
||||
|
|
||||
|
# define bin directory
|
||||
|
BIN := bin |
||||
|
|
||||
|
# define include directory
|
||||
|
INC := include |
||||
|
|
||||
|
# define lib directory
|
||||
|
LIB := lib |
||||
|
|
||||
|
# define source directory
|
||||
|
SRC := src |
||||
|
|
||||
|
# define object directory
|
||||
|
OBJ := obj |
||||
|
|
||||
|
VPATH := $(SRC) $(INC) $(LIB) |
||||
|
|
||||
|
# Generate extension depending on the operating system
|
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
TARGET := $(BIN)/$(APPNAME).exe |
||||
|
else |
||||
|
TARGET := $(BIN)/$(APPNAME) |
||||
|
endif |
||||
|
|
||||
|
# define the color of the console text
|
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
RED := $(tput setaf "1") |
||||
|
GREEN := $(tput setaf "2") |
||||
|
YELLOW := $(tput setaf "3") |
||||
|
BLUE := $(tput setaf "4") |
||||
|
PURPLE := $(tput setaf "5") |
||||
|
CYAN := $(tput setaf "6") |
||||
|
WHITE := $(tput setaf "7") |
||||
|
RESET := $(tput sgr0) |
||||
|
else |
||||
|
RED := $(shell echo -e "\033[031m") |
||||
|
GREEN := $(shell echo -e "\033[032m") |
||||
|
YELLOW := $(shell echo -e "\033[033m") |
||||
|
BLUE := $(shell echo -e "\033[034m") |
||||
|
PURPLE := $(shell echo -e "\033[035m") |
||||
|
CYAN := $(shell echo -e "\033[036m") |
||||
|
WHITE := $(shell echo -e "\033[037m") |
||||
|
RESET := $(shell echo -e "\033[0m") |
||||
|
endif |
||||
|
|
||||
|
OBJS := $(patsubst %.cpp, $(OBJ)/%.o, $(notdir $(wildcard $(SRC)/*.cpp) $(wildcard $(LIB)/*.cpp))) |
||||
|
|
||||
|
# Generate object files
|
||||
|
$(OBJ)/%.o: %.cpp |
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
@IF NOT EXIST $(subst /,\,$(OBJ)) mkdir $(subst /,\,$(OBJ)) |
||||
|
else |
||||
|
@mkdir -p $(OBJ) |
||||
|
endif |
||||
|
@echo $(CYAN)Compiling: $(RED)$(@F)$(RESET) |
||||
|
@$(CXX) -I $(INC) -c $< -o $@ |
||||
|
|
||||
|
# Generate executable
|
||||
|
$(TARGET): $(OBJS) |
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
@IF NOT EXIST $(subst /,\,$(BIN)) mkdir $(subst /,\,$(BIN)) |
||||
|
else |
||||
|
@mkdir -p $(BIN) |
||||
|
endif |
||||
|
@echo $(CYAN)Creating executable: $(GREEN)$(@F)$(RESET) |
||||
|
@$(CXX) $(OBJS) -o $@ $(FLAGS) |
||||
|
|
||||
|
.PHONY: run |
||||
|
run: |
||||
|
@$(TARGET) |
||||
|
|
||||
|
.PHONY: clean |
||||
|
clean: |
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
@if exist $(OBJ)\*.o @del /Q $(OBJ)\*.o |
||||
|
@if exist $(OBJ)\*.exe @del /Q $(BIN)\*.exe |
||||
|
else |
||||
|
@rm -f $(OBJ)/*.o |
||||
|
@rm -f $(BIN)/* |
||||
|
endif |
||||
|
|
||||
|
.PHONY: delete |
||||
|
delete: |
||||
|
ifeq ($(OS),Windows_NT) |
||||
|
@if exist $(OBJ) @rd /Q /S $(OBJ) |
||||
|
@if exist $(BIN) @rd /Q /S $(BIN) |
||||
|
else |
||||
|
@rm -rf $(OBJ) |
||||
|
@rm -rf $(BIN) |
||||
|
endif |
@ -0,0 +1,24 @@ |
|||||
|
// Copyright 2023 The Accumulate Authors
|
||||
|
//
|
||||
|
// Use of this source code is governed by an MIT-style
|
||||
|
// license that can be found in the LICENSE file or at
|
||||
|
// https://opensource.org/licenses/MIT.
|
||||
|
|
||||
|
unsigned long long const Size = 0x40000000; // Size of the BitMap. Should be 1 GB (0x40000000) for production
|
||||
|
int const Passes = 6; //
|
||||
|
int const Loops = 16; // How many times the hash is looped
|
||||
|
unsigned long long const checksum = 0xed0536be7833ca15; // Checksum of byteMap to ensure we don't use a corrupted file
|
||||
|
|
||||
|
// Lookup XoR Hash (Ram Hash)
|
||||
|
class LXRHash |
||||
|
{ |
||||
|
unsigned char byteMap[Size]; // 1 GB is 30 bits, 2^30, or hex 4 with 7 zeros
|
||||
|
unsigned long long MapMask = Size - 1; // MapMask is byteMap length -1
|
||||
|
public: //
|
||||
|
unsigned long long mix(char unsigned hash[32], unsigned long long nonce); // Mixes the hash with the nonce prior to
|
||||
|
unsigned long long LxrPoW(char unsigned hash[32], unsigned long long nonce); // Returns the PoW for a hash + nonce
|
||||
|
void init(); // Init the byteMap; do it only once.
|
||||
|
private: //
|
||||
|
bool load(); // Load the byteMap.dat file
|
||||
|
unsigned long long check(); // Quick check of correct byteMap
|
||||
|
}; |
@ -0,0 +1,233 @@ |
|||||
|
// Copyright 2023 The Accumulate Authors
|
||||
|
//
|
||||
|
// Use of this source code is governed by an MIT-style
|
||||
|
// license that can be found in the LICENSE file or at
|
||||
|
// https://opensource.org/licenses/MIT.
|
||||
|
|
||||
|
#include <filesystem> |
||||
|
#include <iostream> |
||||
|
#include <fstream> |
||||
|
#include <cstdio> |
||||
|
#include <chrono> |
||||
|
#include <ctime> |
||||
|
#include "../include/lxrhash.h" |
||||
|
|
||||
|
// LXRHash uses a combination of shifts and exclusive or's to combine inputs and states to
|
||||
|
// create a hash with strong avalanche properties. This means that if any one bit is changed
|
||||
|
// in the inputs, on average half of the bits of the output change. This quality makes an
|
||||
|
// algorithmic attack on mining very, very unlikely.
|
||||
|
//
|
||||
|
// First, the hash and nonce are "mixed" such that a reasonable avalanche property is obtained.
|
||||
|
//
|
||||
|
// Secondly, the resulting 48 bytes are mapped through a 1 GB byteMap where random accesses have
|
||||
|
// an even chance of producing a value between 0-255. Cycling through lookups from random bytes in
|
||||
|
// the 1 GB space produces a resulting value to be graded.
|
||||
|
//
|
||||
|
// The Shift XoR Random Number Generator (RNG) was invented by George Marsaglia and published
|
||||
|
// in 2003. Please refer to the readme on the LXRHashing repository.
|
||||
|
// https://gitlab.com/accumulatenetwork/ecosystem/LXRMining/-/blob/main/README.md
|
||||
|
//
|
||||
|
// * No elements of the triplets are zero
|
||||
|
// * All elements are relatively prime to each other
|
||||
|
// * All elements Are small relative to an unsigned long long (64)
|
||||
|
// * The right shift generally smaller than the left shifts
|
||||
|
//
|
||||
|
// In my testing, and according to Marsaglia, no elements of these triplets fitting this criteria
|
||||
|
// perform better or worse. Adding constants and other outside elements help the distribution of
|
||||
|
// values.
|
||||
|
//
|
||||
|
// Further, two different sponge states are used, mix() and LXRPoW()
|
||||
|
//
|
||||
|
// mix()
|
||||
|
// Combines the 32 byte hash with the unsigned long long nonce. This is done as rapidly as possible
|
||||
|
// with an avalanche property only enough to ensure repeated hashes with minimal bit changes to
|
||||
|
// nonces do not gain an advantage during mining by tracing the same paths through the byteMap,
|
||||
|
// making better use of the cache.
|
||||
|
//
|
||||
|
// LXRPoW()
|
||||
|
// Accepts a 32 byte hash with the unsigned long long nonce. The sponge is initialized using mix().
|
||||
|
// Then Each byte is translated using a sequenced Pseudo random sequenced index into the
|
||||
|
// 1 GB byteMap. This process is repeated for a number of loops, building up a sponge value.
|
||||
|
// More loops makes the hash slower and more dependent on the random access speed to the
|
||||
|
// 1 GB byteMap. As processors grow in speed, and chips accommodate greater caches, the
|
||||
|
// byteMap and the loop number increased.
|
||||
|
//
|
||||
|
// mix() is then used again to "squeeze out" the hash, where the high 8 bytes represent the
|
||||
|
// possible PoW solution.
|
||||
|
|
||||
|
// check()
|
||||
|
// Quick checksum, with a bit of bit spreading to make the checksum stronger
|
||||
|
unsigned long long LXRHash::check() |
||||
|
{ |
||||
|
unsigned long long state = 0; |
||||
|
for (int i = 0; i < Size; i += 8) |
||||
|
{ |
||||
|
unsigned long long a = 0; // Pull a long Big Endian value from byteMap
|
||||
|
for (int j = 0; j < 8; j++) |
||||
|
{ |
||||
|
a <<= 8; |
||||
|
a ^= (unsigned long long)(byteMap[i + j]); |
||||
|
} |
||||
|
state ^= state << 23 ^ a << 11; // Randomize state, fold in the long from byteMap
|
||||
|
state ^= state >> 3; // in the byteMap, running them through a
|
||||
|
state ^= state << 17; // Marsaglia Xorshift RNG
|
||||
|
} |
||||
|
return state; // Return resulting state as the checksum
|
||||
|
} |
||||
|
|
||||
|
// init()
|
||||
|
// initializes the 1 GB byteMap
|
||||
|
// Please note that I just wrote cheap code to cache the byteMap. Since it takes about 5 minutes
|
||||
|
// or more to generate the byteMap, this code looks for a byteMap.dat file and loads it if it
|
||||
|
// exists.
|
||||
|
void LXRHash::init() |
||||
|
{ |
||||
|
if (LXRHash::load()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
printf("\nbyteMap.dat file not found. Building byteMap.dat file is slow. This takes six passes:\n"); |
||||
|
// Initialize the byteMap with values from 0 to 255 repeated for the whole array
|
||||
|
for (unsigned long long i = 0; i < Size; i++) |
||||
|
{ |
||||
|
byteMap[i] = i; |
||||
|
} |
||||
|
printf("start cs %llx\n", check()); |
||||
|
unsigned long long offset = 0x7a43b26c611e135f; // Arbitrary 64 bit initial offset (no zero bytes)
|
||||
|
unsigned long long cnt = 0; // Marsaglia found a counter improves Xorshift
|
||||
|
for (unsigned long long i = 0; i < Passes; i++) // Passes. 2 passes at least are needed.
|
||||
|
{ //
|
||||
|
for (unsigned long long j = 0; j < Size; j++) // Shuffle the byteMap by swapping every byte with
|
||||
|
{ // another randomly chosen byte.
|
||||
|
offset ^= offset << 13 ^ cnt; // More classical Marsaglia Xorshift RNG
|
||||
|
offset ^= offset >> 23; //
|
||||
|
offset ^= offset << 5; //
|
||||
|
unsigned long long r = offset & MapMask; // Mask r to an index within the byteMap
|
||||
|
unsigned char a = byteMap[r]; // Get the random byte
|
||||
|
byteMap[r] = byteMap[j]; // Put the ith value there
|
||||
|
byteMap[j] = a; // Put the random byte at the ith position
|
||||
|
cnt += a; // Walk cnt forward by a, (0-255)
|
||||
|
if (j % 200000000 == 0) // Give feedback
|
||||
|
{ //
|
||||
|
printf("."); // A period every 200M bytes swapped
|
||||
|
fflush(stdout); // flush so user can see
|
||||
|
} //
|
||||
|
} //
|
||||
|
printf("%llu", i + 1); // Count the passes
|
||||
|
fflush(stdout); |
||||
|
} |
||||
|
printf("\n"); |
||||
|
|
||||
|
printf("Checksum: %llx\n", check()); // Print the file checksum
|
||||
|
|
||||
|
std::fstream byteMapFile; |
||||
|
byteMapFile = std::fstream("byteMap.dat", std::ios::out | std::ios::binary); |
||||
|
byteMapFile.write((char *)(byteMap), Size); |
||||
|
byteMapFile.close(); |
||||
|
} |
||||
|
|
||||
|
bool LXRHash::load() |
||||
|
{ |
||||
|
// open the file:
|
||||
|
std::streampos fileSize; |
||||
|
std::ifstream file("byteMap.dat", std::ios::binary); |
||||
|
|
||||
|
// get its size:
|
||||
|
file.seekg(0, std::ios::end); // Seek to the end
|
||||
|
fileSize = file.tellg(); // get the file size
|
||||
|
if (fileSize != Size) // if not what we expect (exactly the length of byteMap)
|
||||
|
{ //
|
||||
|
return (false); // then return false (to generate the right file)
|
||||
|
} //
|
||||
|
file.seekg(0, std::ios::beg); // Seek to the start of the file,
|
||||
|
file.read((char *)(byteMap), Size); // and read the full byteMap
|
||||
|
file.close(); //
|
||||
|
unsigned long long cs = check(); //
|
||||
|
if (check() != checksum) // Then check that the checksum is correct
|
||||
|
{ //
|
||||
|
printf("checksum mismatch l:%llx != cs:%llx\n", cs, checksum); |
||||
|
std::remove("byteMap.dat"); // Remove the bad file
|
||||
|
return (false); // Return fail
|
||||
|
} //
|
||||
|
return true; // If so, all good, don't need to regenerate the byteMap
|
||||
|
} |
||||
|
|
||||
|
unsigned long long LXRHash::LxrPoW(char unsigned hash[32], unsigned long long nonce) |
||||
|
{ |
||||
|
// Mix the hash with the nonce to ensure the path through the byteMap is unique even if one bit
|
||||
|
unsigned long long state = LXRHash::mix(hash, nonce); // is changed from another submission.
|
||||
|
|
||||
|
// Make the specified "loops" through the hash. The initial state is returned by Mix,
|
||||
|
// bringing the total number of bits involved in the "sponge" to 48. Increasing the
|
||||
|
// loops would slow down the hash, giving this mechanism an easy way to keep difficulty
|
||||
|
// within the limits of the total hash power in a protocol
|
||||
|
for (int i = 0; i < Loops; i++) // Make our loops over the
|
||||
|
{ // entire hash
|
||||
|
for (int j = 0; j < 32; j++) // Process each byte
|
||||
|
{ //
|
||||
|
unsigned long long b, v; // Do all math in unsigned long long
|
||||
|
b = byteMap[state & MapMask]; // Pull a byte from the ByteMap
|
||||
|
v = hash[j]; // Get a byte from the hash
|
||||
|
state ^= state << 17 ^ b << 31; // A modified XorShift RNG
|
||||
|
state ^= state >> 7 ^ v << 23; // Fold in a random byte from
|
||||
|
state ^= state << 5; // the byteMap and the byte
|
||||
|
hash[j] = state; // from the hash.
|
||||
|
} // Then update the hash byte.
|
||||
|
} |
||||
|
state = LXRHash::mix(hash, state); // Do a final mix() using state
|
||||
|
return state; // as the nonce and return the state.
|
||||
|
} |
||||
|
|
||||
|
// mix()
|
||||
|
// Mix spreads the bits of the hash and nonce throughout the hash and a "state"
|
||||
|
unsigned long long LXRHash::mix(char unsigned hash[32], unsigned long long nonce) |
||||
|
{ |
||||
|
unsigned long long state = 0xb32c25d16e362f32; // Set the state to an arbitrary unsigned long long with bits
|
||||
|
nonce ^= nonce << 19 ^ state; // Run the nonce through a Xorshift
|
||||
|
nonce ^= nonce >> 1; |
||||
|
nonce ^= nonce << 3; |
||||
|
|
||||
|
unsigned long long array[5]; // Array of longs, the nonce, and 4 longs holding hash
|
||||
|
array[0] = nonce; // this array along with the state is the sponge for the LXRHash
|
||||
|
for (int i = 1; i < 5; i++) // Walk through the array
|
||||
|
{ //
|
||||
|
array[i] = 0; // Clear the array (not really needed, but it's cleaner)
|
||||
|
for (int j = 0; j < 8; j++) // Get 8 bytes of the hash as array entry
|
||||
|
{ //
|
||||
|
array[i] <<= 8; // Shift the array to the left a byte
|
||||
|
array[i] |= hash[((i - 1) << 3) + j]; // Or in the next byte
|
||||
|
} //
|
||||
|
state ^= state << 7 ^ array[i]; // shift state combine the whole hash into
|
||||
|
state ^= state >> 3; // the state while randomizing the state
|
||||
|
state ^= state << 5; // through a Xorshift RNG.
|
||||
|
} |
||||
|
|
||||
|
// mix what is effectively sponge of 5 elements and a state
|
||||
|
for (int i = 0; i < 5; i++) |
||||
|
{ |
||||
|
unsigned long long a, left1, right, left2; |
||||
|
a = array[i]; // Get each element of the array
|
||||
|
left1 = (a & 0x1F) | 1; // Use the element to pick 3 random shifts for the Xorshift
|
||||
|
right = ((a & 0xF0) >> 5) | 1; // Note that the right is smaller than the left
|
||||
|
left2 = (((a & 0x1F0000) >> 17) << 1) ^ left1; // And xor-ing left1 with left2 ensures they are different
|
||||
|
state ^= state << left1 ^ a << 5; // Randomize the state and array element
|
||||
|
state ^= state >> right; // using the random shifts
|
||||
|
state ^= state << left2; //
|
||||
|
array[i] ^= state; // apply to the array
|
||||
|
} |
||||
|
|
||||
|
// Extract the 32 byte hash into the *hash passed in.
|
||||
|
for (int i = 0; i < 4; i++) |
||||
|
{ |
||||
|
unsigned long long a = array[i] ^ state; |
||||
|
for (int j = 0; j < 8; j++) // for 8 bytes
|
||||
|
{ // Put each byte into hash, Big Endian order
|
||||
|
hash[i * 8 + j] = a >> ((7 - j) * 8); // i indexes 8 byte group, j each byte
|
||||
|
} //
|
||||
|
state ^= state << 27 ^ i << 19; // Mix the state a bit more, fold in the counter
|
||||
|
state ^= state >> 11; //
|
||||
|
state ^= state << 13; //
|
||||
|
} |
||||
|
return state; |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
// Copyright 2023 The Accumulate Authors
|
||||
|
//
|
||||
|
// Use of this source code is governed by an MIT-style
|
||||
|
// license that can be found in the LICENSE file or at
|
||||
|
// https://opensource.org/licenses/MIT.
|
||||
|
|
||||
|
#include <iostream> |
||||
|
#include <fstream> |
||||
|
#include <cstdio> |
||||
|
#include <chrono> |
||||
|
#include <ctime> |
||||
|
#include "../include/lxrhash.h" |
||||
|
|
||||
|
LXRHash lxrHash; |
||||
|
|
||||
|
int main() |
||||
|
{ |
||||
|
printf("Load byteMap\n"); |
||||
|
lxrHash.init(); // init() loads/computes byteMap
|
||||
|
printf("The byteMap is loaded, mining begins!\n"); //
|
||||
|
printf("%13s %13s %10s %16s %15s\n", //
|
||||
|
"total(s)", "block(s)", "nonce", "PoW", "hashes/sec"); //
|
||||
|
unsigned char hash[32]; // Start with a hash of all zeros
|
||||
|
std::fill_n(hash, 32, 0); //
|
||||
|
unsigned long long hashCnt = 0; // Count hashes to compute hash/second (hps)
|
||||
|
unsigned long long ms = 0; // Set the current time passed to zero
|
||||
|
for (int i = 0; i < 1000; i++) //
|
||||
|
{ //
|
||||
|
printf("Now Mining: "); // Start mining the new hash
|
||||
|
for (int i = 0; i < 32; i++) // Print the new hash in hex
|
||||
|
{ //
|
||||
|
printf("%02x", hash[i]); //
|
||||
|
} //
|
||||
|
printf("\n"); //
|
||||
|
auto last = std::chrono::system_clock::now(); // time
|
||||
|
unsigned long long ms1 = 0; // block time
|
||||
|
unsigned long long min = 0xFFFFFFFFFFFFFFFF; // set min to max unsigned long long value
|
||||
|
bool done = false; // Done is set when a block difficulty is found
|
||||
|
for (unsigned long long nonce = 0; !done; nonce++, hashCnt++) // Loop until done, count nonces and hashes
|
||||
|
{ //
|
||||
|
unsigned char tmpHash[32]; // Copy hash since LxrPoW will overwrite
|
||||
|
std::copy(hash, hash + 32, tmpHash); //
|
||||
|
unsigned long long v = lxrHash.LxrPoW(tmpHash, nonce); // Get the LxrPow for current nonce
|
||||
|
if (v < min && v < (unsigned long long)(1) << 52) // Print new solutions < some minimum difficulty
|
||||
|
{ //
|
||||
|
min = v; // Set as the new highest solution found
|
||||
|
auto end = std::chrono::system_clock::now(); // Calculate time stamps
|
||||
|
unsigned long long ms2 = //
|
||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(end - last).count(); |
||||
|
ms1 += ms2; // Add to the time in this block
|
||||
|
ms += ms2; // Add to total time spent
|
||||
|
last = std::chrono::system_clock::now(); // Reset timer for this block
|
||||
|
printf("%13.3f %13.3f %10llu %016llx %15.3f \n", // Print out the new solution
|
||||
|
float(ms) / 1000, // Total time
|
||||
|
float(ms1) / 1000, // Time mining this block
|
||||
|
nonce, // The nonce solution found
|
||||
|
v, // The mining value using the nonce
|
||||
|
float(hashCnt) / (float(ms) / 1000 + 1)); // Total hashes per second in this test
|
||||
|
} //
|
||||
|
done = v < (unsigned long long)(1) << 45; // Check against the difficulty for EOB
|
||||
|
if (done) // If at EOB
|
||||
|
{ // then set up a new block to mine
|
||||
|
std::copy(tmpHash, tmpHash + 32, hash); // Use the tmpHash as a new hash!
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return 0; |
||||
|
} |
Loading…
Reference in new issue