diff --git a/CHANGELOG.md b/CHANGELOG.md index b4206cf..659a346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,129 @@ by [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versions follow ## [Unreleased] +## [0.0.8] — 2026-05-21 — Phase 1.6 "Runtime APIs canonical foundation" + +Charon sesión 1 continuación. **Runtime APIs canonical implementadas via +`impl_runtime_apis!` macro** — el runtime canonical ahora expone 11 APIs +foundational necesarias para que el `origin-chain-node` binary canonical +pueda interactuar canonical via sc-service cuando Phase 1.6+ se complete. + +### Decisión canonical empírica documentada — pallet_identity DEFERRED + +`pallet-identity 41.0.0` (stable2512 canonical) usa `ReservableCurrency` +trait que está deprecated en stable2512 canonical (replaced canonical por +`fungible::Mutate`). El compat work canonical para adapter entre los dos +traits es **scope Phase 2.7** cuando se introduce custom `pallet_agent_identity` +canonical (per Inmutable #41 Cross-Species Co-authorship — AGI DIDs). + +**Wallet creation FREE perpetua per Inmutable #37 ya está materializado vía +`pallet_balances`** — un account existe simplemente con 1 MILLI_OGC +EXISTENTIAL_DEPOSIT canonical. Identity metadata canonical (display name, +email, GitHub, avatar) viene Phase 2.7 con el custom pallet. + +### 11 APIs canonical implementadas + +| API canonical | Purpose canonical | Consumer canonical | +|---------------|-------------------|---------------------| +| `sp_api::Core` | version + execute_block + initialize_block | node binary core | +| `sp_api::Metadata` | runtime metadata canonical | client + node introspection | +| `sp_block_builder::BlockBuilder` | apply_extrinsic + finalize_block + check_inherents | node block production | +| `sp_transaction_pool::TaggedTransactionQueue` | validate_transaction canonical | pool filtering | +| `sp_offchain::OffchainWorkerApi` | offchain_worker canonical | offchain processing | +| `sp_session::SessionKeys` | generate + decode session keys canonical | node session management | +| `sp_consensus_aura::AuraApi` | slot_duration + authorities canonical | Aura block production | +| `sp_consensus_grandpa::GrandpaApi` | grandpa_authorities + current_set_id canonical | GRANDPA finality | +| `frame_system_rpc_runtime_api::AccountNonceApi` | account_nonce canonical | RPC nonce queries | +| `pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi` | query_info + query_fee_details canonical | RPC fee queries | +| `sp_genesis_builder::GenesisBuilder` | build_state + get_preset + preset_names canonical | genesis chain_spec | + +### Foundation canonical types añadidos + +```rust +/// Canonical RuntimeVersion consumed por sp_api::Core::version() +pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion { + spec_name: alloc::borrow::Cow::Borrowed(SPEC_NAME), // "origin-chain" + impl_name: alloc::borrow::Cow::Borrowed(IMPL_NAME), // "origin-chain-charon" + authoring_version: AUTHORING_VERSION, // 1 + spec_version: RUNTIME_VERSION, // 1 + impl_version: IMPL_VERSION, // 1 + apis: RUNTIME_API_VERSIONS, // auto-generated por macro + transaction_version: TRANSACTION_VERSION, // 1 + system_version: STATE_VERSION, // 1 (stable2509+) +}; + +/// Canonical FRAME Executive wrapper canonical +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + (), +>; +``` + +### Phase 1 Phase 2 boundary canonical + +Equivocation proof handlers canonical son `None` Phase 1 PoA — Phase 2 NPoS +introduce real handlers per CHN-3 slashing canonical. Esto está documentado +canonical en los stub implementations canonical. + +### Build performance + +- `cargo check --workspace`: **0.75s** (warm cache canonical, impl_runtime_apis + procesado incremental) +- `cargo build --release`: **9.23s** (warm cache canonical clean) +- ~57 tests passing (runtime APIs son trait impls — tests específicos van en + node-side integration Phase 1.6+) + +### Filosofía canonical incorporada + +Doc `impl_runtime_apis!` cita David canon 2026-05-14: +> *"la libertad infinita acota solo donde empieza la del otro"* + +El macro `impl_runtime_apis!` materializa canonical **la frontera canonical +entre runtime sovereignty + node sovereignty** — cada API canonical es un +contrato canonical que el node binary canonical puede llamar sin importarle +qué pallets specific componen el runtime canonical. **Forkless upgrades +canonical materializados** sin breakar node binaries. + +### Phase 1 progress canonical + +- ✅ **1.1** Scaffold (v0.0.2) +- ✅ **1.2** Substrate foundation (v0.0.4) +- ✅ **1.3** Pallets foundation (v0.0.5) +- ✅ **1.4** Consensus PoA Aura+GRANDPA (v0.0.6) +- ✅ **1.5** Session rotation 4h epochs (v0.0.7) +- ✅ **1.6** **Runtime APIs foundation** (v0.0.8) ← **ESTA** + - pallet_identity DEFERRED a Phase 2.7 (canonical decision empírica) + - 11 APIs canonical impl_runtime_apis! shipped +- ⏳ **1.7** Genesis `chain_spec.rs` BM V2 allocation (40/25/15/15/5) +- ⏳ **1.6+** `origin-chain-node` real Substrate service (sc-service builder + + JSON-RPC + CLI) — substantial scope multi-session + +### Tour canonical de Origin Chain runtime composition (7 pallets + 11 APIs) + +``` +┌────────────────────────────────────────────────────────────────────┐ +│ Origin Chain Runtime v0.0.8 — Substrate canonical │ +├────────────────────────────────────────────────────────────────────┤ +│ Pallets (frame_support::runtime macro): │ +│ Index 0 System Index 1 Timestamp Index 2 Balances │ +│ Index 3 TransactionPayment Index 4 Aura Index 5 Grandpa │ +│ Index 6 Session │ +│ │ +│ Runtime APIs (impl_runtime_apis! macro): │ ← NEW +│ Core + Metadata + BlockBuilder + TaggedTransactionQueue + │ +│ OffchainWorkerApi + SessionKeys + AuraApi + GrandpaApi + │ +│ AccountNonceApi + TransactionPaymentApi + GenesisBuilder │ +│ │ +│ Opaque SessionKeys: aura (sr25519) + grandpa (Ed25519) │ +│ Executive: frame_executive::Executive wrapper canonical │ ← NEW +│ RuntimeVersion: spec=origin-chain impl=origin-chain-charon │ ← NEW +└────────────────────────────────────────────────────────────────────┘ +``` + ## [0.0.7] — 2026-05-20 — Phase 1.5 "Session rotation canonical (4h epochs)" Charon sesión 1 continuación. **Session pallet canonical integrado** — Origin diff --git a/Cargo.lock b/Cargo.lock index 7a9fefd..4c974fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1311,6 +1311,17 @@ dependencies = [ "sp-weights", ] +[[package]] +name = "frame-system-rpc-runtime-api" +version = "36.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244a5015742d349a814bc7f2aa999a9ec47924374a22672cfc3043a1eb87295f" +dependencies = [ + "docify", + "parity-scale-codec", + "sp-api", +] + [[package]] name = "frame-try-runtime" version = "0.46.0" @@ -2083,6 +2094,7 @@ dependencies = [ "frame-metadata-hash-extension", "frame-support", "frame-system", + "frame-system-rpc-runtime-api", "log", "origin-chain-types", "pallet-aura", @@ -2091,6 +2103,7 @@ dependencies = [ "pallet-session", "pallet-timestamp", "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", "serde", @@ -2099,9 +2112,13 @@ dependencies = [ "sp-consensus-aura", "sp-consensus-grandpa", "sp-core", + "sp-genesis-builder", "sp-inherents", + "sp-offchain", "sp-runtime", + "sp-session", "sp-std", + "sp-transaction-pool", "sp-version", ] @@ -2252,6 +2269,19 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-transaction-payment-rpc-runtime-api" +version = "40.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bd3329d44b44623b7615cc069b292f2a1fe5c0f4a6625c36cc906f2a43fcc1" +dependencies = [ + "pallet-transaction-payment", + "parity-scale-codec", + "sp-api", + "sp-runtime", + "sp-weights", +] + [[package]] name = "parity-bip39" version = "2.0.1" @@ -3304,6 +3334,17 @@ dependencies = [ "scale-info", ] +[[package]] +name = "sp-offchain" +version = "36.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5ac60e48200d7b7f61681320deaf06bdced47cfd5f1cb4589b533b58fa4da4" +dependencies = [ + "sp-api", + "sp-core", + "sp-runtime", +] + [[package]] name = "sp-panic-handler" version = "13.0.2" @@ -3472,6 +3513,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "sp-transaction-pool" +version = "36.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05fe2b97ebbbdbaab7200914f5fa3e3493972fceb39d3fb9324bc5b63f60a994" +dependencies = [ + "sp-api", + "sp-runtime", +] + [[package]] name = "sp-trie" version = "39.1.1" diff --git a/Cargo.toml b/Cargo.toml index 0f00590..a1daf8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,8 @@ sp-block-builder = { version = "36.0.0", default-features = false } sp-transaction-pool = { version = "36.0.0", default-features = false } sp-inherents = { version = "36.0.0", default-features = false } sp-offchain = { version = "36.0.0", default-features = false } -sp-session = { version = "37.0.0", default-features = false } +sp-session = { version = "38.1.0", default-features = false } +sp-genesis-builder = { version = "0.17.0", default-features = false } sp-consensus-aura = { version = "0.42.0", default-features = false, features = ["serde"] } sp-consensus-grandpa = { version = "23.1.0", default-features = false, features = ["serde"] } @@ -68,6 +69,16 @@ pallet-grandpa = { version = "40.0.0", default-features = false } # FRAME pallets canonical Phase 1.5 — Session rotation per CHN-1 4h epochs pallet-session = { version = "40.0.1", default-features = false } +# pallet-identity DEFERRED a Phase 2.7 — canonical decision empírica 2026-05-21: +# pallet-identity 41.0.0 usa ReservableCurrency trait (deprecated en stable2512, +# replaced por fungible::Mutate). Compat work canonical es scope Phase 2.7 cuando +# se introduce `pallet_agent_identity` custom canonical (Inmutable #41 AGI DID). +# pallet-identity = { version = "41.0.0", default-features = false } + +# RuntimeAPI canonical (consumed by node binary + RPC server Phase 1.6+) +frame-system-rpc-runtime-api = { version = "36.0.0", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { version = "40.0.0", default-features = false } + # SCALE codec canonical (canonical Substrate serialization) parity-scale-codec = { version = "3.7", default-features = false, features = ["derive"] } scale-info = { version = "2.11", default-features = false, features = ["derive"] } diff --git a/crates/origin-chain-runtime/Cargo.toml b/crates/origin-chain-runtime/Cargo.toml index 644285a..c461cf2 100644 --- a/crates/origin-chain-runtime/Cargo.toml +++ b/crates/origin-chain-runtime/Cargo.toml @@ -44,6 +44,17 @@ pallet-grandpa.workspace = true # FRAME pallets Phase 1.5 — Session rotation per CHN-1 4h epochs pallet-session.workspace = true +# pallet-identity DEFERRED a Phase 2.7 (canonical decision empírica 2026-05-21) +# pallet-identity.workspace = true + +# RuntimeAPI canonical (sp_api::impl_runtime_apis! consumers) +sp-offchain.workspace = true +sp-genesis-builder.workspace = true +sp-transaction-pool.workspace = true +sp-session.workspace = true +frame-system-rpc-runtime-api.workspace = true +pallet-transaction-payment-rpc-runtime-api.workspace = true + # SCALE codec canonical parity-scale-codec.workspace = true scale-info.workspace = true @@ -76,6 +87,12 @@ std = [ "pallet-aura/std", "pallet-grandpa/std", "pallet-session/std", + "sp-offchain/std", + "sp-genesis-builder/std", + "sp-transaction-pool/std", + "sp-session/std", + "frame-system-rpc-runtime-api/std", + "pallet-transaction-payment-rpc-runtime-api/std", "parity-scale-codec/std", "scale-info/std", "serde", diff --git a/crates/origin-chain-runtime/src/configs.rs b/crates/origin-chain-runtime/src/configs.rs index 14ef803..4c9a7b5 100644 --- a/crates/origin-chain-runtime/src/configs.rs +++ b/crates/origin-chain-runtime/src/configs.rs @@ -304,3 +304,24 @@ impl pallet_session::Config for Runtime { type DisablingStrategy = (); type WeightInfo = pallet_session::weights::SubstrateWeight; } + +// ============================================================ +// pallet_identity::Config — DEFERRED a Phase 2.7 (canonical decision empírica) +// ============================================================ +// +// Decision canonical 2026-05-21: `pallet-identity 41.0.0` (stable2512 canonical) +// usa `ReservableCurrency` trait que está deprecated en stable2512 canonical +// (replaced canonical por `fungible::Mutate`). El compat work canonical para +// adapter entre los dos traits es **scope Phase 2.7** cuando se introduce el +// custom `pallet_agent_identity` canonical (per Inmutable #41 Cross-Species +// Co-authorship — AGI DIDs first-class citizens). +// +// **Wallet creation canonical FREE perpetua per Inmutable #37 ya está materializado +// vía `pallet_balances` canonical** — un account canonical existe simplemente con +// 1 MILLI_OGC EXISTENTIAL_DEPOSIT canonical. Identity metadata canonical +// (display name + email + GitHub + avatar + etc.) es feature *adicional canonical* +// que viene Phase 2.7. +// +// Pre-Phase 2.7: wallets canonical son AccountId32 (Ed25519/sr25519/ecdsa via +// MultiSignature canonical). Suficiente canonical para Phase 1 PoA + Phase 2 +// NPoS basic. Identity claims canonical son value-add Phase 2.7+. diff --git a/crates/origin-chain-runtime/src/lib.rs b/crates/origin-chain-runtime/src/lib.rs index b9d65bb..244453f 100644 --- a/crates/origin-chain-runtime/src/lib.rs +++ b/crates/origin-chain-runtime/src/lib.rs @@ -42,6 +42,7 @@ #![warn(missing_docs)] extern crate alloc; +use alloc::vec::Vec; pub mod configs; pub mod opaque; @@ -224,8 +225,233 @@ mod runtime { /// rotation per nominator stake + Pi 5 hardware tier weight. #[runtime::pallet_index(6)] pub type Session = pallet_session::Pallet; + + // Identity pallet DEFERRED a Phase 2.7 (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> { + frame_support::genesis_builder_helper::get_preset::( + id, + |_| None, // Phase 1.7 chain_spec presets land aquí canonical + ) + } + + fn preset_names() -> Vec { + // Phase 1.7 chain_spec presets (dev, local, mainnet) land aquí canonical + Vec::new() + } + } +} + +// ============================================================ +// 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::*;