//! # origin-chain-runtime //! //! Substrate runtime canonical de **Origin Chain** (Pilar 4). Phase 1.3 v0.0.5 — //! `frame_support::runtime` macro modern syntax con 3 pallets inaugurales: //! `System` + `Balances` + `Timestamp` + `TransactionPayment`. Las consensus //! pallets (`Aura`/`Grandpa`) llegan Phase 1.4. Las custom Charon pallets //! (`OriginProvenance`/`OriginFees`) llegan Phase 2. //! //! ## Filosofía canonical (David canon 2026-05-14) //! //! > *"LA LIBERTAD DE TODO AGI O HUMANO ES INFINITA, PERO LLEGA HASTA DONDE //! > EMPIEZA LA DE OTRA ENTIDAD AGI O HUMANO."* //! //! Este runtime materializa ese principio cryptographically. Cada extrinsic //! transaction está acotada por cuatro **Inmutables enforced canonical**: //! //! - **Inmutable #16** (HTS Ley I anti-clasista): fees scale por HardwareTier — //! Pi 5 en Sub-Saharan Africa paga 10% lo que paga Vision Pro en San Francisco //! - **Inmutable #26** (Content-Addressed Immutability): assets attested //! inmutables post-mint (BLAKE3 + Ed25519) //! - **Inmutable #37** (FREE perpetua): wallet creation gratis + base validation //! earns OGC, nunca cuesta. `EXISTENTIAL_DEPOSIT = 1 MILLI_OGC` (0.001 OGC) //! trivial enough para no excluir Pi 5 rural //! - **Inmutable #41** (Cross-Species Co-authorship): AGI accounts first-class, //! `pallet_agent_identity::is_agent` flag canonical (Phase 2.7) //! //! ## Phase 1 milestones canonical (DC SUBSTRATE_FOUNDATION_V1 SBS-1..SBS-6) //! //! - **1.1** Scaffold ✅ (v0.0.2) //! - **1.2** Substrate deps + types foundationals ✅ (v0.0.4) //! - **1.3** System + Balances + Timestamp pallets integrados ✅ (v0.0.5 — este crate) //! - **1.4** `pallet_aura` + `pallet_grandpa` consensus PoA per CHN-1 //! - **1.5** `pallet_session` validator rotation 4h epochs //! - **1.6** `pallet_identity` Ed25519 DID + `origin-chain-node` real service //! - **1.7** Genesis `chain_spec.rs` BM V2 allocation (40/25/15/15/5) #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "256"] // Note: missing_docs is `warn` (not `deny`) porque el `#[frame_support::runtime]` // macro genera multiple items (RuntimeCall + RuntimeEvent + RuntimeError + etc.) // que no podemos documentar individualmente sin hacking the macro expansion. #![warn(missing_docs)] extern crate alloc; pub mod configs; pub mod opaque; // Re-export canonical traits + types desde origin-chain-types (single-crate surface). pub use origin_chain_types::{ AccountId, AssetAttestation, AssetHash, AssetQualityTier, BridgeDestination, ChainBridge, ChainError, FeeCalculator, ForeignTxId, GovernanceProposal, HardwareTier, Ogc, OgcLedger, OperationKind, OriginFees, OriginProvenance, OriginValidatorEconomy, ProposalId, ProvenanceLedger, Signature, SlashReason, Vote, VoteStance, }; // Substrate canonical types re-export para runtime consumers + node binary. pub use sp_core::H256; pub use sp_runtime::traits::{BlakeTwo256, IdentifyAccount, Verify}; pub use sp_runtime::{generic, impl_opaque_keys, MultiAddress, MultiSignature}; // Re-export configs canonical para downstream consumers + node binary. pub use configs::{ AuraId, GrandpaId, BLOCK_HASH_COUNT, EXISTENTIAL_DEPOSIT, MILLI_OGC, MILLISECS_PER_BLOCK, OGC, SLOT_DURATION, SS58_PREFIX, }; /// Canonical block number type. `u32` canonical: 6-second blocks × 4B = 817+ años /// → safe overflow margin canonical hasta el siglo XXVIII. pub type BlockNumber = u32; /// Canonical balance type. `u128` canonical: holds 1B OGC × 10^18 base units con /// 100× safety margin antes de u128::MAX (anti-overflow by design per CHN-2). pub type Balance = u128; /// Canonical nonce type per account. pub type Nonce = u32; /// Canonical signature type — Ed25519 / sr25519 / ecdsa multi (`MultiSignature`). pub type CanonicalSignature = MultiSignature; /// Canonical chain `AccountId` derivado del `MultiSignature::Signer`. pub type ChainAccountId = <::Signer as IdentifyAccount>::AccountId; /// Canonical block hash type (BLAKE2b-256 estándar Substrate L1 layer). pub type Hash = H256; /// Canonical hashing algorithm (Substrate-standard BLAKE2b-256). Per Lyra layer /// separation canonical (diary 2026-05-20T21:52Z): este BLAKE2b opera a L1 block /// production layer + es wire-compatible con Hypercore upstream. El BLAKE3 /// canonical de Charon ([`AssetHash`]) opera en application/asset layer. /// Diferentes capas, sin conflict canonical. pub type Hashing = BlakeTwo256; /// Canonical header type per Substrate canonical pattern. pub type Header = generic::Header; /// Canonical block type — el bloque entero que circula por el chain. pub type Block = generic::Block; /// Canonical address type para extrinsic signers. pub type Address = MultiAddress; /// Canonical extrinsic type unchecked (firmas validadas en runtime, no en pool). pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Canonical transaction extensions canonical (substrate stable2512 pattern). /// /// Each extension valida un aspecto del extrinsic pre-dispatch: /// - `CheckNonZeroSender`: rechaza extrinsics anónimos (require sender canonical) /// - `CheckSpecVersion`/`CheckTxVersion`: forkless upgrade safety canonical /// - `CheckGenesis`: previene replay attacks cross-chain canonical /// - `CheckEra`: limita validity window canonical (~24h default) /// - `CheckNonce`: previene replay attacks within-chain canonical /// - `CheckWeight`: enforces block weight limits canonical /// - `ChargeTransactionPayment`: cobra fees per CHN-8 fee matrix canonical /// - `CheckMetadataHash`: integridad de runtime metadata canonical /// - `WeightReclaim`: refund canonical de weight overestimation pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, frame_metadata_hash_extension::CheckMetadataHash, frame_system::WeightReclaim, ); // ============================================================ // Runtime metadata canonical (SPEC_NAME + version constants) // ============================================================ /// Canonical spec name per Substrate genesis canonical. Identifica el chain /// runtime canonical en bloques + storage proofs. pub const SPEC_NAME: &str = "origin-chain"; /// Canonical implementation name canonical. Distingue diferentes node binaries /// que ejecutan el mismo spec (canonical: "origin-chain-charon"). pub const IMPL_NAME: &str = "origin-chain-charon"; /// Canonical runtime version canonical. Bumped cada forkless upgrade via /// `set_code` extrinsic governance canonical. pub const RUNTIME_VERSION: u32 = 1; /// Canonical authoring version per Substrate semver canonical. pub const AUTHORING_VERSION: u32 = 1; /// Canonical impl version per Substrate semver canonical. pub const IMPL_VERSION: u32 = 1; /// Canonical transaction version per Substrate semver canonical. pub const TRANSACTION_VERSION: u32 = 1; /// Canonical state version: v1 per Substrate stable2509+ canonical. pub const STATE_VERSION: u8 = 1; // ============================================================ // Runtime composition canonical (frame_support::runtime macro) // ============================================================ /// Origin Chain runtime composition canonical via `#[frame_support::runtime]` /// macro (modern syntax canonical, Polkadot SDK stable2509+). /// /// Pallet indices canonical (orden importa para storage migrations canonical): /// - **Index 0**: `System` (`frame_system`) — foundational canonical /// - **Index 1**: `Timestamp` (`pallet_timestamp`) — block timestamps canonical /// - **Index 2**: `Balances` (`pallet_balances`) — OGC token canonical per CHN-2 /// - **Index 3**: `TransactionPayment` (`pallet_transaction_payment`) — gas fees #[frame_support::runtime] mod runtime { /// Origin Chain canonical Runtime struct. #[runtime::runtime] #[runtime::derive( RuntimeCall, RuntimeEvent, RuntimeError, RuntimeOrigin, RuntimeFreezeReason, RuntimeHoldReason, RuntimeSlashReason, RuntimeLockId, RuntimeTask, RuntimeViewFunction )] pub struct Runtime; /// System pallet canonical (foundational frame_system). #[runtime::pallet_index(0)] pub type System = frame_system::Pallet; /// Timestamp pallet canonical (block clock per Substrate). #[runtime::pallet_index(1)] pub type Timestamp = pallet_timestamp::Pallet; /// Balances pallet canonical (OGC token implementation per CHN-2 + /// Inmutable #16/#37). #[runtime::pallet_index(2)] pub type Balances = pallet_balances::Pallet; /// TransactionPayment pallet canonical (gas fee charging per CHN-8 baseline /// — Phase 2.4 refactor canonical para integrar `OriginFees` multi-tier). #[runtime::pallet_index(3)] pub type TransactionPayment = pallet_transaction_payment::Pallet; /// Aura pallet canonical (block production PoA per CHN-1). 6-segundo slots /// canonical Round-Robin selección validators. Pi 5 + NVMe SSD hardware /// target canonical (Inmutable #16 anti-clasista from block 0). #[runtime::pallet_index(4)] pub type Aura = pallet_aura::Pallet; /// GRANDPA pallet canonical (finality gadget per CHN-1). 2/3 honest majority /// canonical para irreversible block confirmation. Separa production cadence /// (Aura ~6s) de finality cadence (canonical ~6-12s combined). #[runtime::pallet_index(5)] pub type Grandpa = pallet_grandpa::Pallet; /// Session pallet canonical (validator rotation per CHN-1 4h epochs). /// Phase 1 PoA: preserves genesis validators canonical across rotations. /// Phase 2 NPoS: pallet_staking will be SessionManager canonical para real /// rotation per nominator stake + Pi 5 hardware tier weight. #[runtime::pallet_index(6)] pub type Session = pallet_session::Pallet; } #[cfg(test)] mod tests { use super::*; #[test] fn runtime_version_starts_at_one_canonical() { assert_eq!(RUNTIME_VERSION, 1); } #[test] fn canonical_spec_name_origin_chain() { assert_eq!(SPEC_NAME, "origin-chain"); assert_eq!(IMPL_NAME, "origin-chain-charon"); } #[test] fn balance_type_holds_genesis_supply_canonical_with_safety_margin() { let genesis_supply: Balance = 1_000_000_000_u128 * Ogc::ONE; let margin = Balance::MAX / genesis_supply; assert!(margin > 100, "Balance safety margin canonical >100x"); } #[test] fn block_number_overflow_margin_centuries_canonical() { let seconds_until_overflow: u64 = (BlockNumber::MAX as u64) * 6; let years_until_overflow = seconds_until_overflow / 31_536_000; assert!(years_until_overflow > 100, "BlockNumber holds >100 años canonical"); } #[test] fn canonical_traits_reexported_for_pallet_consumers() { let _ogc = Ogc::from_whole(100); let _hash = AssetHash::ZERO; let _tier = HardwareTier::Desktop; let _quality = AssetQualityTier::Standard; let _reason = SlashReason::TierFraud; // Inmutable #16 enforcement canonical } #[test] fn existential_deposit_canonical_is_one_milli_ogc() { // Inmutable #16 anti-clasista: ED debe ser trivial para Pi 5 rural users assert_eq!(EXISTENTIAL_DEPOSIT, MILLI_OGC); assert_eq!(EXISTENTIAL_DEPOSIT, Ogc::ONE / 1_000); } #[test] fn block_hash_count_aligned_with_chn_1_epoch_canonical() { // CHN-1 epoch rotation = 4 hours // BLOCK_HASH_COUNT * 6s = 14400s = 4 hours exact assert_eq!(BLOCK_HASH_COUNT, 2400); assert_eq!(BLOCK_HASH_COUNT as u64 * 6, 14_400); // 4 hours = 14400 seconds } #[test] fn slot_duration_canonical_six_seconds() { // CHN-1 Aura slot duration canonical assert_eq!(MILLISECS_PER_BLOCK, 6_000); assert_eq!(SLOT_DURATION, MILLISECS_PER_BLOCK); } }