Skip to content

Commit f68e8f0

Browse files
authored
feat: Add signature_slot in light client finality and optimistic content keys (#896)
1 parent 902ae6c commit f68e8f0

File tree

2 files changed

+62
-57
lines changed

2 files changed

+62
-57
lines changed

ethportal-api/src/types/content_key/beacon.rs

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,8 @@ use std::fmt;
1313
pub enum BeaconContentKey {
1414
LightClientBootstrap(LightClientBootstrapKey),
1515
LightClientUpdatesByRange(LightClientUpdatesByRangeKey),
16-
LightClientFinalityUpdate(ZeroKey),
17-
LightClientOptimisticUpdate(ZeroKey),
18-
}
19-
20-
/// Represents a zero ssz bytes for a portal content key.
21-
#[derive(Clone, Debug, PartialEq, Eq)]
22-
pub struct ZeroKey;
23-
24-
impl Encode for ZeroKey {
25-
fn is_ssz_fixed_len() -> bool {
26-
true
27-
}
28-
29-
fn ssz_bytes_len(&self) -> usize {
30-
8
31-
}
32-
33-
fn ssz_append(&self, buf: &mut Vec<u8>) {
34-
buf.extend_from_slice(&[0u8; 8]);
35-
}
36-
}
37-
38-
impl Decode for ZeroKey {
39-
fn is_ssz_fixed_len() -> bool {
40-
true
41-
}
42-
43-
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
44-
if bytes.len() != 8 {
45-
return Err(ssz::DecodeError::InvalidByteLength {
46-
len: bytes.len(),
47-
expected: 8,
48-
});
49-
}
50-
if bytes != [0u8; 8] {
51-
return Err(ssz::DecodeError::BytesInvalid(
52-
"ZeroKey Bytes should be all 0".to_string(),
53-
));
54-
}
55-
56-
Ok(Self)
57-
}
16+
LightClientFinalityUpdate(LightClientFinalityUpdateKey),
17+
LightClientOptimisticUpdate(LightClientOptimisticUpdateKey),
5818
}
5919

6020
/// Key used to identify a light client bootstrap.
@@ -73,6 +33,32 @@ pub struct LightClientUpdatesByRangeKey {
7333
pub count: u64,
7434
}
7535

36+
/// Key used to identify a light client finality update.
37+
#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq)]
38+
pub struct LightClientFinalityUpdateKey {
39+
/// Finalized slot number
40+
pub signature_slot: u64,
41+
}
42+
43+
impl LightClientFinalityUpdateKey {
44+
pub fn new(signature_slot: u64) -> Self {
45+
Self { signature_slot }
46+
}
47+
}
48+
49+
/// Key used to identify a light client optimistic update.
50+
#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq)]
51+
pub struct LightClientOptimisticUpdateKey {
52+
/// Optimistic slot number
53+
pub signature_slot: u64,
54+
}
55+
56+
impl LightClientOptimisticUpdateKey {
57+
pub fn new(signature_slot: u64) -> Self {
58+
Self { signature_slot }
59+
}
60+
}
61+
7662
impl From<&BeaconContentKey> for Vec<u8> {
7763
fn from(val: &BeaconContentKey) -> Self {
7864
val.as_ssz_bytes()
@@ -107,8 +93,14 @@ impl fmt::Display for BeaconContentKey {
10793
"LightClientUpdatesByRange {{ start_period: {}, count: {} }}",
10894
key.start_period, key.count
10995
),
110-
Self::LightClientFinalityUpdate(_) => "LightClientFinalityUpdate".to_string(),
111-
Self::LightClientOptimisticUpdate(_) => "LightClientOptimisticUpdate".to_string(),
96+
Self::LightClientFinalityUpdate(key) => format!(
97+
"LightClientFinalityUpdate {{ signature_slot: {} }}",
98+
key.signature_slot
99+
),
100+
Self::LightClientOptimisticUpdate(key) => format!(
101+
"LightClientOptimisticUpdate {{ signature_slot: {} }}",
102+
key.signature_slot
103+
),
112104
};
113105

114106
write!(f, "{s}")
@@ -137,11 +129,11 @@ impl OverlayContentKey for BeaconContentKey {
137129
}
138130
BeaconContentKey::LightClientFinalityUpdate(key) => {
139131
bytes.push(0x02);
140-
bytes.extend_from_slice(&key.as_ssz_bytes())
132+
bytes.extend_from_slice(&key.signature_slot.as_ssz_bytes())
141133
}
142134
BeaconContentKey::LightClientOptimisticUpdate(key) => {
143135
bytes.push(0x03);
144-
bytes.extend_from_slice(&key.as_ssz_bytes())
136+
bytes.extend_from_slice(&key.signature_slot.as_ssz_bytes())
145137
}
146138
}
147139

