Adding solution detections for blocks
This will finally fix all block finding issues with a 4 way detection. The find upstream method will continue to try other ways to find a proper share until they are all exhausted or a match was found. * Use stratum solution, create scrypt hash from block header * Use pushpoold solution, create solution string from block header * Use first available upstream share in timerange of block time * Use *any* first available valid share older than time of block This will fix #405 - no more unknown blocks. Ever.
This commit is contained in:
parent
0f69032fd3
commit
f6b350370d
@ -72,7 +72,8 @@ if (empty($aAllBlocks)) {
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if (empty($aBlock['share_id'])) {
|
||||
// Fetch this blocks upstream ID
|
||||
if ($share->setUpstream($block->getLastUpstreamId(), $aBlock['time'])) {
|
||||
$aBlockInfo = $bitcoin->query('getblock', $aBlock['blockhash']);
|
||||
if ($share->setUpstream($aBlockInfo, $block->getLastUpstreamId())) {
|
||||
$iCurrentUpstreamId = $share->getUpstreamId();
|
||||
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
||||
} else {
|
||||
|
||||
@ -177,7 +177,41 @@ class Share {
|
||||
* @param last int Skips all shares up to last to find new share
|
||||
* @return bool
|
||||
**/
|
||||
public function setUpstream($last=0, $time=0) {
|
||||
public function setUpstream($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));
|
||||
$scrypt_hash = swapEndian(bin2hex(Scrypt::calc($header_bin, $header_bin, 1024, 1, 1, 32)));
|
||||
|
||||
|
||||
// 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']);
|
||||
echo "ppheader : $ppheader \n";
|
||||
echo "header : $header_hex \n";
|
||||
echo "Scrypt hash : $scrypt_hash \n";
|
||||
|
||||
$stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id FROM $this->table WHERE solution = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $scrypt_hash) && $stmt->execute() && $result = $stmt->get_result()->num_rows > 0) {
|
||||
$this->oUpstream = $result->fetch_object();
|
||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed to fetch via startum solution, try pushpoold
|
||||
$stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, 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();
|
||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Still no match, try upstream result with timerange
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
||||
@ -185,13 +219,15 @@ class Share {
|
||||
WHERE upstream_result = 'Y'
|
||||
AND id > ?
|
||||
AND UNIX_TIMESTAMP(time) >= ?
|
||||
AND UNIX_TIMESTAMP(time) <= ? + 60
|
||||
ORDER BY id ASC LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $last, $time) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('iii', $last, $aBlock['time'], $Block['time']) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$this->oUpstream = $result->fetch_object();
|
||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||
return true;
|
||||
}
|
||||
// First attempt failed, we do a fallback with any share available for now
|
||||
|
||||
// We failed again, now we take ANY result matching the timestamp
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
||||
@ -200,7 +236,7 @@ class Share {
|
||||
AND id > ?
|
||||
AND UNIX_TIMESTAMP(time) >= ?
|
||||
ORDER BY id ASC LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $last, $time) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $last, $aBlock['time']) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$this->oUpstream = $result->fetch_object();
|
||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||
return true;
|
||||
|
||||
@ -523,4 +523,14 @@ $value = Scrypt::calc($i, $i, 1024, 1, 1, 32);
|
||||
*/
|
||||
|
||||
|
||||
// Function used for pushpoold solution checks
|
||||
function word_reverse($str) {
|
||||
$ret = '';
|
||||
while (strlen($str) > 0) {
|
||||
$ret .= substr($str, -8, 8);
|
||||
$str = substr($str, 0, -8);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user