consensus/cmd/web/views/tpl_poolblock.qtpl
DataHoarder 55661a12da
All checks were successful
continuous-integration/drone/push Build is passing
WIP: Bootstrap-based responsive interface, CSS only
2024-03-20 13:37:26 +01:00

242 lines
14 KiB
Plaintext

{% import "git.gammaspectra.live/P2Pool/p2pool-observer/cmd/index" %}
{% import "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain" %}
{% import "git.gammaspectra.live/P2Pool/p2pool-observer/types" %}
{% func TemplatePoolBlock(ctx *GlobalRequestContext, poolBlock *sidechain.PoolBlock, header string) %}
{%= TemplatePoolBlockWithSideBlock(ctx, poolBlock, header, false, nil, nil, nil, 0, nil) %}
{% endfunc %}
{% func TemplatePoolBlockWithSideBlock(ctx *GlobalRequestContext, poolBlock *sidechain.PoolBlock, header string, navigation bool, sideBlock *index.SideBlock, payouts <-chan *index.Payout, coinbaseOutputs index.MainCoinbaseOutputs, sweepsCount int, sweeps [][]*index.MainLikelySweepTransaction) %}
<div class="center" style="text-align: center">
{% if sideBlock != nil %}
{% if sideBlock.MinedMainAtHeight %}
<h1 style="color:#00C000">This share mined Monero block at height {%dul sideBlock.MainHeight %}</h1>
{% elseif (sideBlock.MainDifficulty > 0) && (sideBlock.PowDifficulty >= sideBlock.MainDifficulty) && !sideBlock.MinedMainAtHeight %}
<h1 style="color:#E0E000">This share mined Monero block at height {%dul sideBlock.MainHeight %}, but was orphaned</h1>
{% endif %}
{% if sideBlock.IsOrphan() %}
<h1 style="color:#E0E000">This share has been orphaned</h1>
{% endif %}
<br/>
{% endif %}
<table class="center" style="max-width: calc(8em + 28em + 8em + 28em)">
{% if navigation && sideBlock != nil %}
<tr>
{% if sideBlock.SideHeight == 0 %}
<td colspan="2">Genesis Block</td>
{% elseif sideBlock.IsUncle() %}
<td colspan="2"><a href="/share/{%= hex(ctx, sideBlock.UncleOf) %}">&lt;&lt; Parent share</a></td>
{% else %}
<td colspan="2"><a href="/share/{%= hex(ctx, sideBlock.ParentTemplateId) %}">&lt;&lt; Previous share</a></td>
{% endif %}
{% if sideBlock.IsOrphan() %}
<td colspan="2">Orphans do not have next blocks</td>
{% elseif sideBlock.IsUncle() %}
<td colspan="2">Uncles do not have next blocks</td>
{% else %}
<td colspan="2"><a href="/share/{%dul sideBlock.SideHeight + 1 %}">Next share &gt;&gt;</a></td>
{% endif %}
</tr>
{% endif %}
<tr><td colspan="4"><h2>{%s header %}</h2></td></tr>
<tr>
<th style="width: 8em">P2Pool Height</th>
<th style="width: 28em">P2Pool Template Id</th>
<th style="width: 8em">Monero Height</th>
<th style="width: 28em">Monero Id</th>
</tr>
<tr>
<td>{%dul poolBlock.Side.Height %}</td>
{% if sideBlock != nil %}
<td class="mono smaller">{%= hex(ctx, sideBlock.TemplateId) %}</td>
{% else %}
<td class="mono smaller">{%= hex(ctx, poolBlock.SideTemplateId(ctx.Consensus)) %}</td>
{% endif %}
{% if sideBlock != nil %}
{% if sideBlock.MinedMainAtHeight %}
<td><a href="/b/{%s benc(sideBlock.MainHeight) %}">{%dul sideBlock.MainHeight %}</a></td>
<td class="mono smaller"><a href="/b/{%s benc(sideBlock.MainHeight) %}">{%= hex(ctx, sideBlock.MainId) %}</a></td>
{% else %}
<td>{%dul sideBlock.MainHeight %}</td>
<td class="mono smaller">{%= hex(ctx, sideBlock.MainId) %}</td>
{% endif %}
{% else %}
<td>{%dul poolBlock.Main.Coinbase.GenHeight %}</td>
<td class="mono smaller">{%= hex(ctx, poolBlock.MainId()) %}</td>
{% endif %}
</tr>
<tr><td colspan="4">&nbsp;</td></tr>
<tr>
<th>Age <small>[h:m:s]</small></th>
<th>PoW Hash</th>
<th>Found by</th>
<th>Difficulty</th>
</tr>
<tr>
<td title="{%s utc_date(poolBlock.Main.Timestamp) %}">{%s date_diff_short(poolBlock.Main.Timestamp) %}</td>
{% if sideBlock != nil %}
<td class="mono smaller">{%= hex(ctx, sideBlock.PowHash) %}</td>
{%= TemplateRowMiner(ctx, sideBlock.MinerAddress, sideBlock.MinerAlias) %}
<td><span class="mono">{%dul sideBlock.Difficulty %}</span> / <span class="mono" title="Proof of Work Difficulty">{%dul sideBlock.PowDifficulty %}</span></td>
{% else %}
<td class="mono smaller">-</td>
{%= TemplateRowMiner(ctx, poolBlock.GetAddress().Reference().ToAddress(ctx.Consensus.NetworkType.AddressNetwork()), "") %}
<td><span class="mono">{%dul poolBlock.Side.Difficulty.Lo %}</span></td>
{% endif %}
</tr>
<tr><td colspan="4">&nbsp;</td></tr>
<tr>
<th>Valuation</th>
<th>Coinbase Id</th>
<th>Coinbase Reward</th>
<th>Coinbase Private Key</th>
</tr>
<tr>
{% if sideBlock != nil %}
<td>{%= side_block_valuation(sideBlock, ctx.Consensus) %}</td>
{% else %}
<td>{%= side_block_valuation(poolBlock, ctx.Consensus) %}</td>
{% endif %}
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
<td class="mono smaller"><a href="/t/{%= henc(poolBlock.CoinbaseId()) %}">{%= hex(ctx, poolBlock.CoinbaseId()) %}</a></td>
{% else %}
<td class="mono smaller">{%= hex(ctx, poolBlock.CoinbaseId()) %}</td>
{% endif %}
<td class="small">{%s monero_to_xmr(poolBlock.Main.Coinbase.TotalReward) %} XMR</td>
<td class="mono smaller">{%= hex(ctx, poolBlock.Side.CoinbasePrivateKey) %}</td>
</tr>
<tr><td colspan="4">&nbsp;</td></tr>
<tr>
<th>Nonce</th>
<th>Cumulative Difficulty</th>
<th>Extra Nonce</th>
<th>Monero Target Difficulty</th>
</tr>
<tr>
<td class="mono" title="{%= hex(ctx, poolBlock.Main.Nonce) %}">{%dul uint64(poolBlock.Main.Nonce) %}</td>
<td class="mono smaller">{%= hex(ctx, poolBlock.Side.CumulativeDifficulty) %}</td>
<td class="mono" title="{%= hex(ctx, poolBlock.ExtraNonce()) %}">{%dul uint64(poolBlock.ExtraNonce()) %}</td>
<td class="mono">{% if sideBlock != nil && sideBlock.MainDifficulty != 0 %}{%dul sideBlock.MainDifficulty %}{% endif %}</td>
</tr>
<tr><td colspan="4">&nbsp;</td></tr>
<tr>
<th>Software</th>
<th>Version Signaling</th>
<th>{% if poolBlock.ShareVersion() > sidechain.ShareVersion_V1 %}Template Extra Buffer{% endif %}</th>
<th title="The seed is used for the deterministic generation of the Coinbase Private Key, and is derived from other fields in the share or historic data.">Deterministic Private Key Seed</th>
</tr>
<tr>
<td>{%= software_info(poolBlock.Side.ExtraBuffer.SoftwareId, poolBlock.Side.ExtraBuffer.SoftwareVersion) %}</td>
<td>{%s= poolBlock.ShareVersion().String() %} <span class="small">({% if poolBlock.ShareVersionSignaling() != sidechain.ShareVersion_None %}signaling {%s= poolBlock.ShareVersionSignaling().String() %} support{% else %}no known signaling{% endif %})</span></td>
<td class="small">{% if poolBlock.ShareVersion() > sidechain.ShareVersion_V1 %}<span class="mono" title="Random Number">{%= hex(ctx, poolBlock.Side.ExtraBuffer.RandomNumber) %}</span> / <span class="mono" title="SideChain Extra Nonce">{%= hex(ctx, poolBlock.Side.ExtraBuffer.SideChainExtraNonce) %}{% endif %}</span></td>
<td>{% if poolBlock.GetPrivateKeySeed() != types.ZeroHash %}<span class="mono smaller">{%= hex(ctx, poolBlock.GetPrivateKeySeed()) %}</span>{% else %}Not Deterministic{% endif %}</td>
</tr>
</table>
</div>
<div class="center" style="text-align: center">
{% if len(poolBlock.Side.Uncles) > 0 %}
<h2>Uncle shares</h2>
{% if sideBlock != nil && sideBlock.IsUncle() %}
<p><strong>NOTE:</strong> Uncle shares do not have their listed uncles accounted for weight, the following list is just for reference.</p>
{% endif %}
<ul class="mono">
{% for _, u := range poolBlock.Side.Uncles %}
<li><a href="/share/{%= hex(ctx, u) %}">{%= hex(ctx, u) %}</a></li>
{% endfor %}
</ul>
{% endif %}
{% if sideBlock != nil && payouts != nil %}
<h2>Payouts share was weighted into</h2>
{% code var total uint64 %}
{%= TemplatePayouts(ctx, payouts, &total) %}
{% if sideBlock.EffectiveHeight > (ctx.Pool.SideChain.LastBlock.SideHeight - uint64(ctx.Pool.SideChain.Window.Blocks)) %}
<div class="center"><h3>Share is inside the PPLNS window. Any Monero blocks found during this period by any P2Pool miner will provide a direct payout.</h3></div>
{% else %}
<div class="center">Share is outside the PPLNS window. No more payouts for this share will be provided by other P2Pool miners.</div>
{% endif %}
{% endif %}
<h2>Coinbase Transaction</h2>
{% if sideBlock != nil && sideBlock.MinedMainAtHeight && sweepsCount > 0 %}
<table class="table table-striped table-hover table-borderless table-sm" style="max-width: calc(8em + 28em + 12em + 10em + 10em + 8em + 12em)">
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}7{% else %}6{% endif %}" class="mono smaller">{%s coinbase_extra(poolBlock) %}</td></tr>
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}7{% else %}6{% endif %}">&nbsp;</td></tr>
{% elseif sideBlock != nil && sideBlock.MinedMainAtHeight %}
<table class="table table-striped table-hover table-borderless table-sm" style="max-width: calc(8em + 28em + 12em + 10em + 10em + 8em)">
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}6{% else %}5{% endif %}" class="mono smaller">{%s coinbase_extra(poolBlock) %}</td></tr>
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}6{% else %}5{% endif %}">&nbsp;</td></tr>
{% else %}
<table class="table table-striped table-hover table-borderless table-sm" style="max-width: calc(8em + 28em + 12em + 10em)">
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}4{% else %}3{% endif %}" class="mono smaller">{%s coinbase_extra(poolBlock) %}</td></tr>
<tr><td colspan="{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}4{% else %}3{% endif %}">&nbsp;</td></tr>
{% endif %}
<thead>
<tr>
<th style="width: 8em">Output Index</th>
<th style="width: 28em">Ephemeral Public Key</th>
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}
<th style="width: 12em">Receiver Address</th>
{% endif %}
<th style="width: 10em">Reward</th>
{% else %}
{% if len(coinbaseOutputs) >= len(poolBlock.Main.Coinbase.Outputs) %}
<th style="width: 12em">Miner Address</th>
{% endif %}
<th style="width: 10em">Reward Share</th>
{% endif %}
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
<th style="width: 10em">Global Output Index</th>
<th style="width: 8em">Proof</th>
{% if sweepsCount > 0 %}
<th style="width: 12em">Swept</th>
{% endif %}
{% endif %}
</tr>
</thead>
<tbody>
{% for _, t := range poolBlock.Main.Coinbase.Outputs %}
<tr>
<td>{%dul t.Index %}</td>
<td class="mono smaller">{%= hex(ctx, t.EphemeralPublicKey) %}</td>
{% code var globalOutputIndex uint64 %}
{% if len(coinbaseOutputs) > int(t.Index) %}
{% code globalOutputIndex = coinbaseOutputs[t.Index].GlobalOutputIndex %}
{%= TemplateRowMiner(ctx, coinbaseOutputs[t.Index].MinerAddress, coinbaseOutputs[t.Index].MinerAlias) %}
{% endif %}
<td class="small" title="{%f.3 (float64(t.Reward) / float64(poolBlock.Main.Coinbase.TotalReward)) * 100 %}%">{%s monero_to_xmr(t.Reward) %} XMR</td>
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
<td class="small">{%dul globalOutputIndex %}</td>
<td class="small"><a href="/proof/{%= hex(ctx, sideBlock.MainId) %}/{%dul t.Index %}" title="Prove you have a matching output for this address on this transaction">[Payout Proof #{%dul t.Index %}]</a></td>
{% if sweepsCount > 0 %}
{% code outputSweeps := sweeps[t.Index] %}
{% if len(outputSweeps) > 0 %}
{% code sweep := outputSweeps[0] %}
<td class="smaller" title="{%s utc_date(sweep.Timestamp) %}"><a href="/transaction-lookup?txid={%= hex(ctx, sweep.Id) %}" class="mono">{%= shorten(ctx, sweep.Id, 10) %} {%d sweep.MinerCount %} / {%d sweep.InputCount %}</a></td>
{% elseif (ctx.Pool.MainChain.Height - sideBlock.MainHeight + 1) < 60 %}
<td class="small">Not unlocked</td>
{% else %}
<td class="small">Not known</td>
{% endif %}
{% endif %}
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% if len(poolBlock.Main.Transactions) > 0 %}
<h2>Included Transactions</h2>
<ul class="mono">
{% for _, t := range poolBlock.Main.Transactions %}
<li><a href="/t/{%= henc(t) %}">{%= hex(ctx, t) %}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfunc %}