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) {
|
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||||
if (empty($aBlock['share_id'])) {
|
if (empty($aBlock['share_id'])) {
|
||||||
// Fetch this blocks upstream 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();
|
$iCurrentUpstreamId = $share->getUpstreamId();
|
||||||
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -177,7 +177,41 @@ class Share {
|
|||||||
* @param last int Skips all shares up to last to find new share
|
* @param last int Skips all shares up to last to find new share
|
||||||
* @return bool
|
* @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("
|
$stmt = $this->mysqli->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
||||||
@ -185,13 +219,15 @@ class Share {
|
|||||||
WHERE upstream_result = 'Y'
|
WHERE upstream_result = 'Y'
|
||||||
AND id > ?
|
AND id > ?
|
||||||
AND UNIX_TIMESTAMP(time) >= ?
|
AND UNIX_TIMESTAMP(time) >= ?
|
||||||
|
AND UNIX_TIMESTAMP(time) <= ? + 60
|
||||||
ORDER BY id ASC LIMIT 1");
|
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();
|
$this->oUpstream = $result->fetch_object();
|
||||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||||
return true;
|
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("
|
$stmt = $this->mysqli->prepare("
|
||||||
SELECT
|
SELECT
|
||||||
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id
|
||||||
@ -200,7 +236,7 @@ class Share {
|
|||||||
AND id > ?
|
AND id > ?
|
||||||
AND UNIX_TIMESTAMP(time) >= ?
|
AND UNIX_TIMESTAMP(time) >= ?
|
||||||
ORDER BY id ASC LIMIT 1");
|
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();
|
$this->oUpstream = $result->fetch_object();
|
||||||
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
if (!empty($this->oUpstream->account) && is_int($this->oUpstream->id))
|
||||||
return true;
|
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