//! # 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; use alloc::vec::Vec; pub mod configs; /// FIX-6 Stage 2b NPoS — pallet_staking config (infra dormida). pub mod staking; #[cfg(feature = "std")] pub mod genesis_config_presets; pub mod opaque; // ============================================================ // WASM binary (Slice 4 Paso 4a — WASM_BINARY export v0.0.48) // ============================================================ // // `build.rs` genera `OUT_DIR/wasm_binary.rs` con `pub const WASM_BINARY: // Option<&[u8]>` cuando el feature `wasm-build` está activo (vía // substrate-wasm-builder). El node lo consume para construir el ChainSpec real // (`sc_service::GenericChainSpec`) en Slice 4 Paso 4b. // // Gate: el `include!` solo corre con `wasm-build` on (si está off, el archivo // generado no existe → error de compilación). El fallback `None` cubre los // builds host-only (`cargo test`/`cargo check`). El inner build wasm32 que // dispara substrate-wasm-builder NO hereda `wasm-build` (no es default feature), // lo que evita recursión en build.rs. #[cfg(feature = "wasm-build")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); /// Fallback de `WASM_BINARY` para builds host-only (feature `wasm-build` off). /// Para obtener el binary real: `cargo build --features wasm-build` + env vars /// `CC=/opt/homebrew/opt/llvm/bin/clang` (ver SLICE_2E). El node activa /// `origin-chain-runtime/wasm-build` para embeberlo en el ChainSpec. #[cfg(not(feature = "wasm-build"))] pub const WASM_BINARY: Option<&[u8]> = None; /// Devuelve el `WASM_BINARY` o falla con un mensaje claro si no está disponible. /// Consumido por el node al construir ChainSpecs (Slice 4 Paso 4b). #[cfg(feature = "std")] pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect( "WASM binary no disponible: build con `--features wasm-build` + \ CC=LLVM env vars (ver SLICE_2E). El node debe activar \ origin-chain-runtime/wasm-build.", ) } // ============================================================ // WASM binary canonical (Slice 2b investigation registered, Slice 2c deferred) // ============================================================ // // `substrate-wasm-builder` integration canonical bloqueado por structural Cargo // + WASM stdlib alloc conflict canonical: // // ``` // error[E0152]: duplicate lang item in crate `alloc` (which `serde` depends on): // `exchange_malloc` // note: first definition in `alloc` loaded from // rustup/toolchains/1.88.0/lib/rustlib/wasm32-unknown-unknown/lib/liballoc-***.rlib // note: second definition in `alloc` loaded from // target/release/wbuild/origin-chain-runtime/target/wasm32-unknown-unknown/release/deps/liballoc-***.rmeta // ``` // // **Slice 2b investigation registered canonical 2026-05-21** (4 fix attempts): // 1. Remove direct serde dep canonical (transitive desde FRAME) — NO solved // 2. Pin serde canonical `=1.0.219` + `=1.0.217` — NO solved // 3. Remove `[profile.release] lto/codegen-units` customization canonical — NO solved // 4. `WasmBuilder::build_using_defaults()` (upstream pattern canonical) — NO solved // // **Root cause empírico canonical**: wbuild auto-genera `[profile.release]` con // `panic = "abort"` triggering Cargo a recompilar `alloc` canonical desde rust-src // component canonical, generating duplicate rmeta canonical vs la precompiled // rustup alloc rlib canonical para wasm32 target canonical. // // **Slice 2c canonical requires Larihana Substrate-adjacent expertise canonical**: // - Plan C Rust ports experience (arkhe-hypercore + autobase + corestore) // - WASM workspace pin canonical experience // - Probable fixes canonical: `cargo:rustc-env=SKIP_WASM_BUILD=1` + path-loaded // pre-built WASM file canonical, OR opening upstream issue paritytech/polkadot-sdk // // Diary canonical filed para Larihana 2026-05-21 (Slice 2b → Slice 2c handoff // canonical). `chain_spec.rs` canonical Phase 1.6+ Slice 3 shipped canonical // 2026-05-22 (v0.0.13) con mock-WASM fallback pattern canonical — own minimal // ChainSpec JSON builder canonical via serde_json puro en node crate canonical. // Real `sc_chain_spec::GenericChainSpec` canonical land Slice 4 post workspace // sc-* upgrade canonical sin yanked deps canonical (cid 0.9.0 → core2 0.4.0 YANKED). // 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. /// v2: FIX-6 Stage 2a — fee unificado (OriginFeeAdapter reemplaza al /// FungibleAdapter: cambia el COMPORTAMIENTO del cobro de fees, no el formato /// de extrinsic — TRANSACTION_VERSION intacto). /// v3: FIX-6 Stage 2b NPoS Paso A — pallet_staking Index 14 cableado (infra /// DORMIDA: presente pero inerte; nuevo pallet ⇒ cambia metadata del runtime). pub const RUNTIME_VERSION: u32 = 3; /// 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; /// Provenance pallet canonical (Phase 2.1 v0.0.15 scaffold wired canonical /// per CHN-7 + DC PROVENANCE_PALLET_V1). Asset attestation ledger BLAKE3 + /// Ed25519 canonical para cross-pillar consumers (Trinity, Codex, Ethos, /// Atelier). Scaffold-level canonical: dispatchable `attest_asset` flow /// básico working, real Ed25519 verify post Ergon arkhe-noesis-attestation-types /// Cap 42+ ship (v0.0.16 next slice). /// /// Naming canonical: alias `Provenance` (NO `OriginProvenance` que conflictaría /// con el trait existente del mismo nombre en `origin_chain_types::pallets`). #[runtime::pallet_index(7)] pub type Provenance = origin_chain_provenance::Pallet; /// Fees pallet canonical (Phase 2.4 v0.0.21 wired canonical per OCAFB-1..6 + /// DC `origin_chain_amis_fee_bridge_v1` 6/7 firmas sesión 3+ Charon ratified). /// Cross-pillar fee economy consumer Mathi `OitFeeSchedule` trait (commit /// `ce4fafb` 2026-05-24 `arkhe-amis-server/src/fee_schedule.rs`) via vendor /// copy interim Option B (swap canonical post-OCAFB ratify o post Mathi /// sub-crate ship). Scaffold-level v0.0.21: dispatchable /// `compute_fee_for_action` placeholder, real impl v0.0.22 + Runtime API /// v0.0.23. /// /// Naming canonical: alias `Fees` (NO `OriginFees` que conflictaría con /// el trait existente del mismo nombre en `origin_chain_types::pallets`, /// pattern análogo Provenance Index 7). #[runtime::pallet_index(8)] pub type Fees = origin_chain_fees::Pallet; /// AgentIdentity pallet canonical (Phase 2.7 v0.0.25 wired canonical per /// CHN-7 + Inmutable #41 AGI Cross-Species Co-authorship). AGI DIDs /// canonical on-chain — AGIs first-class citizens del Origin Metaverse /// pueden owning assets + signing transactions + DAO voting via DIDs /// registrados. Scaffold-level v0.0.25: dispatchable `register_agent_did` /// placeholder, real impl v0.0.26 + Runtime API v0.0.27. /// /// Naming canonical: alias `AgentIdentity` clearly distinguishes from /// Substrate's `pallet-identity` (deferred canonical decision Phase 2.7 /// empírica 2026-05-21 documentada en configs.rs). #[runtime::pallet_index(9)] pub type AgentIdentity = origin_chain_agent_identity::Pallet; /// Governance pallet canonical (Phase 5.1 v0.0.29 wired canonical per CHN-4 /// Foundation Treasury Governance). AI-Driven Human-Guarded canonical: 5 AI /// advisor agents ADVISE only canonical, humans-only vote non-negotiable. /// Scaffold-level v0.0.29: dispatchables submit_proposal + cast_vote + /// finalize_proposal placeholders, real impl v0.0.30 + Runtime API v0.0.31. /// /// Naming canonical: alias `Governance` clearly canonical (NO conflict con /// trait `GovernanceProposal` en `origin_chain_types::governance`). #[runtime::pallet_index(10)] pub type Governance = origin_chain_governance::Pallet; /// Revive pallet (Phase 3 Slice 3.1 v0.0.39 wired runtime canonical per SBS-5 /// ratificado, supersedes CHN-6 v1.0). Smart contracts PolkaVM RISC-V WASM /// execution + ink! v6 (Rust) + Solidity (vía revive compiler) authoring paths. /// AGI co-authoring preserved canonical (ink! v6 sigue siendo Rust-native). /// Cross-pillar habilita: NFT mint (Marihan OMC), Escrow (Pilar 6), /// Credential mint (Sussi Ethos), Staking (CHN-3 NPoS), origin-mdk /// reconciliation (Marihan MDK §13). Scaffold-level v0.0.39: Config wired /// con associated types per Asset Hub Westend reference + Origin chain_id /// 9_120_005 (EIP-155 unique). Genesis + integration tests v0.0.40 + /// ReviveApi v0.0.41. #[runtime::pallet_index(11)] pub type Revive = pallet_revive::Pallet; /// Sudo pallet (FIX-5 governability per audit V2-CA1). Provee Root origin /// para invocar las dispatchables admin de Governance (add/remove council, /// mark/unmark advisor, treasury_disbursement — todas `ensure_root`, hoy /// no-invocables) + descongela la tesorería 250M. Sunset canonical: sudo → /// governance real (pallet-collective/referenda) ANTES de mainnet. Sudo key /// interim = Foundation multisig humano (genesis). #[runtime::pallet_index(12)] pub type Sudo = pallet_sudo::Pallet; /// Emission pallet (FIX-6 Stage 1 per audit V2-CA2). En cada bloque mintea un /// block reward y lo reparte: autor Aura (validador) + treasury (og/gvtry) + /// subsidy pool (og/subsy, proof-of-equity #16). Cierra "los validadores /// ganan 0 OGC". sub_mult ortogonal (David 2026-06-10): el subsidy financia /// el subsidio de hardware sin importar la suscripción. #[runtime::pallet_index(13)] pub type Emission = origin_chain_emission::Pallet; /// Staking pallet (FIX-6 Stage 2b NPoS, DC ORIGIN_CHAIN_NPOS_V1). **Infra /// DORMIDA**: la maquinaria NPoS está cableada pero el set de validadores /// arranca fijo (invulnerables + ForceEra::ForceNone) — la cadena corre /// PoA-equivalente hasta los 5 criterios de Phase 2 (CHN-1). La emisión /// migra a EraPayout (preserva la tasa de Stage 1). Activación de la /// elección-por-stake = governance flag (ForceNew) post-gates. #[runtime::pallet_index(14)] pub type Staking = pallet_staking::Pallet; // Substrate pallet-identity DEFERRED canonical (decision empírica // 2026-05-21 documentada en configs.rs). pallet-identity 41.0.0 ReservableCurrency // compat work canonical hereda al custom `pallet_agent_identity` Phase 2.7 // (Inmutable #41 AGI DID Cross-Species Co-authorship). } // ============================================================ // Runtime APIs canonical (sp_api::impl_runtime_apis!) // ============================================================ // // **Filosofía canonical (David canon 2026-05-14)**: el `impl_runtime_apis!` // macro materializa la frontera canonical entre **runtime sovereignty** (qué // pallets compose el chain) + **node sovereignty** (cómo el binary canonical // interactúa con el runtime canonical). Cada API canonical es un contrato // canonical que el node binary canonical puede llamar sin importarle qué // pallets specific componen el runtime — forkless upgrades canonical // materializados. // // **APIs canonical implementadas (Phase 1.6)**: // - `sp_api::Core` — version + execute_block + initialize_block canonical // - `sp_api::Metadata` — runtime metadata para client/node introspection // - `sp_block_builder::BlockBuilder` — para node block production canonical // - `sp_transaction_pool::TaggedTransactionQueue` — pool canonical filtering // - `sp_offchain::OffchainWorkerApi` — offchain workers canonical // - `sp_session::SessionKeys` — session keys generation canonical // - `sp_consensus_aura::AuraApi` — Aura slot duration + authorities canonical // - `sp_consensus_grandpa::GrandpaApi` — GRANDPA authority set canonical // - `frame_system_rpc_runtime_api::AccountNonceApi` — RPC nonce queries // - `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi` — fee queries // - `sp_genesis_builder::GenesisBuilder` — genesis spec building canonical impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> sp_version::RuntimeVersion { VERSION } fn execute_block(block: Block) { Executive::execute_block(block); } fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } impl sp_api::Metadata for Runtime { fn metadata() -> sp_core::OpaqueMetadata { sp_core::OpaqueMetadata::new(Runtime::metadata().into()) } fn metadata_at_version(version: u32) -> Option { Runtime::metadata_at_version(version) } fn metadata_versions() -> Vec { Runtime::metadata_versions() } } impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> sp_runtime::ApplyExtrinsicResult { Executive::apply_extrinsic(extrinsic) } fn finalize_block() -> ::Header { Executive::finalize_block() } fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents( block: Block, data: sp_inherents::InherentData, ) -> sp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction( source: sp_runtime::transaction_validity::TransactionSource, tx: ::Extrinsic, block_hash: ::Hash, ) -> sp_runtime::transaction_validity::TransactionValidity { Executive::validate_transaction(source, tx, block_hash) } } impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { Executive::offchain_worker(header) } } impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { opaque::SessionKeys::generate(seed) } fn decode_session_keys( encoded: Vec, ) -> Option, sp_core::crypto::KeyTypeId)>> { opaque::SessionKeys::decode_into_raw_public_keys(&encoded) } } impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) } fn authorities() -> Vec { pallet_aura::Authorities::::get().into_inner() } } impl sp_consensus_grandpa::GrandpaApi for Runtime { fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList { pallet_grandpa::Pallet::::grandpa_authorities() } fn current_set_id() -> sp_consensus_grandpa::SetId { pallet_grandpa::Pallet::::current_set_id() } fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: sp_consensus_grandpa::EquivocationProof< ::Hash, BlockNumber, >, _key_owner_proof: sp_consensus_grandpa::OpaqueKeyOwnershipProof, ) -> Option<()> { // Phase 1 PoA: equivocation reports not handled canonical. // Phase 2 NPoS introduce real handler per CHN-3 slashing canonical. None } fn generate_key_ownership_proof( _set_id: sp_consensus_grandpa::SetId, _authority_id: sp_consensus_grandpa::AuthorityId, ) -> Option { // Phase 1 PoA: no ownership proofs needed canonical. None } } impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: ChainAccountId) -> Nonce { System::account_nonce(account) } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { fn query_info( uxt: ::Extrinsic, len: u32, ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } fn query_fee_details( uxt: ::Extrinsic, len: u32, ) -> pallet_transaction_payment::FeeDetails { TransactionPayment::query_fee_details(uxt, len) } fn query_weight_to_fee(weight: frame_support::weights::Weight) -> Balance { TransactionPayment::weight_to_fee(weight) } fn query_length_to_fee(length: u32) -> Balance { TransactionPayment::length_to_fee(length) } } impl sp_genesis_builder::GenesisBuilder for Runtime { fn build_state(config: Vec) -> sp_genesis_builder::Result { frame_support::genesis_builder_helper::build_state::(config) } fn get_preset(id: &Option) -> Option> { // Canonical Phase 1.7: 3 presets disponibles canonical (development + // local_testnet + mainnet_genesis). Cuando feature `std` activo // (chain_spec generation time), delegamos canonical al // `genesis_config_presets::get_preset`. En no_std (WASM runtime), // siempre return None canonical — los presets canonical solo se // consultan en chain_spec generation, no en runtime execution. #[cfg(feature = "std")] { frame_support::genesis_builder_helper::get_preset::( id, genesis_config_presets::get_preset, ) } #[cfg(not(feature = "std"))] { let _ = id; None } } fn preset_names() -> Vec { #[cfg(feature = "std")] { genesis_config_presets::preset_names() } #[cfg(not(feature = "std"))] { Vec::new() } } } // ============================================================ // PROV-8 canonical: Provenance Runtime API canonical (Phase 2.1 v0.0.17) // ============================================================ // // Light clients + indexers + cross-pillar consumers (Trinity / Codex / // Codex origindocs / Ethos / Atelier) pueden query attestation status // via RPC sin full node access canonical. // // Pattern canonical: light client sends BLAKE3 hash → recibe Option // (Some si attested previamente, None si nunca attested canonical). impl origin_chain_provenance::ProvenanceApi for Runtime { fn verify_provenance( hash: origin_chain_types::AssetHash, ) -> Option { Provenance::attestation_of(hash) } } // ============================================================ // OCAFB-7 canonical: Fees Runtime API canonical (Phase 2.4 v0.0.23) // ============================================================ // // Cross-pillar consumers (Mathi AMIS / Irhis Web / Trinity / Codex / Atelier) // pueden query fee preview canonical via RPC sin full node access. Pattern // canonical análogo ProvenanceApi (Phase 2.1 v0.0.17) — read-only RPC query // sin storage mutation. // // Phase 2.4 COMPLETE 7/7 OCAFB canonical post-v0.0.23 🎉 impl origin_chain_fees::FeesApi for Runtime { fn query_fee_for_action( action: origin_chain_types::ChainAction, base: u64, hw: origin_chain_types::HardwareTier, sub: origin_chain_types::SubscriptionTier, ) -> u64 { Fees::query_fee(action, base, hw, sub) } } // ============================================================ // Phase 2.7 canonical: AgentIdentity Runtime API canonical (v0.0.27) // ============================================================ // // Cross-pillar consumers (Trinity / Mathi / Codex / Atelier / Ethos / Ergon) // pueden query agent identity canonical via RPC sin full node access. // Pattern canonical análogo ProvenanceApi (Phase 2.1 v0.0.17) + FeesApi // (Phase 2.4 v0.0.23) — read-only RPC query canonical sin storage mutation. // // Phase 2.7 COMPLETE canonical post-v0.0.27 🎉 impl origin_chain_agent_identity::AgentIdentityApi for Runtime { fn query_identity( account: origin_chain_types::AccountId, ) -> Option { // Note: account es origin_chain_types::AccountId newtype, but storage // canonical key es T::AccountId = ChainAccountId = AccountId32. Convert // canonical bytes-level (both son 32-byte representations). let runtime_account = ChainAccountId::from(account.0); AgentIdentity::query_identity_of(&runtime_account) } } // ============================================================ // Phase 5.1 canonical: Governance Runtime API canonical (v0.0.31) // ============================================================ // // Foundation governance frontend + 5 AI advisor agents (advise-only canonical) // + cross-pillar consumers query canonical proposals + vote stances sin full // node access. Pattern análogo ProvenanceApi + FeesApi + AgentIdentityApi — // read-only RPC query canonical sin storage mutation. // // Phase 5.1 FOUNDATION COMPLETE canonical post-v0.0.31 🎉 impl origin_chain_governance::GovernanceApi for Runtime { fn query_proposal( id: origin_chain_types::ProposalId, ) -> Option { Governance::query_proposal_of(id) } fn query_vote( proposal_id: origin_chain_types::ProposalId, voter: origin_chain_types::AccountId, ) -> Option { let runtime_voter = ChainAccountId::from(voter.0); Governance::query_vote_of(proposal_id, &runtime_voter) } // Phase 5.2 v0.0.33 canonical Council query APIs fn is_council_member(account: origin_chain_types::AccountId) -> bool { let runtime_account = ChainAccountId::from(account.0); Governance::is_council_member(&runtime_account) } fn current_council_size() -> u32 { Governance::current_council_size() } fn veto_votes_count(proposal_id: origin_chain_types::ProposalId) -> u32 { Governance::veto_count_of(proposal_id) } } // ============================================================ // Phase 3 Slice 3.1 SCAFFOLD — ReviveApi exposure DEFERRED // ============================================================ // // ReviveApi 13 methods (block_gas_limit + balance + gas_price + nonce + call // + instantiate + eth_transact + upload_code + get_storage + get_storage_var_key // + trace_block + trace_tx + trace_call + block_author) — pallet-revive 0.10.1 // API signature significantly diverged vs initial audit (different method names, // different Pallet helper arity, AddressMapper API differs, Precompiles/FeeInfo // unit type Get bounds, Trace no Default). 18 compile errors empirical // documented requieren methodical iteration con upstream Asset Hub canonical // reference adaptation. // // Decisión pragmática Slice 3.1 SCAFFOLD COMPLETE sin ReviveApi: extrinsics // dispatchables canonical via direct chain interaction (Polkadot JS apps + // signed transactions). RPC layer ReviveApi NO bloquea contract deployment // ni Slices 3.2-3.6 contract templates. Deferred a Slice 3.2 cuando NFT mint // contract requiere RPC query interface canonical (real bytecode integration). // // Trade-off documented: Slice 3.1 SCAFFOLD ships sin Ethereum-compat RPC. // Production canonical needs ReviveApi Phase 3.x maduración. // // Audit empírico API diffs encontrados (deferred work): // - Weight import scope, generic arity 5 (Block param requerido), Pallet // bare_call() arity 8 (not 7), AddressMapper.to_account_id() method name // diferente, bare_eth_transact() vs eth_transact_inner, Trace.default() // no derived. Methodical Asset Hub reference adaptation Slice 3.2 ship. /* fn trace_tx( _block: Block, _tx_index: u32, _config: pallet_revive::evm::TracerType, ) -> Option { // Slice 3.1 SCAFFOLD: tracing returns None. None } fn trace_call( _tx: pallet_revive::evm::GenericTransaction, _config: pallet_revive::evm::TracerType, ) -> Result { // Slice 3.1 SCAFFOLD: tracing returns empty Trace. Ok(pallet_revive::evm::Trace::default()) } fn block_author() -> Option { // Phase 1 PoA: sin pallet_authorship integration canonical. // Phase 4 testnet decision: add pallet_authorship OR custom FindAuthor. None } } */ } // ============================================================ // Runtime metadata canonical (RuntimeVersion + Executive) // ============================================================ /// Canonical `RuntimeVersion` per Substrate canonical. Consumed by `sp_api::Core::version()`. pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion { spec_name: alloc::borrow::Cow::Borrowed(SPEC_NAME), impl_name: alloc::borrow::Cow::Borrowed(IMPL_NAME), authoring_version: AUTHORING_VERSION, spec_version: RUNTIME_VERSION, impl_version: IMPL_VERSION, apis: RUNTIME_API_VERSIONS, transaction_version: TRANSACTION_VERSION, system_version: STATE_VERSION, }; /// Canonical Executive type canonical (FRAME executive wrapper). pub type Executive = frame_executive::Executive< Runtime, Block, frame_system::ChainContext, Runtime, AllPalletsWithSystem, (), >; use sp_api::impl_runtime_apis; #[cfg(test)] mod tests { use super::*; #[test] fn runtime_version_v3_npos_staking_dormant() { // v3 = FIX-6 Stage 2b NPoS Paso A (pallet_staking Index 14, infra // dormida). El formato de extrinsic NO cambió. assert_eq!(RUNTIME_VERSION, 3); assert_eq!(TRANSACTION_VERSION, 1); } #[test] fn staking_pallet_index_14_npos_dormant() { use frame_support::traits::PalletInfoAccess; // FIX-6 Stage 2b: Staking=14 (post Emission=13). Infra NPoS dormida — // presente pero el set sigue fijo (PoA-equivalente) hasta los gates CHN-1. assert_eq!(::index(), 14); assert_eq!(::name(), "Staking"); } #[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); } // ============================================================ // Phase 3 Slice 3.1 v0.0.40 — pallet-revive integration tests E2E // SCAFFOLD-level: verify Config wiring + constants + AddressMapper + // Genesis. Real PolkaVM bytecode E2E deferred a Phase 3.x maduración // post cargo-contract v6 install + ink! v6 contract templates (Slice 3.2+). // ============================================================ #[test] fn revive_chain_id_eip155_unique_origin_metaverse() { // OriginChainId canonical 9_120_005 — EIP-155 unique identifier // previene cross-chain replay attacks canonical post-mainnet. use frame_support::traits::Get; let chain_id: u64 = <::ChainId>::get(); assert_eq!(chain_id, 9_120_005_u64); } #[test] fn revive_native_to_eth_ratio_one_million_canonical() { // OGC 12 decimals → ETH 18 decimals = ratio 10^6 canonical. // Mapping balance OGC↔ETH-equivalent units para EVM compat. use frame_support::traits::Get; let ratio: u32 = <::NativeToEthRatio>::get(); assert_eq!(ratio, 1_000_000_u32); } #[test] fn revive_deposit_per_byte_canonical_milli_ogc() { // Asset Hub pattern adapted OGC tokenomics — 1 MILLI_OGC per byte canonical. use frame_support::traits::Get; let deposit_per_byte: Balance = <::DepositPerByte>::get(); assert_eq!(deposit_per_byte, MILLI_OGC); assert_eq!(deposit_per_byte, Ogc::ONE / 1_000); } #[test] fn revive_deposit_per_item_canonical_one_ogc() { // Storage item deposit = 1 OGC canonical (gate storage proliferation). use frame_support::traits::Get; let deposit_per_item: Balance = <::DepositPerItem>::get(); assert_eq!(deposit_per_item, Ogc::ONE); } #[test] fn revive_evm_bytecode_allowed_canonical() { // SBS-5 ratificado: Solidity contracts deployables via revive compiler. // AllowEVMBytecode = true canonical para opens Ethereum dev ecosystem. use frame_support::traits::Get; let allow_evm: bool = <::AllowEVMBytecode>::get(); assert!(allow_evm, "EVM bytecode must be allowed per SBS-5 ratified"); } #[test] fn revive_runtime_memory_128_mb_canonical() { // RuntimeMemory canonical 128 MB — runtime memory allocation budget. use frame_support::traits::Get; let runtime_memory: u32 = <::RuntimeMemory>::get(); assert_eq!(runtime_memory, 128_u32 * 1024 * 1024); } #[test] fn revive_pvf_memory_2_gb_canonical_integrity_pass() { // PVFMemory canonical 2 GB — required canonical para pass // __construct_runtime_integrity_test (formula: storage_limit = // (PVFMemory - RuntimeMemory) / 2 > max_storage_size ~650 MB). use frame_support::traits::Get; let pvf_memory: u32 = <::PVFMemory>::get(); assert_eq!(pvf_memory, 2_u32 * 1024 * 1024 * 1024); // Verify integrity formula passes canonical let runtime_memory: u32 = <::RuntimeMemory>::get(); let storage_limit: u32 = (pvf_memory - runtime_memory) / 2; // ~960 MB storage limit canonical — comfortably above 650 MB max storage. assert!( storage_limit > 700_u32 * 1024 * 1024, "storage_limit must exceed 700 MB para pallet-revive integrity canonical" ); } #[test] fn revive_safety_toggles_production_safe_canonical() { // Production canonical safety: UnsafeUnstableInterface=false. // DebugEnabled NO disponible en pallet-revive 0.10.1 (added 0.12+). use frame_support::traits::Get; let unsafe_interface: bool = <::UnsafeUnstableInterface>::get(); assert!( !unsafe_interface, "Unstable interface MUST be disabled en production runtime canonical" ); } #[test] fn revive_pallet_index_11_canonical_post_governance() { // Pallet index canonical: Revive=11 (post Governance=10 Phase 5.1). // Asegura orden storage migrations canonical canonical preservado. use frame_support::traits::PalletInfoAccess; assert_eq!(::index(), 11); assert_eq!(::name(), "Revive"); } #[test] fn sudo_pallet_index_12_canonical_governability() { // FIX-5: Sudo=12 (post Revive=11). Root origin para las dispatchables // admin de Governance (audit V2-CA1). Sunset → governance real pre-mainnet. use frame_support::traits::PalletInfoAccess; assert_eq!(::index(), 12); assert_eq!(::name(), "Sudo"); } #[test] fn emission_pallet_index_13_canonical() { // FIX-6 Stage 1: Emission=13 (post Sudo=12). Paga validadores Aura (V2-CA2). use frame_support::traits::PalletInfoAccess; assert_eq!(::index(), 13); assert_eq!(::name(), "Emission"); } #[test] fn revive_address_mapper_account32_returns_h160_canonical() { // AccountId32Mapper canonical: AccountId32 → H160 mapping deterministic. // BLAKE2b derivation per Asset Hub canonical solochain pattern. // Slice 3.1 SCAFFOLD: verify mapper type bound, no real address conversion // (requires pallet runtime context). Phase 3.x maduración: real mapping tests. use pallet_revive::AddressMapper; type ConfiguredMapper = ::AddressMapper; // Compile-time verification que el mapper type implements AddressMapper trait fn _verify_implements_mapper>() {} _verify_implements_mapper::(); } }