Пример #1
0
 /**
  * Find upstream accepted share that should be valid for a specific block
  * Assumptions:
  *  * Shares are matching blocks in ASC order
  *  * We can skip all upstream shares of previously found ones used in a block
  * @param last int Skips all shares up to last to find new share
  * @return bool
  **/
 public function findUpstreamShare($aBlock, $last = 0)
 {
     // Many use stratum, so we create our stratum check first
     $version = pack("I*", sprintf('%08d', $aBlock['version']));
     $previousblockhash = pack("H*", swapEndian($aBlock['previousblockhash']));
     $merkleroot = pack("H*", swapEndian($aBlock['merkleroot']));
     $time = pack("I*", $aBlock['time']);
     $bits = pack("H*", swapEndian($aBlock['bits']));
     $nonce = pack("I*", $aBlock['nonce']);
     $header_bin = $version . $previousblockhash . $merkleroot . $time . $bits . $nonce;
     $header_hex = implode(unpack("H*", $header_bin));
     // Stratum supported blockhash solution entry
     $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id FROM {$this->table} WHERE solution = ? LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('s', $aBlock['hash']) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'stratum_blockhash';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     // Stratum scrypt hash check
     $scrypt_hash = swapEndian(bin2hex(Scrypt::calc($header_bin, $header_bin, 1024, 1, 1, 32)));
     $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id FROM {$this->table} WHERE solution = ? LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('s', $scrypt_hash) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'stratum_solution';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     // Failed to fetch via startum solution, try pushpoold
     // Fallback to pushpoold solution type
     $ppheader = sprintf('%08d', $aBlock['version']) . word_reverse($aBlock['previousblockhash']) . word_reverse($aBlock['merkleroot']) . dechex($aBlock['time']) . $aBlock['bits'] . dechex($aBlock['nonce']);
     $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id FROM {$this->table} WHERE solution LIKE CONCAT(?, '%') LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('s', $ppheader) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'pp_solution';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     // Still no match, try upstream result with timerange
     $stmt = $this->mysqli->prepare("\n      SELECT\n      SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id\n      FROM {$this->table}\n      WHERE upstream_result = 'Y'\n      AND id > ?\n      AND UNIX_TIMESTAMP(time) >= ?\n      AND UNIX_TIMESTAMP(time) <= ( ? + 60 )\n      ORDER BY id ASC LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $last, $aBlock['time'], $aBlock['time']) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'upstream_share';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     // We failed again, now we take ANY result matching the timestamp
     $stmt = $this->mysqli->prepare("\n      SELECT\n      SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id\n      FROM {$this->table}\n      WHERE our_result = 'Y'\n      AND id > ?\n      AND UNIX_TIMESTAMP(time) >= ?\n      ORDER BY id ASC LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $last, $aBlock['time']) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'any_share';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     $this->setErrorMessage($this->getErrorMsg('E0052', $aBlock['height']));
     return false;
 }
Пример #2
0
 public function findUpstreamShareStrict($aBlock, $last = 0)
 {
     // Many use stratum, so we create our stratum check first
     $version = pack("I*", sprintf('%08d', $aBlock['version']));
     $previousblockhash = pack("H*", swapEndian($aBlock['previousblockhash']));
     $merkleroot = pack("H*", swapEndian($aBlock['merkleroot']));
     $time = pack("I*", $aBlock['time']);
     $bits = pack("H*", swapEndian($aBlock['bits']));
     $nonce = pack("I*", $aBlock['nonce']);
     $header_bin = $version . $previousblockhash . $merkleroot . $time . $bits . $nonce;
     $header_hex = implode(unpack("H*", $header_bin));
     // Stratum supported blockhash solution entry
     $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id FROM {$this->table} WHERE solution = ? LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('s', $aBlock['hash']) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'stratum_blockhash';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     // Stratum scrypt hash check
     $scrypt_hash = swapEndian(bin2hex(Scrypt::calc($header_bin, $header_bin, 1024, 1, 1, 32)));
     $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, username as worker, id FROM {$this->table} WHERE solution = ? LIMIT 1");
     if ($this->checkStmt($stmt) && $stmt->bind_param('s', $scrypt_hash) && $stmt->execute() && ($result = $stmt->get_result())) {
         $this->oUpstream = $result->fetch_object();
         $this->share_type = 'stratum_solution';
         if (!empty($this->oUpstream->account) && !empty($this->oUpstream->worker) && is_int($this->oUpstream->id)) {
             return true;
         }
     }
     return false;
 }