Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support LightClientFinalityUpdate and LightClientOptimisticUpdate rpcs #3849

Merged
merged 49 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
42245b7
add light client optimistic and finality update rpc
GeemoCandama Dec 20, 2022
5d59207
Arc the updates in the response
GeemoCandama Jan 7, 2023
9643686
add conditional advertisement for both LightClientOptimisticUpdate an…
GeemoCandama Jan 30, 2023
9b0901c
alter display for inboundrequest light client optimistic and finality…
GeemoCandama Jan 30, 2023
17e6436
remove LightClientOptimistic/FinalityReuest struct and some minor fixes
GeemoCandama Feb 14, 2023
ddf0874
rebase
GeemoCandama Mar 15, 2023
29bfdb8
failing rpc_test for LightClientBootstrap and beginning of MockLib2pL…
GeemoCandama Mar 12, 2023
e6c4c72
minor change
GeemoCandama Mar 13, 2023
5620c74
added MockRPCHandler by importing everything except OutboundRequest. …
GeemoCandama Mar 13, 2023
520962f
almost there but ran into issue where needed to implement BaseOutboun…
GeemoCandama Mar 14, 2023
68d43d5
failing but running with a light client service of sorts
GeemoCandama Mar 14, 2023
cf4a24c
small test change
GeemoCandama Mar 14, 2023
555bf46
changed Protocol::LightClientBootstrap response limit
GeemoCandama Mar 14, 2023
d5ae43d
deleted some stuff from ConnectionHandler Implementation for the mock…
GeemoCandama Mar 14, 2023
2a6299a
deleted purging expired inbound/outbound streams code
GeemoCandama Mar 14, 2023
d7cdae1
deleted drive inbound streams that need to be processed
GeemoCandama Mar 14, 2023
909c34c
removed unused imports
GeemoCandama Mar 14, 2023
194d8d3
made things private again
GeemoCandama Mar 14, 2023
9abc31e
deleted inject_fully_negotiated_inbound
GeemoCandama Mar 14, 2023
81ba801
made more things private again
GeemoCandama Mar 14, 2023
4c41643
more
GeemoCandama Mar 14, 2023
f55977f
turned the logger off in the test
GeemoCandama Mar 14, 2023
f7371e2
added failing test for new rpc
GeemoCandama Mar 15, 2023
5027b83
add rate limit for new rpcs
GeemoCandama Mar 15, 2023
8226f05
change InboundUpgrade function to use new rpcs. fmt. add test for Lig…
GeemoCandama Mar 15, 2023
474d512
rebasing fix
GeemoCandama Mar 29, 2023
86aa148
add LightClientUpdate to handle_rpc functions
GeemoCandama Mar 30, 2023
3f7c8c2
added context bytes
GeemoCandama Mar 30, 2023
55a4596
fmt
GeemoCandama Mar 30, 2023
8ffd209
use correct unsed_tcp4_port function
GeemoCandama Mar 31, 2023
c9fa08f
fix for recent config changes and adding context_bytes for the light …
GeemoCandama Apr 2, 2023
691f688
fix clippy complaint
GeemoCandama Apr 5, 2023
64dac1b
Merge branch 'unstable' into lc-reqresp
jimmygchen Nov 4, 2023
38a029a
Error handling updates and various cleanups.
jimmygchen Nov 4, 2023
9b5d14f
Moar minor clean ups.
jimmygchen Nov 4, 2023
e5f9738
Do not ban peer for rate limiting light client requests
jimmygchen Nov 4, 2023
8e72d38
Merge branch 'unstable' into lc-reqresp. Also removed the mock light …
jimmygchen Feb 1, 2024
a610e2a
Remove unnecessary changes
jimmygchen Feb 1, 2024
8d3b26f
Add missing light client queue handling.
jimmygchen Feb 2, 2024
e393bf3
Merge branch 'unstable' into lc-reqresp
jimmygchen Mar 11, 2024
8015b2d
Merge branch 'unstable' into lc-reqresp
jimmygchen Mar 25, 2024
2e8ccbb
Add context bytes for light client RPC responses.
jimmygchen Mar 25, 2024
c888923
Add RPC limits for light client object.
jimmygchen Apr 2, 2024
bd167fa
Fix lint
jimmygchen Apr 2, 2024
00144af
Fix incorrect light client max size computation.
jimmygchen Apr 8, 2024
50c463d
Merge branch 'unstable' into lc-reqresp
jimmygchen Apr 8, 2024
08ed69e
Remove unwanted local changes.
jimmygchen Apr 8, 2024
1df31be
Merge branch 'unstable' into lc-reqresp
jimmygchen Apr 9, 2024
51fe0ce
Replace `unimplemented` electra code path with deneb values.
jimmygchen Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions beacon_node/beacon_processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ const MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN: usize = 16_384;
/// will be stored before we start dropping them.
const MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN: usize = 1_024;

/// The maximum number of queued `LightClientOptimisticUpdateRequest` objects received from the network RPC that
/// will be stored before we start dropping them.
const MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN: usize = 512;

/// The maximum number of queued `LightClientFinalityUpdateRequest` objects received from the network RPC that
/// will be stored before we start dropping them.
const MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN: usize = 512;

/// The maximum number of priority-0 (highest priority) messages that will be queued before
/// they begin to be dropped.
const MAX_API_REQUEST_P0_QUEUE_LEN: usize = 1_024;
Expand Down Expand Up @@ -243,6 +251,8 @@ pub const BLOCKS_BY_ROOTS_REQUEST: &str = "blocks_by_roots_request";
pub const BLOBS_BY_RANGE_REQUEST: &str = "blobs_by_range_request";
pub const BLOBS_BY_ROOTS_REQUEST: &str = "blobs_by_roots_request";
pub const LIGHT_CLIENT_BOOTSTRAP_REQUEST: &str = "light_client_bootstrap";
pub const LIGHT_CLIENT_FINALITY_UPDATE_REQUEST: &str = "light_client_finality_update_request";
pub const LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST: &str = "light_client_optimistic_update_request";
pub const UNKNOWN_BLOCK_ATTESTATION: &str = "unknown_block_attestation";
pub const UNKNOWN_BLOCK_AGGREGATE: &str = "unknown_block_aggregate";
pub const UNKNOWN_LIGHT_CLIENT_UPDATE: &str = "unknown_light_client_update";
Expand Down Expand Up @@ -620,6 +630,8 @@ pub enum Work<E: EthSpec> {
BlobsByRootsRequest(BlockingFn),
GossipBlsToExecutionChange(BlockingFn),
LightClientBootstrapRequest(BlockingFn),
LightClientOptimisticUpdateRequest(BlockingFn),
LightClientFinalityUpdateRequest(BlockingFn),
ApiRequestP0(BlockingOrAsync),
ApiRequestP1(BlockingOrAsync),
}
Expand Down Expand Up @@ -659,6 +671,8 @@ impl<E: EthSpec> Work<E> {
Work::BlobsByRangeRequest(_) => BLOBS_BY_RANGE_REQUEST,
Work::BlobsByRootsRequest(_) => BLOBS_BY_ROOTS_REQUEST,
Work::LightClientBootstrapRequest(_) => LIGHT_CLIENT_BOOTSTRAP_REQUEST,
Work::LightClientOptimisticUpdateRequest(_) => LIGHT_CLIENT_OPTIMISTIC_UPDATE_REQUEST,
Work::LightClientFinalityUpdateRequest(_) => LIGHT_CLIENT_FINALITY_UPDATE_REQUEST,
Work::UnknownBlockAttestation { .. } => UNKNOWN_BLOCK_ATTESTATION,
Work::UnknownBlockAggregate { .. } => UNKNOWN_BLOCK_AGGREGATE,
Work::GossipBlsToExecutionChange(_) => GOSSIP_BLS_TO_EXECUTION_CHANGE,
Expand Down Expand Up @@ -820,7 +834,11 @@ impl<E: EthSpec> BeaconProcessor<E> {
let mut gossip_bls_to_execution_change_queue =
FifoQueue::new(MAX_BLS_TO_EXECUTION_CHANGE_QUEUE_LEN);

let mut lcbootstrap_queue = FifoQueue::new(MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN);
let mut lc_bootstrap_queue = FifoQueue::new(MAX_LIGHT_CLIENT_BOOTSTRAP_QUEUE_LEN);
let mut lc_optimistic_update_queue =
FifoQueue::new(MAX_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUEUE_LEN);
let mut lc_finality_update_queue =
FifoQueue::new(MAX_LIGHT_CLIENT_FINALITY_UPDATE_QUEUE_LEN);

let mut api_request_p0_queue = FifoQueue::new(MAX_API_REQUEST_P0_QUEUE_LEN);
let mut api_request_p1_queue = FifoQueue::new(MAX_API_REQUEST_P1_QUEUE_LEN);
Expand Down Expand Up @@ -1137,9 +1155,14 @@ impl<E: EthSpec> BeaconProcessor<E> {
// Handle backfill sync chain segments.
} else if let Some(item) = backfill_chain_segment.pop() {
self.spawn_worker(item, idle_tx);
// This statement should always be the final else statement.
} else if let Some(item) = lcbootstrap_queue.pop() {
// Handle light client requests.
} else if let Some(item) = lc_bootstrap_queue.pop() {
self.spawn_worker(item, idle_tx);
} else if let Some(item) = lc_optimistic_update_queue.pop() {
self.spawn_worker(item, idle_tx);
} else if let Some(item) = lc_finality_update_queue.pop() {
self.spawn_worker(item, idle_tx);
// This statement should always be the final else statement.
} else {
// Let the journal know that a worker is freed and there's nothing else
// for it to do.
Expand Down Expand Up @@ -1249,7 +1272,13 @@ impl<E: EthSpec> BeaconProcessor<E> {
blbrange_queue.push(work, work_id, &self.log)
}
Work::LightClientBootstrapRequest { .. } => {
lcbootstrap_queue.push(work, work_id, &self.log)
lc_bootstrap_queue.push(work, work_id, &self.log)
}
Work::LightClientOptimisticUpdateRequest { .. } => {
lc_optimistic_update_queue.push(work, work_id, &self.log)
}
Work::LightClientFinalityUpdateRequest { .. } => {
lc_finality_update_queue.push(work, work_id, &self.log)
}
Work::UnknownBlockAttestation { .. } => {
unknown_block_attestation_queue.push(work)
Expand Down Expand Up @@ -1480,7 +1509,9 @@ impl<E: EthSpec> BeaconProcessor<E> {
| Work::GossipLightClientOptimisticUpdate(process_fn)
| Work::Status(process_fn)
| Work::GossipBlsToExecutionChange(process_fn)
| Work::LightClientBootstrapRequest(process_fn) => {
| Work::LightClientBootstrapRequest(process_fn)
| Work::LightClientOptimisticUpdateRequest(process_fn)
| Work::LightClientFinalityUpdateRequest(process_fn) => {
task_spawner.spawn_blocking(process_fn)
}
};
Expand Down
10 changes: 9 additions & 1 deletion beacon_node/lighthouse_network/src/peer_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,11 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::BlocksByRange => PeerAction::MidToleranceError,
Protocol::BlocksByRoot => PeerAction::MidToleranceError,
Protocol::BlobsByRange => PeerAction::MidToleranceError,
Protocol::LightClientBootstrap => PeerAction::LowToleranceError,
// Lighthouse does not currently make light client requests; therefore, this
// is an unexpected scenario. We do not ban the peer for rate limiting.
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::BlobsByRoot => PeerAction::MidToleranceError,
Protocol::Goodbye => PeerAction::LowToleranceError,
Protocol::MetaData => PeerAction::LowToleranceError,
Expand All @@ -575,6 +579,8 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::BlobsByRoot => return,
Protocol::Goodbye => return,
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::MetaData => PeerAction::Fatal,
Protocol::Status => PeerAction::Fatal,
}
Expand All @@ -592,6 +598,8 @@ impl<E: EthSpec> PeerManager<E> {
Protocol::BlobsByRange => PeerAction::MidToleranceError,
Protocol::BlobsByRoot => PeerAction::MidToleranceError,
Protocol::LightClientBootstrap => return,
Protocol::LightClientOptimisticUpdate => return,
Protocol::LightClientFinalityUpdate => return,
Protocol::Goodbye => return,
Protocol::MetaData => return,
Protocol::Status => return,
Expand Down
112 changes: 81 additions & 31 deletions beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ use std::io::{Read, Write};
use std::marker::PhantomData;
use std::sync::Arc;
use tokio_util::codec::{Decoder, Encoder};
use types::ChainSpec;
use types::{
BlobSidecar, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap,
RuntimeVariableList, SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase,
SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra,
SignedBeaconBlockMerge,
BlobSidecar, ChainSpec, EthSpec, ForkContext, ForkName, Hash256, LightClientBootstrap,
LightClientFinalityUpdate, LightClientOptimisticUpdate, RuntimeVariableList, SignedBeaconBlock,
SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockCapella,
SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBeaconBlockMerge,
};
use unsigned_varint::codec::Uvi;

Expand Down Expand Up @@ -72,6 +71,8 @@ impl<E: EthSpec> Encoder<RPCCodedResponse<E>> for SSZSnappyInboundCodec<E> {
RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(),
RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(),
RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(),
RPCResponse::LightClientOptimisticUpdate(res) => res.as_ssz_bytes(),
RPCResponse::LightClientFinalityUpdate(res) => res.as_ssz_bytes(),
RPCResponse::Pong(res) => res.data.as_ssz_bytes(),
RPCResponse::MetaData(res) =>
// Encode the correct version of the MetaData response based on the negotiated version.
Expand Down Expand Up @@ -387,32 +388,51 @@ fn context_bytes<E: EthSpec>(
// Add the context bytes if required
if protocol.has_context_bytes() {
if let RPCCodedResponse::Success(rpc_variant) = resp {
if let RPCResponse::BlocksByRange(ref_box_block)
| RPCResponse::BlocksByRoot(ref_box_block) = rpc_variant
{
return match **ref_box_block {
// NOTE: If you are adding another fork type here, be sure to modify the
// `fork_context.to_context_bytes()` function to support it as well!
SignedBeaconBlock::Electra { .. } => {
fork_context.to_context_bytes(ForkName::Electra)
}
SignedBeaconBlock::Deneb { .. } => {
fork_context.to_context_bytes(ForkName::Deneb)
}
SignedBeaconBlock::Capella { .. } => {
fork_context.to_context_bytes(ForkName::Capella)
}
SignedBeaconBlock::Merge { .. } => {
fork_context.to_context_bytes(ForkName::Merge)
}
SignedBeaconBlock::Altair { .. } => {
fork_context.to_context_bytes(ForkName::Altair)
}
SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()),
};
}
if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant {
return fork_context.to_context_bytes(ForkName::Deneb);
match rpc_variant {
RPCResponse::BlocksByRange(ref_box_block)
| RPCResponse::BlocksByRoot(ref_box_block) => {
return match **ref_box_block {
// NOTE: If you are adding another fork type here, be sure to modify the
// `fork_context.to_context_bytes()` function to support it as well!
SignedBeaconBlock::Electra { .. } => {
fork_context.to_context_bytes(ForkName::Electra)
}
SignedBeaconBlock::Deneb { .. } => {
fork_context.to_context_bytes(ForkName::Deneb)
}
SignedBeaconBlock::Capella { .. } => {
fork_context.to_context_bytes(ForkName::Capella)
}
SignedBeaconBlock::Merge { .. } => {
fork_context.to_context_bytes(ForkName::Merge)
}
SignedBeaconBlock::Altair { .. } => {
fork_context.to_context_bytes(ForkName::Altair)
}
SignedBeaconBlock::Base { .. } => {
Some(fork_context.genesis_context_bytes())
}
};
}
RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) => {
return fork_context.to_context_bytes(ForkName::Deneb);
}
RPCResponse::LightClientBootstrap(lc_bootstrap) => {
return lc_bootstrap
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RPCResponse::LightClientOptimisticUpdate(lc_optimistic_update) => {
return lc_optimistic_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
RPCResponse::LightClientFinalityUpdate(lc_finality_update) => {
return lc_finality_update
.map_with_fork_name(|fork_name| fork_context.to_context_bytes(fork_name));
}
// These will not pass the has_context_bytes() check
RPCResponse::Status(_) | RPCResponse::Pong(_) | RPCResponse::MetaData(_) => {
return None;
}
}
}
}
Expand Down Expand Up @@ -500,6 +520,12 @@ fn handle_rpc_request<E: EthSpec>(
root: Hash256::from_ssz_bytes(decoded_buffer)?,
}),
)),
SupportedProtocol::LightClientOptimisticUpdateV1 => {
Ok(Some(InboundRequest::LightClientOptimisticUpdate))
}
SupportedProtocol::LightClientFinalityUpdateV1 => {
Ok(Some(InboundRequest::LightClientFinalityUpdate))
}
// MetaData requests return early from InboundUpgrade and do not reach the decoder.
// Handle this case just for completeness.
SupportedProtocol::MetaDataV2 => {
Expand Down Expand Up @@ -596,6 +622,30 @@ fn handle_rpc_response<E: EthSpec>(
),
)),
},
SupportedProtocol::LightClientOptimisticUpdateV1 => match fork_name {
Some(fork_name) => Ok(Some(RPCResponse::LightClientOptimisticUpdate(Arc::new(
LightClientOptimisticUpdate::from_ssz_bytes(decoded_buffer, fork_name)?,
)))),
None => Err(RPCError::ErrorResponse(
RPCResponseErrorCode::InvalidRequest,
format!(
"No context bytes provided for {:?} response",
versioned_protocol
),
)),
},
SupportedProtocol::LightClientFinalityUpdateV1 => match fork_name {
Some(fork_name) => Ok(Some(RPCResponse::LightClientFinalityUpdate(Arc::new(
LightClientFinalityUpdate::from_ssz_bytes(decoded_buffer, fork_name)?,
)))),
None => Err(RPCError::ErrorResponse(
RPCResponseErrorCode::InvalidRequest,
format!(
"No context bytes provided for {:?} response",
versioned_protocol
),
)),
},
// MetaData V2 responses have no context bytes, so behave similarly to V1 responses
SupportedProtocol::MetaDataV2 => Ok(Some(RPCResponse::MetaData(MetaData::V2(
MetaDataV2::from_ssz_bytes(decoded_buffer)?,
Expand Down
21 changes: 21 additions & 0 deletions beacon_node/lighthouse_network/src/rpc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ pub struct RateLimiterConfig {
pub(super) blobs_by_range_quota: Quota,
pub(super) blobs_by_root_quota: Quota,
pub(super) light_client_bootstrap_quota: Quota,
pub(super) light_client_optimistic_update_quota: Quota,
pub(super) light_client_finality_update_quota: Quota,
}

impl RateLimiterConfig {
Expand All @@ -104,6 +106,8 @@ impl RateLimiterConfig {
pub const DEFAULT_BLOBS_BY_RANGE_QUOTA: Quota = Quota::n_every(768, 10);
pub const DEFAULT_BLOBS_BY_ROOT_QUOTA: Quota = Quota::n_every(128, 10);
pub const DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA: Quota = Quota::one_every(10);
pub const DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA: Quota = Quota::one_every(10);
pub const DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA: Quota = Quota::one_every(10);
}

impl Default for RateLimiterConfig {
Expand All @@ -118,6 +122,9 @@ impl Default for RateLimiterConfig {
blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA,
blobs_by_root_quota: Self::DEFAULT_BLOBS_BY_ROOT_QUOTA,
light_client_bootstrap_quota: Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA,
light_client_optimistic_update_quota:
Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA,
light_client_finality_update_quota: Self::DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA,
}
}
}
Expand Down Expand Up @@ -164,6 +171,8 @@ impl FromStr for RateLimiterConfig {
let mut blobs_by_range_quota = None;
let mut blobs_by_root_quota = None;
let mut light_client_bootstrap_quota = None;
let mut light_client_optimistic_update_quota = None;
let mut light_client_finality_update_quota = None;

for proto_def in s.split(';') {
let ProtocolQuota { protocol, quota } = proto_def.parse()?;
Expand All @@ -180,6 +189,14 @@ impl FromStr for RateLimiterConfig {
Protocol::LightClientBootstrap => {
light_client_bootstrap_quota = light_client_bootstrap_quota.or(quota)
}
Protocol::LightClientOptimisticUpdate => {
light_client_optimistic_update_quota =
light_client_optimistic_update_quota.or(quota)
}
Protocol::LightClientFinalityUpdate => {
light_client_finality_update_quota =
light_client_finality_update_quota.or(quota)
}
}
}
Ok(RateLimiterConfig {
Expand All @@ -196,6 +213,10 @@ impl FromStr for RateLimiterConfig {
blobs_by_root_quota: blobs_by_root_quota.unwrap_or(Self::DEFAULT_BLOBS_BY_ROOT_QUOTA),
light_client_bootstrap_quota: light_client_bootstrap_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_BOOTSTRAP_QUOTA),
light_client_optimistic_update_quota: light_client_optimistic_update_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_OPTIMISTIC_UPDATE_QUOTA),
light_client_finality_update_quota: light_client_finality_update_quota
.unwrap_or(Self::DEFAULT_LIGHT_CLIENT_FINALITY_UPDATE_QUOTA),
})
}
}
Expand Down
Loading
Loading