Refactor pool_info API, deprecate several fields
This commit is contained in:
parent
e7e1aee11b
commit
b601e49a8a
154
cmd/api/api.go
154
cmd/api/api.go
|
@ -93,7 +93,40 @@ func main() {
|
|||
return result
|
||||
}
|
||||
|
||||
fillSideBlockResult := func(params url.Values, sideBlocks chan *index.SideBlock) chan *index.SideBlock {
|
||||
fillSideBlockResult := func(fillUncles, fillMined, fillMiner bool, sideBlock *index.SideBlock) *index.SideBlock {
|
||||
if fillMiner {
|
||||
miner := indexDb.GetMiner(sideBlock.Miner)
|
||||
sideBlock.MinerAddress = miner.Address()
|
||||
sideBlock.MinerAlias = miner.Alias()
|
||||
}
|
||||
if fillMined {
|
||||
mainTipAtHeight := indexDb.GetMainBlockByHeight(sideBlock.MainHeight)
|
||||
if mainTipAtHeight != nil {
|
||||
sideBlock.MinedMainAtHeight = mainTipAtHeight.Id == sideBlock.MainId
|
||||
sideBlock.MainDifficulty = mainTipAtHeight.Difficulty
|
||||
} else {
|
||||
poolInfo := lastPoolInfo.Load()
|
||||
if (poolInfo.MainChain.Height + 1) == sideBlock.MainHeight {
|
||||
sideBlock.MainDifficulty = lastPoolInfo.Load().MainChain.NextDifficulty.Lo
|
||||
} else if poolInfo.MainChain.Height == sideBlock.MainHeight {
|
||||
sideBlock.MainDifficulty = lastPoolInfo.Load().MainChain.Difficulty.Lo
|
||||
}
|
||||
}
|
||||
}
|
||||
if fillUncles {
|
||||
for u := range indexDb.GetSideBlocksByUncleOfId(sideBlock.TemplateId) {
|
||||
sideBlock.Uncles = append(sideBlock.Uncles, index.SideBlockUncleEntry{
|
||||
TemplateId: u.TemplateId,
|
||||
Miner: u.Miner,
|
||||
SideHeight: u.SideHeight,
|
||||
Difficulty: u.Difficulty,
|
||||
})
|
||||
}
|
||||
}
|
||||
return sideBlock
|
||||
}
|
||||
|
||||
fillSideBlockChannelResult := func(params url.Values, sideBlocks chan *index.SideBlock) chan *index.SideBlock {
|
||||
result := make(chan *index.SideBlock)
|
||||
fillUncles := !params.Has("noUncles")
|
||||
fillMined := !params.Has("noMainStatus")
|
||||
|
@ -101,36 +134,7 @@ func main() {
|
|||
go func() {
|
||||
defer close(result)
|
||||
for sideBlock := range sideBlocks {
|
||||
if fillMiner {
|
||||
miner := indexDb.GetMiner(sideBlock.Miner)
|
||||
sideBlock.MinerAddress = miner.Address()
|
||||
sideBlock.MinerAlias = miner.Alias()
|
||||
}
|
||||
if fillMined {
|
||||
mainTipAtHeight := indexDb.GetMainBlockByHeight(sideBlock.MainHeight)
|
||||
if mainTipAtHeight != nil {
|
||||
sideBlock.MinedMainAtHeight = mainTipAtHeight.Id == sideBlock.MainId
|
||||
sideBlock.MainDifficulty = mainTipAtHeight.Difficulty
|
||||
} else {
|
||||
poolInfo := lastPoolInfo.Load()
|
||||
if (poolInfo.MainChain.Height + 1) == sideBlock.MainHeight {
|
||||
sideBlock.MainDifficulty = lastPoolInfo.Load().MainChain.NextDifficulty.Lo
|
||||
} else if poolInfo.MainChain.Height == sideBlock.MainHeight {
|
||||
sideBlock.MainDifficulty = lastPoolInfo.Load().MainChain.Difficulty.Lo
|
||||
}
|
||||
}
|
||||
}
|
||||
if fillUncles {
|
||||
for u := range indexDb.GetSideBlocksByUncleOfId(sideBlock.TemplateId) {
|
||||
sideBlock.Uncles = append(sideBlock.Uncles, index.SideBlockUncleEntry{
|
||||
TemplateId: u.TemplateId,
|
||||
Miner: u.Miner,
|
||||
SideHeight: u.SideHeight,
|
||||
Difficulty: u.Difficulty,
|
||||
})
|
||||
}
|
||||
}
|
||||
result <- sideBlock
|
||||
result <- fillSideBlockResult(fillUncles, fillMined, fillMiner, sideBlock)
|
||||
}
|
||||
}()
|
||||
return result
|
||||
|
@ -160,7 +164,7 @@ func main() {
|
|||
|
||||
tip := indexDb.GetSideBlockTip()
|
||||
|
||||
if oldPoolInfo != nil && oldPoolInfo.SideChain.Id == tip.TemplateId {
|
||||
if oldPoolInfo != nil && oldPoolInfo.SideChain.LastBlock.TemplateId == tip.TemplateId {
|
||||
//no changes!
|
||||
|
||||
//this race is ok
|
||||
|
@ -168,6 +172,8 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
var bottom *index.SideBlock
|
||||
var bottomUncles []*index.SideBlock
|
||||
blockCount := 0
|
||||
uncleCount := 0
|
||||
|
||||
|
@ -197,7 +203,9 @@ func main() {
|
|||
}
|
||||
}, func(slot index.SideBlockWindowSlot) {
|
||||
blockCount++
|
||||
bottomUncles = slot.Uncles
|
||||
uncleCount += len(slot.Uncles)
|
||||
bottom = slot.Block
|
||||
}); err != nil {
|
||||
log.Printf("error scanning PPLNS window: %s", err)
|
||||
|
||||
|
@ -286,13 +294,9 @@ func main() {
|
|||
result := &cmdutils.PoolInfoResult{
|
||||
SideChain: cmdutils.PoolInfoResultSideChain{
|
||||
Consensus: consensus,
|
||||
Id: tip.TemplateId,
|
||||
Height: tip.SideHeight,
|
||||
Version: sidechain.P2PoolShareVersion(consensus, tip.Timestamp),
|
||||
Difficulty: types.DifficultyFrom64(tip.Difficulty),
|
||||
CumulativeDifficulty: tip.CumulativeDifficulty,
|
||||
Timestamp: tip.Timestamp,
|
||||
LastBlock: fillSideBlockResult(true, false, true, tip),
|
||||
SecondsSinceLastBlock: max(0, time.Now().Unix()-int64(tip.Timestamp)),
|
||||
LastFound: nil, //to be filled later
|
||||
Effort: cmdutils.PoolInfoResultSideChainEffort{
|
||||
Current: currentEffort,
|
||||
Average10: averageEffort(10),
|
||||
|
@ -306,22 +310,45 @@ func main() {
|
|||
Uncles: uncleCount,
|
||||
Weight: pplnsWeight,
|
||||
Versions: versions,
|
||||
|
||||
Top: tip.TemplateId,
|
||||
Bottom: bottom.TemplateId,
|
||||
BottomUncles: func() (result []types.Hash) {
|
||||
for _, u := range bottomUncles {
|
||||
result = append(result, u.TemplateId)
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
},
|
||||
WindowSize: blockCount,
|
||||
MaxWindowSize: int(consensus.ChainWindowSize),
|
||||
BlockTime: int(consensus.TargetBlockTime),
|
||||
UnclePenalty: int(consensus.UnclePenalty),
|
||||
Found: totalKnown.blocksFound,
|
||||
Miners: totalKnown.minersKnown,
|
||||
|
||||
Found: totalKnown.blocksFound,
|
||||
Miners: totalKnown.minersKnown,
|
||||
|
||||
Id: tip.TemplateId,
|
||||
Height: tip.SideHeight,
|
||||
Version: sidechain.P2PoolShareVersion(consensus, tip.Timestamp),
|
||||
Difficulty: types.DifficultyFrom64(tip.Difficulty),
|
||||
CumulativeDifficulty: tip.CumulativeDifficulty,
|
||||
Timestamp: tip.Timestamp,
|
||||
WindowSize: blockCount,
|
||||
MaxWindowSize: int(consensus.ChainWindowSize),
|
||||
BlockTime: int(consensus.TargetBlockTime),
|
||||
UnclePenalty: int(consensus.UnclePenalty),
|
||||
},
|
||||
MainChain: cmdutils.PoolInfoResultMainChain{
|
||||
Consensus: cmdutils.PoolInfoResultMainChainConsensus{
|
||||
HardForks: sidechain.NetworkHardFork(consensus),
|
||||
BlockTime: monero.BlockTime,
|
||||
},
|
||||
Id: mainTip.Id,
|
||||
CoinbaseId: mainTip.CoinbaseId,
|
||||
Height: mainTip.Height,
|
||||
Difficulty: networkDifficulty,
|
||||
Reward: mainTip.Reward,
|
||||
BaseReward: expectedBaseBlockReward,
|
||||
NextDifficulty: minerDifficulty,
|
||||
BlockTime: monero.BlockTime,
|
||||
|
||||
BlockTime: monero.BlockTime,
|
||||
},
|
||||
Versions: struct {
|
||||
P2Pool cmdutils.VersionInfo `json:"p2pool"`
|
||||
|
@ -329,6 +356,10 @@ func main() {
|
|||
}{P2Pool: getP2PoolVersion(), Monero: getMoneroVersion()},
|
||||
}
|
||||
|
||||
if len(lastBlocksFound) > 0 {
|
||||
result.SideChain.LastFound = fillFoundBlockResult(nil, lastBlocksFound[:1])[0]
|
||||
}
|
||||
|
||||
lastPoolInfo.Store(result)
|
||||
}
|
||||
|
||||
|
@ -724,7 +755,7 @@ func main() {
|
|||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
|
||||
result := fillSideBlockResult(params, indexDb.GetSideBlocksInWindow(from, window))
|
||||
result := fillSideBlockChannelResult(params, indexDb.GetSideBlocksInWindow(from, window))
|
||||
_ = httputils.StreamJsonSlice(request, writer, result)
|
||||
})
|
||||
|
||||
|
@ -782,7 +813,7 @@ func main() {
|
|||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
|
||||
result := fillSideBlockResult(params, indexDb.GetSideBlocksByMinerIdInWindow(miner.Id(), from, window))
|
||||
result := fillSideBlockChannelResult(params, indexDb.GetSideBlocksByMinerIdInWindow(miner.Id(), from, window))
|
||||
_ = httputils.StreamJsonSlice(request, writer, result)
|
||||
})
|
||||
|
||||
|
@ -1192,7 +1223,7 @@ func main() {
|
|||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
|
||||
result := fillSideBlockResult(params, indexDb.GetShares(limit, minerId, onlyBlocks, inclusion))
|
||||
result := fillSideBlockChannelResult(params, indexDb.GetShares(limit, minerId, onlyBlocks, inclusion))
|
||||
_ = httputils.StreamJsonSlice(request, writer, result)
|
||||
})
|
||||
|
||||
|
@ -1249,7 +1280,7 @@ func main() {
|
|||
|
||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
result := fillSideBlockResult(params, indexDb.GetShares(limit, minerId, onlyBlocks, index.InclusionInVerifiedChain))
|
||||
result := fillSideBlockChannelResult(params, indexDb.GetShares(limit, minerId, onlyBlocks, index.InclusionInVerifiedChain))
|
||||
_ = httputils.StreamJsonSlice(request, writer, result)
|
||||
})
|
||||
|
||||
|
@ -1483,7 +1514,7 @@ func main() {
|
|||
c := make(chan *index.SideBlock, 1)
|
||||
c <- block
|
||||
close(c)
|
||||
_ = httputils.EncodeJson(request, writer, <-fillSideBlockResult(params, c))
|
||||
_ = httputils.EncodeJson(request, writer, <-fillSideBlockChannelResult(params, c))
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1711,15 +1742,15 @@ func main() {
|
|||
SidechainDifficulty uint64 `json:"sidechainDifficulty"`
|
||||
SidechainHeight uint64 `json:"sidechainHeight"`
|
||||
}{
|
||||
HashRate: poolInfo.SideChain.Difficulty.Div64(consensus.TargetBlockTime).Lo,
|
||||
HashRate: poolInfo.SideChain.LastBlock.Difficulty / consensus.TargetBlockTime,
|
||||
Miners: poolInfo.SideChain.Miners,
|
||||
TotalHashes: poolInfo.SideChain.CumulativeDifficulty.Lo,
|
||||
TotalHashes: poolInfo.SideChain.LastBlock.CumulativeDifficulty.Lo,
|
||||
LastBlockFound: lastBlockFound,
|
||||
LastBlockFoundTime: lastBlockFoundTime,
|
||||
TotalBlocksFound: poolInfo.SideChain.Found,
|
||||
PPLNSWindowSize: uint64(poolInfo.SideChain.WindowSize),
|
||||
SidechainDifficulty: poolInfo.SideChain.Difficulty.Lo,
|
||||
SidechainHeight: poolInfo.SideChain.Height,
|
||||
PPLNSWindowSize: uint64(poolInfo.SideChain.Window.Blocks),
|
||||
SidechainDifficulty: poolInfo.SideChain.LastBlock.Difficulty,
|
||||
SidechainHeight: poolInfo.SideChain.LastBlock.SideHeight,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
@ -1748,7 +1779,18 @@ func main() {
|
|||
|
||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
_, _ = writer.Write([]byte(fmt.Sprintf("{\"config\":{\"ports\":[{\"port\":3333,\"tls\":false}],\"fee\":0,\"minPaymentThreshold\":300000000},\"network\":{\"height\":%d},\"pool\":{\"stats\":{\"lastBlockFound\":\"%d\"},\"blocks\":[\"%s...%s:%d\",\"%d\"],\"miners\":%d,\"hashrate\":%d,\"roundHashes\":%d}}", mainTip.Height, lastBlockFoundTime*1000, hex.EncodeToString(lastBlockFoundHash[:2]), hex.EncodeToString(lastBlockFoundHash[types.HashSize-2:]), lastBlockFoundTime, lastBlockFound, poolInfo.SideChain.Miners, poolInfo.SideChain.Difficulty.Div64(consensus.TargetBlockTime).Lo, poolInfo.SideChain.CumulativeDifficulty.Sub(lastBlockCumulativeDifficulty).Lo)))
|
||||
_, _ = writer.Write([]byte(fmt.Sprintf(
|
||||
"{\"config\":{\"ports\":[{\"port\":3333,\"tls\":false}],\"fee\":0,\"minPaymentThreshold\":300000000},\"network\":{\"height\":%d},\"pool\":{\"stats\":{\"lastBlockFound\":\"%d\"},\"blocks\":[\"%s...%s:%d\",\"%d\"],\"miners\":%d,\"hashrate\":%d,\"roundHashes\":%d}}",
|
||||
mainTip.Height,
|
||||
lastBlockFoundTime*1000,
|
||||
hex.EncodeToString(lastBlockFoundHash[:2]),
|
||||
hex.EncodeToString(lastBlockFoundHash[types.HashSize-2:]),
|
||||
lastBlockFoundTime,
|
||||
lastBlockFound,
|
||||
poolInfo.SideChain.Miners,
|
||||
poolInfo.SideChain.LastBlock.Difficulty/consensus.TargetBlockTime,
|
||||
poolInfo.SideChain.LastBlock.CumulativeDifficulty.Sub(lastBlockCumulativeDifficulty).Lo,
|
||||
)))
|
||||
})
|
||||
|
||||
server := &http.Server{
|
||||
|
|
|
@ -72,11 +72,11 @@ type SideBlock struct {
|
|||
|
||||
// Extra information filled just for JSON purposes
|
||||
|
||||
MinedMainAtHeight bool `json:"mined_main_at_height"`
|
||||
MinedMainAtHeight bool `json:"mined_main_at_height,omitempty"`
|
||||
MinerAddress *address.Address `json:"miner_address,omitempty"`
|
||||
MinerAlias string `json:"miner_alias,omitempty"`
|
||||
Uncles []SideBlockUncleEntry `json:"uncles,omitempty"`
|
||||
MainDifficulty uint64 `json:"main_difficulty"`
|
||||
MainDifficulty uint64 `json:"main_difficulty,omitempty"`
|
||||
}
|
||||
|
||||
type SideBlockUncleEntry struct {
|
||||
|
|
|
@ -56,19 +56,54 @@ type PoolInfoResult struct {
|
|||
}
|
||||
|
||||
type PoolInfoResultSideChain struct {
|
||||
Consensus *sidechain.Consensus `json:"consensus"`
|
||||
Id types.Hash `json:"id"`
|
||||
Height uint64 `json:"height"`
|
||||
Version sidechain.ShareVersion `json:"version"`
|
||||
Difficulty types.Difficulty `json:"difficulty"`
|
||||
CumulativeDifficulty types.Difficulty `json:"cumulative_difficulty"`
|
||||
SecondsSinceLastBlock int64 `json:"seconds_since_last_block"`
|
||||
Timestamp uint64 `json:"timestamp"`
|
||||
Effort PoolInfoResultSideChainEffort `json:"effort"`
|
||||
Window PoolInfoResultSideChainWindow `json:"window"`
|
||||
WindowSize int `json:"window_size"`
|
||||
Found uint64 `json:"found"`
|
||||
Miners uint64 `json:"miners"`
|
||||
// Consensus Specifies the consensus parameters for the backing p2pool instance
|
||||
Consensus *sidechain.Consensus `json:"consensus"`
|
||||
|
||||
// LastBlock Last sidechain block on database
|
||||
LastBlock *index.SideBlock `json:"last_block"`
|
||||
|
||||
// SecondsSinceLastBlock
|
||||
// Prefer using max(0, time.Now().Unix()-int64(LastBlock .Timestamp)) instead
|
||||
SecondsSinceLastBlock int64 `json:"seconds_since_last_block"`
|
||||
|
||||
// LastFound Last sidechain block on database found and accepted on Monero network
|
||||
LastFound *index.FoundBlock `json:"last_found"`
|
||||
|
||||
Effort PoolInfoResultSideChainEffort `json:"effort"`
|
||||
Window PoolInfoResultSideChainWindow `json:"window"`
|
||||
|
||||
// Found Total count of found blocks in database
|
||||
Found uint64 `json:"found"`
|
||||
// Miners Total count of miners in database
|
||||
Miners uint64 `json:"miners"`
|
||||
|
||||
// Id Available on LastBlock .TemplateId
|
||||
// Deprecated
|
||||
Id types.Hash `json:"id"`
|
||||
|
||||
// Height Available on LastBlock .SideHeight
|
||||
// Deprecated
|
||||
Height uint64 `json:"height"`
|
||||
|
||||
// Version Available via sidechain.P2PoolShareVersion
|
||||
// Deprecated
|
||||
Version sidechain.ShareVersion `json:"version"`
|
||||
|
||||
// Difficulty Available on LastBlock .Difficulty
|
||||
// Deprecated
|
||||
Difficulty types.Difficulty `json:"difficulty"`
|
||||
|
||||
// CumulativeDifficulty Available on LastBlock .CumulativeDifficulty
|
||||
// Deprecated
|
||||
CumulativeDifficulty types.Difficulty `json:"cumulative_difficulty"`
|
||||
|
||||
// Timestamp Available on LastBlock .Timestamp
|
||||
// Deprecated
|
||||
Timestamp uint64 `json:"timestamp"`
|
||||
|
||||
// WindowSize Available on Window .Blocks
|
||||
// Deprecated
|
||||
WindowSize int `json:"window_size"`
|
||||
|
||||
// MaxWindowSize Available on Consensus
|
||||
// Deprecated
|
||||
|
@ -96,21 +131,44 @@ type PoolInfoResultSideChainEffort struct {
|
|||
Last []PoolInfoResultSideChainEffortLastEntry `json:"last"`
|
||||
}
|
||||
type PoolInfoResultSideChainWindow struct {
|
||||
Miners int `json:"miners"`
|
||||
Blocks int `json:"blocks"`
|
||||
Uncles int `json:"uncles"`
|
||||
// Miners Unique miners found in window
|
||||
Miners int `json:"miners"`
|
||||
// Blocks total count of blocks in the window, including uncles
|
||||
Blocks int `json:"blocks"`
|
||||
Uncles int `json:"uncles"`
|
||||
|
||||
// Top TemplateId of the window tip
|
||||
Top types.Hash `json:"top"`
|
||||
// Bottom TemplateId of the last non-uncle block in the window
|
||||
Bottom types.Hash `json:"bottom"`
|
||||
|
||||
// BottomUncles TemplateId of the uncles included under the last block, if any
|
||||
BottomUncles []types.Hash `json:"bottom_uncles,omitempty"`
|
||||
|
||||
Weight types.Difficulty `json:"weight"`
|
||||
Versions []SideChainVersionEntry `json:"versions"`
|
||||
}
|
||||
|
||||
type PoolInfoResultMainChainConsensus struct {
|
||||
BlockTime uint64 `json:"block_time"`
|
||||
// HardFork information for Monero known hardfork by backing p2pool
|
||||
HardForks []sidechain.HardFork `json:"hard_forks,omitempty"`
|
||||
}
|
||||
|
||||
type PoolInfoResultMainChain struct {
|
||||
Id types.Hash `json:"id"`
|
||||
Height uint64 `json:"height"`
|
||||
Difficulty types.Difficulty `json:"difficulty"`
|
||||
Reward uint64 `json:"reward"`
|
||||
BaseReward uint64 `json:"base_reward"`
|
||||
Consensus PoolInfoResultMainChainConsensus `json:"consensus"`
|
||||
Id types.Hash `json:"id"`
|
||||
CoinbaseId types.Hash `json:"coinbase_id"`
|
||||
Height uint64 `json:"height"`
|
||||
Difficulty types.Difficulty `json:"difficulty"`
|
||||
Reward uint64 `json:"reward"`
|
||||
BaseReward uint64 `json:"base_reward"`
|
||||
|
||||
NextDifficulty types.Difficulty `json:"next_difficulty"`
|
||||
BlockTime int `json:"block_time"`
|
||||
|
||||
// BlockTime included in Consensus
|
||||
// Deprecated
|
||||
BlockTime int `json:"block_time"`
|
||||
}
|
||||
|
||||
type MinerInfoBlockData struct {
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
{% import cmdutils "git.gammaspectra.live/P2Pool/p2pool-observer/cmd/utils" %}
|
||||
|
||||
{% code
|
||||
type ApiPage struct {
|
||||
// inherit from base page, so its' title is used in error page.
|
||||
BasePage
|
||||
|
||||
PoolInfoExample cmdutils.PoolInfoResult
|
||||
}
|
||||
%}
|
||||
|
||||
|
@ -37,122 +41,9 @@ pre {
|
|||
<h3 class="mono">/api/pool_info</h3>
|
||||
<p>Response contains general information on the current status of the P2Pool sidechain and Monero network, release versions, and other parameters.</p>
|
||||
<pre class="smaller">
|
||||
[result has been cut due to size, relevant portions shown]
|
||||
[Live result. Has been cut due to size, relevant portions shown]
|
||||
curl --silent https://{%s p.Context().NetServiceAddress %}/api/pool_info
|
||||
{
|
||||
"sidechain": {
|
||||
"consensus": {
|
||||
"network_type": "mainnet",
|
||||
"name": "mainnet test 2",
|
||||
"password": "",
|
||||
"block_time": 10,
|
||||
"min_diff": 100000,
|
||||
"pplns_window": 2160,
|
||||
"uncle_penalty": 20
|
||||
},
|
||||
"id": "d526cf516019ece4dbb5782f429a8333df9979932510ef26a91a5c2d02e6ac4a",
|
||||
"height": 4868262,
|
||||
"difficulty": "00000000000000000000000077cdd958",
|
||||
"cumulative_difficulty": "0000000000000000001aed8a900b6e8e",
|
||||
"timestamp": 1681256801,
|
||||
"effort": {
|
||||
"current": 109.31824000162864,
|
||||
"average10": 32.98600297507685,
|
||||
"average": 77.65727684146015,
|
||||
"average200": 89.19728805502012,
|
||||
"last": [
|
||||
{
|
||||
"id": "e3ec5e7e7cb76cfd2cff284a8812e4b0aeddf04115eb04440e6d26bd9825b7bb",
|
||||
"effort": 9.403366358670995
|
||||
},
|
||||
{
|
||||
"id": "e6ceaa02039c09022baaec73146340e20a64b6da19ecd234169c7bf73a569bdd",
|
||||
"effort": 1.8807123325645854
|
||||
},
|
||||
{
|
||||
"id": "393abe826d25c72fb320fa4bad980728c8e54756fa3ae8945bbb13af964c251c",
|
||||
"effort": 91.37117352907373
|
||||
},
|
||||
{
|
||||
"id": "d6ff0c1956d6743e137475a3b23823f620bf964ec89eb4891870af4c5db77a2a",
|
||||
"effort": 22.115510860859477
|
||||
},
|
||||
{
|
||||
"id": "544ad16d7c83f6e3636e965eed17a92449e64538d571064d1f3fa0c3d35d2768",
|
||||
"effort": 47.80476995257288
|
||||
},
|
||||
{
|
||||
"id": "6220069168433fa220f94600dbca7468d0e94a29a669eeb5e1449e181bdac624",
|
||||
"effort": 6.130222064837835
|
||||
},
|
||||
{
|
||||
"id": "108ae4af9aad47a1968c205a76ea57fd2fa0cc480d6109ee36f4a0eaa4422810",
|
||||
"effort": 32.87182581089726
|
||||
},
|
||||
{
|
||||
"id": "7a3d57b90e537f6414f9f898e76f16c22af20f77512dc2cbcf7571b561ecb88c",
|
||||
"effort": 39.24260486339777
|
||||
}
|
||||
]
|
||||
},
|
||||
"window": {
|
||||
"miners": 28,
|
||||
"blocks": 323,
|
||||
"uncles": 13,
|
||||
"weight": "00000000000000000000009eb206d209",
|
||||
"versions": [
|
||||
{
|
||||
"weight": "00000000000000000000005487eca8a5",
|
||||
"share": 53.266160234670814,
|
||||
"count": 179,
|
||||
"software_id": 0,
|
||||
"software_version": 196610,
|
||||
"software_string": "P2Pool v3.2"
|
||||
},
|
||||
{
|
||||
"weight": "00000000000000000000003245f084b0",
|
||||
"share": 31.679050570070547,
|
||||
"count": 106,
|
||||
"software_id": 0,
|
||||
"software_version": 196609,
|
||||
"software_string": "P2Pool v3.1"
|
||||
},
|
||||
{
|
||||
"weight": "000000000000000000000017e429a4b4",
|
||||
"share": 15.054789195258637,
|
||||
"count": 51,
|
||||
"software_id": 0,
|
||||
"software_version": 196608,
|
||||
"software_string": "P2Pool v3.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"window_size": 323,
|
||||
"max_window_size": 2160,
|
||||
"block_time": 10,
|
||||
"uncle_penalty": 20,
|
||||
"found": 22805,
|
||||
"miners": 5142
|
||||
},
|
||||
"mainchain": {
|
||||
"id": "8bc31d75dadb3d2eae8f30232f327d5726e8f9cea9185f3ef56255594605a1c8",
|
||||
"height": 2862299,
|
||||
"difficulty": "00000000000000000000004c2f36c75d",
|
||||
"block_time": 120
|
||||
},
|
||||
"versions": {
|
||||
"p2pool": {
|
||||
"version": "v3.2",
|
||||
"timestamp": 1680284891,
|
||||
"link": "https://github.com/SChernykh/p2pool/releases/tag/v3.2"
|
||||
},
|
||||
"monero": {
|
||||
"version": "v0.18.2.2",
|
||||
"timestamp": 1681139283,
|
||||
"link": "https://github.com/monero-project/monero/releases/tag/v0.18.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
{%= encodeJson(p.PoolInfoExample, true) %}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -58,19 +58,19 @@ type CalculateShareTimePageEffortEntry struct {
|
|||
<div style="text-align: center">
|
||||
|
||||
<table class="center" style="max-width: calc(15em + 15em + 15em + 15em);">
|
||||
{% code between := (float64(p.Context().Pool.SideChain.Difficulty.Lo) / (p.Hashrate * p.Magnitude)) %}
|
||||
{% code between := (float64(p.Context().Pool.SideChain.LastBlock.Difficulty) / (p.Hashrate * p.Magnitude)) %}
|
||||
{% code between_solo := (float64(p.Context().Pool.MainChain.Difficulty.Lo) / (p.Hashrate * p.Magnitude)) %}
|
||||
<tr style="line-height: 1.5;">
|
||||
<td style="width: 15em"><strong>P2Pool Difficulty</strong><br/>{%s si_units(p.Context().Pool.SideChain.Difficulty.Lo, 2) %}</td>
|
||||
<td style="width: 15em"><strong>P2Pool Hashrate</strong><br/>{%s si_units(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime), 2) %}H/s</td>
|
||||
<td style="width: 15em"><strong>P2Pool Difficulty</strong><br/>{%s si_units(p.Context().Pool.SideChain.LastBlock.Difficulty, 2) %}</td>
|
||||
<td style="width: 15em"><strong>P2Pool Hashrate</strong><br/>{%s si_units(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime), 2) %}H/s</td>
|
||||
<td style="width: 15em"><strong>Your Hashrate</strong><br/>{%s si_units(p.Hashrate * p.Magnitude, 2) %}H/s</td>
|
||||
<td title="Mean frequency between P2Pool shares" style="width: 15em; border: #ff6600 dashed 1px;"><strong>Your Share Mean<br/>{%s time_duration_long(between) %}</strong></td>
|
||||
</tr>
|
||||
<tr><th colspan="4"> </th></tr>
|
||||
<tr style="line-height: 1.5;">
|
||||
<td><strong>Monero Difficulty</strong><br/>{%s si_units(p.Context().Pool.MainChain.Difficulty.Lo, 2) %}</td>
|
||||
<td><strong>Monero Hashrate</strong><br/>{%s si_units(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.BlockTime)), 2) %}H/s</td>
|
||||
<td title="Mean frequency between P2Pool finds Monero Blocks"><strong>P2Pool Block Mean</strong><br/><em>{%s time_duration_long(float64(p.Context().Pool.MainChain.Difficulty.Lo) / float64(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime))) %}</em></td>
|
||||
<td><strong>Monero Hashrate</strong><br/>{%s si_units(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.Consensus.BlockTime)), 2) %}H/s</td>
|
||||
<td title="Mean frequency between P2Pool finds Monero Blocks"><strong>P2Pool Block Mean</strong><br/><em>{%s time_duration_long(float64(p.Context().Pool.MainChain.Difficulty.Lo) / float64(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime))) %}</em></td>
|
||||
<td title="Mean frequency between Solo Monero Blocks (without P2Pool)"><strong>Your Solo Block Mean</strong><br/><em>{%s time_duration_long(between_solo) %}</em></td>
|
||||
</tr>
|
||||
<tr><th colspan="4"> </th></tr>
|
||||
|
|
|
@ -161,6 +161,8 @@ func diff_hashrate(v any, blockTime uint64) uint64 {
|
|||
}
|
||||
} else if d, ok := v.(types.Difficulty); ok {
|
||||
return d.Div64(blockTime).Lo
|
||||
} else if d, ok := v.(uint64); ok {
|
||||
return d / blockTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -11,9 +11,21 @@
|
|||
{% import hex2 "encoding/hex" %}
|
||||
{% import fasthex "github.com/tmthrgd/go-hex" %}
|
||||
|
||||
{% import qt "github.com/valyala/quicktemplate" %}
|
||||
|
||||
{% stripspace %}
|
||||
|
||||
|
||||
{% code
|
||||
func streamencodeJson(w *qt.Writer, val any, indent bool) {
|
||||
encoder := utils.NewJSONEncoder(w.E())
|
||||
if indent {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
if err := encoder.EncodeWithOption(val, utils.JsonEncodeOptions...); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
{% func hex(ctx *GlobalRequestContext, val any) %}
|
||||
{% switch s := val.(type) %}
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
</h4>
|
||||
{% if pool := ctx.Pool; pool != nil %}
|
||||
|
||||
{% if uint64(pool.Versions.P2Pool.Timestamp+3600*24*30) > pool.SideChain.Timestamp || uint64(pool.Versions.Monero.Timestamp+3600*24*7) > pool.SideChain.Timestamp %}
|
||||
{% if uint64(pool.Versions.P2Pool.Timestamp+3600*24*30) > pool.SideChain.LastBlock.Timestamp || uint64(pool.Versions.Monero.Timestamp+3600*24*7) > pool.SideChain.LastBlock.Timestamp %}
|
||||
<h4 style="font-size: 15px; margin: 4px 0px 0px; color:yellow;">
|
||||
{% else %}
|
||||
<h4 style="font-size: 13px; margin-top: 5px; ">
|
||||
{% endif %}
|
||||
Latest releases: <a href="{%s pool.Versions.P2Pool.Link %}" target="_blank">P2Pool {%s pool.Versions.P2Pool.Version %}</a> <em title="{%s utc_date(uint64(pool.Versions.P2Pool.Timestamp)) %}"><small>{%f.1 float64((pool.SideChain.Timestamp - uint64(pool.Versions.P2Pool.Timestamp))) / (3600*24) %} day(s) ago</small></em>
|
||||
Latest releases: <a href="{%s pool.Versions.P2Pool.Link %}" target="_blank">P2Pool {%s pool.Versions.P2Pool.Version %}</a> <em title="{%s utc_date(uint64(pool.Versions.P2Pool.Timestamp)) %}"><small>{%f.1 float64((pool.SideChain.LastBlock.Timestamp - uint64(pool.Versions.P2Pool.Timestamp))) / (3600*24) %} day(s) ago</small></em>
|
||||
::
|
||||
<a href="{%s pool.Versions.Monero.Link %}" target="_blank">Monero {%s pool.Versions.Monero.Version %}</a> <em title="{%s utc_date(uint64(pool.Versions.Monero.Timestamp)) %}"><small>{%f.1 float64((pool.SideChain.Timestamp - uint64(pool.Versions.Monero.Timestamp))) / (3600*24) %} day(s) ago</small></em>
|
||||
<a href="{%s pool.Versions.Monero.Link %}" target="_blank">Monero {%s pool.Versions.Monero.Version %}</a> <em title="{%s utc_date(uint64(pool.Versions.Monero.Timestamp)) %}"><small>{%f.1 float64((pool.SideChain.LastBlock.Timestamp - uint64(pool.Versions.Monero.Timestamp))) / (3600*24) %} day(s) ago</small></em>
|
||||
</h4>
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -35,10 +35,10 @@ type IndexPage struct {
|
|||
<th style="width: 15em">Monero Hashrate</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td title="{%= hex(p.Context(), p.Context().Pool.SideChain.Id) %}"><a href="/share/{%= hex(p.Context(), p.Context().Pool.SideChain.Id) %}">{%dul p.Context().Pool.SideChain.Height %}</a></td>
|
||||
<td>{%s si_units(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime), 2) %}H/s</td>
|
||||
<td title="{%= hex(p.Context(), p.Context().Pool.SideChain.LastBlock.TemplateId) %}"><a href="/share/{%= hex(p.Context(), p.Context().Pool.SideChain.LastBlock.TemplateId) %}">{%dul p.Context().Pool.SideChain.LastBlock.SideHeight %}</a></td>
|
||||
<td>{%s si_units(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime), 2) %}H/s</td>
|
||||
<td title="{%= hex(p.Context(), p.Context().Pool.MainChain.Id) %}"><a href="/b/{%s benc(p.Context().Pool.MainChain.Height) %}">{%dul p.Context().Pool.MainChain.Height %}</a></td>
|
||||
<td>{%s si_units(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.BlockTime)), 2) %}H/s</td>
|
||||
<td>{%s si_units(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.Consensus.BlockTime)), 2) %}H/s</td>
|
||||
</tr>
|
||||
<tr><th colspan="4"> </th></tr>
|
||||
<tr>
|
||||
|
@ -48,8 +48,8 @@ type IndexPage struct {
|
|||
<th title="This includes blocks the site knows about since it started observing. There might be more orphaned or produced by other sidechain not included here.">Blocks Found</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{%s si_units(p.Context().Pool.SideChain.Difficulty.Lo, 2) %}</td>
|
||||
<td>{%f.2 (float64(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime)) / float64(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.BlockTime))))*100 %}%</td>
|
||||
<td>{%s si_units(p.Context().Pool.SideChain.LastBlock.Timestamp, 2) %}</td>
|
||||
<td>{%f.2 (float64(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime)) / float64(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.Consensus.BlockTime))))*100 %}%</td>
|
||||
<td>{%s si_units(p.Context().Pool.MainChain.Difficulty.Lo, 2) %}</td>
|
||||
<td>{%dul p.Context().Pool.SideChain.Found %}</td>
|
||||
</tr>
|
||||
|
@ -69,9 +69,9 @@ type IndexPage struct {
|
|||
/
|
||||
<span class="small" style="color: {%s effort_color(p.Context().Pool.SideChain.Effort.Average200) %};" title="Last 200 found blocks">{%f.2 p.Context().Pool.SideChain.Effort.Average200 %}%</span>
|
||||
</td>
|
||||
<td>{%s time_duration_long(float64(p.Context().Pool.MainChain.Difficulty.Lo) / float64(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime))) %}</td>
|
||||
{% if len(p.FoundBlocks) > 0 %}
|
||||
<td title="{%s utc_date(p.FoundBlocks[0].MainBlock.Timestamp) %}">{%s time_elapsed_short(p.FoundBlocks[0].MainBlock.Timestamp) %}</td>
|
||||
<td>{%s time_duration_long(float64(p.Context().Pool.MainChain.Difficulty.Lo) / float64(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime))) %}</td>
|
||||
{% if p.Context().Pool.SideChain.LastFound != nil %}
|
||||
<td title="{%s utc_date(p.Context().Pool.SideChain.LastFound.MainBlock.Timestamp) %}">{%s time_elapsed_short(p.Context().Pool.SideChain.LastFound.MainBlock.Timestamp) %}</td>
|
||||
{% else %}
|
||||
<td>-</td>
|
||||
{% endif %}
|
||||
|
@ -89,7 +89,7 @@ type IndexPage struct {
|
|||
{%f.2 p.Context().Pool.SideChain.Effort.Current %}%
|
||||
</td>
|
||||
<td>{%d p.Context().Pool.SideChain.Window.Blocks %} blocks (+{%d p.Context().Pool.SideChain.Window.Uncles %} uncles)</td>
|
||||
<td title="{%s utc_date(p.Context().Pool.SideChain.Timestamp) %}">{%s time_elapsed_short(p.Context().Pool.SideChain.Timestamp) %}</td>
|
||||
<td title="{%s utc_date(p.Context().Pool.SideChain.LastBlock.Timestamp) %}">{%s time_elapsed_short(p.Context().Pool.SideChain.LastBlock.Timestamp) %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -140,7 +140,7 @@ type MinerPage struct {
|
|||
<td title="{%s utc_date(p.Miner.LastShareTimestamp) %}">{%s time_elapsed_short(p.Miner.LastShareTimestamp) %}</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>{%s si_units(windowWeightRatio * float64(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
|
||||
<td>{%f.3 windowWeightRatio*100 %}%</td>
|
||||
<td>{%s monero_to_xmr(p.ExpectedRewardPerWindow) %} XMR</td>
|
||||
</tr>
|
||||
|
@ -155,8 +155,8 @@ type MinerPage struct {
|
|||
<tr>
|
||||
<td>{% if p.LastPoolBlock != nil %}{%dul p.Miner.Shares[1].ShareCount %} blocks (+{%dul p.Miner.Shares[1].UncleCount %} uncles{% if p.Miner.Shares[0].ShareCount > 0 %}, +{%dul p.Miner.Shares[0].ShareCount %} orphans{% endif %}){% else %}No shares reported{% endif %}</td>
|
||||
<td>{%dul p.Positions.Blocks.Total() %} blocks (+{%dul p.Positions.Uncles.Total() %} uncles)</td>
|
||||
{% code weightRatio := (float64(p.Weight) / (float64(p.Context().Pool.SideChain.Window.Weight.Mul64(4).Lo) * (float64(p.Context().Pool.SideChain.MaxWindowSize) / float64(p.Context().Pool.SideChain.WindowSize)))) %}
|
||||
<td>{%s si_units(weightRatio * float64(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
|
||||
{% code weightRatio := (float64(p.Weight) / (float64(p.Context().Pool.SideChain.Window.Weight.Mul64(4).Lo) * (float64(p.Context().Pool.SideChain.Consensus.ChainWindowSize) / float64(p.Context().Pool.SideChain.Window.Blocks)))) %}
|
||||
<td>{%s si_units(weightRatio * float64(diff_hashrate(p.Context().Pool.SideChain.LastBlock.Difficulty, p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
|
||||
<td>{%f.3 weightRatio*100 %}%</td>
|
||||
<td>{%s monero_to_xmr(p.ExpectedRewardPerDay) %} XMR</td>
|
||||
</tr>
|
||||
|
|
|
@ -85,7 +85,7 @@ type MinersPageMinerEntry struct {
|
|||
<td style="vertical-align: middle">{%= software_info(m.SoftwareId, m.SoftwareVersion) %}</td>
|
||||
{% code minerRatio := float64(m.Weight.Lo) / float64(p.WindowWeight.Lo) %}
|
||||
<td style="vertical-align: middle">{%f.3 minerRatio*100 %}%</td>
|
||||
<td style="vertical-align: middle">{%s si_units(minerRatio * (float64(p.Context().Pool.SideChain.Difficulty.Lo) / float64(p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
|
||||
<td style="vertical-align: middle">{%s si_units(minerRatio * (float64(p.Context().Pool.SideChain.LastBlock.Difficulty) / float64(p.Context().Consensus.TargetBlockTime)), 3) %}H/s</td>
|
||||
<td style="vertical-align: middle">{%dul m.Shares.Total() %} block(s) +{%dul m.Uncles.Total() %} uncle(s)</td>
|
||||
<td>
|
||||
<code class="mono small">{%s m.Shares.String() %}</code>
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
{% code var total uint64 %}
|
||||
|
||||
{%= TemplatePayouts(ctx, payouts, &total) %}
|
||||
{% if sideBlock.EffectiveHeight > (ctx.Pool.SideChain.Height - uint64(ctx.Pool.SideChain.WindowSize)) %}
|
||||
{% 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>
|
||||
|
|
|
@ -182,7 +182,7 @@ func main() {
|
|||
time.Sleep(1)
|
||||
continue
|
||||
}
|
||||
if t.SideChain.Id != types.ZeroHash {
|
||||
if t.SideChain.LastBlock != nil {
|
||||
basePoolInfo = t
|
||||
break
|
||||
}
|
||||
|
@ -199,6 +199,15 @@ func main() {
|
|||
|
||||
var lastPoolInfo atomic.Pointer[cmdutils.PoolInfoResult]
|
||||
|
||||
ensureGetLastPoolInfo := func() *cmdutils.PoolInfoResult {
|
||||
poolInfo := lastPoolInfo.Load()
|
||||
if poolInfo == nil {
|
||||
poolInfo = getTypeFromAPI[cmdutils.PoolInfoResult]("pool_info", 5)
|
||||
lastPoolInfo.Store(poolInfo)
|
||||
}
|
||||
return poolInfo
|
||||
}
|
||||
|
||||
baseContext := views.GlobalRequestContext{
|
||||
DonationAddress: types.DonationAddress,
|
||||
SiteTitle: os.Getenv("SITE_TITLE"),
|
||||
|
@ -269,7 +278,7 @@ func main() {
|
|||
poolInfo := getTypeFromAPI[cmdutils.PoolInfoResult]("pool_info", 5)
|
||||
lastPoolInfo.Store(poolInfo)
|
||||
|
||||
secondsPerBlock := float64(poolInfo.MainChain.Difficulty.Lo) / float64(poolInfo.SideChain.Difficulty.Div64(consensus.TargetBlockTime).Lo)
|
||||
secondsPerBlock := float64(poolInfo.MainChain.Difficulty.Lo) / float64(poolInfo.SideChain.LastBlock.Difficulty/consensus.TargetBlockTime)
|
||||
|
||||
blocksToFetch := uint64(math.Ceil((((time.Hour*24).Seconds()/secondsPerBlock)*2)/100) * 100)
|
||||
|
||||
|
@ -278,7 +287,7 @@ func main() {
|
|||
|
||||
blocksFound := cmdutils.NewPositionChart(30*4, consensus.ChainWindowSize*4)
|
||||
|
||||
tip := int64(poolInfo.SideChain.Height)
|
||||
tip := int64(poolInfo.SideChain.LastBlock.SideHeight)
|
||||
for _, b := range blocks {
|
||||
blocksFound.Add(int(tip-int64(b.SideHeight)), 1)
|
||||
}
|
||||
|
@ -300,7 +309,15 @@ func main() {
|
|||
})
|
||||
|
||||
serveMux.HandleFunc("/api", func(writer http.ResponseWriter, request *http.Request) {
|
||||
renderPage(request, writer, &views.ApiPage{})
|
||||
poolInfo := *ensureGetLastPoolInfo()
|
||||
if len(poolInfo.SideChain.Effort.Last) > 5 {
|
||||
poolInfo.SideChain.Effort.Last = poolInfo.SideChain.Effort.Last[:5]
|
||||
}
|
||||
|
||||
p := &views.ApiPage{
|
||||
PoolInfoExample: poolInfo,
|
||||
}
|
||||
renderPage(request, writer, p)
|
||||
})
|
||||
|
||||
serveMux.HandleFunc("/calculate-share-time", func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
@ -333,7 +350,7 @@ func main() {
|
|||
efforts = append(efforts, views.CalculateShareTimePageEffortEntry{
|
||||
Effort: v,
|
||||
Probability: (1 - math.Exp(-(v / 100))) * 100,
|
||||
Between: (float64(poolInfo.SideChain.Difficulty.Lo) * (v / 100)) / currentHashRate,
|
||||
Between: (float64(poolInfo.SideChain.LastBlock.Difficulty) * (v / 100)) / currentHashRate,
|
||||
BetweenSolo: (float64(poolInfo.MainChain.Difficulty.Lo) * (v / 100)) / currentHashRate,
|
||||
})
|
||||
}
|
||||
|
@ -641,9 +658,9 @@ func main() {
|
|||
poolInfo := getTypeFromAPI[cmdutils.PoolInfoResult]("pool_info", 5)
|
||||
lastPoolInfo.Store(poolInfo)
|
||||
|
||||
currentWindowSize := uint64(poolInfo.SideChain.WindowSize)
|
||||
currentWindowSize := uint64(poolInfo.SideChain.Window.Blocks)
|
||||
windowSize := currentWindowSize
|
||||
if poolInfo.SideChain.Height <= windowSize {
|
||||
if poolInfo.SideChain.LastBlock.SideHeight <= windowSize {
|
||||
windowSize = consensus.ChainWindowSize
|
||||
}
|
||||
size := uint64(30)
|
||||
|
@ -661,7 +678,7 @@ func main() {
|
|||
|
||||
miners := make(map[uint64]*views.MinersPageMinerEntry)
|
||||
|
||||
tipHeight := poolInfo.SideChain.Height
|
||||
tipHeight := poolInfo.SideChain.LastBlock.SideHeight
|
||||
wend := tipHeight - windowSize
|
||||
|
||||
tip := shares[0]
|
||||
|
@ -850,9 +867,9 @@ func main() {
|
|||
const totalWindows = 4
|
||||
wsize := consensus.ChainWindowSize * totalWindows
|
||||
|
||||
currentWindowSize := uint64(poolInfo.SideChain.WindowSize)
|
||||
currentWindowSize := uint64(poolInfo.SideChain.Window.Blocks)
|
||||
|
||||
tipHeight := poolInfo.SideChain.Height
|
||||
tipHeight := poolInfo.SideChain.LastBlock.SideHeight
|
||||
|
||||
var shares, lastShares, lastOrphanedShares []*index.SideBlock
|
||||
|
||||
|
@ -910,8 +927,8 @@ func main() {
|
|||
close(sweepC)
|
||||
}
|
||||
|
||||
sharesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.WindowSize))
|
||||
unclesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.WindowSize))
|
||||
sharesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.Window.Blocks))
|
||||
unclesInWindow := cmdutils.NewPositionChart(30, uint64(poolInfo.SideChain.Window.Blocks))
|
||||
|
||||
sharesFound := cmdutils.NewPositionChart(30*totalWindows, consensus.ChainWindowSize*totalWindows)
|
||||
unclesFound := cmdutils.NewPositionChart(30*totalWindows, consensus.ChainWindowSize*totalWindows)
|
||||
|
@ -992,7 +1009,7 @@ func main() {
|
|||
}
|
||||
|
||||
if windowDiff.Cmp64(0) > 0 {
|
||||
longWindowWeight := poolInfo.SideChain.Window.Weight.Mul64(4).Mul64(poolInfo.SideChain.Consensus.ChainWindowSize).Div64(uint64(poolInfo.SideChain.WindowSize))
|
||||
longWindowWeight := poolInfo.SideChain.Window.Weight.Mul64(4).Mul64(poolInfo.SideChain.Consensus.ChainWindowSize).Div64(uint64(poolInfo.SideChain.Window.Blocks))
|
||||
averageRewardPerBlock := longDiff.Mul64(poolInfo.MainChain.BaseReward).Div(longWindowWeight).Lo
|
||||
minerPage.ExpectedRewardPerDay = longWindowWeight.Mul64(averageRewardPerBlock).Div(poolInfo.MainChain.NextDifficulty).Lo
|
||||
|
||||
|
@ -1000,8 +1017,8 @@ func main() {
|
|||
minerPage.ExpectedRewardPerWindow = poolInfo.SideChain.Window.Weight.Mul64(expectedRewardNextBlock).Div(poolInfo.MainChain.NextDifficulty).Lo
|
||||
}
|
||||
|
||||
totalWeight := poolInfo.SideChain.Window.Weight.Mul64(4).Mul64(poolInfo.SideChain.Consensus.ChainWindowSize).Div64(uint64(poolInfo.SideChain.WindowSize))
|
||||
dailyHashRate := poolInfo.SideChain.Difficulty.Mul(longDiff).Div(totalWeight).Div64(consensus.TargetBlockTime).Lo
|
||||
totalWeight := poolInfo.SideChain.Window.Weight.Mul64(4).Mul64(poolInfo.SideChain.Consensus.ChainWindowSize).Div64(uint64(poolInfo.SideChain.Window.Blocks))
|
||||
dailyHashRate := types.DifficultyFrom64(poolInfo.SideChain.LastBlock.Difficulty).Mul(longDiff).Div(totalWeight).Div64(consensus.TargetBlockTime).Lo
|
||||
|
||||
hashRate := float64(0)
|
||||
magnitude := float64(1000)
|
||||
|
|
|
@ -93,7 +93,9 @@ type Consensus struct {
|
|||
MinimumDifficulty uint64 `json:"min_diff"`
|
||||
ChainWindowSize uint64 `json:"pplns_window"`
|
||||
UnclePenalty uint64 `json:"uncle_penalty"`
|
||||
|
||||
// HardFork optional hardfork information for p2pool
|
||||
// If empty it will be filled with the default hardfork list to the corresponding NetworkType
|
||||
HardForks []HardFork `json:"hard_forks,omitempty"`
|
||||
|
||||
hasher randomx.Hasher
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package sidechain
|
||||
|
||||
import "log"
|
||||
|
||||
type HardFork struct {
|
||||
Version uint8 `json:"version"`
|
||||
Height uint64 `json:"height"`
|
||||
|
@ -119,19 +117,21 @@ var p2poolStageNetHardForks = []HardFork{
|
|||
{p2poolMainNetHardForks[len(p2poolMainNetHardForks)-1].Version, 0, 0, 0},
|
||||
}
|
||||
|
||||
func NetworkMajorVersion(consensus *Consensus, height uint64) uint8 {
|
||||
var hardForks []HardFork
|
||||
func NetworkHardFork(consensus *Consensus) []HardFork {
|
||||
switch consensus.NetworkType {
|
||||
case NetworkMainnet:
|
||||
hardForks = mainNetHardForks
|
||||
return mainNetHardForks
|
||||
case NetworkTestnet:
|
||||
hardForks = testNetHardForks
|
||||
return testNetHardForks
|
||||
case NetworkStagenet:
|
||||
hardForks = stageNetHardForks
|
||||
return stageNetHardForks
|
||||
default:
|
||||
log.Panicf("invalid network type for determining share version")
|
||||
return 0
|
||||
panic("invalid network type for determining share version")
|
||||
}
|
||||
}
|
||||
|
||||
func NetworkMajorVersion(consensus *Consensus, height uint64) uint8 {
|
||||
hardForks := NetworkHardFork(consensus)
|
||||
|
||||
if len(hardForks) == 0 {
|
||||
return 0
|
||||
|
|
Loading…
Reference in a new issue