Store pubkey cache uncompressed

This commit is contained in:
Michael Sproul
2022-10-20 23:05:07 +11:00
parent 03fde98737
commit 2350a955e8
4 changed files with 45 additions and 16 deletions

View File

@@ -31,3 +31,4 @@ take-until = "0.1.0"
zstd = "0.11.0" zstd = "0.11.0"
strum = { version = "0.24.0", features = ["derive"] } strum = { version = "0.24.0", features = ["derive"] }
bls = { path = "../../crypto/bls" } bls = { path = "../../crypto/bls" }
smallvec = "1.0.0"

View File

@@ -1,5 +1,8 @@
use crate::{DBColumn, Error, HotColdDB, ItemStore, StoreItem}; use crate::{DBColumn, Error, HotColdDB, ItemStore, StoreItem};
use bls::PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN;
use smallvec::SmallVec;
use ssz::{Decode, Encode}; use ssz::{Decode, Encode};
use ssz_derive::{Decode, Encode};
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryInto; use std::convert::TryInto;
use std::marker::PhantomData; use std::marker::PhantomData;
@@ -64,16 +67,14 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> ValidatorPubkeyCache<E,
let mut validators = vec![]; let mut validators = vec![];
for validator_index in 0.. { for validator_index in 0.. {
if let Some(DatabaseValidator(validator)) = if let Some(db_validator) =
store.get_item(&DatabaseValidator::key_for_index(validator_index))? store.get_item(&DatabaseValidator::key_for_index(validator_index))?
{ {
pubkeys.push( let (pubkey, validator) =
(&validator.pubkey) DatabaseValidator::into_immutable_validator(&db_validator)?;
.try_into() pubkeys.push(pubkey);
.map_err(|e| Error::ValidatorPubkeyCacheError(format!("{:?}", e)))?,
);
indices.insert(validator.pubkey, validator_index); indices.insert(validator.pubkey, validator_index);
validators.push(validator); validators.push(Arc::new(validator));
} else { } else {
break; break;
} }
@@ -125,6 +126,10 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> ValidatorPubkeyCache<E,
return Err(Error::DuplicateValidatorPublicKey); return Err(Error::DuplicateValidatorPublicKey);
} }
let pubkey = (&validator.pubkey)
.try_into()
.map_err(Error::InvalidValidatorPubkeyBytes)?;
// The item is written to disk _before_ it is written into // The item is written to disk _before_ it is written into
// the local struct. // the local struct.
// //
@@ -136,14 +141,10 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> ValidatorPubkeyCache<E,
// that are never referenced in a state. // that are never referenced in a state.
store.put_item( store.put_item(
&DatabaseValidator::key_for_index(i), &DatabaseValidator::key_for_index(i),
&DatabaseValidator(validator.clone()), &DatabaseValidator::from_immutable_validator(&pubkey, &validator),
)?; )?;
self.pubkeys.push( self.pubkeys.push(pubkey);
(&validator.pubkey)
.try_into()
.map_err(Error::InvalidValidatorPubkeyBytes)?,
);
self.indices.insert(validator.pubkey, i); self.indices.insert(validator.pubkey, i);
self.validators.push(validator); self.validators.push(validator);
} }
@@ -190,7 +191,11 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> ValidatorPubkeyCache<E,
/// Wrapper for a public key stored in the database. /// Wrapper for a public key stored in the database.
/// ///
/// Keyed by the validator index as `Hash256::from_low_u64_be(index)`. /// Keyed by the validator index as `Hash256::from_low_u64_be(index)`.
struct DatabaseValidator(Arc<ValidatorImmutable>); #[derive(Encode, Decode)]
struct DatabaseValidator {
pubkey: SmallVec<[u8; PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN]>,
withdrawal_credentials: Hash256,
}
impl StoreItem for DatabaseValidator { impl StoreItem for DatabaseValidator {
fn db_column() -> DBColumn { fn db_column() -> DBColumn {
@@ -198,11 +203,11 @@ impl StoreItem for DatabaseValidator {
} }
fn as_store_bytes(&self) -> Result<Vec<u8>, Error> { fn as_store_bytes(&self) -> Result<Vec<u8>, Error> {
Ok(self.0.as_ssz_bytes()) Ok(self.as_ssz_bytes())
} }
fn from_store_bytes(bytes: &[u8]) -> Result<Self, Error> { fn from_store_bytes(bytes: &[u8]) -> Result<Self, Error> {
Ok(Self(Arc::new(ValidatorImmutable::from_ssz_bytes(bytes)?))) Ok(Self::from_ssz_bytes(bytes)?)
} }
} }
@@ -210,6 +215,27 @@ impl DatabaseValidator {
fn key_for_index(index: usize) -> Hash256 { fn key_for_index(index: usize) -> Hash256 {
Hash256::from_low_u64_be(index as u64) Hash256::from_low_u64_be(index as u64)
} }
fn from_immutable_validator(pubkey: &PublicKey, validator: &ValidatorImmutable) -> Self {
DatabaseValidator {
pubkey: pubkey.serialize_uncompressed().into(),
withdrawal_credentials: validator.withdrawal_credentials,
}
}
fn into_immutable_validator(&self) -> Result<(PublicKey, ValidatorImmutable), Error> {
let pubkey = PublicKey::deserialize_uncompressed(&self.pubkey)
.map_err(Error::InvalidValidatorPubkeyBytes)?;
let pubkey_bytes = pubkey.compress();
let withdrawal_credentials = self.withdrawal_credentials;
Ok((
pubkey,
ValidatorImmutable {
pubkey: pubkey_bytes,
withdrawal_credentials,
},
))
}
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -407,6 +407,7 @@ impl_for_vec!(SmallVec<[T; 5]>, None);
impl_for_vec!(SmallVec<[T; 6]>, None); impl_for_vec!(SmallVec<[T; 6]>, None);
impl_for_vec!(SmallVec<[T; 7]>, None); impl_for_vec!(SmallVec<[T; 7]>, None);
impl_for_vec!(SmallVec<[T; 8]>, None); impl_for_vec!(SmallVec<[T; 8]>, None);
impl_for_vec!(SmallVec<[T; 96]>, None);
impl<K, V> Decode for BTreeMap<K, V> impl<K, V> Decode for BTreeMap<K, V>
where where

View File

@@ -307,6 +307,7 @@ impl_for_vec!(SmallVec<[T; 5]>);
impl_for_vec!(SmallVec<[T; 6]>); impl_for_vec!(SmallVec<[T; 6]>);
impl_for_vec!(SmallVec<[T; 7]>); impl_for_vec!(SmallVec<[T; 7]>);
impl_for_vec!(SmallVec<[T; 8]>); impl_for_vec!(SmallVec<[T; 8]>);
impl_for_vec!(SmallVec<[T; 96]>);
impl<K, V> Encode for BTreeMap<K, V> impl<K, V> Encode for BTreeMap<K, V>
where where