Skip to content

Commit 82ca8fb

Browse files
committed
ignore rebroadcasting lc data in certain circumstances
1 parent 7b861ac commit 82ca8fb

File tree

4 files changed

+97
-11
lines changed

4 files changed

+97
-11
lines changed

beacon_node/beacon_chain/src/light_client_finality_update_verification.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub enum Error {
2727
SigSlotStartIsNone,
2828
/// Failed to construct a LightClientFinalityUpdate from state.
2929
FailedConstructingUpdate,
30+
/// Silently ignore this light client finality update
31+
Ignore,
3032
}
3133

3234
/// Wraps a `LightClientFinalityUpdate` that has been verified for propagation on the gossip network.
@@ -57,16 +59,46 @@ impl<T: BeaconChainTypes> VerifiedLightClientFinalityUpdate<T> {
5759
return Err(Error::TooEarly);
5860
}
5961

62+
if let Some(latest_broadcasted_finality_update) = chain
63+
.light_client_server_cache
64+
.get_latest_broadcasted_finality_update()
65+
{
66+
// Ignore the incoming finality update if we've already broadcasted it
67+
if latest_broadcasted_finality_update == rcv_finality_update {
68+
return Err(Error::Ignore);
69+
}
70+
71+
// Ignore the incoming finality update if the latest broadcasted attested header slot
72+
// is greater than the incoming attested header slot.
73+
if latest_broadcasted_finality_update.get_attested_header_slot()
74+
> rcv_finality_update.get_attested_header_slot()
75+
{
76+
return Err(Error::Ignore);
77+
}
78+
}
79+
6080
let latest_finality_update = chain
6181
.light_client_server_cache
6282
.get_latest_finality_update()
6383
.ok_or(Error::FailedConstructingUpdate)?;
6484

85+
// Ignore the incoming finality update if the latest constructed attested header slot
86+
// is greater than the incoming attested header slot.
87+
if latest_finality_update.get_attested_header_slot()
88+
> rcv_finality_update.get_attested_header_slot()
89+
{
90+
return Err(Error::Ignore);
91+
}
92+
6593
// verify that the gossiped finality update is the same as the locally constructed one.
6694
if latest_finality_update != rcv_finality_update {
6795
return Err(Error::InvalidLightClientFinalityUpdate);
6896
}
6997

