sui_config/
certificate_deny_config.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use once_cell::sync::OnceCell;
5use serde::{Deserialize, Serialize};
6use std::collections::HashSet;
7use sui_types::base_types::TransactionDigest;
8
9#[derive(Clone, Debug, Default, Deserialize, Serialize)]
10#[serde(rename_all = "kebab-case")]
11pub struct CertificateDenyConfig {
12    /// A list of certificate digests that are known to be either deterministically crashing
13    /// every validator, or causing every validator to hang forever, i.e. there is no way
14    /// for such transaction to execute successfully today.
15    /// Now with this config, a validator will decide that this transaction will always yield
16    /// ExecutionError and charge gas accordingly.
17    /// This config is meant for a fast temporary fix for a known issue, and should be removed
18    /// once the issue is fixed. However, since a certificate once executed will be included
19    /// in checkpoints, all future executions of this transaction through replay must also lead
20    /// to the same result (i.e. ExecutionError). So when we remove this config, we need to make
21    /// sure it's added to the constant certificate deny list in the Rust code (TODO: code link).
22    #[serde(default, skip_serializing_if = "Vec::is_empty")]
23    certificate_deny_list: Vec<TransactionDigest>,
24
25    /// In-memory cache for faster lookup of the certificate deny list.
26    #[serde(skip)]
27    certificate_deny_set: OnceCell<HashSet<TransactionDigest>>,
28}
29
30impl CertificateDenyConfig {
31    pub fn new() -> Self {
32        Self::default()
33    }
34
35    pub fn certificate_deny_set(&self) -> &HashSet<TransactionDigest> {
36        self.certificate_deny_set.get_or_init(|| {
37            self.certificate_deny_list
38                .iter()
39                .cloned()
40                .collect::<HashSet<_>>()
41        })
42    }
43}
44
45#[derive(Default)]
46pub struct CertificateDenyConfigBuilder {
47    config: CertificateDenyConfig,
48}
49
50impl CertificateDenyConfigBuilder {
51    pub fn new() -> Self {
52        Self::default()
53    }
54
55    pub fn build(self) -> CertificateDenyConfig {
56        self.config
57    }
58
59    pub fn add_certificate_deny(mut self, certificate: TransactionDigest) -> Self {
60        self.config.certificate_deny_list.push(certificate);
61        self
62    }
63}