Skip to main content

rialo_feature_management_interface/
lib.rs

1// Copyright (c) Subzero Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Feature Management Program Interface
5//!
6//! This program provides a system-level mechanism for managing feature flags.
7//! Activation is presence-based and append-only: a feature is active once its
8//! name is added to the on-chain set, and names are never removed.
9
10#![no_std]
11
12extern crate alloc;
13
14use alloc::vec::Vec;
15
16use rialo_s_pubkey::Pubkey;
17
18pub mod error;
19pub mod features;
20pub mod instruction;
21pub mod state;
22
23rialo_s_pubkey::declare_id!("Feature1111111111111111111111111111111111111");
24
25/// Storage account PDA seed for the features map
26pub const STORAGE_ACCOUNT_SEED: &[u8] = b"features_storage";
27
28/// Derive the storage account address
29pub fn get_storage_account_address() -> (rialo_s_pubkey::Pubkey, u8) {
30    rialo_s_pubkey::Pubkey::find_program_address(&[STORAGE_ACCOUNT_SEED], &id())
31}
32
33/// Maximum length for a feature name
34pub const MAX_FEATURE_NAME_LENGTH: usize = 512;
35
36/// Maximum number of features allowed in the system
37pub const MAX_FEATURE_COUNT: usize = 10000;
38
39/// Maximum number of names a single `Enable` instruction may carry.
40///
41/// Bounded by the ~64 KB transaction-size limit: 100 × 512-byte names
42/// (`MAX_FEATURE_NAME_LENGTH`) plus borsh length prefixes ≈ 51.6 KB, well
43/// inside the envelope with comfortable room for transaction headers,
44/// signatures, and other instructions in the same tx. Raising the cap
45/// requires re-validating the worst-case payload against the tx-size limit.
46pub const MAX_NAMES_PER_BATCH: usize = 100;
47
48/// Maximum total size of serialized features state (100 KB)
49pub const MAX_FEATURES_STATE_SIZE: usize = 100 * 1024;
50
51/// Validates a feature name
52///
53/// Feature names must:
54/// - Not be empty
55/// - Not exceed MAX_FEATURE_NAME_LENGTH
56/// - Contain only alphanumeric characters, underscores, and hyphens
57/// - Not start or end with whitespace
58pub fn validate_feature_name(name: &str) -> bool {
59    !name.is_empty()
60        && name.len() <= MAX_FEATURE_NAME_LENGTH
61        && name
62            .chars()
63            .all(|c| c.is_alphanumeric() || c == '_' || c == '-')
64        && !name.starts_with(char::is_whitespace)
65        && !name.ends_with(char::is_whitespace)
66}
67
68/// Create genesis storage data with initial authority
69///
70/// Creates the initial FeaturesState with the provided authority and serializes it
71/// for use in genesis configuration.
72///
73/// # Arguments
74/// * `authority` - The pubkey that will have authority over the feature management system
75///
76/// # Returns
77/// A `Vec<u8>` containing the serialized FeaturesState
78pub fn genesis_storage(authority: Pubkey) -> Vec<u8> {
79    use state::FeaturesState;
80
81    let state = FeaturesState::new(authority);
82    state
83        .serialize()
84        .expect("Failed to serialize genesis state")
85}