Skip to main content

tempo_contracts/precompiles/
validator_config.rs

1use alloc::string::String;
2
3pub use IValidatorConfig::IValidatorConfigErrors as ValidatorConfigError;
4
5crate::sol! {
6    /// Validator config interface for managing consensus validators.
7    ///
8    /// This precompile manages the set of validators that participate in consensus.
9    /// Validators can update their own information, rotate their identity to a new address,
10    /// and the owner can manage validator status.
11    #[derive(Debug, PartialEq, Eq)]
12    #[sol(abi)]
13    interface IValidatorConfig {
14        /// Validator information
15        struct Validator {
16            bytes32 publicKey;
17            bool active;
18            uint64 index;
19            address validatorAddress;
20            /// Address where other validators can connect to this validator.
21            /// Format: `<hostname|ip>:<port>`
22            string inboundAddress;
23            /// IP address for firewall whitelisting by other validators.
24            /// Format: `<ip>:<port>` - must be an IP address, not a hostname.
25            string outboundAddress;
26        }
27
28        /// Get the complete set of validators
29        /// @return validators Array of all validators with their information
30        function getValidators() external view returns (Validator[] memory validators);
31
32        /// Add a new validator (owner only)
33        /// @param newValidatorAddress The address of the new validator
34        /// @param publicKey The validator's communication public publicKey
35        /// @param inboundAddress The validator's inbound address `<hostname|ip>:<port>` for incoming connections
36        /// @param outboundAddress The validator's outbound IP address `<ip>:<port>` for firewall whitelisting (IP only, no hostnames)
37        function addValidator(address newValidatorAddress, bytes32 publicKey, bool active, string calldata inboundAddress, string calldata outboundAddress) external;
38
39        /// Update validator information (only validator)
40        /// @param newValidatorAddress The new address for this validator
41        /// @param publicKey The validator's new communication public publicKey
42        /// @param inboundAddress The validator's inbound address `<hostname|ip>:<port>` for incoming connections
43        /// @param outboundAddress The validator's outbound IP address `<ip>:<port>` for firewall whitelisting (IP only, no hostnames)
44        function updateValidator(address newValidatorAddress, bytes32 publicKey, string calldata inboundAddress, string calldata outboundAddress) external;
45
46        /// Change validator active status (owner only)
47        /// @param validator The validator address
48        /// @param active Whether the validator should be active
49        /// @dev Deprecated: Use changeValidatorStatusByIndex to prevent front-running attacks
50        function changeValidatorStatus(address validator, bool active) external;
51
52        /// Change validator active status by index (owner only) - T1+
53        /// @param index The validator index in the validators array
54        /// @param active Whether the validator should be active
55        /// @dev Added in T1 to prevent front-running attacks where a validator changes its address
56        function changeValidatorStatusByIndex(uint64 index, bool active) external;
57
58        /// Get the owner of the precompile
59        /// @return owner The owner address
60        function owner() external view returns (address);
61
62        /// Change owner
63        /// @param newOwner The new owner address
64        function changeOwner(address newOwner) external;
65
66        /// Get the epoch at which a fresh DKG ceremony will be triggered
67        ///
68        /// @return The epoch number. The fresh DKG ceremony runs in epoch N, and epoch N+1 uses the new DKG polynomial.
69        function getNextFullDkgCeremony() external view returns (uint64);
70
71        /// Set the epoch at which a fresh DKG ceremony will be triggered (owner only)
72        ///
73        /// @param epoch The epoch in which to run the fresh DKG ceremony. Epoch N runs the ceremony, and epoch N+1 uses the new DKG polynomial.
74        function setNextFullDkgCeremony(uint64 epoch) external;
75
76        /// Get validator address at a specific index in the validators array
77        /// @param index The index in the validators array
78        /// @return The validator address at the given index
79        function validatorsArray(uint256 index) external view returns (address);
80
81        /// Get validator information by address
82        /// @param validator The validator address to look up
83        /// @return The validator struct for the given address
84        function validators(address validator) external view returns (Validator memory);
85
86        /// Get the total number of validators
87        /// @return The count of validators
88        function validatorCount() external view returns (uint64);
89
90        // Errors
91        error Unauthorized();
92        error ValidatorAlreadyExists();
93        error ValidatorNotFound();
94        error InvalidPublicKey();
95
96        error NotHostPort(string field, string input, string backtrace);
97        error NotIpPort(string field, string input, string backtrace);
98    }
99}
100
101impl ValidatorConfigError {
102    /// Creates an error for unauthorized access.
103    pub const fn unauthorized() -> Self {
104        Self::Unauthorized(IValidatorConfig::Unauthorized {})
105    }
106
107    /// Creates an error when validator already exists.
108    pub const fn validator_already_exists() -> Self {
109        Self::ValidatorAlreadyExists(IValidatorConfig::ValidatorAlreadyExists {})
110    }
111
112    /// Creates an error when validator is not found.
113    pub const fn validator_not_found() -> Self {
114        Self::ValidatorNotFound(IValidatorConfig::ValidatorNotFound {})
115    }
116
117    /// Creates an error when public key is invalid (zero).
118    pub const fn invalid_public_key() -> Self {
119        Self::InvalidPublicKey(IValidatorConfig::InvalidPublicKey {})
120    }
121
122    pub fn not_host_port(field: String, input: String, backtrace: String) -> Self {
123        Self::NotHostPort(IValidatorConfig::NotHostPort {
124            field,
125            input,
126            backtrace,
127        })
128    }
129
130    pub fn not_ip_port(field: String, input: String, backtrace: String) -> Self {
131        Self::NotIpPort(IValidatorConfig::NotIpPort {
132            field,
133            input,
134            backtrace,
135        })
136    }
137}