mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-25 05:08:16 -05:00
Compare commits
2 Commits
gloas-api-
...
replaceWit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8572352e1 | ||
|
|
1848d76796 |
@@ -4,16 +4,16 @@ package blst
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
lruwrpr "github.com/prysmaticlabs/prysm/v4/cache/lru"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls/common"
|
"github.com/prysmaticlabs/prysm/v4/crypto/bls/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var maxKeys = 1_000_000
|
var pubkeyLock sync.RWMutex
|
||||||
var pubkeyCache = lruwrpr.New(maxKeys)
|
var pubkeyMap = make(map[[48]byte]*PublicKey)
|
||||||
|
|
||||||
// PublicKey used in the BLS signature scheme.
|
// PublicKey used in the BLS signature scheme.
|
||||||
type PublicKey struct {
|
type PublicKey struct {
|
||||||
@@ -26,9 +26,13 @@ func PublicKeyFromBytes(pubKey []byte) (common.PublicKey, error) {
|
|||||||
return nil, fmt.Errorf("public key must be %d bytes", params.BeaconConfig().BLSPubkeyLength)
|
return nil, fmt.Errorf("public key must be %d bytes", params.BeaconConfig().BLSPubkeyLength)
|
||||||
}
|
}
|
||||||
newKey := (*[fieldparams.BLSPubkeyLength]byte)(pubKey)
|
newKey := (*[fieldparams.BLSPubkeyLength]byte)(pubKey)
|
||||||
if cv, ok := pubkeyCache.Get(*newKey); ok {
|
pubkeyLock.RLock()
|
||||||
return cv.(*PublicKey).Copy(), nil
|
if cv, ok := pubkeyMap[*newKey]; ok {
|
||||||
|
pubkeyLock.RUnlock()
|
||||||
|
return cv.Copy(), nil
|
||||||
}
|
}
|
||||||
|
pubkeyLock.RUnlock()
|
||||||
|
|
||||||
// Subgroup check NOT done when decompressing pubkey.
|
// Subgroup check NOT done when decompressing pubkey.
|
||||||
p := new(blstPublicKey).Uncompress(pubKey)
|
p := new(blstPublicKey).Uncompress(pubKey)
|
||||||
if p == nil {
|
if p == nil {
|
||||||
@@ -41,8 +45,16 @@ func PublicKeyFromBytes(pubKey []byte) (common.PublicKey, error) {
|
|||||||
}
|
}
|
||||||
pubKeyObj := &PublicKey{p: p}
|
pubKeyObj := &PublicKey{p: p}
|
||||||
copiedKey := pubKeyObj.Copy()
|
copiedKey := pubKeyObj.Copy()
|
||||||
|
assertedKey, ok := (copiedKey).(*PublicKey)
|
||||||
|
// Should be impossible to happen, this is checked
|
||||||
|
// to satisfy lint tools.
|
||||||
|
if !ok {
|
||||||
|
return pubKeyObj, nil
|
||||||
|
}
|
||||||
cacheKey := *newKey
|
cacheKey := *newKey
|
||||||
pubkeyCache.Add(cacheKey, copiedKey)
|
pubkeyLock.Lock()
|
||||||
|
pubkeyMap[cacheKey] = assertedKey
|
||||||
|
pubkeyLock.Unlock()
|
||||||
return pubKeyObj, nil
|
return pubKeyObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package blst_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls/blst"
|
"github.com/prysmaticlabs/prysm/v4/crypto/bls/blst"
|
||||||
@@ -98,26 +99,51 @@ func TestPublicKeysEmpty(t *testing.T) {
|
|||||||
require.ErrorContains(t, "nil or empty public keys", err)
|
require.ErrorContains(t, "nil or empty public keys", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPublicKeyMap(t *testing.T) {
|
||||||
|
priv, err := blst.RandKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
pubkeyA := priv.PublicKey().Marshal()
|
||||||
|
|
||||||
|
priv2, err := blst.RandKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
pubkeyB := priv2.PublicKey().Marshal()
|
||||||
|
km := blst.KeyMap()
|
||||||
|
_, ok := km[[48]byte(pubkeyA)]
|
||||||
|
require.Equal(t, false, ok, "pubkey a exists")
|
||||||
|
_, ok = km[[48]byte(pubkeyB)]
|
||||||
|
require.Equal(t, false, ok, "pubkey b exists")
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
_, err := blst.PublicKeyFromBytes(pubkeyA)
|
||||||
|
require.NoError(t, err)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
_, err := blst.PublicKeyFromBytes(pubkeyB)
|
||||||
|
require.NoError(t, err)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
km = blst.KeyMap()
|
||||||
|
_, ok = km[[48]byte(pubkeyA)]
|
||||||
|
require.Equal(t, true, ok, "pubkey a does not exist")
|
||||||
|
_, ok = km[[48]byte(pubkeyB)]
|
||||||
|
require.Equal(t, true, ok, "pubkey b does not exist")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkPublicKeyFromBytes(b *testing.B) {
|
func BenchmarkPublicKeyFromBytes(b *testing.B) {
|
||||||
priv, err := blst.RandKey()
|
priv, err := blst.RandKey()
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
pubkey := priv.PublicKey()
|
pubkey := priv.PublicKey()
|
||||||
pubkeyBytes := pubkey.Marshal()
|
pubkeyBytes := pubkey.Marshal()
|
||||||
|
|
||||||
b.Run("cache on", func(b *testing.B) {
|
for i := 0; i < b.N; i++ {
|
||||||
blst.EnableCaches()
|
_, err := blst.PublicKeyFromBytes(pubkeyBytes)
|
||||||
for i := 0; i < b.N; i++ {
|
require.NoError(b, err)
|
||||||
_, err := blst.PublicKeyFromBytes(pubkeyBytes)
|
}
|
||||||
require.NoError(b, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
b.Run("cache off", func(b *testing.B) {
|
|
||||||
blst.DisableCaches()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_, err := blst.PublicKeyFromBytes(pubkeyBytes)
|
|
||||||
require.NoError(b, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
package blst
|
package blst
|
||||||
|
|
||||||
// Note: These functions are for tests to access private globals, such as pubkeyCache.
|
// Note: These functions are for tests to access private globals, such as pubkeyMap.
|
||||||
|
|
||||||
// DisableCaches sets the cache sizes to 0.
|
// KeyMap returns the pubkey cache.
|
||||||
func DisableCaches() {
|
func KeyMap() map[[48]byte]*PublicKey {
|
||||||
pubkeyCache.Resize(0)
|
return pubkeyMap
|
||||||
}
|
|
||||||
|
|
||||||
// EnableCaches sets the cache sizes to the default values.
|
|
||||||
func EnableCaches() {
|
|
||||||
pubkeyCache.Resize(maxKeys)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user