ethstats has this statistic, currently at 48.3TH/s, but how do they determine it? Are hashrates reported by nodes added up and averaged over so many blocks?
[Ethereum] How is average network hashrate determined
hashrate
Related Solutions
First
Update Ethereum to 1.3.5
“Failed to submit hashrate” error
The function eth_submitHashrate
is only implemented from certain version of theethminer
. And the reason could be multiple.
Workaround
Install a miner proxy like eth-stratum-mining-proxy
Here is a Perl script that will calculate your average hashrate and display the important lines in your ethminer
log files:
ℹ 21:19:58.840|ethminer B-) Submitted and accepted.
✘ 20:23:53.048|ethminer FAILURE: GPU gave incorrect result!`
This script works on Linux and Mac OS X as the Perl interpreter is available on these platforms by default. For Windows, you may have to try Perl from perl.org.
Note that this hashrate is calculated when ethminer
is calculating it's hashes, and does not include the time that ethminer
is getting a new work package from geth
(or the pool) or when it is submitting the results to geth
/pool.
Copy the following lines into $HOME/bin/calcHashrate
, and set the executable bit for this file by running the command chmod 700 $HOME/bin/calcHashrate
.
calcHashrate
#!/usr/bin/perl -W
use Getopt::Long;
my $DEFAULTHASHLINES = 1000;
my $DEFAULTACCEPTLINES = 4;
my $DEFAULTFAILURELINES = 4;
my ($hashlines, $acceptlines, $failurelines, $removecolour, $help);
GetOptions(
"hashlines:i" => \$hashlines,
"acceptlines:i" => \$acceptlines,
"failurelines:i" => \$failurelines,
"removecolour" => \$removecolour,
"help" => \$help
);
die "Usage: $0 [options]\n\n" .
" where the options are:\n" .
" --hashlines=x Calculate average hashrate over the last x lines, default $DEFAULTHASHLINES\n" .
" --acceptlines=y Display the last y 'accept' lines, default $DEFAULTACCEPTLINES\n" .
" --failurelines=z Display the last z 'FAILURE' lines, default $DEFAULTFAILURELINES\n" .
" --removecolour Don't display colour in the accept and failure lines\n" .
" --help Display this help\n\n" .
"Enjoy. BokkyPooBah 2016.\n\n" .
"Stopped"
if defined $help;
$hashlines = $DEFAULTHASHLINES
unless defined $hashlines;
$acceptlines = $DEFAULTACCEPTLINES
unless defined $acceptlines;
$failurelines = $DEFAULTFAILURELINES
unless defined $failurelines;
my (@hashlinearray, @acceptlinearray, @failurelinearray) = ((), (), ());
while (<>) {
if (/(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/) {
push @hashlinearray, $_;
shift @hashlinearray
if ($#hashlinearray >= $hashlines);
} elsif (/accept/) {
push @acceptlinearray, $_;
shift @acceptlinearray
if ($#acceptlinearray >= $acceptlines);
} elsif (/FAILURE/) {
push @failurelinearray, $_;
shift @failurelinearray
if ($#failurelinearray >= $failurelines);
}
}
my ($totalhashes, $totalperiod) = (0, 0);
my ($lasttime) = ();
foreach (@hashlinearray) {
if (/(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/) {
my ($time, $rate, $hashes, $period) = $_ =~ /(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/;
$totalhashes += $hashes;
$totalperiod += $period;
$lasttime = $time;
}
}
foreach (@acceptlinearray) {
s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g
if defined $removecolour;
print;
}
foreach (@failurelinearray) {
s/\x1b\[[0-9;]*m//g
if defined $removecolour;
print;
}
if ($totalperiod > 0) {
my $averagehashrate = $totalhashes / $totalperiod / 1000 / 1000;
printf "%s %.3f MH/s\n", $lasttime, $averagehashrate;
} else {
print "No statistics\n";
}
Sample Usage
user@Kumquat:~$ calcHashrate --help
Usage: calcHashrate [options]
where the options are:
--hashlines=x Calculate average hashrate over the last x lines, default 1000
--acceptlines=y Display the last y 'accept' lines, default 4
--failurelines=z Display the last z 'FAILURE' lines, default 4
--removecolour Don't display colour in the accept and failure lines
--help Display this help
Enjoy. BokkyPooBah 2016.
Stopped at ./calcHashrate line 18.
Run the script with the default settings, calculating the average hashrate over the last 1,000 lines, show up to 4 accept
lines and show up to 4 FAILURE
lines. The line at the bottom shows the last hashrate time and the average hashrate in megahashes per second.
user@Kumquat:~$ calcHashrate logs/ethminer.log --removecolour
ℹ 21:24:12.221|ethminer B-) Submitted and accepted.
ℹ 21:24:14.671|ethminer B-) Submitted and accepted.
ℹ 21:24:17.519|ethminer B-) Submitted and accepted.
ℹ 21:24:30.835|ethminer B-) Submitted and accepted.
✘ 18:11:00.367|ethminer FAILURE: GPU gave incorrect result!
✘ 18:41:12.725|ethminer FAILURE: GPU gave incorrect result!
✘ 20:03:32.135|ethminer FAILURE: GPU gave incorrect result!
✘ 20:23:53.048|ethminer FAILURE: GPU gave incorrect result!
21:25:04.239 62.619 MH/s
Run the script to just display the hashrate over the last 1,000 hashrate lines.
user@Kumquat:~$ calcHashrate ethminer.log --acceptlines=0 --failurelines=0
21:25:04.239 62.619 MH/s
Best Answer
While I can't tell you how ethstats calculates the average network hash rate, I can tell you that they almost certainly don't use reported values from nodes. Firstly, it would be difficult for them to connect to all nodes. This would be okay if they were to connect to all the nodes with substantial mining capacity, but I don't think all nodes report a speed.
More likely, and the way I would calculate it, is to look at the average difficulty (this is baked into the blocks themselves) and the average time to solve a block. Since the expected time to solve a block is
difficulty / hash rate
(this relationship can be derived from the Ethereum source code), one can solve, algebraically, and find that the network hash rate is the average difficulty divided by the average block time. Then you just need to pick your window in terms of number of blocks used for computing the average. For example, right now, the difficulty is ~1240TH - which means that one successful hash is expected to be found every 1240 trillion hashes. Since the average block time is roughly 18.9s, the current network hash rate is roughly 65TH/s.