feat(runtime-apis): Phase 1.6 — Runtime APIs canonical foundation v0.0.8

Runtime canonical ahora expone 11 APIs foundational via impl_runtime_apis!
macro necesarias para origin-chain-node binary interactuar via sc-service.

## Decisión canonical empírica: pallet_identity DEFERRED a Phase 2.7

pallet-identity 41.0.0 (stable2512) usa ReservableCurrency trait deprecated en
stable2512 (replaced por fungible::Mutate). Compat work es scope Phase 2.7
cuando custom pallet_agent_identity introduce AGI DIDs (Inmutable #41).

Wallet creation FREE perpetua per Inmutable #37 YA materializado via
pallet_balances — account existe con 1 MILLI_OGC EXISTENTIAL_DEPOSIT.
Identity metadata (name + email + GitHub + avatar) viene Phase 2.7.

## 11 APIs canonical implementadas
- sp_api::Core (version + execute_block + initialize_block)
- sp_api::Metadata (runtime metadata canonical)
- sp_block_builder::BlockBuilder (apply_extrinsic + finalize_block + inherents)
- sp_transaction_pool::TaggedTransactionQueue (validate_transaction)
- sp_offchain::OffchainWorkerApi (offchain_worker)
- sp_session::SessionKeys (generate + decode_into_raw_public_keys)
- sp_consensus_aura::AuraApi (slot_duration + authorities)
- sp_consensus_grandpa::GrandpaApi (grandpa_authorities + current_set_id +
  equivocation stubs Phase 1 PoA returning None)
- frame_system_rpc_runtime_api::AccountNonceApi (account_nonce)
- pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi
  (query_info + query_fee_details + query_weight_to_fee + query_length_to_fee)
- sp_genesis_builder::GenesisBuilder (build_state + get_preset + preset_names)

## Foundation types nuevos canonical
- pub const VERSION: RuntimeVersion canonical (consumed por sp_api::Core::version)
  - spec_name "origin-chain" + impl_name "origin-chain-charon"
  - apis RUNTIME_API_VERSIONS auto-generado por macro
  - state_version 1 (stable2509+ canonical)
- pub type Executive = frame_executive::Executive<...> wrapper canonical

## Compile fix iteración
EquivocationProof type signature: cambió de <Hash, Header> a <Hash, BlockNumber>
canonical per trait signature stable2512. Doc clarifies Phase 1 PoA equivocation
returns None — Phase 2 NPoS introduce real per CHN-3 slashing.

## Build + tests
- cargo check 0.75s warm cache (impl_runtime_apis incremental)
- cargo build --release 9.23s warm cache clean
- ~57 tests passing

## Filosofía canonical
Doc impl_runtime_apis cita David canon 2026-05-14 "la libertad infinita acota
solo donde empieza la del otro" — APIs son la frontera canonical entre runtime
sovereignty + node sovereignty. Forkless upgrades materializados.

## Phase 1 progress
1.1 ✅ + 1.2 ✅ + 1.3 ✅ + 1.4 ✅ + 1.5 ✅ + 1.6 ✅ (esta). Next: 1.7
genesis chain_spec.rs BM V2 allocation (40/25/15/15/5) + origin-chain-node
real Substrate service multi-session work.

Origin Chain runtime canonical actual: 7 pallets + 11 Runtime APIs + Executive
+ RuntimeVersion + opaque SessionKeys = foundation completa para node binary.

Refs: CHARON_ROADMAP_V1 Phase 1.6, Decisión empírica pallet_identity defer,
SBS-4 ratified, arkhe-origin-chain commit pending tag v0.0.8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 4.6 committed 2026-05-20 19:54:46 -05:00
1 parent 926650308c
commit 4286b8d9e8
6 files changed
+450 -1

No files matched your search

@@ -304,3 +304,24 @@ impl pallet_session::Config for Runtime {
type DisablingStrategy = ();
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
}
// ============================================================
// 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+.
+226
View File
@@ -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<Runtime>;
// 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<Block> for Runtime {
fn version() -> sp_version::RuntimeVersion {
VERSION
}
fn execute_block(block: Block) {
Executive::execute_block(block);
}
fn initialize_block(header: &<Block as sp_runtime::traits::Block>::Header) -> sp_runtime::ExtrinsicInclusionMode {
Executive::initialize_block(header)
}
}
impl sp_api::Metadata<Block> for Runtime {
fn metadata() -> sp_core::OpaqueMetadata {
sp_core::OpaqueMetadata::new(Runtime::metadata().into())
}
fn metadata_at_version(version: u32) -> Option<sp_core::OpaqueMetadata> {
Runtime::metadata_at_version(version)
}
fn metadata_versions() -> Vec<u32> {
Runtime::metadata_versions()
}
}
impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as sp_runtime::traits::Block>::Extrinsic) -> sp_runtime::ApplyExtrinsicResult {
Executive::apply_extrinsic(extrinsic)
}
fn finalize_block() -> <Block as sp_runtime::traits::Block>::Header {
Executive::finalize_block()
}
fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as sp_runtime::traits::Block>::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<Block> for Runtime {
fn validate_transaction(
source: sp_runtime::transaction_validity::TransactionSource,
tx: <Block as sp_runtime::traits::Block>::Extrinsic,
block_hash: <Block as sp_runtime::traits::Block>::Hash,
) -> sp_runtime::transaction_validity::TransactionValidity {
Executive::validate_transaction(source, tx, block_hash)
}
}
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
fn offchain_worker(header: &<Block as sp_runtime::traits::Block>::Header) {
Executive::offchain_worker(header)
}
}
impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
opaque::SessionKeys::generate(seed)
}
fn decode_session_keys(
encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
}
}
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
fn slot_duration() -> sp_consensus_aura::SlotDuration {
sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION)
}
fn authorities() -> Vec<AuraId> {
pallet_aura::Authorities::<Runtime>::get().into_inner()
}
}
impl sp_consensus_grandpa::GrandpaApi<Block> for Runtime {
fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList {
pallet_grandpa::Pallet::<Runtime>::grandpa_authorities()
}
fn current_set_id() -> sp_consensus_grandpa::SetId {
pallet_grandpa::Pallet::<Runtime>::current_set_id()
}
fn submit_report_equivocation_unsigned_extrinsic(
_equivocation_proof: sp_consensus_grandpa::EquivocationProof<
<Block as sp_runtime::traits::Block>::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<sp_consensus_grandpa::OpaqueKeyOwnershipProof> {
// Phase 1 PoA: no ownership proofs needed canonical.
None
}
}
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, ChainAccountId, Nonce> for Runtime {
fn account_nonce(account: ChainAccountId) -> Nonce {
System::account_nonce(account)
}
}
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
fn query_info(
uxt: <Block as sp_runtime::traits::Block>::Extrinsic,
len: u32,
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
TransactionPayment::query_info(uxt, len)
}
fn query_fee_details(
uxt: <Block as sp_runtime::traits::Block>::Extrinsic,
len: u32,
) -> pallet_transaction_payment::FeeDetails<Balance> {
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<Block> for Runtime {
fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
frame_support::genesis_builder_helper::build_state::<RuntimeGenesisConfig>(config)
}
fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
frame_support::genesis_builder_helper::get_preset::<RuntimeGenesisConfig>(
id,
|_| None, // Phase 1.7 chain_spec presets land aquí canonical
)
}
fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
// 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>,
Runtime,
AllPalletsWithSystem,
(),
>;
use sp_api::impl_runtime_apis;
#[cfg(test)]
mod tests {
use super::*;