sui_types/
supported_protocol_versions.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::ops::RangeInclusive;
5
6use crate::{crypto::DefaultHash, digests::Digest};
7use fastcrypto::hash::HashFunction;
8use serde::{Deserialize, Serialize};
9pub use sui_protocol_config::{Chain, ProtocolConfig, ProtocolVersion};
10
11/// Models the set of protocol versions supported by a validator.
12/// The `sui-node` binary will always use the SYSTEM_DEFAULT constant, but for testing we need
13/// to be able to inject arbitrary versions into SuiNode.
14#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, PartialEq, Eq)]
15pub struct SupportedProtocolVersions {
16    pub min: ProtocolVersion,
17    pub max: ProtocolVersion,
18}
19
20impl SupportedProtocolVersions {
21    pub const SYSTEM_DEFAULT: Self = Self {
22        min: ProtocolVersion::MIN,
23        max: ProtocolVersion::MAX,
24    };
25
26    /// Use by VersionedProtocolMessage implementors to describe in which range of versions a
27    /// message variant is supported.
28    pub fn new_for_message(min: u64, max: u64) -> Self {
29        let min = ProtocolVersion::new(min);
30        let max = ProtocolVersion::new(max);
31        Self { min, max }
32    }
33
34    pub fn new_for_testing(min: u64, max: u64) -> Self {
35        let min = min.into();
36        let max = max.into();
37        Self { min, max }
38    }
39
40    pub fn is_version_supported(&self, v: ProtocolVersion) -> bool {
41        v.as_u64() >= self.min.as_u64() && v.as_u64() <= self.max.as_u64()
42    }
43
44    pub fn as_range(&self) -> RangeInclusive<u64> {
45        self.min.as_u64()..=self.max.as_u64()
46    }
47
48    pub fn truncate_below(self, v: ProtocolVersion) -> Self {
49        let min = std::cmp::max(self.min, v);
50        Self { min, max: self.max }
51    }
52}
53
54/// Models the set of protocol versions supported by a validator.
55/// The `sui-node` binary will always use the SYSTEM_DEFAULT constant, but for testing we need
56/// to be able to inject arbitrary versions into SuiNode.
57#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
58pub struct SupportedProtocolVersionsWithHashes {
59    pub versions: Vec<(ProtocolVersion, Digest)>,
60}
61
62impl SupportedProtocolVersionsWithHashes {
63    pub fn get_version_digest(&self, v: ProtocolVersion) -> Option<Digest> {
64        self.versions
65            .iter()
66            .find(|(version, _)| *version == v)
67            .map(|(_, digest)| *digest)
68    }
69
70    // Ideally this would be in sui-protocol-config, but sui-types depends on sui-protocol-config,
71    // so it would introduce a circular dependency.
72    fn protocol_config_digest(config: &ProtocolConfig) -> Digest {
73        let mut digest = DefaultHash::default();
74        bcs::serialize_into(&mut digest, &config).expect("serialization cannot fail");
75        Digest::new(digest.finalize().into())
76    }
77
78    pub fn from_supported_versions(supported: SupportedProtocolVersions, chain: Chain) -> Self {
79        Self {
80            versions: supported
81                .as_range()
82                .map(|v| {
83                    (
84                        v.into(),
85                        Self::protocol_config_digest(&ProtocolConfig::get_for_version(
86                            v.into(),
87                            chain,
88                        )),
89                    )
90                })
91                .collect(),
92        }
93    }
94}