Skip to content

Conversation

@bart-linera
Copy link
Contributor

Motivation

Node service plugins introduced an interface in the ChainListener that allows contracts to request listening to chains. However, the background sync task wasn't started for chains being listened to due to such requests.

Proposal

Make sure background sync is started if there is a request to listen in the FullChain mode.

Test Plan

CI will catch regressions

Release Plan

  • These changes should be backported to the latest testnet branch, then
    • be released in a new SDK,

Links

@bart-linera bart-linera requested review from deuszx and ma2bd December 18, 2025 11:35
@bart-linera bart-linera added this pull request to the merge queue Dec 18, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 18, 2025
@bart-linera bart-linera added this pull request to the merge queue Dec 18, 2025
Copy link
Contributor

@deuszx deuszx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see how this will start a chain listener if we add new chains but what if we change chains we already listen to? from FullChain to FollowOnly and vice versa?

@bart-linera bart-linera removed this pull request from the merge queue due to a manual request Dec 18, 2025
@bart-linera
Copy link
Contributor Author

bart-linera commented Dec 18, 2025

Hmm, fair point. I mean - if we change to FullChain from any other mode, this will work correctly, because it will just start the task. But if we stop listening, the background task won't be stopped 🤔 Maybe we should keep a handle, or a separate cancellation token, in the ListeningClient, so that we can abort it when the ListeningClient is stopped?

BTW, it's currently not possible to switch listening to a "lower" mode - the assumption being that if there are two separate reasons for listening, and one implies a "higher" mode than the other, we should just be listening in the "higher" mode of the two. More sophisticated management of the listening tasks would require a lot more work, I'm afraid 😬

mut self,
enable_background_sync: bool,
) -> Result<impl Future<Output = Result<(), Error>>, Error> {
pub async fn run(mut self) -> Result<impl Future<Output = Result<(), Error>>, Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because background sync for a chain can now be started at a point different than when the whole Chain Listener is started - so we need to remember the setting in the struct itself, to know whether we want to start background sync for chains or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds wrong – i.e. we decide to spawn the background sync at a different point in time than when we decide whether we (will) want to run it. Shouldn't those two be done at the same time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But background sync is per chain, and we may want to start listening to a chain at any point while the listener (as in, the component) is running. So we initialize the listener at startup, but then we might want to start to listen to some chain much later, and if background sync is enabled, we will start the background sync for that chain then.

Comment on lines +511 to +516
if !self.enable_background_sync {
return None;
}
if mode != ListeningMode::FullChain {
return None;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add some logging for the less obvious cases:

  1. enable_background_sync == true but mode != ListeningMode::FullChain
  2. enable_background_sync == false but mode == ListeningMode::FullChain

🤔

Actually, how could we end up with FullChain listening mode but disabled background sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we enable background sync in all production scenarios, anyway. This setting only exists to make it possible to disable starting background sync tasks in unit tests, AFAIK.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some logging regardless?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's that useful - because both cases will be pretty common. The first one will pop up in production when listening to sparse event chains, or with followed chains. The second one will be everywhere in unit tests, where we disable background sync for convenience. Neither case is unusual in any way (but I can of course add some debug or maybe even trace logs).

@bart-linera bart-linera added this pull request to the merge queue Jan 6, 2026
Merged via the queue into linera-io:main with commit caf8df4 Jan 6, 2026
34 checks passed
@bart-linera bart-linera deleted the spawn-background-sync branch January 6, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants