-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2c5a2e8
commit 9ccd63c
Showing
9 changed files
with
134 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package state_native | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/prysmaticlabs/prysm/v5/config/features" | ||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" | ||
consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" | ||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" | ||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// validatorIndexCache maintains a mapping from validator public keys to their indices within the beacon state. | ||
// It includes a lastFinalizedIndex to track updates up to the last finalized validator index, | ||
// and uses a mutex for concurrent read/write access to the cache. | ||
type validatorIndexCache struct { | ||
indexMap map[[fieldparams.BLSPubkeyLength]byte]primitives.ValidatorIndex // Maps BLS public keys to validator indices. | ||
lastFinalizedIndex int // Index of the last finalized validator to avoid reading validators before this point. | ||
mutex sync.RWMutex | ||
} | ||
|
||
// newValidatorIndexCache initializes a new validator index cache with an empty index map. | ||
func newValidatorIndexCache() *validatorIndexCache { | ||
return &validatorIndexCache{ | ||
indexMap: make(map[[fieldparams.BLSPubkeyLength]byte]primitives.ValidatorIndex), | ||
} | ||
} | ||
|
||
// getValidatorIndex retrieves the validator index for a given public key from the cache. | ||
// If the public key is not found in the cache, it searches through the state starting from the last finalized index. | ||
func (b *BeaconState) getValidatorIndex(pubKey [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool) { | ||
b.validatorIndexCache.mutex.RLock() | ||
index, found := b.validatorIndexCache.indexMap[pubKey] | ||
b.validatorIndexCache.mutex.RUnlock() | ||
if found { | ||
return index, true | ||
} | ||
|
||
finalizedIndex := b.validatorIndexCache.lastFinalizedIndex | ||
pubKeys, err := b.publicKeysSinceIndexReadOnly(finalizedIndex) | ||
if err != nil { | ||
log.WithError(err).Errorf("Failed to get public keys since last finalized index %d", finalizedIndex) | ||
return 0, false | ||
} | ||
for i, key := range pubKeys { | ||
if key == pubKey { | ||
index := primitives.ValidatorIndex(finalizedIndex + i) | ||
return index, true | ||
} | ||
} | ||
return 0, false | ||
} | ||
|
||
// saveValidatorIndices updates the validator index cache with new indices. | ||
// It processes validator indices starting after the last finalized index and updates the tracker. | ||
func (b *BeaconState) saveValidatorIndices() { | ||
b.validatorIndexCache.mutex.Lock() | ||
defer b.validatorIndexCache.mutex.Unlock() | ||
|
||
finalizedIndex := b.validatorIndexCache.lastFinalizedIndex | ||
pubKeys, err := b.publicKeysSinceIndexReadOnly(finalizedIndex) | ||
if err != nil { | ||
log.WithError(err).Errorf("Failed to retrieve public keys starting from the last finalized index %d", finalizedIndex) | ||
return | ||
} | ||
for i, key := range pubKeys { | ||
b.validatorIndexCache.indexMap[key] = primitives.ValidatorIndex(finalizedIndex + i) | ||
} | ||
b.validatorIndexCache.lastFinalizedIndex += len(pubKeys) | ||
} | ||
|
||
// publicKeysSinceIndexReadOnly constructs a list of validator public keys starting from a specified index. | ||
// The indices in the returned list correspond to their respective validator indices in the state. | ||
// It returns an error if the specified index is out of bounds. This function is read-only and does not use locks. | ||
func (b *BeaconState) publicKeysSinceIndexReadOnly(index int) ([][fieldparams.BLSPubkeyLength]byte, error) { | ||
totalValidators := b.validatorsLen() | ||
if index >= totalValidators { | ||
return nil, errors.Wrapf(consensus_types.ErrOutOfBounds, "index %d is out of bounds %d", index, totalValidators) | ||
} | ||
result := make([][fieldparams.BLSPubkeyLength]byte, totalValidators-index) | ||
for i := index; i < totalValidators; i++ { | ||
var publicKey [fieldparams.BLSPubkeyLength]byte | ||
if features.Get().EnableExperimentalState { | ||
val, err := b.validatorsMultiValue.At(b, uint64(i)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
publicKey = bytesutil.ToBytes48(val.PublicKey) | ||
} else { | ||
publicKey = bytesutil.ToBytes48(b.validators[i].PublicKey) | ||
} | ||
result[i-index] = publicKey | ||
} | ||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters