Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 48 additions & 7 deletions KIPs/kip-290.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ struct NodeInfo {
uint256 gcId;
/// @dev BLS public key and proof-of-possession (immutable)
BlsPublicKeyInfo blsInfo;
/// @dev Human-readable node name (mutable)
string name;
/// @dev Validator metadata in JSON format (mutable)
string metadata;
/// @dev Current state of the node
Expand Down Expand Up @@ -118,9 +120,10 @@ enum State {

The `metadata` field in `NodeInfo` is a JSON-encoded string. All fields are optional. Unrecognized fields SHOULD be ignored by readers.

> **Note**: The node operator name is stored as the top-level `name` field in `NodeInfo` (a required parameter of `createNode`), not inside `metadata`.

| Field | Type | Description |
| ------------- | -------- | ---------------------------------- |
| `name` | string | Human-readable node operator name |
| `thumbnail` | string | URL to operator thumbnail/logo |
| `summary` | string | Short description |
| `description` | string | Long description |
Expand All @@ -132,7 +135,6 @@ Example:

```json
{
"name": "Kaia Foundation",
"thumbnail": "https://cdn.prod.website-files.com/66a8ba5239a3fbe8e678da2a/69866193d03bf54b81aa0283_66ce395e60f880698890073dcc91fa28_kaia-logo.svg",
"summary": "The organization behind the Kaia blockchain.",
"description": "The Kaia Foundation is the organization behind the Kaia blockchain, an EVM-compatible Layer 1 built for stablecoin settlement and onchain finance across Asia.",
Expand All @@ -144,27 +146,53 @@ Example:

#### Interface

AddressBookV2 replaces the existing AddressBook at `0x0000000000000000000000000000000000000400` starting from `FORK_BLOCK`. The interface is divided into user functions (called by node manager), system functions (called by core client via system transaction following [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) convention), and admin functions (called by contract owner).
AddressBookV2 replaces the existing AddressBook at `0x0000000000000000000000000000000000000400` starting from `FORK_BLOCK`. The interface is divided into user functions (called by node manager), system functions (called by core client via system transaction following [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) convention), and admin functions (called by contract owner or designated roles).

```solidity
pragma solidity ^0.8.0;

import {State, BlsPublicKeyInfo, NodeInfo, Profile} from "./types/Node.sol";

interface IAddressBookV2 {
// ── Errors ──
error OnlySuspender();
error OnlyConfigurator();
error InvalidState();
error SlotsFull();
error InvalidInput();
error StakingTooLow();
error NodeAlreadyExists();
error NodeNotFound();
error TimeoutExpired();
error AlreadySuspended();
error NotSuspended();
error PDEnabled();
error InsufficientNodeBalance();
error GcIdAlreadyAssigned();
error GcIdNotAssigned();

// ── Events ──
event StateChanged(address indexed nodeId, State indexed fromState, State indexed toState);
event NodeCreated(address indexed nodeId, uint256 gcId);
event NodeCreated(address indexed nodeId);
event GcIdAssigned(address indexed nodeId, uint256 gcId);
event NodeDeleted(address indexed nodeId);
event ValidatorSuspended(address indexed nodeId);
event ValidatorUnsuspended(address indexed nodeId);
event CandidateReadied(address indexed nodeId);
event CandidateUnreadied(address indexed nodeId);
event ValidatorsInitialized(address[] nodeIds);
event SystemTransitionProcessed(address[] nodeIds, State[] newStates);
event EpochTransitionProcessed(uint256 epochVACount);
event UintConfigUpdated(uint8 indexed configId, uint256 oldValue, uint256 newValue);
event AddressConfigUpdated(uint8 indexed configId, address oldValue, address newValue);

// ── User Functions (called by node manager) ──

/// @notice Register a new node in Registered state
/// @notice Register a new node in Registered state; name must be non-empty
function createNode(
address nodeId, address stakingContract, address rewardAddress,
address voterAddress, BlsPublicKeyInfo memory blsInfo, string memory metadata
address voterAddress, BlsPublicKeyInfo memory blsInfo,
string memory name, string memory metadata
) external;

/// @notice Remove a Registered node entirely
Expand Down Expand Up @@ -207,10 +235,21 @@ interface IAddressBookV2 {
uint256 epochVACount
) external;

// ── Admin Functions (called by contract owner) ──
// ── Admin Functions ──

/// @notice Emergency suspension (called by suspender)
function suspendValidator(address nodeId) external;
/// @notice Lift suspension (called by suspender)
function unsuspendValidator(address nodeId) external;
/// @notice Update suspender address (called by owner)
function updateSuspender(address newSuspender) external;
/// @notice Update configurator address (called by owner)
function updateConfigurator(address newConfigurator) external;
/// @notice Assign auto-incremented gcId to a node (called by configurator)
function assignGcId(address nodeId) external;
/// @notice Revoke gcId from a node, setting it back to 0 (called by configurator)
function revokeGcId(address nodeId) external;

function updatePauseTimeout(uint256 newPauseTimeout) external;
function updateIdleTimeout(uint256 newIdleTimeout) external;
function updateMaxNodeCount(uint256 newMaxNodeCount) external;
Expand All @@ -221,6 +260,8 @@ interface IAddressBookV2 {

// ── Getters ──

function getSuspender() external view returns (address);
function getConfigurator() external view returns (address);
function getNodeInfo(address nodeId) external view returns (NodeInfo memory);
function getNodeInfos(address[] calldata nodeIds) external view returns (NodeInfo[] memory);
function getAllProfiles() external view returns (Profile[] memory);
Expand Down
Loading