Round it... ;-)
[core.git] / contrib / chash / chash.php
index 1bc7f147e5b7c68fb9ac13231c47bd1b9aa47ce1..83ddd2f320d26006c4d4a472a7e975ae09359c02 100644 (file)
@@ -1,17 +1,17 @@
 <?php
 error_reporting(E_ALL | E_STRICT);
 
-define('HASH_ALGO', MHASH_RIPEMD320);
-define('BLOCK_SIZE', 100);
+define('HASH_ALGO'      , MHASH_RIPEMD320);
+define('BLOCK_SIZE'     , 100);
 define('NONCE_INCREMENT', 0.0000000000000001);
-define('START_TIME', microtime(TRUE));
-define('CHECK_POINT', 'chash.pos');
+define('START_TIME'     , microtime(TRUE));
+define('CHECK_POINT'    , 'chash.pos');
 
-// Found hashes
-$foundHashes = array();
+// Hashes per call
+$GLOBALS['cycles'] = 3;
 
-// Time when last flush occured
-global $timeFlush;
+// Found hashes
+$GLOBALS['found_hashes'] = array(0 => array());
 
 /**
  * Continued-hashing
@@ -37,15 +37,24 @@ function hashString ($str) {
 }
 
 /**
- * Double-hashes given string. This is done by hashing the given string and
+ * Multiple-hashes given string. This is done by hashing the given string and
  * then hashing the generated hash again.
  *
  * @param      $str    The string to be hashed 4 times
  * @return     $hash   The generated hash
  */
