Sync speed improvements by better crypto cache
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
db5a26de4f
commit
2ad5e1ba38
|
@ -60,7 +60,7 @@ func BenchmarkCoinbaseDerivation(b *testing.B) {
|
|||
var i atomic.Uint64
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
GetEphemeralPublicKeyAndViewTag(&packed, txKey, i.Load())
|
||||
GetEphemeralPublicKeyAndViewTag(&packed, txKey, i.Add(1))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ func BenchmarkCoinbaseDerivationInline(b *testing.B) {
|
|||
b.RunParallel(func(pb *testing.PB) {
|
||||
p := new(edwards25519.Point)
|
||||
for pb.Next() {
|
||||
getEphemeralPublicKeyInline(spendPub, viewPub, privateKey, i.Load(), p)
|
||||
getEphemeralPublicKeyInline(spendPub, viewPub, privateKey, i.Add(1), p)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -81,14 +81,16 @@ func BenchmarkCoinbaseDerivationInline(b *testing.B) {
|
|||
func BenchmarkCoinbaseDerivationNoAllocate(b *testing.B) {
|
||||
packed := testAddress3.ToPackedAddress()
|
||||
|
||||
txKey := (*crypto.PrivateKeyScalar)(privateKey)
|
||||
spendPub, viewPub := packed.SpendPublicKey().AsPoint().Point(), packed.ViewPublicKey().AsPoint().Point()
|
||||
|
||||
txKey := 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)
|
||||
GetEphemeralPublicKeyAndViewTagNoAllocate(spendPub, viewPub, txKey, i.Add(1), hasher)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -42,18 +42,15 @@ func GetEphemeralPublicKeyAndViewTag(a Interface, txKey crypto.PrivateKey, outpu
|
|||
}
|
||||
|
||||
// GetEphemeralPublicKeyAndViewTagNoAllocate Special version of GetEphemeralPublicKeyAndViewTag
|
||||
func GetEphemeralPublicKeyAndViewTagNoAllocate(a *PackedAddress, txKey *crypto.PrivateKeyScalar, outputIndex uint64, hasher *sha3.HasherState) (crypto.PublicKeyBytes, uint8) {
|
||||
scalar := txKey.Scalar()
|
||||
var spendPublicKeyPoint, viewPublicKeyPoint, point, cofactor, intermediatePublicKey, ephemeralPublicKey edwards25519.Point
|
||||
_, _ = spendPublicKeyPoint.SetBytes((*a)[0][:])
|
||||
_, _ = viewPublicKeyPoint.SetBytes((*a)[1][:])
|
||||
point.UnsafeVarTimeScalarMult(scalar, &viewPublicKeyPoint)
|
||||
func GetEphemeralPublicKeyAndViewTagNoAllocate(spendPublicKeyPoint, viewPublicKeyPoint *edwards25519.Point, txKey *edwards25519.Scalar, outputIndex uint64, hasher *sha3.HasherState) (crypto.PublicKeyBytes, uint8) {
|
||||
var point, cofactor, intermediatePublicKey, ephemeralPublicKey edwards25519.Point
|
||||
point.UnsafeVarTimeScalarMult(txKey, viewPublicKeyPoint)
|
||||
cofactor.MultByCofactor(&point)
|
||||
|
||||
pK, viewTag := crypto.GetDerivationSharedDataAndViewTagForOutputIndexNoAllocate(crypto.PublicKeyBytes(cofactor.Bytes()), outputIndex, hasher)
|
||||
derivationSharedData, viewTag := crypto.GetDerivationSharedDataAndViewTagForOutputIndexNoAllocate(crypto.PublicKeyBytes(cofactor.Bytes()), outputIndex, hasher)
|
||||
|
||||
intermediatePublicKey.ScalarBaseMult(&pK)
|
||||
ephemeralPublicKey.Add(&intermediatePublicKey, &spendPublicKeyPoint)
|
||||
intermediatePublicKey.ScalarBaseMult(&derivationSharedData)
|
||||
ephemeralPublicKey.Add(&intermediatePublicKey, spendPublicKeyPoint)
|
||||
|
||||
var ephemeralPublicKeyBytes crypto.PublicKeyBytes
|
||||
copy(ephemeralPublicKeyBytes[:], ephemeralPublicKey.Bytes())
|
||||
|
|
|
@ -2,6 +2,7 @@ package sidechain
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"git.gammaspectra.live/P2Pool/edwards25519"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/address"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
|
@ -25,12 +26,14 @@ type DerivationCacheInterface interface {
|
|||
type DerivationCache struct {
|
||||
deterministicKeyCache utils.Cache[deterministicTransactionCacheKey, *crypto.KeyPair]
|
||||
ephemeralPublicKeyCache utils.Cache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag]
|
||||
pubKeyToPointCache utils.Cache[crypto.PublicKeyBytes, *edwards25519.Point]
|
||||
}
|
||||
|
||||
func NewDerivationLRUCache() *DerivationCache {
|
||||
d := &DerivationCache{
|
||||
deterministicKeyCache: utils.NewLRUCache[deterministicTransactionCacheKey, *crypto.KeyPair](32),
|
||||
ephemeralPublicKeyCache: utils.NewLRUCache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag](2000),
|
||||
pubKeyToPointCache: utils.NewLRUCache[crypto.PublicKeyBytes, *edwards25519.Point](2000),
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
@ -39,6 +42,7 @@ func NewDerivationMapCache() *DerivationCache {
|
|||
d := &DerivationCache{
|
||||
deterministicKeyCache: utils.NewMapCache[deterministicTransactionCacheKey, *crypto.KeyPair](32),
|
||||
ephemeralPublicKeyCache: utils.NewMapCache[ephemeralPublicKeyCacheKey, ephemeralPublicKeyWithViewTag](2000),
|
||||
pubKeyToPointCache: utils.NewLRUCache[crypto.PublicKeyBytes, *edwards25519.Point](2000),
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
@ -46,6 +50,7 @@ func NewDerivationMapCache() *DerivationCache {
|
|||
func (d *DerivationCache) Clear() {
|
||||
d.deterministicKeyCache.Clear()
|
||||
d.ephemeralPublicKeyCache.Clear()
|
||||
d.pubKeyToPointCache.Clear()
|
||||
}
|
||||
|
||||
func (d *DerivationCache) GetEphemeralPublicKey(a *address.PackedAddress, txKeySlice crypto.PrivateKeySlice, txKeyScalar *crypto.PrivateKeyScalar, outputIndex uint64, hasher *sha3.HasherState) (crypto.PublicKeyBytes, uint8) {
|
||||
|
@ -57,7 +62,7 @@ func (d *DerivationCache) GetEphemeralPublicKey(a *address.PackedAddress, txKeyS
|
|||
if ephemeralPubKey, ok := d.ephemeralPublicKeyCache.Get(key); ok {
|
||||
return ephemeralPubKey.PublicKey, ephemeralPubKey.ViewTag
|
||||
} else {
|
||||
pKB, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(a, txKeyScalar, outputIndex, hasher)
|
||||
pKB, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(d.getPublicKeyPoint(*a.SpendPublicKey()), d.getPublicKeyPoint(*a.ViewPublicKey()), txKeyScalar.Scalar(), outputIndex, hasher)
|
||||
d.ephemeralPublicKeyCache.Set(key, ephemeralPublicKeyWithViewTag{PublicKey: pKB, ViewTag: viewTag})
|
||||
return pKB, viewTag
|
||||
}
|
||||
|
@ -76,3 +81,13 @@ func (d *DerivationCache) GetDeterministicTransactionKey(seed types.Hash, prevId
|
|||
return data
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DerivationCache) getPublicKeyPoint(publicKey crypto.PublicKeyBytes) *edwards25519.Point {
|
||||
if point, ok := d.pubKeyToPointCache.Get(publicKey); ok {
|
||||
return point
|
||||
} else {
|
||||
point = publicKey.AsPoint().Point()
|
||||
d.pubKeyToPointCache.Set(publicKey, point)
|
||||
return point
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ func (d *NilDerivationCache) Clear() {
|
|||
}
|
||||
|
||||
func (d *NilDerivationCache) GetEphemeralPublicKey(a *address.PackedAddress, _ crypto.PrivateKeySlice, txKeyScalar *crypto.PrivateKeyScalar, outputIndex uint64, hasher *sha3.HasherState) (crypto.PublicKeyBytes, uint8) {
|
||||
ephemeralPubKey, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(a, txKeyScalar, outputIndex, hasher)
|
||||
ephemeralPubKey, viewTag := address.GetEphemeralPublicKeyAndViewTagNoAllocate(a.SpendPublicKey().AsPoint().Point(), a.ViewPublicKey().AsPoint().Point(), txKeyScalar.Scalar(), outputIndex, hasher)
|
||||
|
||||
return ephemeralPubKey.AsBytes(), viewTag
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
"git.gammaspectra.live/P2Pool/sha3"
|
||||
"golang.org/x/exp/slices"
|
||||
"log"
|
||||
"lukechampine.com/uint128"
|
||||
"math"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
type GetByMainIdFunc func(h types.Hash) *PoolBlock
|
||||
|
@ -256,7 +256,7 @@ func GetShares(tip *PoolBlock, consensus *Consensus, difficultyByHeight block.Ge
|
|||
|
||||
// ShuffleShares Sorts shares according to consensus parameters. Requires pre-sorted shares based on address
|
||||
func ShuffleShares[T any](shares []T, shareVersion ShareVersion, privateKeySeed types.Hash) {
|
||||
n := len(shares)
|
||||
n := uint64(len(shares))
|
||||
if shareVersion > ShareVersion_V1 && n > 1 {
|
||||
h := crypto.PooledKeccak256(privateKeySeed[:])
|
||||
seed := binary.LittleEndian.Uint64(h[:])
|
||||
|
@ -265,9 +265,9 @@ func ShuffleShares[T any](shares []T, shareVersion ShareVersion, privateKeySeed
|
|||
seed = 1
|
||||
}
|
||||
|
||||
for i := 0; i < (n - 1); i++ {
|
||||
for i := uint64(0); i < (n - 1); i++ {
|
||||
seed = utils.XorShift64Star(seed)
|
||||
k := int(uint128.From64(seed).Mul64(uint64(n - i)).Hi)
|
||||
k, _ := bits.Mul64(seed, n-i)
|
||||
//swap
|
||||
shares[i], shares[i+k] = shares[i+k], shares[i]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package utils
|
||||
|
||||
// XorShift64Star Implementation of xorshift* https://en.wikipedia.org/wiki/Xorshift#xorshift*
|
||||
// x must be initialized to a non-zero value
|
||||
func XorShift64Star(x uint64) uint64 {
|
||||
x ^= x >> 12
|
||||
x ^= x << 25
|
||||
|
|
Loading…
Reference in a new issue