@@ -237,25 +229,32 @@ mod test {
237229

238230
#[test]
239231
fn light_client_finality_update() {
240-
const KEY_STR: &str = "0x020000000000000000";
232+
const KEY_STR: &str = "0x02c2f36e0000000000";
241233
let expected_content_key = hex_decode(KEY_STR).unwrap();
242-
243-
let content_key = BeaconContentKey::LightClientFinalityUpdate(ZeroKey);
234+
let content_key =
235+
BeaconContentKey::LightClientFinalityUpdate(LightClientFinalityUpdateKey::new(7271362));
244236

245237
assert_eq!(content_key.to_bytes(), expected_content_key);
246-
assert_eq!(content_key.to_string(), "LightClientFinalityUpdate");
238+
assert_eq!(
239+
content_key.to_string(),
240+
"LightClientFinalityUpdate { signature_slot: 7271362 }"
241+
);
247242
assert_eq!(content_key.to_hex(), KEY_STR);
248243
}
249244

250245
#[test]
251246
fn light_client_optimistic_update() {
252-
const KEY_STR: &str = "0x030000000000000000";
247+
const KEY_STR: &str = "0x03c2f36e0000000000";
253248
let expected_content_key = hex_decode(KEY_STR).unwrap();
254-
255-
let content_key = BeaconContentKey::LightClientOptimisticUpdate(ZeroKey);
249+
let content_key = BeaconContentKey::LightClientOptimisticUpdate(
250+
LightClientOptimisticUpdateKey::new(7271362),
251+
);
256252

257253
assert_eq!(content_key.to_bytes(), expected_content_key);
258-
assert_eq!(content_key.to_string(), "LightClientOptimisticUpdate");
254+
assert_eq!(
255+
content_key.to_string(),
256+
"LightClientOptimisticUpdate { signature_slot: 7271362 }"
257+
);
259258
assert_eq!(content_key.to_hex(), KEY_STR);
260259
}
261260
}

portal-bridge/src/beacon_bridge.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use ethportal_api::types::consensus::light_client::optimistic_update::LightClien
1212
use ethportal_api::types::consensus::light_client::update::{
1313
LightClientUpdate, LightClientUpdateCapella,
1414
};
15-
use ethportal_api::types::content_key::beacon::ZeroKey;
1615
use ethportal_api::types::content_value::beacon::{
1716
ForkVersionedLightClientUpdate, LightClientUpdatesByRange,
1817
};
@@ -30,6 +29,9 @@ use std::sync::Arc;
3029
use std::time::SystemTime;
3130
use tracing::{info, warn};
3231

32+
use ethportal_api::types::content_key::beacon::{
33+
LightClientFinalityUpdateKey, LightClientOptimisticUpdateKey,
34+
};
3335
use tokio::time::{interval, sleep, Duration, MissedTickBehavior};
3436

3537
pub struct BeaconBridge {
@@ -285,8 +287,10 @@ impl BeaconBridge {
285287
"Got lc optimistic update for slot {:?}",
286288
update.attested_header.beacon.slot
287289
);
290+
let content_key = BeaconContentKey::LightClientOptimisticUpdate(
291+
LightClientOptimisticUpdateKey::new(update.signature_slot),
292+
);
288293
let content_value = BeaconContentValue::LightClientOptimisticUpdate(update.into());
289-
let content_key = BeaconContentKey::LightClientOptimisticUpdate(ZeroKey);
290294

291295
Self::gossip_beacon_content(portal_clients, content_key, content_value).await
292296
}
@@ -303,8 +307,10 @@ impl BeaconBridge {
303307
"Got lc finality update for slot {:?}",
304308
update.attested_header.beacon.slot
305309
);
310+
let content_key = BeaconContentKey::LightClientFinalityUpdate(
311+
LightClientFinalityUpdateKey::new(update.signature_slot),
312+
);
306313
let content_value = BeaconContentValue::LightClientFinalityUpdate(update.into());
307-
let content_key = BeaconContentKey::LightClientFinalityUpdate(ZeroKey);
308314

309315
Self::gossip_beacon_content(portal_clients, content_key, content_value).await
310316
}

0 commit comments

Comments
 (0)