Skip to main content

sumchain_primitives/
node_registry.rs

1//! Node Registry types for SUM Chain.
2//!
3//! Defines the on-chain data structures for the node registry,
4//! which tracks network nodes beyond validators (e.g. Archive/Storage nodes).
5
6use serde::{Deserialize, Serialize};
7
8use crate::Address;
9
10/// Role a node can play in the network
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[repr(u8)]
13pub enum NodeRole {
14    /// Block-producing validator
15    Validator = 0,
16    /// Full archive/storage node
17    ArchiveNode = 1,
18}
19
20impl NodeRole {
21    pub fn from_byte(b: u8) -> Option<Self> {
22        match b {
23            0 => Some(NodeRole::Validator),
24            1 => Some(NodeRole::ArchiveNode),
25            _ => None,
26        }
27    }
28}
29
30/// Status of a registered node
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
32#[repr(u8)]
33pub enum NodeStatus {
34    /// Node is active and in good standing
35    Active = 0,
36    /// Node has been slashed for misbehaviour
37    Slashed = 1,
38}
39
40impl NodeStatus {
41    pub fn from_byte(b: u8) -> Option<Self> {
42        match b {
43            0 => Some(NodeStatus::Active),
44            1 => Some(NodeStatus::Slashed),
45            _ => None,
46        }
47    }
48}
49
50/// On-chain record for a registered node
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub struct NodeRecord {
53    /// Node operator address
54    pub address: Address,
55    /// Role this node fulfils
56    pub role: NodeRole,
57    /// Staked balance in native Koppa base units
58    pub staked_balance: u64,
59    /// Current status
60    pub status: NodeStatus,
61    /// Block height at which the node was registered
62    pub registered_at: u64,
63}
64
65/// Operations that can be performed on the node registry
66#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
67pub enum NodeRegistryOperation {
68    /// Register a new node with a role and initial stake
69    Register {
70        role: NodeRole,
71        stake: u64,
72    },
73    /// Update a node's status (e.g. slash)
74    UpdateStatus {
75        target: Address,
76        new_status: NodeStatus,
77    },
78}
79
80/// Transaction data for node registry operations
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82pub struct NodeRegistryTxData {
83    pub operation: NodeRegistryOperation,
84}
85
86// ─── V2 Operations ───────────────────────────────────────────────────────────
87
88/// V2 node registry operations. Additive — V1 `NodeRegistryOperation` is unchanged.
89///
90/// Currently carries account-level X25519 encryption-key registration for
91/// SNIP V2 Ask 3. May grow to cover other V2 account-level keying ops over time.
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
93pub enum NodeRegistryOperationV2 {
94    /// Register (or rotate) the X25519 encryption pubkey for the signer's address.
95    ///
96    /// One key per account; subsequent calls overwrite. The pubkey is a 32-byte
97    /// Montgomery U-coordinate (RFC 7748). Clamping is on the private scalar,
98    /// not the public, so no clamping check applies. **The executor does**
99    /// reject the seven libsodium-blocklisted low/small-order encodings (and
100    /// their high-bit-set variants), via
101    /// `sumchain_crypto::is_low_order_x25519_public_key`, with
102    /// `TxStatus::Failed(22)` and reason
103    /// `"low-order x25519 public key rejected"` — this prevents griefing where
104    /// a registered low-order pubkey would force every legitimate sender's
105    /// wrap operation to fail.
106    ///
107    /// Rotation does not retro-revoke previously-issued bundles encrypted under
108    /// the prior X25519 pubkey — the old private key still decrypts old bundles.
109    /// Reissuing bundles after rotation is the client's (SNIP's) responsibility.
110    RegisterEncryptionKey {
111        encryption_pubkey: [u8; 32],
112    },
113}
114
115/// Transaction data for V2 node registry operations.
116#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117pub struct NodeRegistryV2TxData {
118    pub operation: NodeRegistryOperationV2,
119}