Optimize address sorting, crypto cache, use unsafe VarTimeScalarMult for sidechain operations
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2023-05-20 10:49:05 +02:00
parent 4a92d3a727
commit e9eb5915ed
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
31 changed files with 257 additions and 155 deletions

View file

@ -59,7 +59,7 @@ func main() {
}
defer outputCache.Close()
derivationCache := sidechain.NewDerivationCache()
derivationCache := sidechain.NewDerivationLRUCache()
blockCache := lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 4))

View file

@ -101,7 +101,7 @@ func main() {
blockCache := lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 4))
derivationCache := sidechain.NewDerivationCache()
derivationCache := sidechain.NewDerivationLRUCache()
getByTemplateIdDirect := func(h types.Hash) *sidechain.PoolBlock {
if v := blockCache.Get(h); v == nil {
if bs := archiveCache.LoadByTemplateId(h); len(bs) != 0 {

View file

@ -39,7 +39,7 @@ func main() {
totalStored := 0
derivationCache := sidechain.NewDerivationCache()
derivationCache := sidechain.NewDerivationLRUCache()
blockCache := lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 4 * 60))

View file

@ -109,7 +109,7 @@ func main() {
blockCache := lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 4))
derivationCache := sidechain.NewDerivationCache()
derivationCache := sidechain.NewDerivationLRUCache()
getByTemplateIdDirect := func(h types.Hash) *sidechain.PoolBlock {
if v := blockCache.Get(h); v == nil {
if bs := archiveCache.LoadByTemplateId(h); len(bs) != 0 {

2
go.mod
View file

@ -3,7 +3,7 @@ module git.gammaspectra.live/P2Pool/p2pool-observer
go 1.20
require (
filippo.io/edwards25519 v1.0.1-0.20220803165937-8c58ed0e3550
git.gammaspectra.live/P2Pool/edwards25519 v0.0.0-20230520084036-0f06fa066019
git.gammaspectra.live/P2Pool/go-monero v0.0.0-20230410011208-910450c4a523
git.gammaspectra.live/P2Pool/go-randomx v0.0.0-20221027085532-f46adfce03a7
git.gammaspectra.live/P2Pool/moneroutil v0.0.0-20230516052049-a566889a4d3b

28
go.sum
View file

@ -1,5 +1,5 @@
filippo.io/edwards25519 v1.0.1-0.20220803165937-8c58ed0e3550 h1:Mqu6Q2e//30TWeP5bM9Th5KEzWdFAFd80Y2ZXN9fmeE=
filippo.io/edwards25519 v1.0.1-0.20220803165937-8c58ed0e3550/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
git.gammaspectra.live/P2Pool/edwards25519 v0.0.0-20230520084036-0f06fa066019 h1:A256rPumLHvYEJdgOQQAHZX7zOZTSYiGcsT5rykpcH4=
git.gammaspectra.live/P2Pool/edwards25519 v0.0.0-20230520084036-0f06fa066019/go.mod h1:336HUKX25mQ1qUtzkwV9Wrqi153tTgUOKcIhpYuF2ts=
git.gammaspectra.live/P2Pool/go-monero v0.0.0-20230410011208-910450c4a523 h1:oIJzm7kQyASS0xlJ79VSWRvvfXp2Qt7M05+E20o9gwE=
git.gammaspectra.live/P2Pool/go-monero v0.0.0-20230410011208-910450c4a523/go.mod h1:TAOAAV972JNDkCzyV5SkbYkKCRvcfhvvFa8LHH4Dg6g=
git.gammaspectra.live/P2Pool/go-randomx v0.0.0-20221027085532-f46adfce03a7 h1:bzHDuu1IgETKqPBOlIdCE2LaZIJ+ZpROSprNn+fnzd8=
@ -14,22 +14,17 @@ github.com/ake-persson/mapslice-json v0.0.0-20210720081907-22c8edf57807 h1:w3nrG
github.com/ake-persson/mapslice-json v0.0.0-20210720081907-22c8edf57807/go.mod h1:fGnnfniJiO/ajHAVHqMSUSL8sE9LmU9rzclCtoeB+y8=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/floatdrop/lru v1.3.0 h1:83abtaKjXcWrPmtzTAk2Ggq8DUKqI29YzrTrB8+vu0c=
github.com/floatdrop/lru v1.3.0/go.mod h1:83zlXKA06Bm32JImNINCiTr0ldadvdAjUe5jSwIaw0s=
github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -52,23 +47,18 @@ github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gordonklaus/ineffassign v0.0.0-20210522101830-0589229737b2 h1:hC4RAQwLzbDbHsa+CwwGBm1uG2oX9o3Frx9G73duPi8=
github.com/gordonklaus/ineffassign v0.0.0-20210522101830-0589229737b2/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk=
github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw=
github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc=
github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY=
github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
@ -78,10 +68,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
@ -89,16 +77,12 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -114,11 +98,9 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -126,13 +108,11 @@ golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -158,13 +138,11 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -172,11 +150,9 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=

View file

@ -60,7 +60,7 @@ func OpenIndex(connStr string, consensus *sidechain.Consensus, difficultyByHeigh
getDifficultyByHeight: difficultyByHeight,
getSeedByHeight: getSeedByHeight,
getByTemplateId: getByTemplateId,
derivationCache: sidechain.NewDerivationCache(),
derivationCache: sidechain.NewDerivationLRUCache(),
blockCache: lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 4)),
}
if index.handle, err = sql.Open("postgres", connStr); err != nil {

View file

@ -16,19 +16,26 @@ type Address struct {
}
func (a *Address) Compare(b Interface) int {
//TODO
return a.ToPackedAddress().Reference().Compare(b)
//compare spend key
resultSpendKey := crypto.CompareConsensusPublicKeyBytes(a.SpendPub, *b.SpendPublicKey())
if resultSpendKey != 0 {
return resultSpendKey
}
// compare view key
return crypto.CompareConsensusPublicKeyBytes(a.ViewPub, *b.ViewPublicKey())
}
func (a *Address) PublicKeys() (spend, view crypto.PublicKey) {
return &a.SpendPub, &a.ViewPub
}
func (a *Address) SpendPublicKey() crypto.PublicKey {
func (a *Address) SpendPublicKey() *crypto.PublicKeyBytes {
return &a.SpendPub
}
func (a *Address) ViewPublicKey() crypto.PublicKey {
func (a *Address) ViewPublicKey() *crypto.PublicKeyBytes {
return &a.ViewPub
}

View file

@ -3,7 +3,7 @@ package address
import (
"bytes"
"encoding/hex"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"log"
@ -60,7 +60,7 @@ func BenchmarkCoinbaseDerivation(b *testing.B) {
var i atomic.Uint64
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
GetEphemeralPublicKey(&packed, txKey, i.Load())
GetEphemeralPublicKeyAndViewTag(&packed, txKey, i.Load())
}
})
}
@ -77,3 +77,18 @@ func BenchmarkCoinbaseDerivationInline(b *testing.B) {
}
})
}
func BenchmarkCoinbaseDerivationNoAllocate(b *testing.B) {
packed := testAddress3.ToPackedAddress()
txKey := (*crypto.PrivateKeyScalar)(privateKey)
var i atomic.Uint64
b.RunParallel(func(pb *testing.PB) {
hasher := crypto.GetKeccak256Hasher()
defer crypto.PutKeccak256Hasher(hasher)
for pb.Next() {
GetEphemeralPublicKeyAndViewTagNoAllocate(&packed, txKey, i.Load(), hasher)
}
})
}

View file

@ -2,7 +2,7 @@ package address
import (
"encoding/binary"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/moneroutil"
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
p2poolcrypto "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/crypto"
@ -25,7 +25,7 @@ func GetEphemeralPublicKey(a Interface, txKey crypto.PrivateKey, outputIndex uin
func getEphemeralPublicKeyInline(spendPub, viewPub *edwards25519.Point, txKey *edwards25519.Scalar, outputIndex uint64, p *edwards25519.Point) {
//derivation
p.ScalarMult(txKey, viewPub).MultByCofactor(p)
p.UnsafeVarTimeScalarMult(txKey, viewPub).MultByCofactor(p)
derivationAsBytes := p.Bytes()
var varIntBuf [binary.MaxVarintLen64]byte
@ -47,7 +47,7 @@ func GetEphemeralPublicKeyAndViewTagNoAllocate(a *PackedAddress, txKey *crypto.P
var spendPublicKeyPoint, viewPublicKeyPoint, point, cofactor, intermediatePublicKey, ephemeralPublicKey edwards25519.Point
_, _ = spendPublicKeyPoint.SetBytes((*a)[0][:])
_, _ = viewPublicKeyPoint.SetBytes((*a)[1][:])
point.ScalarMult(scalar, &viewPublicKeyPoint)
point.UnsafeVarTimeScalarMult(scalar, &viewPublicKeyPoint)
cofactor.MultByCofactor(&point)
pK, viewTag := crypto.GetDerivationSharedDataAndViewTagForOutputIndexNoAllocate(crypto.PublicKeyBytes(cofactor.Bytes()), outputIndex, hasher)

View file

@ -9,8 +9,8 @@ type Interface interface {
PublicKeys() (spend, view crypto.PublicKey)
SpendPublicKey() crypto.PublicKey
ViewPublicKey() crypto.PublicKey
SpendPublicKey() *crypto.PublicKeyBytes
ViewPublicKey() *crypto.PublicKeyBytes
ToAddress(network uint8, err ...error) *Address
ToPackedAddress() PackedAddress

View file

@ -2,7 +2,6 @@ package address
import (
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
"runtime"
"unsafe"
)
@ -22,11 +21,11 @@ func (p *PackedAddress) PublicKeys() (spend, view crypto.PublicKey) {
return &(*p)[0], &(*p)[1]
}
func (p *PackedAddress) SpendPublicKey() crypto.PublicKey {
func (p *PackedAddress) SpendPublicKey() *crypto.PublicKeyBytes {
return &(*p)[0]
}
func (p *PackedAddress) ViewPublicKey() crypto.PublicKey {
func (p *PackedAddress) ViewPublicKey() *crypto.PublicKeyBytes {
return &(*p)[1]
}
@ -35,75 +34,28 @@ func (p *PackedAddress) ToPackedAddress() PackedAddress {
}
// Compare special consensus comparison
func (p *PackedAddress) Compare(otherI Interface) int {
other := otherI.ToPackedAddress()
//golang might free other otherwise
defer runtime.KeepAlive(other)
defer runtime.KeepAlive(p)
a := (*[(2 * crypto.PublicKeySize) / 8]uint64)(unsafe.Pointer(p))
b := (*[(2 * crypto.PublicKeySize) / 8]uint64)(unsafe.Pointer(&other))
func (p *PackedAddress) Compare(b Interface) int {
//compare spend key
if a[3] < b[3] {
return -1
}
if a[3] > b[3] {
return 1
resultSpendKey := crypto.CompareConsensusPublicKeyBytes(p[0], *b.SpendPublicKey())
if resultSpendKey != 0 {
return resultSpendKey
}
if a[2] < b[2] {
return -1
}
if a[2] > b[2] {
return 1
// compare view key
return crypto.CompareConsensusPublicKeyBytes(p[1], *b.ViewPublicKey())
}
func (p PackedAddress) ComparePacked(other PackedAddress) int {
//compare spend key
resultSpendKey := crypto.CompareConsensusPublicKeyBytes(p[0], other[0])
if resultSpendKey != 0 {
return resultSpendKey
}
if a[1] < b[1] {
return -1
}
if a[1] > b[1] {
return 1
}
if a[0] < b[0] {
return -1
}
if a[0] > b[0] {
return 1
}
//compare view key
if a[4+3] < b[4+3] {
return -1
}
if a[4+3] > b[4+3] {
return 1
}
if a[4+2] < b[4+2] {
return -1
}
if a[4+2] > b[4+2] {
return 1
}
if a[4+1] < b[4+1] {
return -1
}
if a[4+1] > b[4+1] {
return 1
}
if a[4+0] < b[4+0] {
return -1
}
if a[4+0] > b[4+0] {
return 1
}
return 0
// compare view key
return crypto.CompareConsensusPublicKeyBytes(p[1], other[1])
}
func (p *PackedAddress) ToAddress(network uint8, err ...error) *Address {

View file

@ -1,6 +1,6 @@
package crypto
import "filippo.io/edwards25519"
import "git.gammaspectra.live/P2Pool/edwards25519"
var infinityPoint = edwards25519.NewIdentityPoint()
var zeroScalar = edwards25519.NewScalar()

View file

@ -1 +1,45 @@
package crypto
import (
"runtime"
"unsafe"
)
// CompareConsensusPublicKeyBytes Compares public keys in a special consensus specific way
func CompareConsensusPublicKeyBytes(a, b PublicKeyBytes) int {
aUint64 := (*[PublicKeySize / 8]uint64)(unsafe.Pointer(&a))
bUint64 := (*[PublicKeySize / 8]uint64)(unsafe.Pointer(&b))
if aUint64[3] < bUint64[3] {
return -1
}
if aUint64[3] > bUint64[3] {
return 1
}
if aUint64[2] < bUint64[2] {
return -1
}
if aUint64[2] > bUint64[2] {
return 1
}
if aUint64[1] < bUint64[1] {
return -1
}
if aUint64[1] > bUint64[1] {
return 1
}
if aUint64[0] < bUint64[0] {
return -1
}
if aUint64[0] > bUint64[0] {
return 1
}
//golang might free other otherwise
runtime.KeepAlive(aUint64)
runtime.KeepAlive(bUint64)
return 0
}

View file

@ -2,7 +2,7 @@ package crypto
import (
"encoding/binary"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"git.gammaspectra.live/P2Pool/sha3"
)

View file

@ -2,7 +2,7 @@ package crypto
import (
"encoding/hex"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"testing"
)

View file

@ -1,7 +1,7 @@
package crypto
import (
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/moneroutil"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"git.gammaspectra.live/P2Pool/sha3"

View file

@ -1,7 +1,7 @@
package crypto
import (
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"git.gammaspectra.live/P2Pool/sha3"
"runtime"

View file

@ -6,7 +6,7 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
)
type PrivateKey interface {

View file

@ -6,7 +6,7 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
)
type PublicKey interface {

View file

@ -3,7 +3,7 @@ package crypto
import (
"crypto/rand"
"encoding/binary"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"unsafe"
)

View file

@ -1,7 +1,7 @@
package crypto
import (
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
)

View file

@ -34,7 +34,7 @@ func NewP2PoolApi(host string) *P2PoolApi {
Client: &http.Client{
Timeout: time.Second * 15,
},
derivationCache: sidechain.NewDerivationCache(),
derivationCache: sidechain.NewDerivationLRUCache(),
difficultyByHeightCache: lru.New[uint64, types.Difficulty](1024),
}
}

View file

@ -54,7 +54,7 @@ func NewCache(path string, consensus *sidechain.Consensus, difficultyByHeight bl
consensus: consensus,
difficultyByHeight: difficultyByHeight,
preAllocatedSharesPool: sidechain.NewPreAllocatedSharesPool(consensus.ChainWindowSize * 2),
derivationCache: sidechain.NewDerivationCache(),
derivationCache: sidechain.NewDerivationLRUCache(),
}, nil
}
}

View file

@ -2,7 +2,7 @@ package crypto
import (
"encoding/hex"
"filippo.io/edwards25519"
"git.gammaspectra.live/P2Pool/edwards25519"
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"os"

View file

@ -463,6 +463,11 @@ func (c *MainChain) HandleMinerData(minerData *p2pooltypes.MinerData) {
log.Printf("[MainChain] new miner data: major_version = %d, height = %d, prev_id = %s, seed_hash = %s, difficulty = %s", minerData.MajorVersion, minerData.Height, minerData.PrevId.String(), minerData.SeedHash.String(), minerData.Difficulty.StringNumeric())
// Tx secret keys from all miners change every block, so cache can be cleared here
if c.sidechain.PreCalcFinished() {
c.sidechain.DerivationCache().Clear()
}
if c.p2pool.Started() {
for h := minerData.Height; h > 0 && (h+BlockHeadersRequired) > minerData.Height; h-- {
if d, ok := c.mainchainByHeight[h]; !ok || d.Difficulty.Equals(types.ZeroDifficulty) {

View file

@ -5,9 +5,8 @@ import (
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/address"
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
"git.gammaspectra.live/P2Pool/sha3"
"github.com/floatdrop/lru"
"sync/atomic"
)
type deterministicTransactionCacheKey [crypto.PublicKeySize + types.HashSize]byte
@ -24,23 +23,29 @@ type DerivationCacheInterface interface {
}
type DerivationCache struct {
deterministicKeyCache atomic.Pointer[lru.LRU[deterministicTransactionCacheKey, *crypto.KeyPair]]
deterministicKeyCacheHits atomic.Uint64
deterministicKeyCacheMisses atomic.Uint64
ephemeralPublicKeyCache atomic.Pointer[lru.LRU[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag]]
ephemeralPublicKeyCacheHits atomic.Uint64
ephemeralPublicKeyCacheMisses atomic.Uint64
deterministicKeyCache utils.Cache[deterministicTransactionCacheKey, *crypto.KeyPair]
ephemeralPublicKeyCache utils.Cache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag]
}
func NewDerivationCache() *DerivationCache {
d := &DerivationCache{}
d.Clear()
func NewDerivationLRUCache() *DerivationCache {
d := &DerivationCache{
deterministicKeyCache: utils.NewLRUCache[deterministicTransactionCacheKey, *crypto.KeyPair](32),
ephemeralPublicKeyCache: utils.NewLRUCache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag](2000),
}
return d
}
func NewDerivationMapCache() *DerivationCache {
d := &DerivationCache{
deterministicKeyCache: utils.NewMapCache[deterministicTransactionCacheKey, *crypto.KeyPair](32),
ephemeralPublicKeyCache: utils.NewMapCache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag](2000),
}
return d
}
func (d *DerivationCache) Clear() {
d.deterministicKeyCache.Store(lru.New[deterministicTransactionCacheKey, *crypto.KeyPair](32))
d.ephemeralPublicKeyCache.Store(lru.New[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag](2000))
d.deterministicKeyCache.Clear()
d.ephemeralPublicKeyCache.Clear()
}
func (d *DerivationCache) GetEphemeralPublicKey(a *address.PackedAddress, txKeySlice crypto.PrivateKeySlice, txKeyScalar *crypto.PrivateKeyScalar, outputIndex uint64, hasher *sha3.HasherState) (crypto.PublicKeyBytes, uint8) {
@ -49,15 +54,12 @@ func (d *DerivationCache) GetEphemeralPublicKey(a *address.PackedAddress, txKeyS
copy(key[crypto.PrivateKeySize:], a.ToPackedAddress().Bytes())
binary.LittleEndian.PutUint64(key[crypto.PrivateKeySize+crypto.PublicKeySize*2:], outputIndex)
ephemeralPublicKeyCache := d.ephemeralPublicKeyCache.Load()
if ephemeralPubKey := ephemeralPublicKeyCache.Get(key); ephemeralPubKey == nil {
d.ephemeralPublicKeyCacheMisses.Add(1)
pKB, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(a, txKeyScalar, outputIndex, hasher)
ephemeralPublicKeyCache.Set(key, ephemeralPublicKeyWithViewTag{PublicKey: pKB, ViewTag: viewTag})
return pKB, viewTag
} else {
d.ephemeralPublicKeyCacheHits.Add(1)
if ephemeralPubKey, ok := d.ephemeralPublicKeyCache.Get(key); ok {
return ephemeralPubKey.PublicKey, ephemeralPubKey.ViewTag
} else {
pKB, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(a, txKeyScalar, outputIndex, hasher)
d.ephemeralPublicKeyCache.Set(key, ephemeralPublicKeyWithViewTag{PublicKey: pKB, ViewTag: viewTag})
return pKB, viewTag
}
}
@ -66,14 +68,11 @@ func (d *DerivationCache) GetDeterministicTransactionKey(seed types.Hash, prevId
copy(key[:], seed[:])
copy(key[types.HashSize:], prevId[:])
deterministicKeyCache := d.deterministicKeyCache.Load()
if kp := deterministicKeyCache.Get(key); kp == nil {
d.deterministicKeyCacheMisses.Add(1)
data := crypto.NewKeyPairFromPrivate(address.GetDeterministicTransactionPrivateKey(seed, prevId))
deterministicKeyCache.Set(key, data)
return data
if kp, ok := d.deterministicKeyCache.Get(key); ok {
return kp
} else {
d.deterministicKeyCacheHits.Add(1)
return *kp
data := crypto.NewKeyPairFromPrivate(address.GetDeterministicTransactionPrivateKey(seed, prevId))
d.deterministicKeyCache.Set(key, data)
return data
}
}

View file

@ -82,7 +82,7 @@ type SideChain struct {
func NewSideChain(server P2PoolInterface) *SideChain {
s := &SideChain{
derivationCache: NewDerivationCache(),
derivationCache: NewDerivationMapCache(),
server: server,
blocksByTemplateId: make(map[types.Hash]*PoolBlock),
blocksByHeight: make(map[uint64][]*PoolBlock),

View file

@ -140,14 +140,13 @@ func TestSideChainMini(t *testing.T) {
t.Fatal()
}
hits, misses := s.DerivationCache().ephemeralPublicKeyCacheHits.Load(), s.DerivationCache().ephemeralPublicKeyCacheMisses.Load()
hits, misses := s.DerivationCache().ephemeralPublicKeyCache.Stats()
total := hits + misses
log.Printf("Ephemeral Public Key Cache hits = %d (%.02f%%), misses = %d (%.02f%%), total = %d", hits, (float64(hits)/float64(total))*100, misses, (float64(misses)/float64(total))*100, total)
hits, misses = s.DerivationCache().deterministicKeyCacheHits.Load(), s.DerivationCache().deterministicKeyCacheMisses.Load()
hits, misses = s.DerivationCache().deterministicKeyCache.Stats()
total = hits + misses
log.Printf("Deterministic Key Cache hits = %d (%.02f%%), misses = %d (%.02f%%), total = %d", hits, (float64(hits)/float64(total))*100, misses, (float64(misses)/float64(total))*100, total)
}
type fakeServer struct {

View file

@ -228,7 +228,7 @@ func GetShares(tip *PoolBlock, consensus *Consensus, difficultyByHeight block.Ge
// Sort shares based on address
slices.SortFunc(shares, func(a *Share, b *Share) bool {
return a.Address.Compare(&b.Address) < 0
return a.Address.ComparePacked(b.Address) < 0
})
//remove dupes

105
utils/cache.go Normal file
View file

@ -0,0 +1,105 @@
package utils
import (
"github.com/floatdrop/lru"
"sync"
"sync/atomic"
)
type Cache[K comparable, T any] interface {
Get(key K) (value T, ok bool)
Set(key K, value T)
Delete(key K)
Clear()
Stats() (hits, misses uint64)
}
type LRUCache[K comparable, T any] struct {
values atomic.Pointer[lru.LRU[K, T]]
hits, misses atomic.Uint64
size int
}
func NewLRUCache[K comparable, T any](size int) *LRUCache[K, T] {
c := &LRUCache[K, T]{
size: size,
}
c.Clear()
return c
}
func (c *LRUCache[K, T]) Get(key K) (value T, ok bool) {
if v := c.values.Load().Get(key); v != nil {
c.hits.Add(1)
return *v, true
} else {
c.misses.Add(1)
return value, false
}
}
func (c *LRUCache[K, T]) Set(key K, value T) {
c.values.Load().Set(key, value)
}
func (c *LRUCache[K, T]) Delete(key K) {
c.values.Load().Remove(key)
}
func (c *LRUCache[K, T]) Clear() {
c.values.Store(lru.New[K, T](c.size))
}
func (c *LRUCache[K, T]) Stats() (hits, misses uint64) {
return c.hits.Load(), c.misses.Load()
}
type MapCache[K comparable, T any] struct {
lock sync.RWMutex
values map[K]T
hits, misses atomic.Uint64
size int
}
func NewMapCache[K comparable, T any](preAllocateSize int) *MapCache[K, T] {
return &MapCache[K, T]{
values: make(map[K]T, preAllocateSize),
size: preAllocateSize,
}
}
func (m *MapCache[K, T]) Get(key K) (value T, ok bool) {
m.lock.RLock()
defer m.lock.RUnlock()
value, ok = m.values[key]
if ok {
m.hits.Add(1)
} else {
m.misses.Add(1)
}
return value, ok
}
func (m *MapCache[K, T]) Set(key K, value T) {
m.lock.Lock()
defer m.lock.Unlock()
m.values[key] = value
}
func (m *MapCache[K, T]) Delete(key K) {
m.lock.Lock()
defer m.lock.Unlock()
delete(m.values, key)
}
func (m *MapCache[K, T]) Clear() {
m.lock.Lock()
defer m.lock.Unlock()
m.values = make(map[K]T, m.size)
}
func (m *MapCache[K, T]) Stats() (hits, misses uint64) {
m.lock.Lock()
defer m.lock.Unlock()
return m.hits.Load(), m.misses.Load()
}