-function doubleHashString ($str) {
+function multipleHashString ($str) {
+       // One less to go (see below)
+       $totalHashes = $GLOBALS['cycles'] - 1;
+
        // Generate hash from given hash
-       $hash = hashString(hashString($str));
+       $hash = hashString($str);
+
+       // Now over-hash it
+       for ($idx = 0; $idx < $totalHashes; $idx++) {
+               // Over-hash the given hash
+               $hash = hashString($hash . $str);
+       } // END - for
 
        // Return it
        return $hash;
@@ -191,19 +200,23 @@ function calculateNonce ($nonce) {
 /**
  * Writes/flushes check-point file
  *
+ * @param      $nonce                  Nonce
+ * @param      $modulaHash             Modula hash (or hash to save)
  * @return     void
  */
-function flushCheckPointFile ($nonce, $modulaHash, array $foundHashes) {
-       global $timeFlush;
-
+function flushCheckPointFile ($nonce, $modulaHash) {
        // Display message
-       print ('FLUSHING: ' . count($foundHashes) . ' total found.' . PHP_EOL);
+       print ('FLUSHING: Writing ' . count($GLOBALS['found_hashes']) . ' blocks ...' . PHP_EOL);
+
+       // Start timer
+       $timer = microtime(TRUE);
 
        // Flush data
-       file_put_contents(CHECK_POINT, base64_encode($nonce) . ':' . $modulaHash . ':' . base64_encode(serialize($foundHashes)));
+       file_put_contents(CHECK_POINT, $GLOBALS['total_blocks'] . ':' . $GLOBALS['total_hashes'] . ':' . $GLOBALS['cycles'] . ':' . base64_encode($nonce) . ':' . $modulaHash . ':' . base64_encode(gzcompress(serialize($GLOBALS['found_hashes']))));
 
        // Set time
-       $timeFlush = microtime(TRUE);
+       $GLOBALS['time_flush'] = microtime(TRUE);
+       print ('FLUSHING: Took ' . ($GLOBALS['time_flush'] - $timer) . ' seconds.' . PHP_EOL);
 }
 
 /*
@@ -211,35 +224,35 @@ function flushCheckPointFile ($nonce, $modulaHash, array $foundHashes) {
  * known to the public as you can read them here in source code and therefore I
  * will not use them for the real genesis hashes.
  */
-$hashes = array(
+$gensisHashes = array(
        // A famous quote from Deus Ex 2 - Invisible War
-       doublehashString('"Informations must be free." - AI Helios from Deus Ex'),
+       multiplehashString('"Informations must be free." - AI Helios from Deus Ex'),
        // My name + URL of my first StatusNet instance
-       doubleHashString('Roland Haeder, https://status.mxchange.org'),
+       multipleHashString('Roland Haeder, https://status.mxchange.org'),
        // A famous quote from Linus Torwalds
-       doubleHashString('"Software is like sex. Its better when its free." - Linus Torwalds'),
+       multipleHashString('"Software is like sex. Its better when its free." - Linus Torwalds'),
        // Possible truth ;-)
-       doubleHashString('September 11 is a big lie.'),
+       multipleHashString('September 11 is a big lie.'),
 
        // GNU is not Uni*
-       doubleHashString('GNU is Not Uni*.'),
+       multipleHashString('GNU is Not Uni*.'),
        // WINE is not an emulator
-       doubleHashString('WINE Is Not an Emulator.'),
+       multipleHashString('WINE Is Not an Emulator.'),
        // FlightGear - Fly free!
-       doubleHashString('FlightGear - Fly free!'),
+       multipleHashString('FlightGear - Fly free!'),
        // Linus Torwalds Quote
-       doubleHashString('Your code is shit.. your argument is shit.'),
+       multipleHashString('Your code is shit.. your argument is shit.'),
 );
 
 // Calculate "modula hash" from 1st/4th and 2nd/3rd
 $modulaHashes = array(
        // "Block" 0
-       modulaHash($hashes[0], $hashes[3]),
-       modulaHash($hashes[1], $hashes[2]),
+       modulaHash($gensisHashes[0], $gensisHashes[3]),
+       modulaHash($gensisHashes[1], $gensisHashes[2]),
 
        // "Block" 1
-       modulaHash($hashes[4], $hashes[7]),
-       modulaHash($hashes[5], $hashes[6]),
+       modulaHash($gensisHashes[4], $gensisHashes[7]),
+       modulaHash($gensisHashes[5], $gensisHashes[6]),
 );
 
 // Calculate "sqrt hash"
@@ -249,21 +262,21 @@ $sqrtHashes = array(
 );
 
 // Calulcate modula hash
-$modulaHash = doubleHashString(modulaHash($sqrtHashes[0], $sqrtHashes[1]));
+$modulaHash = multipleHashString(modulaHash($sqrtHashes[0], $sqrtHashes[1]));
 
 // This is also the "genesis hash"
 $genesisHash = $modulaHash;
 
 // Output results
-print ('hashes=' . print_r($hashes, TRUE));
+print ('hashes=' . print_r($gensisHashes, TRUE));
 print ('modulaHashes=' . print_r($modulaHashes, TRUE));
 print ('sqrtHashes=' . print_r($sqrtHashes, TRUE));
 print ('modulaHash=' . $modulaHash . PHP_EOL);
 
 // Total reward + hashes
 $totalReward = 0;
-$totalHashes = 0;
-$totalBlocks = 0;
+$GLOBALS['total_hashes'] = 0;
+$GLOBALS['total_blocks'] = 0;
 
 // Is the check point there?
 if (is_readable(CHECK_POINT)) {
@@ -274,12 +287,15 @@ if (is_readable(CHECK_POINT)) {
        $data = explode(':', $checkPoint);
 
        // Assert on count
-       assert(count($data) == 3);
+       assert(count($data) == 6);
 
        // 1st element is nonce, 2nd hash, 3rd found hashes
-       $nonce       = base64_decode($data[0]);
-       $modulaHash  = $data[1];
-       $foundHashes = unserialize(base64_decode($data[2]));
+       $GLOBALS['total_blocks'] = $data[0];
+       $GLOBALS['total_hashes'] = $data[1];
+       $GLOBALS['cycles']       = intval($data[2]);
+       $nonce                   = base64_decode($data[3]);
+       $modulaHash              = $data[4];
+       $GLOBALS['found_hashes'][$GLOBALS['total_blocks']] = unserialize(gzuncompress(base64_decode($data[5])));
 } else {
        // Create nonce (small)
        $nonce = 1 / mt_rand();
@@ -288,7 +304,7 @@ if (is_readable(CHECK_POINT)) {
 // Output again
 print ('modulaHash=' . $modulaHash . PHP_EOL);
 print ('nonce=' . $nonce . PHP_EOL);
-print ('found=' . count($foundHashes) . PHP_EOL);
+print ('found=' . count($GLOBALS['found_hashes'][$GLOBALS['total_blocks']]) . PHP_EOL);
 
 // Start "mining"
 while (TRUE) {
@@ -299,14 +315,14 @@ while (TRUE) {
        // Wait for BLOCK_SIZE iterations (= found hashes). This is one block
        $timeBlock   = microtime(TRUE);
        $timeDisplay = $timeBlock;
-       $timeFlush   = $timeBlock;
+       $GLOBALS['time_flush'] = $timeBlock;
 
        // Time waited for a good block again (no iteration)
        $timeBadHashes = 0;
 
-       while (count($foundHashes) <= BLOCK_SIZE) {
+       while (count($GLOBALS['found_hashes'][$GLOBALS['total_blocks']]) <= BLOCK_SIZE) {
                // Create hash from modulaHash ("genesis hash") and nonce
-               $nonceHash = doubleHashString($modulaHash . $nonce);
+               $nonceHash = multipleHashString($modulaHash . $nonce);
 
                // Calculate sums
                $sumNonce  = calculateSumFromHash($nonceHash);
@@ -323,7 +339,7 @@ while (TRUE) {
                        $nonce = calculateNonce($nonce);
 
                        // And hash again
-                       $nonceHash = doubleHashString($modulaHash . $nonce);
+                       $nonceHash = multipleHashString($modulaHash . $nonce);
 
                        // Calculate sums
                        $sumNonce  = calculateSumFromHash($nonceHash);
@@ -332,12 +348,12 @@ while (TRUE) {
                        $testTime = abs(microtime(TRUE) - $timeDisplay);
 
                        // Calculate hashrate/sec
-                       $hashrate = 1 / $testTime * $iterSecond * 2;
+                       $hashrate = 1 / $testTime * $iterSecond * $GLOBALS['cycles'];
 
                        // Only every second
                        if ($testTime >= 1) {
                                // Display hash rate
-                               print ('hashrate=' . $hashrate . ' hashes/sec,iterSecond=' . $iterSecond . ' iterations/sec' . PHP_EOL);
+                               print ('hashrate=' . round($hashrate) . ' hashes/sec,iterSecond=' . $iterSecond . ' iterations/sec' . PHP_EOL);
 
                                // Reset timer
                                $timeDisplay = microtime(TRUE);
@@ -345,12 +361,12 @@ while (TRUE) {
                        } // END - if
 
                        // Time spend from last flush
-                       $testTime = abs(microtime(TRUE) - $timeFlush);
+                       $testTime = abs(microtime(TRUE) - $GLOBALS['time_flush']);
 
                        // Only once per 10 seconds
                        if ($testTime >= 10) {
                                // Flush check-point file
-                               flushCheckPointFile($nonce, $modulaHash, $foundHashes);
+                               flushCheckPointFile($nonce, $modulaHash);
                        } // END - if
 
                        // Next round
@@ -375,11 +391,11 @@ while (TRUE) {
                        continue;
                } // END - if
 
-               // Add amount of hashes per block (double-hash)
-               $hashesPerBlock += $iter * 2 + 2;
+               // Add amount of hashes per block (multiple-hash)
+               $hashesPerBlock += $iter * $GLOBALS['cycles'] + $GLOBALS['cycles'];
 
                // Push found hash
-               array_push($foundHashes, array(
+               array_push($GLOBALS['found_hashes'][$GLOBALS['total_blocks']], array(
                        'modula_hash'  => $modulaHash,
                        'genesis_hash' => $genesisHash,
                        'nonce'        => $nonce,
@@ -392,7 +408,7 @@ while (TRUE) {
                print ('FOUND: nonceHash=' . $nonceHash . ',nonce=' . $nonce . ',iter=' . $iter . PHP_EOL);
 
                // Flush check-point file after new hash is found
-               flushCheckPointFile($nonce, $nonceHash, $foundHashes);
+               flushCheckPointFile($nonce, $nonceHash);
 
                // Use nonceHash as next modula hash
                $modulaHash = $nonceHash;
@@ -406,10 +422,12 @@ while (TRUE) {
        print ('timeBlock=' . $timeBlock . ',timeBadHashes=' . $timeBadHashes . ',hashesPerBlock=' . $hashesPerBlock .',reward=' . $reward . PHP_EOL);
 
        // Block completed
-       $totalHashes += $hashesPerBlock;
-       $totalBlocks++;
+       $GLOBALS['total_hashes'] += $hashesPerBlock;
+       $GLOBALS['total_blocks']++;
        $hashesPerBlock = 0;
-       $foundHashes = array();
+
+       // Init next block
+       $GLOBALS['found_hashes'][$GLOBALS['total_blocks']] = array();
 
        // Calculate new nonce
        $nonce = calculateNonce($nonce);
@@ -418,7 +436,7 @@ while (TRUE) {
        $totalReward += $reward;
 
        // Calculate average block value
-       $blockValue = $totalReward / $totalBlocks * $totalHashes / (BLOCK_SIZE * $totalBlocks);
+       $blockValue = $totalReward / $GLOBALS['total_blocks'] * $GLOBALS['total_hashes'] / (BLOCK_SIZE * $GLOBALS['total_blocks']);
 
        // Calculate reward per hour (= 3600 seconds)
        $rewardPerHour = $totalReward / abs(microtime(TRUE) - START_TIME) * 3600;