Skip to content

Commit 8705594

Browse files
bart-lineraafck
andauthored
Add a limit for the number of received_log entries in a chain info response (#4639)
## Motivation The huge amount of entries in the `received_log` seems to be making it impossible to sync the old GoL chain on Testnet Conway. ## Proposal Limit the number of returned entries in a single response. Client should request more entries with an increased offset until the number of returned entries is less than the limit (indicating that there are no more entries). ## Test Plan CI; Manual testing on the testnet will show whether this fixes the syncing issue ## Release Plan - These changes should be backported to the latest `testnet` branch, then - be released in a new SDK, - be released in a validator hotfix. ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist) --------- Signed-off-by: Bartłomiej Kamiński <[email protected]> Co-authored-by: Andreas Fackler <[email protected]>
1 parent ec4b61c commit 8705594

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

linera-core/src/chain_worker/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ pub(crate) use self::state::CrossChainUpdateHelper;
1414
pub(crate) use self::{
1515
actor::{ChainWorkerActor, ChainWorkerRequest},
1616
config::ChainWorkerConfig,
17-
state::BlockOutcome,
17+
state::{
18+
BlockOutcome, CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_DEFAULT,
19+
CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_VAR,
20+
},
1821
};

linera-core/src/chain_worker/state.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ use crate::{
4848
worker::{NetworkActions, Notification, Reason, WorkerError},
4949
};
5050

51+
/// The maximum number of entries in a `received_log` included in a `ChainInfo` response.
52+
// TODO(#4638): Revisit the number.
53+
pub const CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_DEFAULT: usize = 1000;
54+
pub const CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_VAR: &str =
55+
"LINERA_CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES";
56+
5157
/// The state of the chain worker.
5258
pub(crate) struct ChainWorkerState<StorageClient>
5359
where
@@ -1411,7 +1417,12 @@ where
14111417
info.requested_sent_certificate_hashes = hashes;
14121418
if let Some(start) = query.request_received_log_excluding_first_n {
14131419
let start = usize::try_from(start).map_err(|_| ArithmeticError::Overflow)?;
1414-
info.requested_received_log = chain.received_log.read(start..).await?;
1420+
let max_entries = std::env::var(CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_VAR)
1421+
.ok()
1422+
.and_then(|var| var.parse().ok())
1423+
.unwrap_or(CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_DEFAULT);
1424+
let end = (start.saturating_add(max_entries)).min(chain.received_log.count());
1425+
info.requested_received_log = chain.received_log.read(start..end).await?;
14151426
}
14161427
if query.request_manager_values {
14171428
info.manager.add_values(&chain.manager);

linera-core/src/client/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
6565
use tracing::{debug, error, info, instrument, trace, warn, Instrument as _};
6666

6767
use crate::{
68+
chain_worker::{
69+
CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_DEFAULT, CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_VAR,
70+
},
6871
data_types::{ChainInfo, ChainInfoQuery, ChainInfoResponse, ClientOutcome, RoundTimeout},
6972
environment::Environment,
7073
local_node::{LocalChainInfoExt as _, LocalNodeClient, LocalNodeError},
@@ -836,9 +839,22 @@ impl<Env: Environment> Client<Env> {
836839
let (max_epoch, committees) = self.admin_committees().await?;
837840

838841
// Retrieve the list of newly received certificates from this validator.
839-
let query = ChainInfoQuery::new(chain_id).with_received_log_excluding_first_n(tracker);
840-
let info = remote_node.handle_chain_info_query(query).await?;
841-
let remote_log = info.requested_received_log;
842+
let mut remote_log = Vec::new();
843+
let mut offset = tracker;
844+
let max_entries = std::env::var(CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_VAR)
845+
.ok()
846+
.and_then(|var| var.parse().ok())
847+
.unwrap_or(CHAIN_INFO_RECEIVED_LOG_MAX_ENTRIES_DEFAULT);
848+
loop {
849+
let query = ChainInfoQuery::new(chain_id).with_received_log_excluding_first_n(offset);
850+
let info = remote_node.handle_chain_info_query(query).await?;
851+
let received_entries = info.requested_received_log.len();
852+
offset += received_entries as u64;
853+
remote_log.extend(info.requested_received_log);
854+
if received_entries < max_entries {
855+
break;
856+
}
857+
}
842858
let remote_heights = Self::heights_per_chain(&remote_log);
843859

844860
// Obtain the next block height we need in the local node, for each chain.

0 commit comments

Comments
 (0)