Skip to content

Commit d223840

Browse files
committed
Merge branch 'release-v7.0.0' of https://github.com/sigp/lighthouse into gossip-light-client-updates
2 parents 75f00af + 522b3cb commit d223840

File tree

40 files changed

+251
-155
lines changed

40 files changed

+251
-155
lines changed

.github/workflows/test-suite.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ env:
1919
# Disable debug info (see https://github.com/sigp/lighthouse/issues/4005)
2020
RUSTFLAGS: "-D warnings -C debuginfo=0"
2121
# Prevent Github API rate limiting.
22-
LIGHTHOUSE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
# NOTE: this token is a personal access token on Jimmy's account due to the default GITHUB_TOKEN
23+
# not having access to other repositories. We should eventually devise a better solution here.
24+
LIGHTHOUSE_GITHUB_TOKEN: ${{ secrets.LIGHTHOUSE_GITHUB_TOKEN }}
2325
# Enable self-hosted runners for the sigp repo only.
2426
SELF_HOSTED_RUNNERS: ${{ github.repository == 'sigp/lighthouse' }}
2527
# Self-hosted runners need to reference a different host for `./watch` tests.

beacon_node/beacon_chain/src/attestation_verification.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,19 +1450,17 @@ where
14501450
return Err(Error::UnknownTargetRoot(target.root));
14511451
}
14521452

1453-
chain
1454-
.with_committee_cache(target.root, attestation_epoch, |committee_cache, _| {
1455-
let committees_per_slot = committee_cache.committees_per_slot();
1456-
1457-
Ok(committee_cache
1458-
.get_beacon_committees_at_slot(attestation.data().slot)
1459-
.map(|committees| map_fn((committees, committees_per_slot)))
1460-
.unwrap_or_else(|_| {
1461-
Err(Error::NoCommitteeForSlotAndIndex {
1462-
slot: attestation.data().slot,
1463-
index: attestation.committee_index().unwrap_or(0),
1464-
})
1465-
}))
1466-
})
1467-
.map_err(BeaconChainError::from)?
1453+
chain.with_committee_cache(target.root, attestation_epoch, |committee_cache, _| {
1454+
let committees_per_slot = committee_cache.committees_per_slot();
1455+
1456+
Ok(committee_cache
1457+
.get_beacon_committees_at_slot(attestation.data().slot)
1458+
.map(|committees| map_fn((committees, committees_per_slot)))
1459+
.unwrap_or_else(|_| {
1460+
Err(Error::NoCommitteeForSlotAndIndex {
1461+
slot: attestation.data().slot,
1462+
index: attestation.committee_index().unwrap_or(0),
1463+
})
1464+
}))
1465+
})?
14681466
}

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6506,9 +6506,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
65066506

65076507
/// Returns `true` if the given slot is prior to the `bellatrix_fork_epoch`.
65086508
pub fn slot_is_prior_to_bellatrix(&self, slot: Slot) -> bool {
6509-
self.spec.bellatrix_fork_epoch.map_or(true, |bellatrix| {
6510-
slot.epoch(T::EthSpec::slots_per_epoch()) < bellatrix
6511-
})
6509+
self.spec
6510+
.bellatrix_fork_epoch
6511+
.is_none_or(|bellatrix| slot.epoch(T::EthSpec::slots_per_epoch()) < bellatrix)
65126512
}
65136513

65146514
/// Returns the value of `execution_optimistic` for `block`.