98+
chain
99+
.light_client_server_cache
100+
.set_latest_broadcasted_finality_update(rcv_finality_update.clone());
101+
70102
Ok(Self {
71103
light_client_finality_update: rcv_finality_update,
72104
seen_timestamp,

beacon_node/beacon_chain/src/light_client_optimistic_update_verification.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub enum Error {
3030
FailedConstructingUpdate,
3131
/// Unknown block with parent root.
3232
UnknownBlockParentRoot(Hash256),
33+
/// Silently ignore this light client optimistic update
34+
Ignore,
3335
}
3436

3537
/// Wraps a `LightClientOptimisticUpdate` that has been verified for propagation on the gossip network.
@@ -61,6 +63,22 @@ impl<T: BeaconChainTypes> VerifiedLightClientOptimisticUpdate<T> {
6163
return Err(Error::TooEarly);
6264
}
6365

66+
if let Some(latest_broadcasted_optimistic_update) = chain
67+
.light_client_server_cache
68+
.get_latest_broadcasted_optimistic_update()
69+
{
70+
// Ignore the incoming optimistic update if we've already broadcasted it
71+
if latest_broadcasted_optimistic_update == rcv_optimistic_update {
72+
return Err(Error::Ignore);
73+
}
74+
75+
// Ignore the incoming optimistic update if the latest broadcasted slot
76+
// is greater than the incoming slot.
77+
if latest_broadcasted_optimistic_update.get_slot() > rcv_optimistic_update.get_slot() {
78+
return Err(Error::Ignore);
79+
}
80+
}
81+
6482
let head = chain.canonical_head.cached_head();
6583
let head_block = &head.snapshot.beacon_block;
6684
// check if we can process the optimistic update immediately
@@ -76,11 +94,21 @@ impl<T: BeaconChainTypes> VerifiedLightClientOptimisticUpdate<T> {
7694
.get_latest_optimistic_update()
7795
.ok_or(Error::FailedConstructingUpdate)?;
7896

97+
// Ignore the incoming optimistic update if the latest constructed slot
98+
// is greater than the incoming slot.
99+
if latest_optimistic_update.get_slot() > rcv_optimistic_update.get_slot() {
100+
return Err(Error::Ignore);
101+
}
102+
79103
// verify that the gossiped optimistic update is the same as the locally constructed one.
80104
if latest_optimistic_update != rcv_optimistic_update {
81105
return Err(Error::InvalidLightClientOptimisticUpdate);
82106
}
83107

108+
chain
109+
.light_client_server_cache
110+
.set_latest_broadcasted_optimistic_update(rcv_optimistic_update.clone());
111+
84112
let parent_root = rcv_optimistic_update.get_parent_root();
85113
Ok(Self {
86114
light_client_optimistic_update: rcv_optimistic_update,

beacon_node/beacon_chain/src/light_client_server_cache.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,16 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
347347
&self,
348348
) -> Option<LightClientFinalityUpdate<T::EthSpec>> {
349349
if let Some(latest_finality_update) = self.get_latest_finality_update() {
350-
let latest_broadcasted_finality_update =
351-
self.latest_broadcasted_finality_update.read().clone();
350+
let latest_broadcasted_finality_update = self.get_latest_broadcasted_finality_update();
352351
match latest_broadcasted_finality_update {
353352
Some(latest_broadcasted_finality_update) => {
354353
if latest_broadcasted_finality_update != latest_finality_update {
355-
*self.latest_broadcasted_finality_update.write() =
356-
Some(latest_finality_update.clone());
354+
self.set_latest_broadcasted_finality_update(latest_finality_update.clone());
357355
return Some(latest_finality_update);
358356
}
359357
}
360358
None => {
361-
*self.latest_broadcasted_finality_update.write() =
362-
Some(latest_finality_update.clone());
359+
self.set_latest_broadcasted_finality_update(latest_finality_update.clone());
363360
return Some(latest_finality_update);
364361
}
365362
}
@@ -372,25 +369,52 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
372369
self.latest_finality_update.read().clone()
373370
}
374371

372+
pub fn get_latest_broadcasted_optimistic_update(
373+
&self,
374+
) -> Option<LightClientOptimisticUpdate<T::EthSpec>> {
375+
self.latest_broadcasted_optimistic_update.read().clone()
376+
}
377+
378+
pub fn get_latest_broadcasted_finality_update(
379+
&self,
380+
) -> Option<LightClientFinalityUpdate<T::EthSpec>> {
381+
self.latest_broadcasted_finality_update.read().clone()
382+
}
383+
384+
pub fn set_latest_broadcasted_optimistic_update(
385+
&self,
386+
optimistic_update: LightClientOptimisticUpdate<T::EthSpec>,
387+
) {
388+
*self.latest_broadcasted_optimistic_update.write() = Some(optimistic_update.clone());
389+
}
390+
391+
pub fn set_latest_broadcasted_finality_update(
392+
&self,
393+
finality_update: LightClientFinalityUpdate<T::EthSpec>,
394+
) {
395+
*self.latest_broadcasted_finality_update.write() = Some(finality_update.clone());
396+
}
397+
375398
/// Checks if we've already broadcasted the latest optimistic update.
376399
/// If we haven't, update the `latest_broadcasted_optimistic_update` cache
377400
/// and return the latest optimistic update for broadcasting, else return `None`.
378401
pub fn should_broadcast_latest_optimistic_update(
379402
&self,
380403
) -> Option<LightClientOptimisticUpdate<T::EthSpec>> {
381404
if let Some(latest_optimistic_update) = self.get_latest_optimistic_update() {
382-
let latest_broadcasted_optimistic_update = self.latest_optimistic_update.read().clone();
405+
let latest_broadcasted_optimistic_update =
406+
self.get_latest_broadcasted_optimistic_update();
383407
match latest_broadcasted_optimistic_update {
384408
Some(latest_broadcasted_optimistic_update) => {
385409
if latest_broadcasted_optimistic_update != latest_optimistic_update {
386-
*self.latest_broadcasted_optimistic_update.write() =
387-
Some(latest_optimistic_update.clone());
410+
self.set_latest_broadcasted_optimistic_update(
411+
latest_optimistic_update.clone(),
412+
);
388413
return Some(latest_optimistic_update);
389414
}
390415
}
391416
None => {
392-
*self.latest_broadcasted_optimistic_update.write() =
393-
Some(latest_optimistic_update.clone());
417+
self.set_latest_broadcasted_optimistic_update(latest_optimistic_update.clone());
394418
return Some(latest_optimistic_update);
395419
}
396420
}

beacon_node/network/src/network_beacon_processor/gossip_methods.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
19981998
error = ?e,
19991999
"Light client error constructing finality update"
20002000
),
2001+
LightClientFinalityUpdateError::Ignore => {}
20012002
}
20022003
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
20032004
}
@@ -2118,6 +2119,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
21182119
"Light client error constructing optimistic update"
21192120
)
21202121
}
2122+
LightClientOptimisticUpdateError::Ignore => {}
21212123
}
21222124
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
21232125
}

0 commit comments

Comments
 (0)