display links to found shares in share explorer
[p2pool.git] / web-static / index.html
index e642e63..62bfc62 100644 (file)
-<html>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
     <head>
-        <title>P2Pool Stats</title>
-        <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
+        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+        <title>P2Pool</title>
+        <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
+        <script type="text/javascript" src="d3.v2.min.js"></script>
         <script type="text/javascript">
             // based on goblin's p2pool-stats project
-            $(document).ajaxError(function(event, request, settings, err) {
-                   alert("error: " + settings.url + ": " + err.message);
+            
+            function values(o){ res = []; for(var x in o) res.push(o[x]); return res; }
+            
+            d3.json('../local_stats', function(local_stats) {
+                d3.select('#peers_in').text(local_stats.peers.incoming);
+                d3.select('#peers_out').text(local_stats.peers.outgoing);
+                
+                var local = d3.sum(values(local_stats.miner_hash_rates));
+                var local_dead = d3.sum(values(local_stats.miner_dead_hash_rates));
+                d3.select('#local_rate').text(d3.format('.3s')(local) + 'H/s');
+                d3.select('#local_doa').text(d3.format('.2p')(local_dead/local));
+                
+                d3.select('#shares_total').text(local_stats.shares.total);
+                d3.select('#shares_orphan').text(local_stats.shares.orphan);
+                d3.select('#shares_dead').text(local_stats.shares.dead);
+                
+                d3.select('#efficiency').text(local_stats.efficiency != null ? d3.format('.4p')(local_stats.efficiency) : '???')
+                d3.select('#uptime_days').text(d3.format('.3f')(local_stats.uptime / 60 / 60 / 24));
+                d3.select('#block_value').text(local_stats.block_value);
+                
+                d3.select('#warnings').selectAll().data(local_stats.warnings).enter().append('p')
+                    .text(function(w){ return 'Warning: ' + w })
+                    .attr('style', 'color:red;border:1px solid red;padding:5px');
+                
+                var time_to_share = local_stats.attempts_to_share/local;
+                d3.select('#time_to_share').text(d3.format('.3r')(time_to_share/3600) + " hours");
+                
+                d3.json('../global_stats', function(global_stats) {
+                    d3.select('#pool_rate').text(d3.format('.3s')(global_stats.pool_hash_rate) + 'H/s');
+                    d3.select('#pool_stale').text(d3.format('.2p')(global_stats.pool_stale_prop));
+                    d3.select('#difficulty').text(d3.format('.3r')(global_stats.min_difficulty));
+                    
+                    var time_to_block = local_stats.attempts_to_block/global_stats.pool_hash_rate;
+                    d3.select('#time_to_block').text(d3.format('.3r')(time_to_block/3600) + " hours");
+                    
+                    d3.select('#expected_payout_amount').text(d3.format('.3r')(local/global_stats.pool_hash_rate*local_stats.block_value*(1-local_stats.donation_proportion)));
+                });
             });
-
-            $.getJSON('/rate', function(rate) {
-                   $('#hashrate').html(rate / 1000000000);
+            
+            d3.json('../web/version', function(version) {
+                d3.selectAll('#version').text(version);
             });
             
-            $.getJSON('/current_payouts', function(pays) {
-                $.getJSON('/payout_addr', function(addr) {
-                       $('#payout').html(addr);
-                       $('#amt').html(pays["Address. Address: " + addr]);
+            d3.json('../web/currency_info', function(currency_info) {
+                d3.selectAll('.symbol').text(currency_info.symbol);
+                
+                d3.json('../current_payouts', function(pays) {
+                    d3.json('../payout_addr', function(addr) {
+                        d3.select('#payout_addr').text(addr).attr('href', currency_info.address_explorer_url_prefix + addr);
+                        d3.select('#payout_amount').text(addr in pays ? pays[addr] : 0);
+                    });
+                    
+                    var arr = []; for(var i in pays) arr.push(i); arr.sort(function(a, b){return pays[b] - pays[a]});
+                    
+                    var tr = d3.select('#payouts').selectAll().data(arr).enter().append('tr');
+                    tr.append('td').append('a').text(function(addr){return addr}).attr('href', function(addr){return currency_info.address_explorer_url_prefix + addr});
+                    tr.append('td').text(function(addr){return pays[addr]});
+                    
+                    var total_tr = d3.select('#payouts').append('tr');
+                    total_tr.append('td').append('strong').text('Total');
+                    total_tr.append('td').text(d3.sum(arr, function(addr){return pays[addr]}).toFixed(8));
                 });
                 
-                   var arr = new Array;
-                   var total = 0;
-                   for(var i in pays) {
-                           arr.push(i);
-                   }
-                   arr.sort(function(a, b) { return (pays[b] - pays[a]); });
-                   for(var j in arr) {
-                           var addr = arr[j];
-                           addr = addr.replace(/^.*: /, "");
-                           $('#payouts tr:last').after('<tr><td><a href="http://blockexplorer.com/address/' + addr + '">' + arr[j] + '</a></td><td>' +
-                                   pays[arr[j]] + '</td></tr>');
-                           total += pays[arr[j]];
-                   }
-                   $('#payouts tr:last').after('<tr><td><b>Total:</b></td><td><b>' + total.toFixed(8) + '</b></td></tr>');
+                d3.json('../recent_blocks', function(blocks) {
+                    var tr = d3.select('#blocks').selectAll().data(blocks).enter().append('tr');
+                    tr.append('td').text(function(block){return new Date(1000*block.ts).toString()});
+                    tr.append('td').text(function(block){return block.number});
+                    tr.append('td').append('a').text(function(block){return block.hash}).attr('href', function(block){return currency_info.block_explorer_url_prefix + block.hash});
+                    tr.append('td').append('a').text('→').attr('href', function(block){return 'share.html#' + block.share});
+                });
             });
-
-            $.getJSON('/recent_blocks', function(blocks) {
-                   for(var i in blocks) {
-                           var ts = new Date(1000 * blocks[i]['ts']);
-                           var padded_hash = blocks[i]['hash'];
-                           while(padded_hash.length < 64) {
-                                   padded_hash = '0' + padded_hash;
-                           }
-                           $('#blocks tr:last').after('<tr><td>' + ts.toString() + 
-                                   '</td><td><a href="http://blockexplorer.com/block/'
-                                   + padded_hash + '">' + padded_hash + '</a></td></tr>');
-                   }
+            
+            d3.json('../web/best_share_hash', function(c) {
+                d3.select('#best_share').append('a').attr('href', 'share.html#' + c).text(c.substr(-8));
             });
+            
+            function fill(url, id) {
+                d3.json(url, function(d) {
+                    d.sort()
+                    d3.select(id).selectAll().data(d).enter().append('span').text(' ').append('a').attr('href', function(c){return 'share.html#' + c}).text(function(c){return c.substr(-8)});
+                });
+            }
+            fill('../web/verified_heads', '#verified_heads');
+            fill('../web/heads', '#heads');
+            fill('../web/verified_tails', '#verified_tails');
+            fill('../web/tails', '#tails');
+            fill('../web/my_share_hashes', '#my_share_hashes');
         </script>
     </head>
     <body>
-        <h1>P2Pool Stats</h1>
+        <h1>P2Pool <span class="symbol"></span></h1>
         <p><a href="graphs.html">Graphs</a></p>
-        <p>Total pool GH/s: <span id="hashrate"></span></p>
-        <p>My payout address: <span id="payout"></span></p>
-        <p>Payout if a block were found NOW: <span id="amt"></span> BTC</p>
+        <p>Version: <span id="version"></span></p>
+        <p>Pool rate: <span id="pool_rate"></span> (<span id="pool_stale"></span> DOA+orphan) Share difficulty: <span id="difficulty"></span></p>
+        <p>Node uptime: <span id="uptime_days"></span> days Peers: <span id="peers_out"></span> out, <span id="peers_in"></span> in</p>
+        <p>Local rate: <span id="local_rate"></span> (<span id="local_doa"></span> DOA) Expected time to share: <span id="time_to_share"></span></p>
+        <p>Shares: <span id="shares_total"></span> total (<span id="shares_orphan"></span> orphaned, <span id="shares_dead"></span> dead) Efficiency: <span id="efficiency"></span></p>
+        <p>Payout if a block were found NOW: <span id="payout_amount"></span> <span class="symbol"></span> to <a id="payout_addr"></a>. Expected after mining for 24 hours:  <span id="expected_payout_amount"></span> <span class="symbol"></span> per block.</p>
+        <p>Current block value: <span id="block_value"></span> <span class="symbol"></span> Expected time to block: <span id="time_to_block"></span></p>
+        <div id="warnings"></div>
+        
+        <h2>Share explorer</h2>
+        <p>Best share: <span id="best_share"></span></p>
+        <p>Verified heads: <span id="verified_heads"></span></p>
+        <p>Heads: <span id="heads"></span></p>
+        <p>Verified tails: <span id="verified_tails"></span></p>
+        <p>Tails: <span id="tails"></span></p>
+        <p>My shares: <span id="my_share_hashes"></span></p>
         
-        <h2>Blocks found since program started:</h2>
+        <h2>Blocks found in last day:</h2>
+        <p>Note that blocks may have been orphaned from the P2Pool chain and so not be here.</p>
         <table border="1" id="blocks">
-               <tr><th>time</th><th>hash</th></tr>
+            <tr><th>time</th><th>number</th><th>hash/explorer link</th><th>share</th></tr>
         </table>
         
         <h2>Payouts if a block were found NOW:</h2>
         <table border="1" id="payouts">
-               <tr><th>address</th><th>amount in BTC</th></tr>
+            <tr><th>address</th><th>amount in <span class="symbol"></span></th></tr>
         </table>
     </body>
 </html>