linera_core/client/chain_client/state.rs
1// Copyright (c) Facebook, Inc. and its affiliates.
2// Copyright (c) Zefchain Labs, Inc.
3// SPDX-License-Identifier: Apache-2.0
4
5use std::sync::Arc;
6
7use tokio::sync::Mutex;
8
9use super::super::PendingProposal;
10
11/// Per-chain state holding the proposal mutex.
12///
13/// The mutex serves two purposes:
14/// 1. It serializes block proposals so the client never makes conflicting proposals
15/// (which could brick the chain in the Fast consensus round).
16/// 2. Its locked value holds the pending proposal, ensuring that reads and writes
17/// to the pending proposal are always synchronized with the proposal flow.
18pub struct State {
19 /// Mutex that serializes block proposals. The locked value is the pending proposal
20 /// (if any) that we are currently trying to commit.
21 proposal_mutex: Arc<Mutex<Option<PendingProposal>>>,
22
23 /// If true, only download blocks for this chain without fetching manager values.
24 /// Use this for chains we're interested in observing but don't intend to propose blocks for.
25 follow_only: bool,
26}
27
28impl State {
29 pub fn new(pending_proposal: Option<PendingProposal>, follow_only: bool) -> State {
30 State {
31 proposal_mutex: Arc::new(Mutex::new(pending_proposal)),
32 follow_only,
33 }
34 }
35
36 /// Returns whether this chain is in follow-only mode.
37 pub fn is_follow_only(&self) -> bool {
38 self.follow_only
39 }
40
41 /// Returns a new `State` with the given `follow_only` value, sharing the same
42 /// proposal mutex.
43 pub(crate) fn with_follow_only(&self, follow_only: bool) -> State {
44 State {
45 proposal_mutex: Arc::clone(&self.proposal_mutex),
46 follow_only,
47 }
48 }
49
50 /// Returns the proposal mutex for this chain.
51 pub(super) fn proposal_mutex(&self) -> Arc<Mutex<Option<PendingProposal>>> {
52 Arc::clone(&self.proposal_mutex)
53 }
54}