Skip to content

Commit d6eae2a

Browse files
authored
Merge of #4946
2 parents 19b0db2 + d9a0b48 commit d6eae2a

File tree

24 files changed

+1083
-323
lines changed

24 files changed

+1083
-323
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,11 +1347,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
13471347
(parent_root, slot, sync_aggregate): LightClientProducerEvent<T::EthSpec>,
13481348
) -> Result<(), Error> {
13491349
self.light_client_server_cache.recompute_and_cache_updates(
1350-
&self.log,
13511350
self.store.clone(),
13521351
&parent_root,
13531352
slot,
13541353
&sync_aggregate,
1354+
&self.log,
1355+
&self.spec,
13551356
)
13561357
}
13571358

@@ -6635,13 +6636,17 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
66356636
&self,
66366637
block_root: &Hash256,
66376638
) -> Result<Option<(LightClientBootstrap<T::EthSpec>, ForkName)>, Error> {
6638-
let Some((state_root, slot)) = self
6639-
.get_blinded_block(block_root)?
6640-
.map(|block| (block.state_root(), block.slot()))
6641-
else {
6639+
let handle = self
6640+
.task_executor
6641+
.handle()
6642+
.ok_or(BeaconChainError::RuntimeShutdown)?;
6643+
6644+
let Some(block) = handle.block_on(async { self.get_block(block_root).await })? else {
66426645
return Ok(None);
66436646
};
66446647

6648+
let (state_root, slot) = (block.state_root(), block.slot());
6649+
66456650
let Some(mut state) = self.get_state(&state_root, Some(slot))? else {
66466651
return Ok(None);
66476652
};
@@ -6651,12 +6656,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
66516656
.map_err(Error::InconsistentFork)?;
66526657

66536658
match fork_name {
6654-
ForkName::Altair | ForkName::Merge => {
6655-
LightClientBootstrap::from_beacon_state(&mut state)
6659+
ForkName::Altair | ForkName::Merge | ForkName::Capella | ForkName::Deneb => {
6660+
LightClientBootstrap::from_beacon_state(&mut state, &block, &self.spec)
66566661
.map(|bootstrap| Some((bootstrap, fork_name)))
66576662
.map_err(Error::LightClientError)
66586663
}
6659-
ForkName::Base | ForkName::Capella | ForkName::Deneb => Err(Error::UnsupportedFork),
6664+
ForkName::Base => Err(Error::UnsupportedFork),
66606665
}
66616666
}
66626667
}

beacon_node/beacon_chain/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ easy_from_to!(StateAdvanceError, BeaconChainError);
250250
easy_from_to!(BlockReplayError, BeaconChainError);
251251
easy_from_to!(InconsistentFork, BeaconChainError);
252252
easy_from_to!(AvailabilityCheckError, BeaconChainError);
253+
easy_from_to!(LightClientError, BeaconChainError);
253254

254255
#[derive(Debug)]
255256
pub enum BlockProductionError {

beacon_node/beacon_chain/src/light_client_finality_update_verification.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl<T: BeaconChainTypes> VerifiedLightClientFinalityUpdate<T> {
4848
// verify that enough time has passed for the block to have been propagated
4949
let start_time = chain
5050
.slot_clock
51-
.start_of(rcv_finality_update.signature_slot)
51+
.start_of(*rcv_finality_update.signature_slot())
5252
.ok_or(Error::SigSlotStartIsNone)?;
5353
let one_third_slot_duration = Duration::new(chain.spec.seconds_per_slot / 3, 0);
5454
if seen_timestamp + chain.spec.maximum_gossip_clock_disparity()

beacon_node/beacon_chain/src/light_client_optimistic_update_verification.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<T: BeaconChainTypes> VerifiedLightClientOptimisticUpdate<T> {
5252
// verify that enough time has passed for the block to have been propagated
5353
let start_time = chain
5454
.slot_clock
55-
.start_of(rcv_optimistic_update.signature_slot)
55+
.start_of(*rcv_optimistic_update.signature_slot())
5656
.ok_or(Error::SigSlotStartIsNone)?;
5757
let one_third_slot_duration = Duration::new(chain.spec.seconds_per_slot / 3, 0);
5858
if seen_timestamp + chain.spec.maximum_gossip_clock_disparity()
@@ -65,10 +65,7 @@ impl<T: BeaconChainTypes> VerifiedLightClientOptimisticUpdate<T> {
6565
let head_block = &head.snapshot.beacon_block;
6666
// check if we can process the optimistic update immediately
6767
// otherwise queue
68-
let canonical_root = rcv_optimistic_update
69-
.attested_header
70-
.beacon
71-
.canonical_root();
68+
let canonical_root = rcv_optimistic_update.get_canonical_root();
7269

7370
if canonical_root != head_block.message().parent_root() {
7471
return Err(Error::UnknownBlockParentRoot(canonical_root));
@@ -84,7 +81,7 @@ impl<T: BeaconChainTypes> VerifiedLightClientOptimisticUpdate<T> {
8481
return Err(Error::InvalidLightClientOptimisticUpdate);
8582
}
8683

87-
let parent_root = rcv_optimistic_update.attested_header.beacon.parent_root;
84+
let parent_root = rcv_optimistic_update.get_parent_root();
8885
Ok(Self {
8986
light_client_optimistic_update: rcv_optimistic_update,
9087
parent_root,

beacon_node/beacon_chain/src/light_client_server_cache.rs

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use types::light_client_update::{FinalizedRootProofLen, FINALIZED_ROOT_INDEX};
88
use types::non_zero_usize::new_non_zero_usize;
99
use types::{
1010
BeaconBlockRef, BeaconState, ChainSpec, EthSpec, ForkName, Hash256, LightClientFinalityUpdate,
11-
LightClientHeader, LightClientOptimisticUpdate, Slot, SyncAggregate,
11+
LightClientOptimisticUpdate, Slot, SyncAggregate,
1212
};
1313

1414
/// A prev block cache miss requires to re-generate the state of the post-parent block. Items in the
@@ -71,24 +71,26 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
7171
/// results are cached either on disk or memory to be served via p2p and rest API
7272
pub fn recompute_and_cache_updates(
7373
&self,
74-
log: &Logger,
7574
store: BeaconStore<T>,
7675
block_parent_root: &Hash256,
7776
block_slot: Slot,
7877
sync_aggregate: &SyncAggregate<T::EthSpec>,
78+
log: &Logger,
79+
chain_spec: &ChainSpec,
7980
) -> Result<(), BeaconChainError> {
8081
let _timer =
8182
metrics::start_timer(&metrics::LIGHT_CLIENT_SERVER_CACHE_RECOMPUTE_UPDATES_TIMES);
8283

8384
let signature_slot = block_slot;
8485
let attested_block_root = block_parent_root;
8586

86-
let attested_block = store.get_blinded_block(attested_block_root)?.ok_or(
87-
BeaconChainError::DBInconsistent(format!(
88-
"Block not available {:?}",
89-
attested_block_root
90-
)),
91-
)?;
87+
let attested_block =
88+
store
89+
.get_full_block(attested_block_root)?
90+
.ok_or(BeaconChainError::DBInconsistent(format!(
91+
"Block not available {:?}",
92+
attested_block_root
93+
)))?;
9294

9395
let cached_parts = self.get_or_compute_prev_block_cache(
9496
store.clone(),
@@ -109,11 +111,12 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
109111
};
110112
if is_latest_optimistic {
111113
// can create an optimistic update, that is more recent
112-
*self.latest_optimistic_update.write() = Some(LightClientOptimisticUpdate {
113-
attested_header: block_to_light_client_header(attested_block.message()),
114-
sync_aggregate: sync_aggregate.clone(),
114+
*self.latest_optimistic_update.write() = Some(LightClientOptimisticUpdate::new(
115+
&attested_block,
116+
sync_aggregate.clone(),
115117
signature_slot,
116-
});
118+
chain_spec,
119+
)?);
117120
};
118121

119122
// Spec: Full nodes SHOULD provide the LightClientFinalityUpdate with the highest
@@ -127,17 +130,16 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
127130
if is_latest_finality & !cached_parts.finalized_block_root.is_zero() {
128131
// Immediately after checkpoint sync the finalized block may not be available yet.
129132
if let Some(finalized_block) =
130-
store.get_blinded_block(&cached_parts.finalized_block_root)?
133+
store.get_full_block(&cached_parts.finalized_block_root)?
131134
{
132-
*self.latest_finality_update.write() = Some(LightClientFinalityUpdate {
133-
// TODO: may want to cache this result from latest_optimistic_update if producing a
134-
// light_client header becomes expensive
135-
attested_header: block_to_light_client_header(attested_block.message()),
136-
finalized_header: block_to_light_client_header(finalized_block.message()),
137-
finality_branch: cached_parts.finality_branch.clone(),
138-
sync_aggregate: sync_aggregate.clone(),
135+
*self.latest_finality_update.write() = Some(LightClientFinalityUpdate::new(
136+
&attested_block,
137+
&finalized_block,
138+
cached_parts.finality_branch.clone(),
139+
sync_aggregate.clone(),
139140
signature_slot,
140-
});
141+
chain_spec,
142+
)?);
141143
} else {
142144
debug!(
143145
log,
@@ -214,7 +216,7 @@ impl LightClientCachedData {
214216
}
215217
}
216218

217-
// Implements spec priorization rules:
219+
// Implements spec prioritization rules:
218220
// > Full nodes SHOULD provide the LightClientFinalityUpdate with the highest attested_header.beacon.slot (if multiple, highest signature_slot)
219221
//
220222
// ref: https://github.com/ethereum/consensus-specs/blob/113c58f9bf9c08867f6f5f633c4d98e0364d612a/specs/altair/light-client/full-node.md#create_light_client_finality_update
@@ -223,14 +225,15 @@ fn is_latest_finality_update<T: EthSpec>(
223225
attested_slot: Slot,
224226
signature_slot: Slot,
225227
) -> bool {
226-
if attested_slot > prev.attested_header.beacon.slot {
228+
let prev_slot = prev.get_attested_header_slot();
229+
if attested_slot > prev_slot {
227230
true
228231
} else {
229-
attested_slot == prev.attested_header.beacon.slot && signature_slot > prev.signature_slot
232+
attested_slot == prev_slot && signature_slot > *prev.signature_slot()
230233
}
231234
}
232235

233-
// Implements spec priorization rules:
236+
// Implements spec prioritization rules:
234237
// > Full nodes SHOULD provide the LightClientOptimisticUpdate with the highest attested_header.beacon.slot (if multiple, highest signature_slot)
235238
//
236239
// ref: https://github.com/ethereum/consensus-specs/blob/113c58f9bf9c08867f6f5f633c4d98e0364d612a/specs/altair/light-client/full-node.md#create_light_client_optimistic_update
@@ -239,18 +242,10 @@ fn is_latest_optimistic_update<T: EthSpec>(
239242
attested_slot: Slot,
240243
signature_slot: Slot,
241244
) -> bool {
242-
if attested_slot > prev.attested_header.beacon.slot {
245+
let prev_slot = prev.get_slot();
246+
if attested_slot > prev_slot {
243247
true
244248
} else {
245-
attested_slot == prev.attested_header.beacon.slot && signature_slot > prev.signature_slot
246-
}
247-
}
248-
249-
fn block_to_light_client_header<T: EthSpec>(
250-
block: BeaconBlockRef<T, types::BlindedPayload<T>>,
251-
) -> LightClientHeader {
252-
// TODO: make fork aware
253-
LightClientHeader {
254-
beacon: block.block_header(),
249+
attested_slot == prev_slot && signature_slot > *prev.signature_slot()
255250
}
256251
}

beacon_node/http_api/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,7 +2337,7 @@ pub fn serve<T: BeaconChainTypes>(
23372337

23382338
let fork_name = chain
23392339
.spec
2340-
.fork_name_at_slot::<T::EthSpec>(update.signature_slot);
2340+
.fork_name_at_slot::<T::EthSpec>(*update.signature_slot());
23412341
match accept_header {
23422342
Some(api_types::Accept::Ssz) => Response::builder()
23432343
.status(200)
@@ -2384,7 +2384,7 @@ pub fn serve<T: BeaconChainTypes>(
23842384

23852385
let fork_name = chain
23862386
.spec
2387-
.fork_name_at_slot::<T::EthSpec>(update.signature_slot);
2387+
.fork_name_at_slot::<T::EthSpec>(*update.signature_slot());
23882388
match accept_header {
23892389
Some(api_types::Accept::Ssz) => Response::builder()
23902390
.status(200)

beacon_node/http_api/tests/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1717,7 +1717,7 @@ impl ApiTester {
17171717
};
17181718

17191719
let expected = block.slot();
1720-
assert_eq!(result.header.beacon.slot, expected);
1720+
assert_eq!(result.get_slot(), expected);
17211721

17221722
self
17231723
}

beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,18 @@ fn handle_rpc_response<T: EthSpec>(
590590
SupportedProtocol::MetaDataV1 => Ok(Some(RPCResponse::MetaData(MetaData::V1(
591591
MetaDataV1::from_ssz_bytes(decoded_buffer)?,
592592
)))),
593-
SupportedProtocol::LightClientBootstrapV1 => Ok(Some(RPCResponse::LightClientBootstrap(
594-
LightClientBootstrap::from_ssz_bytes(decoded_buffer)?,
595-
))),
593+
SupportedProtocol::LightClientBootstrapV1 => match fork_name {
594+
Some(fork_name) => Ok(Some(RPCResponse::LightClientBootstrap(Arc::new(
595+
LightClientBootstrap::from_ssz_bytes(decoded_buffer, fork_name)?,
596+
)))),
597+
None => Err(RPCError::ErrorResponse(
598+
RPCResponseErrorCode::InvalidRequest,
599+
format!(
600+
"No context bytes provided for {:?} response",
601+
versioned_protocol
602+
),
603+
)),
604+
},
596605
// MetaData V2 responses have no context bytes, so behave similarly to V1 responses
597606
SupportedProtocol::MetaDataV2 => Ok(Some(RPCResponse::MetaData(MetaData::V2(
598607
MetaDataV2::from_ssz_bytes(decoded_buffer)?,

beacon_node/lighthouse_network/src/rpc/methods.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ pub enum RPCResponse<T: EthSpec> {
388388
BlobsByRange(Arc<BlobSidecar<T>>),
389389

390390
/// A response to a get LIGHT_CLIENT_BOOTSTRAP request.
391-
LightClientBootstrap(LightClientBootstrap<T>),
391+
LightClientBootstrap(Arc<LightClientBootstrap<T>>),
392392

393393
/// A response to a get BLOBS_BY_ROOT request.
394394
BlobsByRoot(Arc<BlobSidecar<T>>),
@@ -569,11 +569,7 @@ impl<T: EthSpec> std::fmt::Display for RPCResponse<T> {
569569
RPCResponse::Pong(ping) => write!(f, "Pong: {}", ping.data),
570570
RPCResponse::MetaData(metadata) => write!(f, "Metadata: {}", metadata.seq_number()),
571571
RPCResponse::LightClientBootstrap(bootstrap) => {
572-
write!(
573-
f,
574-
"LightClientBootstrap Slot: {}",
575-
bootstrap.header.beacon.slot
576-
)
572+
write!(f, "LightClientBootstrap Slot: {}", bootstrap.get_slot())
577573
}
578574
}
579575
}

beacon_node/lighthouse_network/src/service/api_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub enum Response<TSpec: EthSpec> {
9393
/// A response to a get BLOBS_BY_ROOT request.
9494
BlobsByRoot(Option<Arc<BlobSidecar<TSpec>>>),
9595
/// A response to a LightClientUpdate request.
96-
LightClientBootstrap(LightClientBootstrap<TSpec>),
96+
LightClientBootstrap(Arc<LightClientBootstrap<TSpec>>),
9797
}
9898

9999
impl<TSpec: EthSpec> std::convert::From<Response<TSpec>> for RPCCodedResponse<TSpec> {

0 commit comments

Comments
 (0)