Skip to content

Commit 9d069a9

Browse files
authored
Fix electra light client types (#6361)
* persist light client updates * update beacon chain to serve light client updates * resolve todos * cache best update * extend cache parts * is better light client update * resolve merge conflict * initial api changes * add lc update db column * fmt * added tests * add sim * Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates * fix some weird issues with the simulator * tests * Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates * test changes * merge conflict * testing * started work on ef tests and some code clean up * update tests * linting * noop pre altair, were still failing on electra though * allow for zeroed light client header * Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-updates * merge unstable * remove unwraps * remove unwraps * fetch bootstrap without always querying for state * storing bootstrap parts in db * mroe code cleanup * test * prune sync committee branches from dropped chains * Update light_client_update.rs * merge unstable * move functionality to helper methods * refactor is best update fn * refactor is best update fn * improve organization of light client server cache logic * fork diget calc, and only spawn as many blcoks as we need for the lc update test * resovle merge conflict * add electra bootstrap logic, add logic to cache current sync committee * add latest sync committe branch cache * fetch lc update from the cache if it exists * fmt * Fix beacon_chain tests * Add debug code to update ranking_order ef test * Fix compare code * merge conflicts * merge conflict * add better error messaging * resolve merge conflicts * remove lc update from basicsim * rename sync comittte variable and fix persist condition * refactor get_light_client_update logic * add better comments, return helpful error messages over http and rpc * pruning canonical non checkpoint slots * fix test * rerun test * update pruning logic, add tests * fix tests * fix imports * fmt * refactor db code * Refactor db method * Refactor db method * lc electra changes * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-electra * add additional comments * testing lc merkle changes * lc electra * update struct defs * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-electra * fix merge * Merge branch 'unstable' of https://github.com/sigp/lighthouse into persist-light-client-bootstrap * fix merge * linting * merge conflict * prevent overflow * enable lc server for http api tests * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-electra * get tests working: * remove related TODOs * fix test lint * Merge branch 'persist-light-client-bootstrap' of https://github.com/eserilev/lighthouse into light-client-electra * fix tests * fix conflicts * remove prints * Merge branch 'persist-light-client-bootstrap' of https://github.com/eserilev/lighthouse into light-client-electra * remove warning * resolve conflicts * merge conflicts * linting * remove comments * cleanup * linting * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-electra * pre/post electra light client cached data * add proof type alias * move is_empty_branch method out of impl * add ssz tests for all forks * refactor beacon state proof codepaths * rename method * fmt * clean up proof logic * refactor merkle proof api * fmt * Merge branch 'unstable' into light-client-electra * Use superstruct mapping macros * Merge branch 'unstable' of https://github.com/sigp/lighthouse into light-client-electra * rename proof to merkleproof * fmt * Resolve merge conflicts * merge conflicts
1 parent 40d3423 commit 9d069a9

File tree

14 files changed

+490
-185
lines changed

14 files changed

+490
-185
lines changed

beacon_node/beacon_chain/src/light_client_server_cache.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
use crate::errors::BeaconChainError;
22
use crate::{metrics, BeaconChainTypes, BeaconStore};
3-
use eth2::types::light_client_update::CurrentSyncCommitteeProofLen;
43
use parking_lot::{Mutex, RwLock};
54
use safe_arith::SafeArith;
65
use slog::{debug, Logger};
76
use ssz::Decode;
8-
use ssz_types::FixedVector;
97
use std::num::NonZeroUsize;
108
use std::sync::Arc;
119
use store::DBColumn;
1210
use store::KeyValueStore;
1311
use tree_hash::TreeHash;
14-
use types::light_client_update::{
15-
FinalizedRootProofLen, NextSyncCommitteeProofLen, CURRENT_SYNC_COMMITTEE_INDEX,
16-
FINALIZED_ROOT_INDEX, NEXT_SYNC_COMMITTEE_INDEX,
17-
};
1812
use types::non_zero_usize::new_non_zero_usize;
1913
use types::{
2014
BeaconBlockRef, BeaconState, ChainSpec, Checkpoint, EthSpec, ForkName, Hash256,
2115
LightClientBootstrap, LightClientFinalityUpdate, LightClientOptimisticUpdate,
22-
LightClientUpdate, Slot, SyncAggregate, SyncCommittee,
16+
LightClientUpdate, MerkleProof, Slot, SyncAggregate, SyncCommittee,
2317
};
2418

2519
/// A prev block cache miss requires to re-generate the state of the post-parent block. Items in the
@@ -69,17 +63,14 @@ impl<T: BeaconChainTypes> LightClientServerCache<T> {
6963
block_post_state: &mut BeaconState<T::EthSpec>,
7064
) -> Result<(), BeaconChainError> {
7165
let _timer = metrics::start_timer(&metrics::LIGHT_CLIENT_SERVER_CACHE_STATE_DATA_TIMES);
72-
66+
let fork_name = spec.fork_name_at_slot::<T::EthSpec>(block.slot());
7367
// Only post-altair
74-
if spec.fork_name_at_slot::<T::EthSpec>(block.slot()) == ForkName::Base {
75-
return Ok(());
68+
if fork_name.altair_enabled() {
69+
// Persist in memory cache for a descendent block
70+
let cached_data = LightClientCachedData::from_state(block_post_state)?;
71+
self.prev_block_cache.lock().put(block_root, cached_data);
7672
}
7773

78-
// Persist in memory cache for a descendent block
79-
80-
let cached_data = LightClientCachedData::from_state(block_post_state)?;
81-
self.prev_block_cache.lock().put(block_root, cached_data);
82-
8374
Ok(())
8475
}
8576

@@ -413,34 +404,31 @@ impl<T: BeaconChainTypes> Default for LightClientServerCache<T> {
413404
}
414405
}
415406

416-
type FinalityBranch = FixedVector<Hash256, FinalizedRootProofLen>;
417-
type NextSyncCommitteeBranch = FixedVector<Hash256, NextSyncCommitteeProofLen>;
418-
type CurrentSyncCommitteeBranch = FixedVector<Hash256, CurrentSyncCommitteeProofLen>;
419-
420407
#[derive(Clone)]
421408
struct LightClientCachedData<E: EthSpec> {
422409
finalized_checkpoint: Checkpoint,
423-
finality_branch: FinalityBranch,
424-
next_sync_committee_branch: NextSyncCommitteeBranch,
425-
current_sync_committee_branch: CurrentSyncCommitteeBranch,
410+
finality_branch: MerkleProof,
411+
next_sync_committee_branch: MerkleProof,
412+
current_sync_committee_branch: MerkleProof,
426413
next_sync_committee: Arc<SyncCommittee<E>>,
427414
current_sync_committee: Arc<SyncCommittee<E>>,
428415
finalized_block_root: Hash256,
429416
}
430417

431418
impl<E: EthSpec> LightClientCachedData<E> {
432419
fn from_state(state: &mut BeaconState<E>) -> Result<Self, BeaconChainError> {
420+
let (finality_branch, next_sync_committee_branch, current_sync_committee_branch) = (
421+
state.compute_finalized_root_proof()?,
422+
state.compute_current_sync_committee_proof()?,
423+
state.compute_next_sync_committee_proof()?,
424+
);
433425
Ok(Self {
434426
finalized_checkpoint: state.finalized_checkpoint(),
435-
finality_branch: state.compute_merkle_proof(FINALIZED_ROOT_INDEX)?.into(),
427+
finality_branch,
436428
next_sync_committee: state.next_sync_committee()?.clone(),
437429
current_sync_committee: state.current_sync_committee()?.clone(),
438-
next_sync_committee_branch: state
439-
.compute_merkle_proof(NEXT_SYNC_COMMITTEE_INDEX)?
440-
.into(),
441-
current_sync_committee_branch: state
442-
.compute_merkle_proof(CURRENT_SYNC_COMMITTEE_INDEX)?
443-
.into(),
430+
next_sync_committee_branch,
431+
current_sync_committee_branch,
444432
finalized_block_root: state.finalized_checkpoint().root,
445433
})
446434
}

beacon_node/beacon_chain/tests/store_tests.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,6 @@ async fn light_client_bootstrap_test() {
206206
.build()
207207
.expect("should build");
208208

209-
let current_state = harness.get_current_state();
210-
211-
if ForkName::Electra == current_state.fork_name_unchecked() {
212-
// TODO(electra) fix beacon state `compute_merkle_proof`
213-
return;
214-
}
215-
216209
let finalized_checkpoint = beacon_chain
217210
.canonical_head
218211
.cached_head()
@@ -353,11 +346,6 @@ async fn light_client_updates_test() {
353346

354347
let current_state = harness.get_current_state();
355348

356-
if ForkName::Electra == current_state.fork_name_unchecked() {
357-
// TODO(electra) fix beacon state `compute_merkle_proof`
358-
return;
359-
}
360-
361349
// calculate the sync period from the previous slot
362350
let sync_period = (current_state.slot() - Slot::new(1))
363351
.epoch(E::slots_per_epoch())

beacon_node/store/src/hot_cold_store.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use std::path::Path;
4444
use std::sync::Arc;
4545
use std::time::Duration;
4646
use types::data_column_sidecar::{ColumnIndex, DataColumnSidecar, DataColumnSidecarList};
47-
use types::light_client_update::CurrentSyncCommitteeProofLen;
4847
use types::*;
4948

5049
/// On-disk database that stores finalized states efficiently.
@@ -641,15 +640,14 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
641640
pub fn get_sync_committee_branch(
642641
&self,
643642
block_root: &Hash256,
644-
) -> Result<Option<FixedVector<Hash256, CurrentSyncCommitteeProofLen>>, Error> {
643+
) -> Result<Option<MerkleProof>, Error> {
645644
let column = DBColumn::SyncCommitteeBranch;
646645

647646
if let Some(bytes) = self
648647
.hot_db
649648
.get_bytes(column.into(), &block_root.as_ssz_bytes())?
650649
{
651-
let sync_committee_branch: FixedVector<Hash256, CurrentSyncCommitteeProofLen> =
652-
FixedVector::from_ssz_bytes(&bytes)?;
650+
let sync_committee_branch = Vec::<Hash256>::from_ssz_bytes(&bytes)?;
653651
return Ok(Some(sync_committee_branch));
654652
}
655653

@@ -677,7 +675,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
677675
pub fn store_sync_committee_branch(
678676
&self,
679677
block_root: Hash256,
680-
sync_committee_branch: &FixedVector<Hash256, CurrentSyncCommitteeProofLen>,
678+
sync_committee_branch: &MerkleProof,
681679
) -> Result<(), Error> {
682680
let column = DBColumn::SyncCommitteeBranch;
683681
self.hot_db.put_bytes(

consensus/types/src/beacon_state.rs

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,33 +2506,64 @@ impl<E: EthSpec> BeaconState<E> {
25062506
Ok(())
25072507
}
25082508

2509-
pub fn compute_merkle_proof(&self, generalized_index: usize) -> Result<Vec<Hash256>, Error> {
2510-
// 1. Convert generalized index to field index.
2511-
let field_index = match generalized_index {
2509+
pub fn compute_current_sync_committee_proof(&self) -> Result<Vec<Hash256>, Error> {
2510+
// Sync committees are top-level fields, subtract off the generalized indices
2511+
// for the internal nodes. Result should be 22 or 23, the field offset of the committee
2512+
// in the `BeaconState`:
2513+
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#beaconstate
2514+
let field_index = if self.fork_name_unchecked().electra_enabled() {
2515+
light_client_update::CURRENT_SYNC_COMMITTEE_INDEX_ELECTRA
2516+
} else {
25122517
light_client_update::CURRENT_SYNC_COMMITTEE_INDEX
2513-
| light_client_update::NEXT_SYNC_COMMITTEE_INDEX => {
2514-
// Sync committees are top-level fields, subtract off the generalized indices
2515-
// for the internal nodes. Result should be 22 or 23, the field offset of the committee
2516-
// in the `BeaconState`:
2517-
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#beaconstate
2518-
generalized_index
2519-
.checked_sub(self.num_fields_pow2())
2520-
.ok_or(Error::IndexNotSupported(generalized_index))?
2521-
}
2522-
light_client_update::FINALIZED_ROOT_INDEX => {
2523-
// Finalized root is the right child of `finalized_checkpoint`, divide by two to get
2524-
// the generalized index of `state.finalized_checkpoint`.
2525-
let finalized_checkpoint_generalized_index = generalized_index / 2;
2526-
// Subtract off the internal nodes. Result should be 105/2 - 32 = 20 which matches
2527-
// position of `finalized_checkpoint` in `BeaconState`.
2528-
finalized_checkpoint_generalized_index
2529-
.checked_sub(self.num_fields_pow2())
2530-
.ok_or(Error::IndexNotSupported(generalized_index))?
2531-
}
2532-
_ => return Err(Error::IndexNotSupported(generalized_index)),
25332518
};
2519+
let leaves = self.get_beacon_state_leaves();
2520+
self.generate_proof(field_index, &leaves)
2521+
}
25342522

2535-
// 2. Get all `BeaconState` leaves.
2523+
pub fn compute_next_sync_committee_proof(&self) -> Result<Vec<Hash256>, Error> {
2524+
// Sync committees are top-level fields, subtract off the generalized indices
2525+
// for the internal nodes. Result should be 22 or 23, the field offset of the committee
2526+
// in the `BeaconState`:
2527+
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#beaconstate
2528+
let field_index = if self.fork_name_unchecked().electra_enabled() {
2529+
light_client_update::NEXT_SYNC_COMMITTEE_INDEX_ELECTRA
2530+
} else {
2531+
light_client_update::NEXT_SYNC_COMMITTEE_INDEX
2532+
};
2533+
let leaves = self.get_beacon_state_leaves();
2534+
self.generate_proof(field_index, &leaves)
2535+
}
2536+
2537+
pub fn compute_finalized_root_proof(&self) -> Result<Vec<Hash256>, Error> {
2538+
// Finalized root is the right child of `finalized_checkpoint`, divide by two to get
2539+
// the generalized index of `state.finalized_checkpoint`.
2540+
let field_index = if self.fork_name_unchecked().electra_enabled() {
2541+
// Index should be 169/2 - 64 = 20 which matches the position
2542+
// of `finalized_checkpoint` in `BeaconState`
2543+
light_client_update::FINALIZED_ROOT_INDEX_ELECTRA
2544+
} else {
2545+
// Index should be 105/2 - 32 = 20 which matches the position
2546+
// of `finalized_checkpoint` in `BeaconState`
2547+
light_client_update::FINALIZED_ROOT_INDEX
2548+
};
2549+
let leaves = self.get_beacon_state_leaves();
2550+
let mut proof = self.generate_proof(field_index, &leaves)?;
2551+
proof.insert(0, self.finalized_checkpoint().epoch.tree_hash_root());
2552+
Ok(proof)
2553+
}
2554+
2555+
fn generate_proof(
2556+
&self,
2557+
field_index: usize,
2558+
leaves: &[Hash256],
2559+
) -> Result<Vec<Hash256>, Error> {
2560+
let depth = self.num_fields_pow2().ilog2() as usize;
2561+
let tree = merkle_proof::MerkleTree::create(leaves, depth);
2562+
let (_, proof) = tree.generate_proof(field_index, depth)?;
2563+
Ok(proof)
2564+
}
2565+
2566+
fn get_beacon_state_leaves(&self) -> Vec<Hash256> {
25362567
let mut leaves = vec![];
25372568
#[allow(clippy::arithmetic_side_effects)]
25382569
match self {
@@ -2568,18 +2599,7 @@ impl<E: EthSpec> BeaconState<E> {
25682599
}
25692600
};
25702601

2571-
// 3. Make deposit tree.
2572-
// Use the depth of the `BeaconState` fields (i.e. `log2(32) = 5`).
2573-
let depth = light_client_update::CURRENT_SYNC_COMMITTEE_PROOF_LEN;
2574-
let tree = merkle_proof::MerkleTree::create(&leaves, depth);
2575-
let (_, mut proof) = tree.generate_proof(field_index, depth)?;
2576-
2577-
// 4. If we're proving the finalized root, patch in the finalized epoch to complete the proof.
2578-
if generalized_index == light_client_update::FINALIZED_ROOT_INDEX {
2579-
proof.insert(0, self.finalized_checkpoint().epoch.tree_hash_root());
2580-
}
2581-
2582-
Ok(proof)
2602+
leaves
25832603
}
25842604
}
25852605

consensus/types/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ pub use crate::light_client_optimistic_update::{
200200
};
201201
pub use crate::light_client_update::{
202202
Error as LightClientUpdateError, LightClientUpdate, LightClientUpdateAltair,
203-
LightClientUpdateCapella, LightClientUpdateDeneb, LightClientUpdateElectra,
203+
LightClientUpdateCapella, LightClientUpdateDeneb, LightClientUpdateElectra, MerkleProof,
204204
};
205205
pub use crate::participation_flags::ParticipationFlags;
206206
pub use crate::payload::{

consensus/types/src/light_client_bootstrap.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,16 @@ pub struct LightClientBootstrap<E: EthSpec> {
5757
/// The `SyncCommittee` used in the requested period.
5858
pub current_sync_committee: Arc<SyncCommittee<E>>,
5959
/// Merkle proof for sync committee
60+
#[superstruct(
61+
only(Altair, Capella, Deneb),
62+
partial_getter(rename = "current_sync_committee_branch_altair")
63+
)]
6064
pub current_sync_committee_branch: FixedVector<Hash256, CurrentSyncCommitteeProofLen>,
65+
#[superstruct(
66+
only(Electra),
67+
partial_getter(rename = "current_sync_committee_branch_electra")
68+
)]
69+
pub current_sync_committee_branch: FixedVector<Hash256, CurrentSyncCommitteeProofLenElectra>,
6170
}
6271

6372
impl<E: EthSpec> LightClientBootstrap<E> {
@@ -115,7 +124,7 @@ impl<E: EthSpec> LightClientBootstrap<E> {
115124
pub fn new(
116125
block: &SignedBlindedBeaconBlock<E>,
117126
current_sync_committee: Arc<SyncCommittee<E>>,
118-
current_sync_committee_branch: FixedVector<Hash256, CurrentSyncCommitteeProofLen>,
127+
current_sync_committee_branch: Vec<Hash256>,
119128
chain_spec: &ChainSpec,
120129
) -> Result<Self, Error> {
121130
let light_client_bootstrap = match block
@@ -126,22 +135,22 @@ impl<E: EthSpec> LightClientBootstrap<E> {
126135
ForkName::Altair | ForkName::Bellatrix => Self::Altair(LightClientBootstrapAltair {
127136
header: LightClientHeaderAltair::block_to_light_client_header(block)?,
128137
current_sync_committee,
129-
current_sync_committee_branch,
138+
current_sync_committee_branch: current_sync_committee_branch.into(),
130139
}),
131140
ForkName::Capella => Self::Capella(LightClientBootstrapCapella {
132141
header: LightClientHeaderCapella::block_to_light_client_header(block)?,
133142
current_sync_committee,
134-
current_sync_committee_branch,
143+
current_sync_committee_branch: current_sync_committee_branch.into(),
135144
}),
136145
ForkName::Deneb => Self::Deneb(LightClientBootstrapDeneb {
137146
header: LightClientHeaderDeneb::block_to_light_client_header(block)?,
138147
current_sync_committee,
139-
current_sync_committee_branch,
148+
current_sync_committee_branch: current_sync_committee_branch.into(),
140149
}),
141150
ForkName::Electra => Self::Electra(LightClientBootstrapElectra {
142151
header: LightClientHeaderElectra::block_to_light_client_header(block)?,
143152
current_sync_committee,
144-
current_sync_committee_branch,
153+
current_sync_committee_branch: current_sync_committee_branch.into(),
145154
}),
146155
};
147156

@@ -155,9 +164,7 @@ impl<E: EthSpec> LightClientBootstrap<E> {
155164
) -> Result<Self, Error> {
156165
let mut header = beacon_state.latest_block_header().clone();
157166
header.state_root = beacon_state.update_tree_hash_cache()?;
158-
let current_sync_committee_branch =
159-
FixedVector::new(beacon_state.compute_merkle_proof(CURRENT_SYNC_COMMITTEE_INDEX)?)?;
160-
167+
let current_sync_committee_branch = beacon_state.compute_current_sync_committee_proof()?;
161168
let current_sync_committee = beacon_state.current_sync_committee()?.clone();
162169

163170
let light_client_bootstrap = match block
@@ -168,22 +175,22 @@ impl<E: EthSpec> LightClientBootstrap<E> {
168175
ForkName::Altair | ForkName::Bellatrix => Self::Altair(LightClientBootstrapAltair {
169176
header: LightClientHeaderAltair::block_to_light_client_header(block)?,
170177
current_sync_committee,
171-
current_sync_committee_branch,
178+
current_sync_committee_branch: current_sync_committee_branch.into(),
172179
}),
173180
ForkName::Capella => Self::Capella(LightClientBootstrapCapella {
174181
header: LightClientHeaderCapella::block_to_light_client_header(block)?,
175182
current_sync_committee,
176-
current_sync_committee_branch,
183+
current_sync_committee_branch: current_sync_committee_branch.into(),
177184
}),
178185
ForkName::Deneb => Self::Deneb(LightClientBootstrapDeneb {
179186
header: LightClientHeaderDeneb::block_to_light_client_header(block)?,
180187
current_sync_committee,
181-
current_sync_committee_branch,
188+
current_sync_committee_branch: current_sync_committee_branch.into(),
182189
}),
183190
ForkName::Electra => Self::Electra(LightClientBootstrapElectra {
184191
header: LightClientHeaderElectra::block_to_light_client_header(block)?,
185192
current_sync_committee,
186-
current_sync_committee_branch,
193+
current_sync_committee_branch: current_sync_committee_branch.into(),
187194
}),
188195
};
189196

@@ -210,8 +217,28 @@ impl<E: EthSpec> ForkVersionDeserialize for LightClientBootstrap<E> {
210217

211218
#[cfg(test)]
212219
mod tests {
213-
use super::*;
214-
use crate::MainnetEthSpec;
220+
// `ssz_tests!` can only be defined once per namespace
221+
#[cfg(test)]
222+
mod altair {
223+
use crate::{LightClientBootstrapAltair, MainnetEthSpec};
224+
ssz_tests!(LightClientBootstrapAltair<MainnetEthSpec>);
225+
}
226+
227+
#[cfg(test)]
228+
mod capella {
229+
use crate::{LightClientBootstrapCapella, MainnetEthSpec};
230+
ssz_tests!(LightClientBootstrapCapella<MainnetEthSpec>);
231+
}
215232

216-
ssz_tests!(LightClientBootstrapDeneb<MainnetEthSpec>);
233+
#[cfg(test)]
234+
mod deneb {
235+
use crate::{LightClientBootstrapDeneb, MainnetEthSpec};
236+
ssz_tests!(LightClientBootstrapDeneb<MainnetEthSpec>);
237+
}
238+
239+
#[cfg(test)]
240+
mod electra {
241+
use crate::{LightClientBootstrapElectra, MainnetEthSpec};
242+
ssz_tests!(LightClientBootstrapElectra<MainnetEthSpec>);
243+
}
217244
}

0 commit comments

Comments
 (0)