beacon_node/beacon_chain/src/block_times_cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl BlockTimesCache {
173173
if block_times
174174
.timestamps
175175
.all_blobs_observed
176-
.map_or(true, |prev| timestamp > prev)
176+
.is_none_or(|prev| timestamp > prev)
177177
{
178178
block_times.timestamps.all_blobs_observed = Some(timestamp);
179179
}
@@ -195,7 +195,7 @@ impl BlockTimesCache {
195195
.entry(block_root)
196196
.or_insert_with(|| BlockTimesCacheValue::new(slot));
197197
let existing_timestamp = field(&mut block_times.timestamps);
198-
if existing_timestamp.map_or(true, |prev| timestamp < prev) {
198+
if existing_timestamp.is_none_or(|prev| timestamp < prev) {
199199
*existing_timestamp = Some(timestamp);
200200
}
201201
}

beacon_node/beacon_chain/src/data_availability_checker/overflow_lru_cache.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ impl<E: EthSpec> PendingComponents<E> {
307307
.map(|b| b.map(|b| b.to_blob()))
308308
.take(num_blobs_expected)
309309
.collect::<Option<Vec<_>>>()
310-
.map(Into::into)
311310
else {
312311
return Err(AvailabilityCheckError::Unexpected);
313312
};

beacon_node/beacon_chain/src/shuffling_cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl ShufflingCache {
138138
.get(&key)
139139
// Replace the committee if it's not present or if it's a promise. A bird in the hand is
140140
// worth two in the promise-bush!
141-
.map_or(true, CacheItem::is_promise)
141+
.is_none_or(CacheItem::is_promise)
142142
{
143143
self.insert_cache_item(
144144
key,

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ where
779779
SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap(),
780780
None,
781781
None,
782+
false,
782783
)
783784
.unwrap();
784785

beacon_node/beacon_chain/src/validator_monitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ impl<E: EthSpec> ValidatorMonitor<E> {
628628
// the proposer shuffling cache lock when there are lots of missed blocks.
629629
if proposers_per_epoch
630630
.as_ref()
631-
.map_or(true, |(_, cached_epoch)| *cached_epoch != slot_epoch)
631+
.is_none_or(|(_, cached_epoch)| *cached_epoch != slot_epoch)
632632
{
633633
proposers_per_epoch = self
634634
.get_proposers_by_epoch_from_cache(

beacon_node/builder_client/src/lib.rs

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ pub const DEFAULT_GET_HEADER_TIMEOUT_MILLIS: u64 = 1000;
2929
/// Default user agent for HTTP requests.
3030
pub const DEFAULT_USER_AGENT: &str = lighthouse_version::VERSION;
3131

32+
/// The value we set on the `ACCEPT` http header to indicate a preference for ssz response.
33+
pub const PREFERENCE_ACCEPT_VALUE: &str = "application/octet-stream;q=1.0,application/json;q=0.9";
34+
/// Only accept json responses.
35+
pub const JSON_ACCEPT_VALUE: &str = "application/json";
36+
3237
#[derive(Clone)]
3338
pub struct Timeouts {
3439
get_header: Duration,
@@ -57,14 +62,20 @@ pub struct BuilderHttpClient {
5762
server: SensitiveUrl,
5863
timeouts: Timeouts,
5964
user_agent: String,
60-
ssz_enabled: Arc<AtomicBool>,
65+
/// Only use json for all requests/responses types.
66+
disable_ssz: bool,
67+
/// Indicates that the `get_header` response had content-type ssz
68+
/// so we can set content-type header to ssz to make the `submit_blinded_blocks`
69+
/// request.
70+
ssz_available: Arc<AtomicBool>,
6171
}
6272

6373
impl BuilderHttpClient {
6474
pub fn new(
6575
server: SensitiveUrl,
6676
user_agent: Option<String>,
6777
builder_header_timeout: Option<Duration>,
78+
disable_ssz: bool,
6879
) -> Result<Self, Error> {
6980
let user_agent = user_agent.unwrap_or(DEFAULT_USER_AGENT.to_string());
7081
let client = reqwest::Client::builder().user_agent(&user_agent).build()?;
@@ -73,7 +84,8 @@ impl BuilderHttpClient {
7384
server,
7485
timeouts: Timeouts::new(builder_header_timeout),
7586
user_agent,
76-
ssz_enabled: Arc::new(false.into()),
87+
disable_ssz,
88+
ssz_available: Arc::new(false.into()),
7789
})
7890
}
7991

@@ -124,15 +136,15 @@ impl BuilderHttpClient {
124136

125137
let Ok(Some(fork_name)) = self.fork_name_from_header(&headers) else {
126138
// if no fork version specified, attempt to fallback to JSON
127-
self.ssz_enabled.store(false, Ordering::SeqCst);
139+
self.ssz_available.store(false, Ordering::SeqCst);
128140
return serde_json::from_slice(&response_bytes).map_err(Error::InvalidJson);
129141
};
130142

131143
let content_type = self.content_type_from_header(&headers);
132144

133145
match content_type {
134146
ContentType::Ssz => {
135-
self.ssz_enabled.store(true, Ordering::SeqCst);
147+
self.ssz_available.store(true, Ordering::SeqCst);
136148
T::from_ssz_bytes_by_fork(&response_bytes, fork_name)
137149
.map(|data| ForkVersionedResponse {
138150
version: Some(fork_name),
@@ -142,15 +154,17 @@ impl BuilderHttpClient {
142154
.map_err(Error::InvalidSsz)
143155
}
144156
ContentType::Json => {
145-
self.ssz_enabled.store(false, Ordering::SeqCst);
157+
self.ssz_available.store(false, Ordering::SeqCst);
146158
serde_json::from_slice(&response_bytes).map_err(Error::InvalidJson)
147159
}
148160
}
149161
}
150162

151163
/// Return `true` if the most recently received response from the builder had SSZ Content-Type.
152-
pub fn is_ssz_enabled(&self) -> bool {
153-
self.ssz_enabled.load(Ordering::SeqCst)
164+
/// Return `false` otherwise.
165+
/// Also returns `false` if we have explicitly disabled ssz.
166+
pub fn is_ssz_available(&self) -> bool {
167+
!self.disable_ssz && self.ssz_available.load(Ordering::SeqCst)
154168
}
155169

156170
async fn get_with_timeout<T: DeserializeOwned, U: IntoUrl>(
@@ -213,19 +227,14 @@ impl BuilderHttpClient {
213227
&self,
214228
url: U,
215229
ssz_body: Vec<u8>,
216-
mut headers: HeaderMap,
230+
headers: HeaderMap,
217231
timeout: Option<Duration>,
218232
) -> Result<Response, Error> {
219233
let mut builder = self.client.post(url);
220234
if let Some(timeout) = timeout {
221235
builder = builder.timeout(timeout);
222236
}
223237

224-
headers.insert(
225-
CONTENT_TYPE_HEADER,
226-
HeaderValue::from_static(SSZ_CONTENT_TYPE_HEADER),
227-
);
228-
229238
let response = builder
230239
.headers(headers)
231240
.body(ssz_body)
@@ -292,9 +301,21 @@ impl BuilderHttpClient {
292301
.push("blinded_blocks");
293302

294303
let mut headers = HeaderMap::new();
295-
if let Ok(value) = HeaderValue::from_str(&blinded_block.fork_name_unchecked().to_string()) {
296-
headers.insert(CONSENSUS_VERSION_HEADER, value);
297-
}
304+
headers.insert(
305+
CONSENSUS_VERSION_HEADER,
306+
HeaderValue::from_str(&blinded_block.fork_name_unchecked().to_string())
307+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
308+
);
309+
headers.insert(
310+
CONTENT_TYPE_HEADER,
311+
HeaderValue::from_str(SSZ_CONTENT_TYPE_HEADER)
312+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
313+
);
314+
headers.insert(
315+
ACCEPT,
316+
HeaderValue::from_str(PREFERENCE_ACCEPT_VALUE)
317+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
318+
);
298319

299320
let result = self
300321
.post_ssz_with_raw_response(
@@ -326,9 +347,21 @@ impl BuilderHttpClient {
326347
.push("blinded_blocks");
327348

328349
let mut headers = HeaderMap::new();
329-
if let Ok(value) = HeaderValue::from_str(&blinded_block.fork_name_unchecked().to_string()) {
330-
headers.insert(CONSENSUS_VERSION_HEADER, value);
331-
}
350+
headers.insert(
351+
CONSENSUS_VERSION_HEADER,
352+
HeaderValue::from_str(&blinded_block.fork_name_unchecked().to_string())
353+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
354+
);
355+
headers.insert(
356+
CONTENT_TYPE_HEADER,
357+
HeaderValue::from_str(JSON_CONTENT_TYPE_HEADER)
358+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
359+
);
360+
headers.insert(
361+
ACCEPT,
362+
HeaderValue::from_str(JSON_ACCEPT_VALUE)
363+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
364+
);
332365

333366
Ok(self
334367
.post_with_raw_response(
@@ -362,12 +395,20 @@ impl BuilderHttpClient {
362395
.push(pubkey.as_hex_string().as_str());
363396

364397
let mut headers = HeaderMap::new();
365-
if let Ok(ssz_content_type_header) = HeaderValue::from_str(&format!(
366-
"{}; q=1.0,{}; q=0.9",
367-
SSZ_CONTENT_TYPE_HEADER, JSON_CONTENT_TYPE_HEADER
368-
)) {
369-
headers.insert(ACCEPT, ssz_content_type_header);
370-
};
398+
if self.disable_ssz {
399+
headers.insert(
400+
ACCEPT,
401+
HeaderValue::from_str(JSON_CONTENT_TYPE_HEADER)
402+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
403+
);
404+
} else {
405+
// Indicate preference for ssz response in the accept header
406+
headers.insert(
407+
ACCEPT,
408+
HeaderValue::from_str(PREFERENCE_ACCEPT_VALUE)
409+
.map_err(|e| Error::InvalidHeaders(format!("{}", e)))?,
410+
);
411+
}
371412

372413
let resp = self
373414
.get_with_header(path, self.timeouts.get_header, headers)
@@ -395,3 +436,18 @@ impl BuilderHttpClient {
395436
.await
396437
}
397438
}
439+
440+
#[cfg(test)]
441+
mod tests {
442+
use super::*;
443+
444+
#[test]
445+
fn test_headers_no_panic() {
446+
for fork in ForkName::list_all() {
447+
assert!(HeaderValue::from_str(&fork.to_string()).is_ok());
448+
}
449+
assert!(HeaderValue::from_str(PREFERENCE_ACCEPT_VALUE).is_ok());
450+
assert!(HeaderValue::from_str(JSON_ACCEPT_VALUE).is_ok());
451+
assert!(HeaderValue::from_str(JSON_CONTENT_TYPE_HEADER).is_ok());
452+
}
453+
}

beacon_node/client/src/notifier.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
187187
let is_backfilling = matches!(current_sync_state, SyncState::BackFillSyncing { .. });
188188
if is_backfilling
189189
&& last_backfill_log_slot
190-
.map_or(true, |slot| slot + BACKFILL_LOG_INTERVAL <= current_slot)
190+
.is_none_or(|slot| slot + BACKFILL_LOG_INTERVAL <= current_slot)
191191
{
192192
last_backfill_log_slot = Some(current_slot);
193193

0 commit comments

Comments
 (0)