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}