Skip to main content

tempo_contracts/precompiles/
validator_config_v2.rs

1pub use IValidatorConfigV2::{
2    IValidatorConfigV2Errors as ValidatorConfigV2Error,
3    IValidatorConfigV2Events as ValidatorConfigV2Event,
4};
5
6crate::sol! {
7    /// Validator Config V2 interface for managing consensus validators with append-only,
8    /// delete-once semantics.
9    ///
10    /// V2 uses an append-only design that eliminates the need for historical state access
11    /// during node recovery. Validators are immutable after creation and can only be deleted once.
12    ///
13    /// Key differences from V1:
14    /// - `active` bool replaced by `addedAtHeight` and `deactivatedAtHeight`
15    /// - No `updateValidator` - validators are immutable after creation
16    /// - Requires Ed25519 signature on `addValidator` to prove key ownership
17    /// - Both address and public key must be unique across all validators (including deleted)
18    #[derive(Debug, PartialEq, Eq)]
19    #[sol(abi)]
20    interface IValidatorConfigV2 {
21        /// Validator information
22        struct Validator {
23            bytes32 publicKey;
24            address validatorAddress;
25            string ingress;
26            string egress;
27            address feeRecipient;
28            uint64 index;
29            uint64 addedAtHeight;
30            uint64 deactivatedAtHeight;
31        }
32
33        // =====================================================================
34        // View functions
35        // =====================================================================
36
37        /// Get only active validators (deactivatedAtHeight == 0)
38        function getActiveValidators() external view returns (Validator[] memory validators);
39
40        /// Get the block height at which the contract was initialized
41        function getInitializedAtHeight() external view returns (uint64);
42
43        /// Get the contract owner
44        function owner() external view returns (address);
45
46        /// Get total count of validators ever added (including deactivated)
47        function validatorCount() external view returns (uint64);
48
49        /// Get validator by index
50        function validatorByIndex(uint64 index) external view returns (Validator memory);
51
52        /// Get validator by address
53        function validatorByAddress(address validatorAddress) external view returns (Validator memory);
54
55        /// Get validator by public key
56        function validatorByPublicKey(bytes32 publicKey) external view returns (Validator memory);
57
58        /// Get the epoch for next network identity rotation (full DKG ceremony)
59        function getNextNetworkIdentityRotationEpoch() external view returns (uint64);
60
61        /// Check if V2 has been initialized
62        function isInitialized() external view returns (bool);
63
64        // =====================================================================
65        // Mutate functions
66        // =====================================================================
67
68        /// Add a new validator (owner only)
69        function addValidator(
70            address validatorAddress,
71            bytes32 publicKey,
72            string calldata ingress,
73            string calldata egress,
74            address feeRecipient,
75            bytes calldata signature
76        ) external returns (uint64 index);
77
78        /// Deactivate a validator (owner or validator)
79        function deactivateValidator(uint64 idx) external;
80
81        /// Rotate a validator to new identity (owner or validator)
82        function rotateValidator(
83            uint64 idx,
84            bytes32 publicKey,
85            string calldata ingress,
86            string calldata egress,
87            bytes calldata signature
88        ) external;
89
90        /// Update fee recipient.
91        function setFeeRecipient(
92            uint64 idx,
93            address feeRecipient
94        ) external;
95
96        /// Update IP addresses (owner or validator)
97        function setIpAddresses(
98            uint64 idx,
99            string calldata ingress,
100            string calldata egress
101        ) external;
102
103        /// Transfer validator ownership to new address (owner or validator)
104        function transferValidatorOwnership(
105            uint64 idx,
106            address newAddress
107        ) external;
108
109        /// Transfer contract ownership (owner only)
110        function transferOwnership(address newOwner) external;
111
112        /// Set the epoch for next network identity rotation via full DKG ceremony (owner only)
113        function setNetworkIdentityRotationEpoch(uint64 epoch) external;
114
115        /// Migrate a single validator from V1 (owner only)
116        function migrateValidator(uint64 idx) external;
117
118        /// Initialize V2 after migration (owner only)
119        function initializeIfMigrated() external;
120
121        // =====================================================================
122        // Events
123        // =====================================================================
124
125        event ValidatorAdded(uint64 indexed index, address indexed validatorAddress, bytes32 publicKey, string ingress, string egress, address feeRecipient);
126        event ValidatorDeactivated(uint64 indexed index, address indexed validatorAddress);
127        event ValidatorRotated(
128            uint64 indexed index,
129            uint64 indexed deactivatedIndex,
130            address indexed validatorAddress,
131            bytes32 oldPublicKey,
132            bytes32 newPublicKey,
133            string ingress,
134            string egress,
135            address caller
136        );
137        event FeeRecipientUpdated(uint64 indexed index, address feeRecipient, address caller);
138        event IpAddressesUpdated(uint64 indexed index, string ingress, string egress, address caller);
139        event ValidatorOwnershipTransferred(uint64 indexed index, address indexed oldAddress, address indexed newAddress, address caller);
140        event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
141        event ValidatorMigrated(uint64 indexed index, address indexed validatorAddress, bytes32 publicKey);
142        event NetworkIdentityRotationEpochSet(uint64 indexed previousEpoch, uint64 indexed nextEpoch);
143        event Initialized(uint64 height);
144        event SkippedValidatorMigration(uint64 indexed index, address indexed validatorAddress, bytes32 publicKey);
145
146        // =====================================================================
147        // Errors
148        // =====================================================================
149
150        error AlreadyInitialized();
151        error IngressAlreadyExists(string ingress);
152        error EmptyV1ValidatorSet();
153        error InvalidMigrationIndex();
154        error InvalidOwner();
155        error InvalidPublicKey();
156        error InvalidSignature();
157        error InvalidSignatureFormat();
158        error InvalidValidatorAddress();
159        error MigrationNotComplete();
160        error NotInitialized();
161        error NotIp(string input, string backtrace);
162        error NotIpPort(string input, string backtrace);
163        error PublicKeyAlreadyExists();
164        error Unauthorized();
165        error AddressAlreadyHasValidator();
166        error ValidatorAlreadyDeactivated();
167        error ValidatorNotFound();
168    }
169}
170
171impl ValidatorConfigV2Error {
172    /// Backwards-compatible alias for the Alloy-generated `empty_v_1_validator_set` constructor.
173    pub fn empty_v1_validator_set() -> Self {
174        Self::empty_v_1_validator_set()
175    }
176}