Refactor PPLNS window display in miner page
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
DataHoarder 2023-06-01 07:35:05 +02:00
parent 2fe65a7a62
commit d40172d479
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
4 changed files with 93 additions and 27 deletions

View file

@ -8,19 +8,29 @@ import (
type PositionChart struct {
totalItems uint64
bucket []uint64
perBucket int
idle byte
}
func (p *PositionChart) Add(index int, value uint64) {
if index < 0 || index > int(p.totalItems) {
if index < 0 || index >= int(p.totalItems) {
return
}
if len(p.bucket) == 1 {
p.bucket[0] += value
return
}
i := uint64(index) * uint64(len(p.bucket)-1) / (p.totalItems - 1)
p.bucket[i] += value
p.bucket[p.indexOf(index)] += value
}
func (p *PositionChart) indexOf(index int) int {
if len(p.bucket) == 1 {
return 0
}
i := (index*len(p.bucket) - 1) / int(p.totalItems-1)
return i
}
func (p *PositionChart) Total() (result uint64) {
@ -61,11 +71,28 @@ func (p *PositionChart) String() string {
return string(position)
}
func (p *PositionChart) StringWithoutDelimiters() string {
position := make([]byte, len(p.bucket))
for i, e := range utils.ReverseSlice(slices.Clone(p.bucket)) {
if e > 0 {
if e > 9 {
position[i] = '+'
} else {
position[i] = 0x30 + byte(e)
}
} else {
position[i] = p.idle
}
}
return string(position)
}
func (p *PositionChart) StringWithSeparator(index int) string {
if index < 0 || index > int(p.totalItems) {
if index < 0 || index >= int(p.totalItems) {
return p.String()
}
separatorIndex := index * (len(p.bucket) - 1) / int(p.totalItems-1)
separatorIndex := p.indexOf(index)
position := make([]byte, 1+2*2+len(p.bucket))
position[0], position[1] = '[', '<'
position[2+separatorIndex] = '|'
@ -92,9 +119,14 @@ func NewPositionChart(size uint64, totalItems uint64) *PositionChart {
if size < 1 {
size = 1
}
perBucket := int(totalItems / size)
if totalItems%size > 0 {
perBucket += 1
}
return &PositionChart{
totalItems: totalItems,
bucket: make([]uint64, size),
perBucket: perBucket,
idle: '.',
}
}

View file

@ -0,0 +1,13 @@
package utils
import (
"testing"
)
func TestChart(t *testing.T) {
p := NewPositionChart(32, 4096)
for i := 0; i < 4096; i++ {
p.Add(i, 1)
}
}

View file

@ -11,13 +11,14 @@ type MinerPage struct {
Refresh int
Positions struct {
Resolution int
ResolutionWindow int
SeparatorIndex int
Blocks *cmdutils.PositionChart
Uncles *cmdutils.PositionChart
BlocksInWindow *cmdutils.PositionChart
UnclesInWindow *cmdutils.PositionChart
Payouts *cmdutils.PositionChart
}
SharesInWindow int
UnclesInWindow int
ExpectedRewardPerWindow uint64
ExpectedRewardPerDay uint64
WindowWeight uint64
@ -136,7 +137,7 @@ type MinerPage struct {
</tr>
<tr>
<td title="{%s utc_date(p.Miner.LastShareTimestamp) %}">{%s time_elapsed_short(p.Miner.LastShareTimestamp) %}</td>
<td>{%d p.SharesInWindow %} blocks (+{%d p.UnclesInWindow %} uncles)</td>
<td>{%dul p.Positions.BlocksInWindow.Total() %} blocks (+{%dul p.Positions.UnclesInWindow.Total() %} uncles)</td>
{% code windowWeightRatio := float64(p.WindowWeight) / float64(p.Context().Pool.SideChain.Window.Weight.Lo) %}
<td>{%s si_units(windowWeightRatio * float64(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
<td>{%f.3 windowWeightRatio*100 %}%</td>
@ -167,16 +168,30 @@ type MinerPage struct {
<div style="text-align: center;">
<h2>Share positions</h2>
<p class="small">
Shares appear on the right, and get older towards the left. The pipe (<code>|</code>) character denotes the current PPLNS window end.
Shares appear on the right, and get older towards the left.
<br/>
Number denotes the amount of shares per slice, with the plus (<code>+</code>) character being more than 9, and dot (<code>.</code>) being none.
<br/>
Each slice accounts for {%d p.Positions.Resolution %} P2Pool blocks, or around {%dul (uint64(p.Positions.Resolution) * p.Context().Consensus.TargetBlockTime) / 60 %} minutes.
</p>
<h3>Shares during last day</h3>
<code class="mono">{%s p.Positions.Blocks.StringWithSeparator(p.Positions.SeparatorIndex) %}</code>
<h3>Shares and uncles in PPLNS window</h3>
<p class="small">
Each slice accounts for {%d p.Positions.ResolutionWindow %} P2Pool block heights, or around {%dul (uint64(p.Positions.ResolutionWindow) * p.Context().Consensus.TargetBlockTime) / 60 %} minutes.
<br/>
Shares within the PPLNS window will be weighted towards receiving a payout when any Monero block is found by any P2Pool miner.
</p>
<code class="mono">{%s p.Positions.BlocksInWindow.String() %}</code>
<br/>
<code class="mono">{%s p.Positions.UnclesInWindow.String() %}</code>
<h3>Uncles during last day</h3>
<h3>Shares and uncles during last day</h3>
<p class="small">
Each slice accounts for {%d p.Positions.Resolution %} P2Pool block heights, or around {%dul (uint64(p.Positions.Resolution) * p.Context().Consensus.TargetBlockTime) / 60 %} minutes.
<br/>
The pipe (<code>|</code>) character denotes roughly the PPLNS window end.
</p>
<code class="mono">{%s p.Positions.Blocks.StringWithSeparator(p.Positions.SeparatorIndex) %}</code>
<br/>
<code class="mono">{%s p.Positions.Uncles.StringWithSeparator(p.Positions.SeparatorIndex) %}</code>
{% if p.Positions.Payouts.Total() > 0 %}

View file

@ -896,10 +896,12 @@ func main() {
wg.Wait()
}
sharesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.WindowSize))
unclesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.WindowSize))
sharesFound := cmdutils.NewPositionChart(30*totalWindows, consensus.ChainWindowSize*totalWindows)
unclesFound := cmdutils.NewPositionChart(30*totalWindows, consensus.ChainWindowSize*totalWindows)
var sharesInWindow, unclesInWindow uint64
var longDiff, windowDiff types.Difficulty
wend := tipHeight - currentWindowSize
@ -927,14 +929,14 @@ func main() {
}
if share.SideHeight > wend {
windowDiff = windowDiff.Add64(uncleWeight)
unclesInWindow++
unclesInWindow.Add(int(int64(tipHeight)-int64(share.SideHeight)), 1)
}
longDiff = longDiff.Add64(uncleWeight)
} else {
sharesFound.Add(int(int64(tipHeight)-toInt64(share.SideHeight)), 1)
if share.SideHeight > wend {
windowDiff = windowDiff.Add64(share.Difficulty)
sharesInWindow++
sharesInWindow.Add(int(int64(tipHeight)-toInt64(share.SideHeight)), 1)
}
longDiff = longDiff.Add64(share.Difficulty)
}
@ -947,20 +949,24 @@ func main() {
minerPage := &views.MinerPage{
Refresh: refresh,
Positions: struct {
Resolution int
SeparatorIndex int
Blocks *cmdutils.PositionChart
Uncles *cmdutils.PositionChart
Payouts *cmdutils.PositionChart
Resolution int
ResolutionWindow int
SeparatorIndex int
Blocks *cmdutils.PositionChart
Uncles *cmdutils.PositionChart
BlocksInWindow *cmdutils.PositionChart
UnclesInWindow *cmdutils.PositionChart
Payouts *cmdutils.PositionChart
}{
Resolution: int(foundPayout.Resolution()),
SeparatorIndex: int(consensus.ChainWindowSize*totalWindows - currentWindowSize),
Blocks: sharesFound,
Uncles: unclesFound,
Payouts: foundPayout,
Resolution: int(foundPayout.Resolution()),
ResolutionWindow: int(sharesInWindow.Resolution()),
SeparatorIndex: int(consensus.ChainWindowSize*totalWindows - currentWindowSize),
Blocks: sharesFound,
BlocksInWindow: sharesInWindow,
Uncles: unclesFound,
UnclesInWindow: unclesInWindow,
Payouts: foundPayout,
},
SharesInWindow: int(sharesInWindow),
UnclesInWindow: int(unclesInWindow),
Weight: longDiff.Lo,
WindowWeight: windowDiff.Lo,
Miner: miner,