Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions beacon_node/beacon_chain/src/light_client_server_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub struct LightClientServerCache<T: BeaconChainTypes> {
latest_written_current_sync_committee: RwLock<Option<Arc<SyncCommittee<T::EthSpec>>>>,
/// Caches state proofs by block root
prev_block_cache: Mutex<lru::LruCache<Hash256, LightClientCachedData<T::EthSpec>>>,
/// Tracks the latest broadcasted finality update
latest_broadcasted_finality_update: RwLock<Option<LightClientFinalityUpdate<T::EthSpec>>>,
/// Tracks the latest broadcasted optimistic update
latest_broadcasted_optimistic_update: RwLock<Option<LightClientOptimisticUpdate<T::EthSpec>>>,
}

impl<T: BeaconChainTypes> LightClientServerCache<T> {
Expand All @@ -49,6 +53,8 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
latest_optimistic_update: None.into(),
latest_light_client_update: None.into(),
latest_written_current_sync_committee: None.into(),
latest_broadcasted_finality_update: None.into(),
latest_broadcasted_optimistic_update: None.into(),
prev_block_cache: lru::LruCache::new(PREV_BLOCK_CACHE_SIZE).into(),
}
}
Expand Down Expand Up @@ -334,10 +340,65 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
Ok(new_value)
}

/// Checks if we've already broadcasted the latest finality update.
/// If we haven't, update the `latest_broadcasted_finality_update` cache
/// and return the latest finality update for broadcasting, else return `None`.
pub fn should_broadcast_latest_finality_update(
&self,
) -> Option<LightClientFinalityUpdate<T::EthSpec>> {
if let Some(latest_finality_update) = self.get_latest_finality_update() {
let latest_broadcasted_finality_update =
self.latest_broadcasted_finality_update.read().clone();
match latest_broadcasted_finality_update {
Some(latest_broadcasted_finality_update) => {
if latest_broadcasted_finality_update != latest_finality_update {
*self.latest_broadcasted_finality_update.write() =
Some(latest_finality_update.clone());
return Some(latest_finality_update);
}
}
None => {
*self.latest_broadcasted_finality_update.write() =
Some(latest_finality_update.clone());
return Some(latest_finality_update);
}
}
}

None
}

pub fn get_latest_finality_update(&self) -> Option<LightClientFinalityUpdate<T::EthSpec>> {
self.latest_finality_update.read().clone()
}

/// Checks if we've already broadcasted the latest optimistic update.
/// If we haven't, update the `latest_broadcasted_optimistic_update` cache
/// and return the latest optimistic update for broadcasting, else return `None`.
pub fn should_broadcast_latest_optimistic_update(
&self,
) -> Option<LightClientOptimisticUpdate<T::EthSpec>> {
if let Some(latest_optimistic_update) = self.get_latest_optimistic_update() {
let latest_broadcasted_optimistic_update = self.latest_optimistic_update.read().clone();
match latest_broadcasted_optimistic_update {
Some(latest_broadcasted_optimistic_update) => {
if latest_broadcasted_optimistic_update != latest_optimistic_update {
*self.latest_broadcasted_optimistic_update.write() =
Some(latest_optimistic_update.clone());
return Some(latest_optimistic_update);
}
}
None => {
*self.latest_broadcasted_optimistic_update.write() =
Some(latest_optimistic_update.clone());
return Some(latest_optimistic_update);
}
}
}

None
}

pub fn get_latest_optimistic_update(&self) -> Option<LightClientOptimisticUpdate<T::EthSpec>> {
self.latest_optimistic_update.read().clone()
}
Expand Down
32 changes: 32 additions & 0 deletions beacon_node/http_api/src/sync_committees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,38 @@ pub fn process_signed_contribution_and_proofs<T: BeaconChainTypes>(

let seen_timestamp = timestamp_now();

if let Some(latest_optimistic_update) = chain
.light_client_server_cache
.should_broadcast_latest_optimistic_update()
{
let _ = publish_pubsub_message(
&network_tx,
PubsubMessage::LightClientOptimisticUpdate(Box::new(latest_optimistic_update)),
)
.inspect_err(|e| {
error!(
error = ?e,
"Unable to broadcast latest light client optimistic update"
);
});
};

if let Some(latest_finality_update) = chain
.light_client_server_cache
.should_broadcast_latest_finality_update()
{
let _ = publish_pubsub_message(
&network_tx,
PubsubMessage::LightClientFinalityUpdate(Box::new(latest_finality_update)),
)
.inspect_err(|e| {
error!(
error = ?e,
"Unable to broadcast latest light client finality update"
);
});
};

// Verify contributions & broadcast to the network.
for (index, contribution) in signed_contribution_and_proofs.into_iter().enumerate() {
let aggregator_index = contribution.message.aggregator_index;
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/store/src/hot_cold_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3538,7 +3538,7 @@ pub fn get_ancestor_state_root<'a, E: EthSpec, Hot: ItemStore<E>, Cold: ItemStor
.get_cold_state_root(target_slot)
.map_err(Box::new)
.map_err(StateSummaryIteratorError::LoadStateRootError)?
.ok_or_else(|| StateSummaryIteratorError::MissingStateRoot {
.ok_or(StateSummaryIteratorError::MissingStateRoot {
target_slot,
state_upper_limit,
});
Expand Down