From d992ce6e18a10db484e5c2291c8a46fac6f7c787 Mon Sep 17 00:00:00 2001
From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com>
Date: Fri, 21 Jul 2023 17:43:24 +0200
Subject: [PATCH] Speedup / less memory allocations on web hex / shorten / henc
calls, fast path difficulty UnmarshalJSON
---
cmd/web/views/connectivity-check.qtpl | 8 +-
cmd/web/views/funcs.go | 66 -------------
cmd/web/views/funcs.qtpl | 133 ++++++++++++++++++++++++++
cmd/web/views/index.qtpl | 4 +-
cmd/web/views/proof.qtpl | 16 ++--
cmd/web/views/tpl_found_blocks.qtpl | 14 +--
cmd/web/views/tpl_payouts.qtpl | 8 +-
cmd/web/views/tpl_poolblock.qtpl | 40 ++++----
cmd/web/views/tpl_row_miner.qtpl | 4 +-
cmd/web/views/tpl_shares.qtpl | 8 +-
cmd/web/views/tpl_sweeps.qtpl | 4 +-
cmd/web/views/transaction-lookup.qtpl | 16 ++--
types/difficulty.go | 11 +++
utils/number.go | 21 ++++
utils/shorten.go | 12 +++
15 files changed, 238 insertions(+), 127 deletions(-)
create mode 100644 cmd/web/views/funcs.qtpl
diff --git a/cmd/web/views/connectivity-check.qtpl b/cmd/web/views/connectivity-check.qtpl
index 1307a71..da991af 100644
--- a/cmd/web/views/connectivity-check.qtpl
+++ b/cmd/web/views/connectivity-check.qtpl
@@ -90,16 +90,16 @@ type ConnectivityCheckPage struct {
{% if p.Check.Tip != nil %}
- Peer SideChain Height {%dul p.YourTipRaw.Side.Height %}
- Peer SideChain Id {%s shorten(hex(p.YourTipRaw.SideTemplateId(p.Context().Consensus)), 10) %}
+ Peer SideChain Height {%dul p.YourTipRaw.Side.Height %}
+ Peer SideChain Id {%= shorten(p.YourTipRaw.SideTemplateId(p.Context().Consensus), 10) %}
Peer MainChain Height {%dul p.YourTipRaw.Main.Coinbase.GenHeight %}
Peer Difficulty {%s si_units(p.YourTipRaw.Side.Difficulty.Lo, 4) %}
Peer Cumulative Difficulty {%s si_units(p.YourTipRaw.Side.CumulativeDifficulty.Lo, 4) %}
Peer Timestamp {%s utc_date(p.YourTipRaw.Main.Timestamp) %}
- Observer SideChain Height {%dul p.OurTip.SideHeight %}
- Observer SideChain Id {%s shorten(hex(p.OurTip.TemplateId), 10) %}
+ Observer SideChain Height {%dul p.OurTip.SideHeight %}
+ Observer SideChain Id {%= shorten(p.OurTip.TemplateId, 10) %}
Observer MainChain Height {%dul p.OurTip.MainHeight %}
Observer Difficulty {%s si_units(p.OurTip.Difficulty, 4) %}
Observer Cumulative Difficulty {%s si_units(p.OurTip.CumulativeDifficulty.Lo, 4) %}
diff --git a/cmd/web/views/funcs.go b/cmd/web/views/funcs.go
index ae653ae..c371ec6 100644
--- a/cmd/web/views/funcs.go
+++ b/cmd/web/views/funcs.go
@@ -1,16 +1,13 @@
package views
import (
- "encoding/binary"
hex2 "encoding/hex"
"fmt"
"git.gammaspectra.live/P2Pool/p2pool-observer/index"
- "git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
types2 "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/types"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
- "log"
"strconv"
"strings"
"time"
@@ -51,21 +48,6 @@ func time_elapsed_short[T int64 | uint64 | int | float64](v T) string {
}
}
-func shorten(val any, n int) string {
- var value string
- if s, ok := val.(string); ok {
- value = s
- } else if h, ok := val.(types.Hash); ok {
- value = h.String()
- } else if s, ok := val.(fmt.Stringer); ok {
- value = s.String()
- } else {
- value = fmt.Sprintf("%s", value)
- }
-
- return utils.Shorten(value, n)
-}
-
func software_info(softwareId types2.SoftwareId, softwareVersion types2.SoftwareVersion) string {
if softwareId == 0 && softwareVersion == 0 {
return "Not present"
@@ -161,24 +143,6 @@ func bencstr(val string) string {
}
}
-func henc(val any) string {
- if h, ok := val.(types.Hash); ok {
- return utils.EncodeHexBinaryNumber(h.String())
- } else if k, ok := val.(crypto.PrivateKeyBytes); ok {
- return utils.EncodeHexBinaryNumber(k.String())
- } else if s, ok := val.(string); ok {
- return utils.EncodeHexBinaryNumber(s)
- } else if h, ok := val.(types.Hash); ok {
- return utils.EncodeHexBinaryNumber(h.String())
- } else if s, ok := val.(fmt.Stringer); ok {
- return utils.EncodeHexBinaryNumber(s.String())
- }
-
- //TODO: remove this
- log.Panic()
- return ""
-}
-
func str(val any) string {
if strVal, ok := val.(fmt.Stringer); ok {
return strVal.String()
@@ -241,33 +205,3 @@ func coinbase_extra(b *sidechain.PoolBlock) string {
}
return strings.Join(result, " ")
}
-
-func hex(val any) string {
- if s, ok := val.(string); ok {
- return s
- } else if s, ok := val.(types.Difficulty); ok {
- return s.String()
- } else if s, ok := val.(crypto.PrivateKey); ok {
- return s.String()
- } else if s, ok := val.(crypto.PublicKey); ok {
- return s.String()
- } else if s, ok := val.(crypto.PrivateKeyBytes); ok {
- return s.String()
- } else if s, ok := val.(crypto.PublicKeyBytes); ok {
- return s.String()
- } else if s, ok := val.(types.Hash); ok {
- return s.String()
- } else if s, ok := val.([]byte); ok {
- return hex2.EncodeToString(s)
- } else if s, ok := val.(uint32); ok {
- var buf [4]byte
- binary.LittleEndian.PutUint32(buf[:], s)
- return hex2.EncodeToString(buf[:])
- } else if s, ok := val.(uint64); ok {
- var buf [8]byte
- binary.LittleEndian.PutUint64(buf[:], s)
- return hex2.EncodeToString(buf[:])
- }
-
- return fmt.Sprintf("%s", val)
-}
diff --git a/cmd/web/views/funcs.qtpl b/cmd/web/views/funcs.qtpl
new file mode 100644
index 0000000..6b80297
--- /dev/null
+++ b/cmd/web/views/funcs.qtpl
@@ -0,0 +1,133 @@
+{% import "git.gammaspectra.live/P2Pool/p2pool-observer/types" %}
+{% import "git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto" %}
+{% import "git.gammaspectra.live/P2Pool/p2pool-observer/utils" %}
+{% import "encoding/binary" %}
+{% import "fmt" %}
+{% import hex2 "encoding/hex" %}
+
+{% stripspace %}
+
+{% func hex(val any) %}
+ {% code
+ var hexBuf [types.HashSize*2]byte
+ %}
+ {% switch s := val.(type) %}
+ {% case string %}
+ {%s s %}
+ {% case types.Difficulty %}
+ {% code
+ hex2.Encode(hexBuf[:types.DifficultySize*2], s.Bytes())
+ %}
+ {%z= hexBuf[:types.DifficultySize*2] %}
+ {% case crypto.PrivateKey %}
+ {% code
+ hex2.Encode(hexBuf[:], s.AsSlice())
+ %}
+ {%z= hexBuf[:] %}
+ {% case crypto.PublicKey %}
+ {% code
+ hex2.Encode(hexBuf[:], s.AsSlice())
+ %}
+ {%z= hexBuf[:] %}
+ {% case crypto.PrivateKeyBytes %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= hexBuf[:] %}
+ {% case crypto.PublicKeyBytes %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= hexBuf[:] %}
+ {% case types.Hash %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= hexBuf[:] %}
+ {% case []byte %}
+ {%s= hex2.EncodeToString(s) %}
+ {% case uint32 %}
+ {% code
+ var buf [4]byte
+ binary.LittleEndian.PutUint32(buf[:], s)
+ hex2.Encode(hexBuf[:4*2], buf[:])
+ %}
+ {%z= hexBuf[:4*2] %}
+ {% case uint64 %}
+ {% code
+ var buf [8]byte
+ binary.LittleEndian.PutUint64(buf[:], s)
+ hex2.Encode(hexBuf[:8*2], buf[:])
+ %}
+ {%z= hexBuf[:8*2] %}
+ {% default %}
+ {%v val %}
+ {% endswitch %}
+{% endfunc %}
+
+{% func shorten(val any, n int) %}
+ {% code
+ var hexBuf [types.HashSize*2]byte
+ %}
+ {% switch s := val.(type) %}
+ {% case string %}
+ {%s utils.Shorten(s, n) %}
+ {% case crypto.PrivateKey %}
+ {% code
+ hex2.Encode(hexBuf[:], s.AsSlice())
+ %}
+ {%z= utils.ShortenSlice(hexBuf[:], n) %}
+ {% case crypto.PublicKey %}
+ {% code
+ hex2.Encode(hexBuf[:], s.AsSlice())
+ %}
+ {%z= utils.ShortenSlice(hexBuf[:], n) %}
+ {% case crypto.PrivateKeyBytes %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= utils.ShortenSlice(hexBuf[:], n) %}
+ {% case crypto.PublicKeyBytes %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= utils.ShortenSlice(hexBuf[:], n) %}
+ {% case types.Hash %}
+ {% code
+ hex2.Encode(hexBuf[:], s[:])
+ %}
+ {%z= utils.ShortenSlice(hexBuf[:], n) %}
+ {% case fmt.Stringer %}
+ {%s utils.Shorten(s.String(), n) %}
+ {% default %}
+ {%s utils.Shorten(fmt.Sprintf("%v", val), n) %}
+ {% endswitch %}
+{% endfunc %}
+
+
+
+{% func henc(val any) %}
+ {% code
+ var buf [types.HashSize*2+1]byte
+ %}
+ {% switch s := val.(type) %}
+ {% case types.Hash %}
+ {% code
+ dst := utils.EncodeSliceBinaryNumber(buf[:], s[:])
+ %}
+ {%z= dst[:] %}
+ {% case crypto.PrivateKeyBytes %}
+ {% code
+ dst := utils.EncodeSliceBinaryNumber(buf[:], s[:])
+ %}
+ {%z= dst[:] %}
+ {% case string %}
+ {%s= utils.EncodeHexBinaryNumber(s) %}
+ {% case fmt.Stringer %}
+ {%s= utils.EncodeHexBinaryNumber(s.String()) %}
+ {% default %}
+ panic("type not allowed")
+ {% endswitch %}
+{% endfunc %}
+
+{% endstripspace %}
\ No newline at end of file
diff --git a/cmd/web/views/index.qtpl b/cmd/web/views/index.qtpl
index 34babb0..d0239f5 100644
--- a/cmd/web/views/index.qtpl
+++ b/cmd/web/views/index.qtpl
@@ -35,9 +35,9 @@ type IndexPage struct {
Monero Hashrate
- {%dul p.Context().Pool.SideChain.Height %}
+ {%dul p.Context().Pool.SideChain.Height %}
{%s si_units(diff_hashrate(p.Context().Pool.SideChain.Difficulty, p.Context().Consensus.TargetBlockTime), 2) %}H/s
- {%dul p.Context().Pool.MainChain.Height %}
+ {%dul p.Context().Pool.MainChain.Height %}
{%s si_units(diff_hashrate(p.Context().Pool.MainChain.Difficulty, uint64(p.Context().Pool.MainChain.BlockTime)), 2) %}H/s
diff --git a/cmd/web/views/proof.qtpl b/cmd/web/views/proof.qtpl
index 46ec804..6d46e61 100644
--- a/cmd/web/views/proof.qtpl
+++ b/cmd/web/views/proof.qtpl
@@ -26,26 +26,26 @@ type ProofPage struct {
Payout Address: {%s encodedMinerAddress %}
{% endif %}
- Received {%s monero_to_xmr(p.Output.Value) %} XMR on transaction id {%s hex(p.Output.Id) %} (output index #{%dul uint64(p.Output.Index) %}, global output index #{%dul p.Output.GlobalOutputIndex %}).
+ Received {%s monero_to_xmr(p.Output.Value) %} XMR on transaction id {%= hex(p.Output.Id) %} (output index #{%dul uint64(p.Output.Index) %}, global output index #{%dul p.Output.GlobalOutputIndex %}).
{%dul p.Context().Pool.MainChain.Height - p.Block.MainHeight + 1 %} confirmation(s) . Coinbase outputs will unlock after 60 confirmations.
Stealth Address: {%s address.GetEphemeralPublicKey(p.Output.MinerAddress, &p.Raw.Side.CoinbasePrivateKey, uint64(p.Output.Index)).String() %}
Payment Proofs
-
OutProofV2: {%s hex(address.GetTxProofV2(p.Output.MinerAddress, p.Output.Id, &p.Raw.Side.CoinbasePrivateKey, "")) %}
-
OutProofV1: {%s hex(address.GetTxProofV1(p.Output.MinerAddress, p.Output.Id, &p.Raw.Side.CoinbasePrivateKey, "")) %}
+
OutProofV2: {%= hex(address.GetTxProofV2(p.Output.MinerAddress, p.Output.Id, &p.Raw.Side.CoinbasePrivateKey, "")) %}
+
OutProofV1: {%= hex(address.GetTxProofV1(p.Output.MinerAddress, p.Output.Id, &p.Raw.Side.CoinbasePrivateKey, "")) %}
Verify on Monero GUI (Advanced -> Prove/check -> Check Transaction)
diff --git a/cmd/web/views/tpl_found_blocks.qtpl b/cmd/web/views/tpl_found_blocks.qtpl
index f9e0d4b..344d3b7 100644
--- a/cmd/web/views/tpl_found_blocks.qtpl
+++ b/cmd/web/views/tpl_found_blocks.qtpl
@@ -21,14 +21,14 @@
{% for i, b := range foundBlocks %}
- {%dul b.MainBlock.Height %}
+ {%dul b.MainBlock.Height %}
{% if b.UncleOf != types.ZeroHash %}
-
- {%dul b.SideHeight %}*
+
+ {%dul b.SideHeight %}*
{% else %}
-
- {%dul b.SideHeight %}
+
+ {%dul b.SideHeight %}
{% endif %}
{%s date_diff_short(b.MainBlock.Timestamp) %}
@@ -49,8 +49,8 @@
{%dul uint64(b.TransactionCount) %}
{%s monero_to_xmr(b.MainBlock.Reward) %} XMR
{%dul uint64(b.WindowOutputs) %}
- {%s shorten(hex(b.MainBlock.CoinbaseId), 10) %}
- {%s hex(b.MainBlock.CoinbasePrivateKey) %}
+ {%= shorten(b.MainBlock.CoinbaseId, 10) %}
+ {%= hex(b.MainBlock.CoinbasePrivateKey) %}
{% endfor %}
diff --git a/cmd/web/views/tpl_payouts.qtpl b/cmd/web/views/tpl_payouts.qtpl
index e19b6a4..563594b 100644
--- a/cmd/web/views/tpl_payouts.qtpl
+++ b/cmd/web/views/tpl_payouts.qtpl
@@ -13,13 +13,13 @@
{% for _, p := range payouts %}
- {%dul p.MainHeight %}
- {%dul p.SideHeight %}
+ {%dul p.MainHeight %}
+ {%dul p.SideHeight %}
{%s date_diff_short(p.Timestamp) %}
{%s monero_to_xmr(p.Reward) %} XMR
{%dul p.GlobalOutputIndex %}
- {%s shorten(hex(p.CoinbaseId), 10) %}
- [Payout Proof #{%dul uint64(p.Index) %}]
+ {%= shorten(p.CoinbaseId, 10) %}
+ [Payout Proof #{%dul uint64(p.Index) %}]
{% endfor %}
diff --git a/cmd/web/views/tpl_poolblock.qtpl b/cmd/web/views/tpl_poolblock.qtpl
index b14dfe7..6047f1a 100644
--- a/cmd/web/views/tpl_poolblock.qtpl
+++ b/cmd/web/views/tpl_poolblock.qtpl
@@ -26,9 +26,9 @@
{% if sideBlock.SideHeight == 0 %}
Genesis Block
{% elseif sideBlock.IsUncle() %}
- << Parent share
+ << Parent share
{% else %}
- << Previous share
+ << Previous share
{% endif %}
{% if sideBlock.IsOrphan() %}
Orphans do not have next blocks
@@ -49,22 +49,22 @@
{%dul poolBlock.Side.Height %}
{% if sideBlock != nil %}
- {%s hex(sideBlock.TemplateId) %}
+ {%= hex(sideBlock.TemplateId) %}
{% else %}
- {%s hex(poolBlock.SideTemplateId(ctx.Consensus)) %}
+ {%= hex(poolBlock.SideTemplateId(ctx.Consensus)) %}
{% endif %}
{% if sideBlock != nil %}
{% if sideBlock.MinedMainAtHeight %}
{%dul sideBlock.MainHeight %}
- {%s hex(sideBlock.MainId) %}
+ {%= hex(sideBlock.MainId) %}
{% else %}
{%dul sideBlock.MainHeight %}
- {%s hex(sideBlock.MainId) %}
+ {%= hex(sideBlock.MainId) %}
{% endif %}
{% else %}
{%dul poolBlock.Main.Coinbase.GenHeight %}
- {%s hex(poolBlock.MainId()) %}
+ {%= hex(poolBlock.MainId()) %}
{% endif %}
@@ -77,7 +77,7 @@
{%s date_diff_short(poolBlock.Main.Timestamp) %}
{% if sideBlock != nil %}
- {%s hex(sideBlock.PowHash) %}
+ {%= hex(sideBlock.PowHash) %}
{%= TemplateRowMiner(sideBlock.MinerAddress, sideBlock.MinerAlias) %}
{%dul sideBlock.Difficulty %} / {%dul sideBlock.PowDifficulty %}
{% else %}
@@ -100,12 +100,12 @@
{%s side_block_valuation(poolBlock, ctx.Consensus) %}
{% endif %}
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
- {%s hex(poolBlock.Main.Coinbase.Id()) %}
+ {%= hex(poolBlock.Main.Coinbase.Id()) %}
{% else %}
- {%s hex(poolBlock.Main.Coinbase.Id()) %}
+ {%= hex(poolBlock.Main.Coinbase.Id()) %}
{% endif %}
{%s monero_to_xmr(poolBlock.Main.Coinbase.TotalReward) %} XMR
- {%s hex(poolBlock.Side.CoinbasePrivateKey) %}
+ {%= hex(poolBlock.Side.CoinbasePrivateKey) %}
@@ -115,9 +115,9 @@
Monero Target Difficulty
- {%dul uint64(poolBlock.Main.Nonce) %}
+ {%dul uint64(poolBlock.Main.Nonce) %}
{%s str(poolBlock.Side.CumulativeDifficulty) %}
- {%dul uint64(poolBlock.ExtraNonce()) %}
+ {%dul uint64(poolBlock.ExtraNonce()) %}
{% if sideBlock != nil && sideBlock.MainDifficulty != 0 %}{%dul sideBlock.MainDifficulty %}{% endif %}
@@ -130,8 +130,8 @@
{%s software_info(poolBlock.Side.ExtraBuffer.SoftwareId, poolBlock.Side.ExtraBuffer.SoftwareVersion) %}
{%s poolBlock.ShareVersion().String() %} ({% if poolBlock.ShareVersionSignaling() != sidechain.ShareVersion_None %}signaling {%s poolBlock.ShareVersionSignaling().String() %} support{% else %}no known signaling{% endif %})
- {% if poolBlock.ShareVersion() > sidechain.ShareVersion_V1 %}{%s hex(poolBlock.Side.ExtraBuffer.RandomNumber) %} / {%s hex(poolBlock.Side.ExtraBuffer.SideChainExtraNonce) %}{% endif %}
- {% if poolBlock.GetPrivateKeySeed() != types.ZeroHash %}{%s hex(poolBlock.GetPrivateKeySeed()) %} {% else %}Not Deterministic{% endif %}
+ {% if poolBlock.ShareVersion() > sidechain.ShareVersion_V1 %}{%= hex(poolBlock.Side.ExtraBuffer.RandomNumber) %} / {%= hex(poolBlock.Side.ExtraBuffer.SideChainExtraNonce) %}{% endif %}
+ {% if poolBlock.GetPrivateKeySeed() != types.ZeroHash %}{%= hex(poolBlock.GetPrivateKeySeed()) %} {% else %}Not Deterministic{% endif %}
@@ -144,7 +144,7 @@
{% endif %}
{% endif %}
@@ -200,7 +200,7 @@
{% for _, t := range poolBlock.Main.Coinbase.Outputs %}
{%dul t.Index %}
- {%s hex(t.EphemeralPublicKey) %}
+ {%= hex(t.EphemeralPublicKey) %}
{% code var globalOutputIndex uint64 %}
{% if len(coinbaseOutputs) > int(t.Index) %}
{% code globalOutputIndex = coinbaseOutputs[t.Index].GlobalOutputIndex %}
@@ -209,12 +209,12 @@
{%s monero_to_xmr(t.Reward) %} XMR
{% if sideBlock != nil && sideBlock.MinedMainAtHeight %}
{%dul globalOutputIndex %}
- [Payout Proof #{%dul t.Index %}]
+ [Payout Proof #{%dul t.Index %}]
{% if sweepsCount > 0 %}
{% code outputSweeps := sweeps[t.Index] %}
{% if len(outputSweeps) > 0 %}
{% code sweep := outputSweeps[0] %}
- {%s shorten(hex(sweep.Id), 10) %} {%d sweep.MinerCount %} / {%d sweep.InputCount %}
+ {%= shorten(sweep.Id, 10) %} {%d sweep.MinerCount %} / {%d sweep.InputCount %}
{% elseif (ctx.Pool.MainChain.Height - sideBlock.MainHeight + 1) < 60 %}
Not unlocked
{% else %}
@@ -229,7 +229,7 @@
Included Transactions
{% endif %}
diff --git a/cmd/web/views/tpl_row_miner.qtpl b/cmd/web/views/tpl_row_miner.qtpl
index 97c2671..50a9778 100644
--- a/cmd/web/views/tpl_row_miner.qtpl
+++ b/cmd/web/views/tpl_row_miner.qtpl
@@ -7,8 +7,8 @@
{% func TemplateRowMinerWithTag(addr *address.Address, alias string, tag string) %}
{% code encodedMinerAddress := addr.ToBase58() %}
{% if alias != "" %}
- <{%s tag %} title="{%s encodedMinerAddress %} ({%s alias %})" class="mono small">{%s shorten(alias, 10) %} {%s tag %}>
+ <{%s tag %} title="{%s encodedMinerAddress %} ({%s alias %})" class="mono small">{%= shorten(alias, 10) %} {%s tag %}>
{% else %}
- <{%s tag %} title="{%s encodedMinerAddress %}" class="mono small">{%s shorten(encodedMinerAddress, 10) %} {%s tag %}>
+ <{%s tag %} title="{%s encodedMinerAddress %}" class="mono small">{%= shorten(encodedMinerAddress, 10) %} {%s tag %}>
{% endif %}
{% endfunc %}
\ No newline at end of file
diff --git a/cmd/web/views/tpl_shares.qtpl b/cmd/web/views/tpl_shares.qtpl
index ca161f7..e17306b 100644
--- a/cmd/web/views/tpl_shares.qtpl
+++ b/cmd/web/views/tpl_shares.qtpl
@@ -19,12 +19,12 @@
{% for i, s := range shares %}
- {%dul s.SideHeight %}
- {%s shorten(s.TemplateId, 10) %}
+ {%dul s.SideHeight %}
+ {%= shorten(s.TemplateId, 10) %}
{% if s.MinedMainAtHeight %}
- {%dul s.MainHeight %}
+ {%dul s.MainHeight %}
{% else %}
- {%dul s.MainHeight %}
+ {%dul s.MainHeight %}
{% endif %}
{%s date_diff_short(s.Timestamp) %}
{% if efforts != nil %}
diff --git a/cmd/web/views/tpl_sweeps.qtpl b/cmd/web/views/tpl_sweeps.qtpl
index 668296b..50159b3 100644
--- a/cmd/web/views/tpl_sweeps.qtpl
+++ b/cmd/web/views/tpl_sweeps.qtpl
@@ -21,10 +21,10 @@
{% for _, s := range sweeps %}
- {%s shorten(hex(s.Id), 10) %}
+ {%= shorten(s.Id, 10) %}
{%s date_diff_short(s.Timestamp) %}
{% if !isMiner %}
- {%s shorten(s.Address.ToBase58(), 10) %}
+ {%= shorten(s.Address.ToBase58(), 10) %}
{% endif %}
{%d s.InputDecoyCount %}
{%d s.InputCount %} / {%d len(s.GlobalOutputIndices) %}
diff --git a/cmd/web/views/transaction-lookup.qtpl b/cmd/web/views/transaction-lookup.qtpl
index 5f1afb6..e5a30d5 100644
--- a/cmd/web/views/transaction-lookup.qtpl
+++ b/cmd/web/views/transaction-lookup.qtpl
@@ -55,7 +55,7 @@ type TransactionLookupPage struct {
Transaction Id
-
+
@@ -75,7 +75,7 @@ type TransactionLookupPage struct {
- Transaction Id: {%s hex(p.TransactionId) %}
+ Transaction Id: {%= hex(p.TransactionId) %}
{% code minerAddress := p.Miner.Address.ToBase58() %}
Miner Payout Address: {%s minerAddress %}
Likely: {% if p.LikelyMiner %}Yes{% else %}Not likely{% endif %}
@@ -127,11 +127,11 @@ type TransactionLookupPage struct {
{% else %}
{%d index %}
- {%s shorten(hex(input.Input.KeyImage), 10) %}
+ {%= shorten(input.Input.KeyImage, 10) %}
{% endif %}
-
{% code out := p.Result.Outs[totalInputCount] %}
- {%s shorten(hex(out.TransactionId), 10) %}
+ {%= shorten(out.TransactionId, 10) %}
{%dul input.Input.KeyOffsets[oindex] %}
-
-
@@ -142,16 +142,16 @@ type TransactionLookupPage struct {
{% else %}
{%d index %}
- {%s shorten(hex(input.Input.KeyImage), 10) %}
+ {%= shorten(input.Input.KeyImage, 10) %}
{% endif %}
- {%s shorten(o.Address.ToBase58(), 10) %}
+ {%= shorten(o.Address.ToBase58(), 10) %}
{% if o.Coinbase != nil %}
- {%s shorten(hex(o.Coinbase.Id), 10) %} #{%dul uint64(o.Coinbase.Index) %}
+ {%= shorten(o.Coinbase.Id, 10) %} #{%dul uint64(o.Coinbase.Index) %}
{%dul o.GlobalOutputIndex %}
Coinbase
{%s monero_to_xmr(o.Coinbase.Value) %} XMR
{% elseif o.Sweep != nil %}
- {%s shorten(hex(o.Sweep.Id), 10) %}
+ {%= shorten(o.Sweep.Id, 10) %}
{% for oindex, goi := range o.Sweep.GlobalOutputIndices %}
{% if goi == o.GlobalOutputIndex %}
#{%d oindex %}/{%d len(o.Sweep.GlobalOutputIndices) %}
diff --git a/types/difficulty.go b/types/difficulty.go
index 2f2c3c4..cbe05ed 100644
--- a/types/difficulty.go
+++ b/types/difficulty.go
@@ -247,6 +247,17 @@ func (d *Difficulty) UnmarshalJSON(b []byte) error {
return err
}
+ if len(b) == DifficultySize*2+2 {
+ // fast path
+ var buf [DifficultySize]byte
+ if _, err := hex.Decode(buf[:], b[1:len(b)-1]); err != nil {
+ return err
+ } else {
+ *d = DifficultyFromBytes(buf[:])
+ return nil
+ }
+ }
+
if diff, err := DifficultyFromString(s); err != nil {
return err
} else {
diff --git a/utils/number.go b/utils/number.go
index f6cf2b9..455e76e 100644
--- a/utils/number.go
+++ b/utils/number.go
@@ -1,6 +1,7 @@
package utils
import (
+ "bytes"
"encoding/hex"
"github.com/jxskiss/base62"
"math/bits"
@@ -49,6 +50,26 @@ func DecodeHexBinaryNumber(i string) string {
return ""
}
+func EncodeSliceBinaryNumber(dst, src []byte) []byte {
+ if len(dst) < 1+(len(src)*2) {
+ return nil
+ }
+ v := encoding.EncodeToBuf(dst[:0], src)
+
+ if !bytes.ContainsAny(v, "GHIJKLMNOPQRSTUVWXYZghijklmnopqrstuvwxyz") {
+ copy(dst[1:], v)
+ dst[0] = '.'
+ v = dst[:len(v)]
+ }
+
+ if len(v) >= (len(src) * 2) {
+ hex.Encode(dst, src)
+ return dst[:len(src)*2]
+ }
+
+ return v
+}
+
func EncodeHexBinaryNumber(v2 string) string {
b, _ := hex.DecodeString(v2)
v1 := encoding.EncodeToString(b)
diff --git a/utils/shorten.go b/utils/shorten.go
index 8ba0b7d..1808f9a 100644
--- a/utils/shorten.go
+++ b/utils/shorten.go
@@ -7,3 +7,15 @@ func Shorten(value string, n int) string {
return value[:n] + "..." + value[len(value)-n:]
}
}
+
+func ShortenSlice(value []byte, n int) []byte {
+ if len(value) <= n*2+3 {
+ return value
+ } else {
+ copy(value[n+3:], value[len(value)-n:])
+ value[n] = '.'
+ value[n+1] = '.'
+ value[n+2] = '.'
+ return value[:n*2+3]
+ }
+}