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}