Reduce allocations on utils.SplitWork, add BufferLength methods for pool block serialization

This commit is contained in:
DataHoarder 2023-05-17 17:29:01 +02:00
parent 4acc0d34af
commit 22077acdfa
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
13 changed files with 153 additions and 90 deletions

View file

@ -395,7 +395,7 @@ func main() {
}
return nil
})
}, nil)
}
nonceSize := sidechain.SideExtraNonceSize

24
go.sum
View file

@ -14,17 +14,22 @@ 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=
@ -47,18 +52,23 @@ 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=
@ -68,8 +78,10 @@ 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=
@ -77,12 +89,16 @@ 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=
@ -98,9 +114,11 @@ 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=
@ -108,11 +126,13 @@ 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=
@ -138,11 +158,13 @@ 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=
@ -150,9 +172,11 @@ 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

@ -49,12 +49,16 @@ func (b *Block) MarshalBinary() (buf []byte, err error) {
return b.MarshalBinaryFlags(false, false)
}
func (b *Block) BufferLength() int {
return 1 + 1 + binary.MaxVarintLen64 + types.HashSize + 4 + b.Coinbase.BufferLength() + binary.MaxVarintLen64 + types.HashSize*len(b.Transactions)
}
func (b *Block) MarshalBinaryFlags(pruned, compact bool) (buf []byte, err error) {
var txBuf []byte
if txBuf, err = b.Coinbase.MarshalBinaryFlags(pruned); err != nil {
return nil, err
}
buf = make([]byte, 0, 1+1+binary.MaxVarintLen64+types.HashSize+4+len(txBuf)+binary.MaxVarintLen64+types.HashSize*len(b.Transactions))
buf = make([]byte, 0, b.BufferLength())
buf = append(buf, b.MajorVersion)
if b.MajorVersion > monero.HardForkSupportedVersion {
return nil, fmt.Errorf("unsupported version %d", b.MajorVersion)
@ -214,7 +218,7 @@ func (b *Block) SideChainHashingBlob(zeroTemplateId bool) (buf []byte, err error
if txBuf, err = b.Coinbase.SideChainHashingBlob(zeroTemplateId); err != nil {
return nil, err
}
buf = make([]byte, 0, 1+1+binary.MaxVarintLen64+types.HashSize+4+len(txBuf)+binary.MaxVarintLen64+types.HashSize*len(b.Transactions))
buf = make([]byte, 0, b.BufferLength())
buf = append(buf, b.MajorVersion)
buf = append(buf, b.MinorVersion)
buf = binary.AppendUvarint(buf, b.Timestamp)

View file

@ -38,7 +38,7 @@ func GetDerivationSharedDataAndViewTagForOutputIndexNoAllocate(k PublicKeyBytes,
n := binary.PutUvarint(buf[PublicKeySize:], outputIndex)
var h types.Hash
hasher.Reset()
hasher.Write(buf[:PublicKeySize+n])
_, _ = hasher.Write(buf[:PublicKeySize+n])
HashFastSum(hasher, h[:])
scReduce32(h[:])
@ -46,8 +46,8 @@ func GetDerivationSharedDataAndViewTagForOutputIndexNoAllocate(k PublicKeyBytes,
_, _ = c.SetCanonicalBytes(h[:])
hasher.Reset()
hasher.Write(viewTagDomain)
hasher.Write(buf[:PublicKeySize+n])
_, _ = hasher.Write(viewTagDomain)
_, _ = hasher.Write(buf[:PublicKeySize+n])
HashFastSum(hasher, h[:])
return c, h[0]

View file

@ -39,7 +39,7 @@ func PooledKeccak256(data ...[]byte) (result types.Hash) {
h := GetKeccak256Hasher()
defer PutKeccak256Hasher(h)
for _, b := range data {
h.Write(b)
_, _ = h.Write(b)
}
HashFastSum(h, result[:])
return

View file

@ -143,33 +143,38 @@ func (c *CoinbaseTransaction) MarshalBinary() ([]byte, error) {
return c.MarshalBinaryFlags(false)
}
func (c *CoinbaseTransaction) BufferLength() int {
return 1 + binary.MaxVarintLen64 + 1 + 1 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + c.Outputs.BufferLength() + binary.MaxVarintLen64 + c.Extra.BufferLength() + 1
}
func (c *CoinbaseTransaction) MarshalBinaryFlags(pruned bool) ([]byte, error) {
buf := new(bytes.Buffer)
varIntBuf := make([]byte, binary.MaxVarintLen64)
_ = binary.Write(buf, binary.LittleEndian, c.Version)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, c.UnlockTime)])
_ = binary.Write(buf, binary.LittleEndian, c.InputCount)
_ = binary.Write(buf, binary.LittleEndian, c.InputType)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, c.GenHeight)])
outputs, _ := c.OutputsBlob()
if pruned {
//pruned output
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, 0)])
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, c.TotalReward)])
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, uint64(len(outputs)))])
} else {
_, _ = buf.Write(outputs)
}
txExtra, _ := c.Extra.MarshalBinary()
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, uint64(len(txExtra)))])
_, _ = buf.Write(txExtra)
_ = binary.Write(buf, binary.LittleEndian, c.ExtraBaseRCT)
return buf.Bytes(), nil
buf := make([]byte, 0, c.BufferLength())
buf = append(buf, c.Version)
buf = binary.AppendUvarint(buf, c.UnlockTime)
buf = append(buf, c.InputCount)
buf = append(buf, c.InputType)
buf = binary.AppendUvarint(buf, c.GenHeight)
if pruned {
//pruned output
buf = binary.AppendUvarint(buf, 0)
buf = binary.AppendUvarint(buf, c.TotalReward)
buf = binary.AppendUvarint(buf, uint64(len(outputs)))
} else {
buf = append(buf, outputs...)
}
buf = binary.AppendUvarint(buf, uint64(len(txExtra)))
buf = append(buf, txExtra...)
buf = append(buf, c.ExtraBaseRCT)
return buf, nil
}
func (c *CoinbaseTransaction) OutputsBlob() ([]byte, error) {
@ -177,25 +182,25 @@ func (c *CoinbaseTransaction) OutputsBlob() ([]byte, error) {
}
func (c *CoinbaseTransaction) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
buf := new(bytes.Buffer)
varIntBuf := make([]byte, binary.MaxVarintLen64)
_ = binary.Write(buf, binary.LittleEndian, c.Version)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, c.UnlockTime)])
_ = binary.Write(buf, binary.LittleEndian, c.InputCount)
_ = binary.Write(buf, binary.LittleEndian, c.InputType)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, c.GenHeight)])
outputs, _ := c.Outputs.MarshalBinary()
_, _ = buf.Write(outputs)
outputs, _ := c.OutputsBlob()
txExtra, _ := c.Extra.SideChainHashingBlob(zeroTemplateId)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, uint64(len(txExtra)))])
_, _ = buf.Write(txExtra)
_ = binary.Write(buf, binary.LittleEndian, c.ExtraBaseRCT)
return buf.Bytes(), nil
buf := make([]byte, 0, c.BufferLength())
buf = append(buf, c.Version)
buf = binary.AppendUvarint(buf, c.UnlockTime)
buf = append(buf, c.InputCount)
buf = append(buf, c.InputType)
buf = binary.AppendUvarint(buf, c.GenHeight)
buf = append(buf, outputs...)
buf = binary.AppendUvarint(buf, uint64(len(txExtra)))
buf = append(buf, txExtra...)
buf = append(buf, c.ExtraBaseRCT)
return buf, nil
}
func (c *CoinbaseTransaction) Id() types.Hash {
@ -215,18 +220,16 @@ func (c *CoinbaseTransaction) Id() types.Hash {
}
func (c *CoinbaseTransaction) CalculateId() (hash types.Hash) {
idHasher := crypto.GetKeccak256Hasher()
defer crypto.PutKeccak256Hasher(idHasher)
txBytes, _ := c.MarshalBinary()
// remove base RCT
idHasher.Write(hashKeccak(txBytes[:len(txBytes)-1]))
// Base RCT, single 0 byte in miner tx
idHasher.Write(hashKeccak([]byte{c.ExtraBaseRCT}))
// Prunable RCT, empty in miner tx
idHasher.Write(types.ZeroHash[:])
crypto.HashFastSum(idHasher, hash[:])
return hash
return crypto.PooledKeccak256(
// remove base RCT
hashKeccak(txBytes[:len(txBytes)-1]),
// Base RCT, single 0 byte in miner tx
hashKeccak([]byte{c.ExtraBaseRCT}),
// Prunable RCT, empty in miner tx
types.ZeroHash[:],
)
}
func hashKeccak(data ...[]byte) []byte {

View file

@ -38,11 +38,18 @@ func (t *ExtraTags) UnmarshalBinary(data []byte) (err error) {
return t.FromReader(reader)
}
func (t *ExtraTags) BufferLength() (length int) {
for _, tag := range *t {
length += tag.BufferLength()
}
return
}
func (t *ExtraTags) MarshalBinary() ([]byte, error) {
if t == nil {
return nil, nil
}
buf := make([]byte, 0, types.HashSize*4)
buf := make([]byte, 0, t.BufferLength())
for _, tag := range *t {
if b, err := tag.MarshalBinary(); err != nil {
return nil, err
@ -58,7 +65,7 @@ func (t *ExtraTags) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
if t == nil {
return nil, nil
}
buf := make([]byte, 0, types.HashSize*4)
buf := make([]byte, 0, t.BufferLength())
for _, tag := range *t {
if b, err := tag.SideChainHashingBlob(zeroTemplateId); err != nil {
return nil, err
@ -101,8 +108,12 @@ func (t *ExtraTag) UnmarshalBinary(data []byte) error {
return t.FromReader(reader)
}
func (t *ExtraTag) BufferLength() int {
return len(t.Data) + 1 + binary.MaxVarintLen64
}
func (t *ExtraTag) MarshalBinary() ([]byte, error) {
buf := make([]byte, 0, len(t.Data)+1+binary.MaxVarintLen64)
buf := make([]byte, 0, t.BufferLength())
buf = append(buf, t.Tag)
if t.HasVarInt {
buf = binary.AppendUvarint(buf, t.VarInt)
@ -112,7 +123,7 @@ func (t *ExtraTag) MarshalBinary() ([]byte, error) {
}
func (t *ExtraTag) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
buf := make([]byte, 0, len(t.Data)+1+binary.MaxVarintLen64)
buf := make([]byte, 0, t.BufferLength())
buf = append(buf, t.Tag)
if t.HasVarInt {
buf = binary.AppendUvarint(buf, t.VarInt)

View file

@ -57,8 +57,12 @@ func (s *Outputs) FromReader(reader readerAndByteReader) (err error) {
return nil
}
func (s *Outputs) BufferLength() int {
return binary.MaxVarintLen64 + len(*s)*(binary.MaxVarintLen64+1+crypto.PublicKeySize+1)
}
func (s *Outputs) MarshalBinary() (data []byte, err error) {
data = make([]byte, 0, binary.MaxVarintLen64+len(*s)*(binary.MaxVarintLen64+1+crypto.PublicKeySize+1))
data = make([]byte, 0, s.BufferLength())
data = binary.AppendUvarint(data, uint64(len(*s)))

View file

@ -398,13 +398,17 @@ func (b *PoolBlock) UnmarshalBinary(consensus *Consensus, derivationCache Deriva
return b.FromReader(consensus, derivationCache, reader)
}
func (b *PoolBlock) BufferLength() int {
return b.Main.BufferLength() + b.Side.BufferLength()
}
func (b *PoolBlock) MarshalBinary() ([]byte, error) {
if mainData, err := b.Main.MarshalBinary(); err != nil {
return nil, err
} else if sideData, err := b.Side.MarshalBinary(b.ShareVersion()); err != nil {
return nil, err
} else {
data := make([]byte, 0, len(mainData)+len(sideData))
data := make([]byte, 0, b.BufferLength())
data = append(data, mainData...)
data = append(data, sideData...)
@ -421,7 +425,7 @@ func (b *PoolBlock) MarshalBinaryFlags(pruned, compact bool) ([]byte, error) {
} else if sideData, err := b.Side.MarshalBinary(b.ShareVersion()); err != nil {
return nil, err
} else {
data := make([]byte, 0, len(mainData)+len(sideData))
data := make([]byte, 0, b.BufferLength())
data = append(data, mainData...)
data = append(data, sideData...)

View file

@ -66,6 +66,8 @@ type SideChain struct {
blocksByTemplateId map[types.Hash]*PoolBlock
blocksByHeight map[uint64][]*PoolBlock
preAllocatedBuffer []byte
syncTip atomic.Pointer[PoolBlock]
chainTip atomic.Pointer[PoolBlock]
currentDifficulty atomic.Pointer[types.Difficulty]
@ -88,6 +90,7 @@ func NewSideChain(server P2PoolInterface) *SideChain {
preAllocatedDifficultyData: make([]DifficultyData, server.Consensus().ChainWindowSize*2),
preAllocatedDifficultyDifferences: make([]uint32, server.Consensus().ChainWindowSize*2),
preAllocatedSharesPool: NewPreAllocatedSharesPool(server.Consensus().ChainWindowSize * 2),
preAllocatedBuffer: make([]byte, 0, PoolBlockMaxTemplateSize),
}
minDiff := types.DifficultyFrom64(server.Consensus().MinimumDifficulty)
s.currentDifficulty.Store(&minDiff)
@ -560,7 +563,15 @@ func (c *SideChain) verifyBlock(block *PoolBlock) (verification error, invalid e
var hashers []*sha3.HasherState
results := utils.SplitWork(-2, uint64(len(rewards)), func(workIndex uint64, workerIndex int) error {
var anyErr atomic.Value
defer func() {
for _, h := range hashers {
crypto.PutKeccak256Hasher(h)
}
}()
if !utils.SplitWork(-2, uint64(len(rewards)), func(workIndex uint64, workerIndex int) error {
out := block.Main.Coinbase.Outputs[workIndex]
if rewards[workIndex] != out.Reward {
return fmt.Errorf("has invalid reward at index %d, got %d, expected %d", workIndex, out.Reward, rewards[workIndex])
@ -575,18 +586,10 @@ func (c *SideChain) verifyBlock(block *PoolBlock) (verification error, invalid e
}, func(routines, routineIndex int) error {
hashers = append(hashers, crypto.GetKeccak256Hasher())
return nil
})
defer func() {
for _, h := range hashers {
crypto.PutKeccak256Hasher(h)
}
}()
for i := range results {
if results[i] != nil {
return nil, results[i]
}
}, func(routineIndex int, err error) {
anyErr.Store(err)
}) {
return nil, anyErr.Load().(error)
}
}

View file

@ -36,8 +36,12 @@ type readerAndByteReader interface {
io.ByteReader
}
func (b *SideData) BufferLength() int {
return crypto.PublicKeySize + crypto.PublicKeySize + types.HashSize + types.HashSize + binary.MaxVarintLen64 + len(b.Uncles)*types.HashSize + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + 4*4
}
func (b *SideData) MarshalBinary(version ShareVersion) (buf []byte, err error) {
buf = make([]byte, 0, types.HashSize+types.HashSize+types.HashSize+types.HashSize+binary.MaxVarintLen64+binary.MaxVarintLen64+binary.MaxVarintLen64+binary.MaxVarintLen64+binary.MaxVarintLen64+binary.MaxVarintLen64+4*4)
buf = make([]byte, 0, b.BufferLength())
buf = append(buf, b.PublicSpendKey[:]...)
buf = append(buf, b.PublicViewKey[:]...)
if version > ShareVersion_V1 {

View file

@ -45,7 +45,13 @@ func CalculateOutputs(block *PoolBlock, consensus *Consensus, difficultyByHeight
var hashers []*sha3.HasherState
_ = utils.SplitWork(-2, n, func(workIndex uint64, workerIndex int) error {
defer func() {
for _, h := range hashers {
crypto.PutKeccak256Hasher(h)
}
}()
utils.SplitWork(-2, n, func(workIndex uint64, workerIndex int) error {
output := transaction.Output{
Index: workIndex,
Type: txType,
@ -59,13 +65,7 @@ func CalculateOutputs(block *PoolBlock, consensus *Consensus, difficultyByHeight
}, func(routines, routineIndex int) error {
hashers = append(hashers, crypto.GetKeccak256Hasher())
return nil
})
defer func() {
for _, h := range hashers {
crypto.PutKeccak256Hasher(h)
}
}()
}, nil)
return outputs, bottomHeight
}

View file

@ -6,7 +6,7 @@ import (
"sync/atomic"
)
func SplitWork(routines int, workSize uint64, do func(workIndex uint64, routineIndex int) error, init func(routines, routineIndex int) error) []error {
func SplitWork(routines int, workSize uint64, do func(workIndex uint64, routineIndex int) error, init func(routines, routineIndex int) error, errorFunc func(routineIndex int, err error)) bool {
if routines <= 0 {
routines = Max(runtime.NumCPU()-routines, 4)
}
@ -17,13 +17,16 @@ func SplitWork(routines int, workSize uint64, do func(workIndex uint64, routineI
var counter atomic.Uint64
results := make([]error, routines)
var wg sync.WaitGroup
var allOk atomic.Bool
allOk.Store(true)
for routineIndex := 0; routineIndex < routines; routineIndex++ {
if init != nil {
if err := init(routines, routineIndex); err != nil {
results[routineIndex] = err
if errorFunc != nil {
errorFunc(routineIndex, err)
}
allOk.Store(false)
continue
}
}
@ -38,7 +41,10 @@ func SplitWork(routines int, workSize uint64, do func(workIndex uint64, routineI
}
if err = do(workIndex-1, routineIndex); err != nil {
results[routineIndex] = err
if errorFunc != nil {
errorFunc(routineIndex, err)
allOk.Store(false)
}
return
}
}
@ -46,5 +52,5 @@ func SplitWork(routines int, workSize uint64, do func(workIndex uint64, routineI
}
wg.Wait()
return results
return allOk.Load()
}