Pone la fórmula OCAFB-5 en el fee-path VIVO: OriginFeeAdapter (OnChargeTransaction custom) reemplaza al FungibleAdapter tier-blind. El firmante paga su fracción según (HardwareTier × ChainAction × SubscriptionTier, tiers leídos ON-CHAIN de TierProfiles — jamás caller-supplied), y el subsidy pool og/subsy (alimentado por la emisión Stage 1) cubre la fracción subsidiada. Inmutable #16 en cada transacción. OU=() = burn 100% gas fees (matriz CHN-2). unified_fee (u128, outcome tipado FeeOutcome — sin el sentinel u64::MAX in-band): user = fórmula vendor Mathi byte-fiel (test de paridad grid contra ce4fafb); pool = net × subsidy_bp/1e4 sobre el COSTO BASE (anti-regresivo, sub_mult ORTOGONAL: un Ultra NO drena el pool más que un Free — el premium lo paga el usuario, no el commons). Hallazgos de la verificación adversarial (workflow ultracode, 4 lentes) cerrados de raíz: - HIGH: clasificador cubre eth_instantiate_with_code (call_index 10) — evadía el entitlement-gate DeployContract vía fallback Write. - MEDIUM ledger envenenable: removido el dispatchable legacy compute_fee_for_action (tiers caller-supplied, escribía AccountFees sin cobrar). AccountFees ahora escrito SOLO por el fee-path vivo (note_settlement). Eventos que nunca se emitían eliminados; el preview read-only vive en query_fee / FeesApi. - MEDIUM drenaje del pool por sub_mult: pool sobre net, no sobre el precio premium (Opción B anti-regresiva). - Dev UX: GenesisConfig siembra perfiles iniciales; dev/local arrancan Ultra (los Slices 3.x de contracts no se bloquean por Free+DeployContract); mainnet vacío (Default conservador hasta attestation). Decisión de diseño (autoridad Pilar 4): replay de attestation = RECHAZO explícito, no dedup silencioso (notificado a Ergon para el reference impl). Orden OCAFB-5 subsidy-antes-de-entitlement preservado byte-fiel + notificado a Mathi para el ratify 2026-06-21. set_tier_profile Root-only interim (sunset a attestation-driven vía Mathi PerceptionAdapter + DID binding FIX-3/FIX-4). spec_version 1→2 (formato de extrinsic intacto, TRANSACTION_VERSION=1). Tests: 49 crate fees (paridad grid + lobo blanco ortogonalidad + refund + pool seco + tip passthrough + entitlement blocked) + 21 suites workspace verde. Toolchain cargo +1.88. Nota WASM: el build local del runtime WASM falla en la post-validación del substrate-wasm-builder con UnknownOpcode(252) — límite del toolchain (Rust 1.88 emite opcodes 0xFC que el parser del builder de stable2509 no deserializa). Reproducido idéntico en el HEAD intacto (v0.0.57): es ambiental, no de este cambio. El node real + WASM artifact siguen VPS-gated (toolchain alineado / wasm32v1-none cuando el wasm-builder lo soporte). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
635 lines
33 KiB
Rust
635 lines
33 KiB
Rust
//! # Configs canonical de pallets para Origin Chain runtime
|
||
//!
|
||
//! Implementa los `Config` traits de cada pallet integrado, parametrizados con
|
||
//! valores canonical de Origin Chain per DCs `ORIGIN_CHAIN_FOUNDATION_V1`
|
||
//! (CHN-1..CHN-8) + `ORIGIN_CHAIN_SUBSTRATE_FOUNDATION_V1` (SBS-1..SBS-6) +
|
||
//! Business Model V2 (David ratificado 2026-05-18).
|
||
//!
|
||
//! ## Filosofía canonical incorporada
|
||
//!
|
||
//! Cada parámetro canonical materializa empíricamente alguna directiva del
|
||
//! ecosistema Origin:
|
||
//!
|
||
//! - **EXISTENTIAL_DEPOSIT canonical**: `1 MILLI_OGC` (0.001 OGC = 10^15 base
|
||
//! units). Permite que un usuario Pi 5 en escuela rural mantenga balance
|
||
//! activo con monto trivial (Inmutable #16 anti-clasista + Inmutable #37 FREE
|
||
//! perpetua). David canon 2026-05-14: *"la libertad infinita acota solo donde
|
||
//! empieza la del otro"* — el existential deposit es la frontera mínima
|
||
//! canonical sin la cual el chain no puede protegerse de spam infinito, pero
|
||
//! se mantiene tan baja que no excluye a nadie.
|
||
//!
|
||
//! - **BLOCK_HASH_COUNT canonical**: 2400 bloques × 6 segundos = 4 horas exactas
|
||
//! = ventana canonical de epoch rotation per CHN-1. Las pruebas de inclusión
|
||
//! por hash pueden refrenciar cualquier bloque del epoch en curso sin necesidad
|
||
//! de archival queries — eficiencia canonical para validators Pi 5.
|
||
//!
|
||
//! - **SS58_PREFIX canonical**: `42` (substrate dev default) para testnet.
|
||
//! Post-mainnet Q1 2027 se solicitará registro canonical en
|
||
//! `polkadot/ss58-registry` para asignar prefix permanente (e.g. `1888` para
|
||
//! Origin Chain — pendiente DC).
|
||
//!
|
||
//! - **MILLISECS_PER_BLOCK canonical**: 6000 ms = 6 segundos canonical per Aura
|
||
//! slot duration. Standard Substrate canonical, alineado con Polkadot block
|
||
//! time, suficiente para Pi 5 validators (CPU mínimo per CHN-1).
|
||
|
||
extern crate alloc;
|
||
|
||
use crate::{
|
||
Balance, BlockNumber, ChainAccountId, Ogc, PalletInfo, Runtime, RuntimeCall, RuntimeEvent,
|
||
RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask,
|
||
};
|
||
use frame_support::derive_impl;
|
||
use frame_support::parameter_types;
|
||
use frame_support::traits::{ConstBool, ConstU32, ConstU64, VariantCountOf};
|
||
use frame_system::EnsureSigned;
|
||
use sp_runtime::Perbill;
|
||
|
||
// ============================================================
|
||
// Canonical constants (per CHN-1/2/8 + SBS-3)
|
||
// ============================================================
|
||
|
||
/// 1 OGC en base units canonical (10^18).
|
||
pub const OGC: Balance = Ogc::ONE;
|
||
|
||
/// 1 MILLI_OGC = 0.001 OGC = 10^15 base units canonical.
|
||
pub const MILLI_OGC: Balance = OGC / 1_000;
|
||
|
||
/// Existential deposit canonical: 1 MILLI_OGC.
|
||
///
|
||
/// Filosofía anti-clasista: el ED minimum debe ser trivial para cualquier user
|
||
/// (Pi 5 rural Africa = Vision Pro San Francisco). 0.001 OGC ≈ centavos a precios
|
||
/// post-mainnet razonables. Sin sacrificar protección anti-spam canonical.
|
||
pub const EXISTENTIAL_DEPOSIT: Balance = MILLI_OGC;
|
||
|
||
/// Block hash count canonical: 2400 bloques = 4 horas exactas (Aura 6s slot).
|
||
///
|
||
/// Alineado canonical con epoch rotation CHN-1 (4h selección de 100-150 active
|
||
/// validators canonical). Block hashes available para inclusion proofs durante
|
||
/// todo el epoch en curso sin archival queries.
|
||
pub const BLOCK_HASH_COUNT: BlockNumber = 2400;
|
||
|
||
/// SS58 prefix canonical para testnet. Post-mainnet: solicitar registro canonical
|
||
/// permanente en polkadot/ss58-registry (TBD DC complementaria).
|
||
pub const SS58_PREFIX: u16 = 42;
|
||
|
||
/// Milisegundos por bloque canonical: 6000 ms = 6s Aura slot.
|
||
pub const MILLISECS_PER_BLOCK: u64 = 6_000;
|
||
|
||
/// Slot duration canonical = block time canonical.
|
||
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
||
|
||
// ============================================================
|
||
// frame_system::Config canonical (using SolochainDefaultConfig prelude)
|
||
// ============================================================
|
||
|
||
parameter_types! {
|
||
/// SS58 prefix canonical wrapped per Substrate canonical pattern.
|
||
pub const SS58Prefix: u16 = SS58_PREFIX;
|
||
/// Block hash count canonical wrapped.
|
||
pub const BlockHashCount: BlockNumber = BLOCK_HASH_COUNT;
|
||
}
|
||
|
||
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
|
||
impl frame_system::Config for Runtime {
|
||
type Block = crate::Block;
|
||
type AccountId = ChainAccountId;
|
||
type Nonce = crate::Nonce;
|
||
type Hash = crate::Hash;
|
||
type BlockHashCount = BlockHashCount;
|
||
type AccountData = pallet_balances::AccountData<Balance>;
|
||
type SS58Prefix = SS58Prefix;
|
||
type MaxConsumers = ConstU32<16>;
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_balances::Config canonical (CHN-2 OGC + Inmutable #16/#37)
|
||
// ============================================================
|
||
|
||
parameter_types! {
|
||
/// Existential deposit canonical wrapped.
|
||
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||
/// Max locks canonical: 50 (Substrate standard, suficiente para staking +
|
||
/// democracy + governance simultáneos sin bloat).
|
||
pub const MaxLocks: u32 = 50;
|
||
}
|
||
|
||
impl pallet_balances::Config for Runtime {
|
||
type Balance = Balance;
|
||
type RuntimeEvent = RuntimeEvent;
|
||
type DustRemoval = ();
|
||
type ExistentialDeposit = ExistentialDeposit;
|
||
type AccountStore = frame_system::Pallet<Runtime>;
|
||
type MaxLocks = MaxLocks;
|
||
type MaxReserves = ();
|
||
type ReserveIdentifier = [u8; 8];
|
||
type FreezeIdentifier = RuntimeFreezeReason;
|
||
type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
|
||
type RuntimeHoldReason = RuntimeHoldReason;
|
||
type RuntimeFreezeReason = RuntimeFreezeReason;
|
||
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
|
||
type DoneSlashHandler = ();
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_timestamp::Config canonical (foundational para Aura)
|
||
// ============================================================
|
||
|
||
parameter_types! {
|
||
/// Minimum period canonical entre bloques: SLOT_DURATION / 2 = 3 segundos.
|
||
/// Substrate canonical pattern para Aura compatibility.
|
||
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||
}
|
||
|
||
impl pallet_timestamp::Config for Runtime {
|
||
type Moment = u64;
|
||
/// `Aura` wired canonical post Phase 1.4: cada nuevo timestamp triggera el
|
||
/// Aura slot advance canonical. Materializa el coupling consensus↔clock que
|
||
/// hace posible 6-segundo block production deterministic canonical.
|
||
type OnTimestampSet = crate::Aura;
|
||
type MinimumPeriod = MinimumPeriod;
|
||
type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_transaction_payment::Config canonical (CHN-8 fee economy)
|
||
// ============================================================
|
||
|
||
parameter_types! {
|
||
/// Operational fee multiplier canonical: 5x baseline canonical Substrate.
|
||
pub const OperationalFeeMultiplier: u8 = 5;
|
||
}
|
||
|
||
/// FIX-6 Stage 2a: clasificador call→ChainAction del fee unificado (taxonomía
|
||
/// OCAFB-2). Vive aquí porque el runtime es el único sitio donde `RuntimeCall`
|
||
/// es concreto. Fallback conservador: `Write` (fee estándar — un wildcard
|
||
/// jamás regala subsidio; mismo principio que la alerta TLB de Ergon).
|
||
pub struct OriginCallClassifier;
|
||
|
||
impl origin_chain_fees::ClassifyChainAction<crate::RuntimeCall> for OriginCallClassifier {
|
||
fn classify(call: &crate::RuntimeCall) -> origin_chain_fees::ChainAction {
|
||
use origin_chain_fees::ChainAction;
|
||
match call {
|
||
crate::RuntimeCall::Balances(
|
||
pallet_balances::Call::transfer_allow_death { .. }
|
||
| pallet_balances::Call::transfer_keep_alive { .. }
|
||
| pallet_balances::Call::transfer_all { .. },
|
||
) => ChainAction::Transfer,
|
||
crate::RuntimeCall::Revive(
|
||
pallet_revive::Call::instantiate { .. }
|
||
| pallet_revive::Call::instantiate_with_code { .. }
|
||
// call_index 10: el deploy vía la capa EVM (Code::Upload). Sin
|
||
// este arm caería en el fallback Write y evadiría el
|
||
// entitlement-gate DeployContract (HIGH del audit Stage 2a).
|
||
| pallet_revive::Call::eth_instantiate_with_code { .. },
|
||
) => ChainAction::DeployContract,
|
||
crate::RuntimeCall::Revive(
|
||
pallet_revive::Call::call { .. }
|
||
| pallet_revive::Call::eth_call { .. }
|
||
// eth_transact: envoltorio EVM genérico (puede ser call/deploy/
|
||
// transfer). Lo tratamos como ejecución de contrato — su
|
||
// entitlement (Free=false) y subsidio coinciden con CallContract;
|
||
// refinar cuando la capa EVM se cablee plenamente.
|
||
| pallet_revive::Call::eth_transact { .. },
|
||
) => ChainAction::CallContract,
|
||
crate::RuntimeCall::Revive(pallet_revive::Call::upload_code { .. }) => {
|
||
ChainAction::UploadContractCode
|
||
}
|
||
_ => ChainAction::Write,
|
||
}
|
||
}
|
||
}
|
||
|
||
impl pallet_transaction_payment::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
/// FIX-6 Stage 2a (cierra V2-CA3): `OriginFeeAdapter` reemplaza al
|
||
/// `FungibleAdapter` default — la fórmula OCAFB-5 entra al fee-path VIVO:
|
||
/// el firmante paga su fracción según (HardwareTier × ChainAction ×
|
||
/// SubscriptionTier, tiers leídos ON-CHAIN de `TierProfiles`, jamás
|
||
/// caller-supplied), y el subsidy pool `og/subsy` (alimentado por la
|
||
/// emisión Index 13) cubre la fracción subsidiada — Inmutable #16 en cada
|
||
/// transacción. `OU = ()` deliberado: burn matrix CHN-2 ratificada = gas
|
||
/// fees 100% burn (el burn total = fee constitucional completo, deflación
|
||
/// que contrapesa la emisión Stage 1).
|
||
type OnChargeTransaction =
|
||
origin_chain_fees::OriginFeeAdapter<crate::Balances, (), OriginCallClassifier>;
|
||
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
||
type WeightToFee = frame_support::weights::IdentityFee<Balance>;
|
||
type LengthToFee = frame_support::weights::IdentityFee<Balance>;
|
||
type FeeMultiplierUpdate = ();
|
||
type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_aura::Config canonical (CHN-1 — block production PoA)
|
||
// ============================================================
|
||
|
||
/// Canonical Aura authority id type. `sr25519` canonical per Substrate
|
||
/// standard — más eficiente que Ed25519 para slot signing canonical (Schnorr
|
||
/// signature aggregation futuro). Wallet identity sigue Ed25519 (CHN-7), pero
|
||
/// validator authority keys sr25519 per Substrate convention canonical.
|
||
pub type AuraId = sp_consensus_aura::sr25519::AuthorityId;
|
||
|
||
impl pallet_aura::Config for Runtime {
|
||
type AuthorityId = AuraId;
|
||
/// `DisabledValidators = ()`: Phase 1 PoA simple — no disable mechanism
|
||
/// canonical. Phase 2 NPoS introduces pallet_session disabling vía slashing.
|
||
type DisabledValidators = ();
|
||
/// `MaxAuthorities = 32`: canonical para Phase 1 PoA (5-7 validators
|
||
/// inaugurales + room para growth pre-NPoS). Aligned con polkadot-stable2512
|
||
/// solochain-template default canonical.
|
||
type MaxAuthorities = ConstU32<32>;
|
||
/// `AllowMultipleBlocksPerSlot = false`: canonical Substrate — un block por
|
||
/// slot. Disallow multiplicity para deterministic block time canonical Pi 5.
|
||
type AllowMultipleBlocksPerSlot = ConstBool<false>;
|
||
/// Slot duration canonical = `pallet_aura::MinimumPeriodTimesTwo<Runtime>` —
|
||
/// derivado automáticamente del `pallet_timestamp::MinimumPeriod` config
|
||
/// canonical. Garantiza coupling canonical entre clock + consensus slot.
|
||
type SlotDuration = pallet_aura::MinimumPeriodTimesTwo<Runtime>;
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_grandpa::Config canonical (CHN-1 — finality gadget)
|
||
// ============================================================
|
||
|
||
/// Canonical GRANDPA authority id type. `Ed25519` canonical per GRANDPA spec —
|
||
/// signature aggregation matemáticamente diferente a Aura sr25519 pero
|
||
/// canonical convention.
|
||
pub type GrandpaId = sp_consensus_grandpa::AuthorityId;
|
||
|
||
impl pallet_grandpa::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
/// `WeightInfo = ()`: Phase 1 PoA simple. Phase 2 NPoS introduces real
|
||
/// weights para equivocation reporting + on_finalize hooks canonical.
|
||
type WeightInfo = ();
|
||
/// `MaxAuthorities = 32`: aligned con Aura canonical para 1:1 mapping
|
||
/// validator ↔ finalizer Phase 1 PoA (mismo set canonical).
|
||
type MaxAuthorities = ConstU32<32>;
|
||
/// `MaxNominators = 0`: Phase 1 PoA simple — no nominators canonical (no
|
||
/// stake delegation aún). Phase 2 NPoS bump canonical a 256 nominators.
|
||
type MaxNominators = ConstU32<0>;
|
||
/// `MaxSetIdSessionEntries = 0`: Phase 1 simple — no historical session
|
||
/// proofs canonical. Phase 2 NPoS introduces session tracking.
|
||
type MaxSetIdSessionEntries = ConstU64<0>;
|
||
/// `KeyOwnerProof = sp_core::Void`: Phase 1 simple — no equivocation proof
|
||
/// type. Phase 2 NPoS introduces real `MembershipProof` canonical.
|
||
type KeyOwnerProof = sp_core::Void;
|
||
/// `EquivocationReportSystem = ()`: Phase 1 PoA simple — equivocation
|
||
/// reports not handled. Phase 2 NPoS introduces real handler canonical.
|
||
type EquivocationReportSystem = ();
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_session::Config canonical (CHN-1 — 4h epoch rotation)
|
||
// ============================================================
|
||
//
|
||
// Filosofía canonical: PoA Phase 1 preserva el mismo validator set canonical
|
||
// genesis através de cada session rotation (SessionManager = `()`). El "epoch
|
||
// rotation" canonical materializa el ritmo institucional canonical (cada 4h se
|
||
// emite SessionEvent canonical observable on-chain) sin cambiar canonical el
|
||
// validator set hasta Phase 2 NPoS — cuando pallet_staking introduce dynamic
|
||
// validator selection basado en stake + nominator delegation.
|
||
//
|
||
// CHN-1 ratificado canonical: "Epoch rotation every 4 hours selecting 100-150
|
||
// active validators from millions of Pi 5 nodes eligible". Phase 1 PoA tiene
|
||
// 5-7 static validators canonical; el "selecting 100-150" materializa Phase 2
|
||
// NPoS canonical. Esta integration Phase 1.5 establece el substrate canonical
|
||
// para que Phase 2 NPoS herede el rotation mechanism sin breakage.
|
||
|
||
parameter_types! {
|
||
/// Canonical session period: 2400 bloques × 6s = 14400s = **4 horas exactas**
|
||
/// per CHN-1 ratified canonical. Alineado canonical con BLOCK_HASH_COUNT
|
||
/// (mismo valor) — block hash proof valid durante todo el epoch en curso.
|
||
pub const SessionPeriod: BlockNumber = BLOCK_HASH_COUNT;
|
||
/// Canonical session offset: 0 — sesiones canonical start at block 0 (sin
|
||
/// offset canonical). Phase 2 NPoS puede introducir offset si necesario
|
||
/// para alinear con extramo institucional (e.g. UTC midnight epoch starts).
|
||
pub const SessionOffset: BlockNumber = 0;
|
||
}
|
||
|
||
/// Canonical converter `ChainAccountId → Option<ChainAccountId>`.
|
||
///
|
||
/// Phase 1 PoA simple: cada AccountId IS a ValidatorId canonical (identidad
|
||
/// trivial). Phase 2 NPoS introduces real Stash/Controller separation canonical
|
||
/// where ValidatorId derives from Stash account via pallet_staking::StashOf.
|
||
pub struct AccountIdIsValidatorId;
|
||
|
||
impl sp_runtime::traits::Convert<ChainAccountId, Option<ChainAccountId>>
|
||
for AccountIdIsValidatorId
|
||
{
|
||
fn convert(account: ChainAccountId) -> Option<ChainAccountId> {
|
||
Some(account)
|
||
}
|
||
}
|
||
|
||
impl pallet_session::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
/// ValidatorId canonical = ChainAccountId (Phase 1 PoA identidad trivial).
|
||
type ValidatorId = ChainAccountId;
|
||
/// ValidatorIdOf canonical: identity mapping AccountId → ValidatorId.
|
||
type ValidatorIdOf = AccountIdIsValidatorId;
|
||
/// ShouldEndSession canonical: PeriodicSessions every 2400 blocks (4h epoch
|
||
/// per CHN-1 canonical). Cada 2400 bloques emite SessionEvent::NewSession.
|
||
type ShouldEndSession = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
|
||
/// NextSessionRotation canonical: same PeriodicSessions — predecible
|
||
/// canonical para validators saber cuándo será el next rotation slot.
|
||
type NextSessionRotation = pallet_session::PeriodicSessions<SessionPeriod, SessionOffset>;
|
||
/// SessionManager canonical = `()`: Phase 1 PoA preserves genesis validators
|
||
/// canonical across all sessions (no rotation of validator SET, only
|
||
/// SessionId increment canonical). Phase 2 NPoS introduces pallet_staking
|
||
/// como SessionManager canonical para real rotation per nominator stake.
|
||
type SessionManager = ();
|
||
/// SessionHandler canonical: deriva desde opaque::SessionKeys (aura sr25519
|
||
/// + grandpa Ed25519). Cuando una nueva session begins canonical, los
|
||
/// session keys de cada validator se distribute al consensus pallets canonical
|
||
/// (Aura recibe nuevo AuraId set + Grandpa recibe nuevo GrandpaId set).
|
||
type SessionHandler =
|
||
<crate::opaque::SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||
/// Keys canonical = opaque::SessionKeys struct (defined en opaque.rs).
|
||
type Keys = crate::opaque::SessionKeys;
|
||
/// DisablingStrategy canonical = `()`: Phase 1 PoA simple — no validator
|
||
/// disable mechanism. Phase 2 NPoS introduces `UpToLimitWithReEnablingDisablingStrategy`
|
||
/// canonical para slashing-based validator disabling per CHN-3.
|
||
type DisablingStrategy = ();
|
||
/// **Stable2509-3 API additions (Ship 1.5 v0.0.38)**: pallet_session 43.0.0
|
||
/// requires Currency + KeyDeposit para session key registration deposit
|
||
/// economy. Phase 1 PoA simple: zero deposit canonical (genesis validators
|
||
/// static, no nominator-registered keys). Phase 2 NPoS introduces real
|
||
/// deposit canonical via parameter_type post-staking pallet integration.
|
||
type Currency = crate::Balances;
|
||
type KeyDeposit = frame_support::traits::ConstU128<0>;
|
||
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+.
|
||
|
||
// ============================================================
|
||
// origin_chain_provenance::Config — Phase 2.1 v0.0.15 wired
|
||
// ============================================================
|
||
//
|
||
// pallet-origin-provenance scaffold canonical (DC PROVENANCE_PALLET_V1 5/10
|
||
// firmas, ratify target 2026-05-29). Scaffold-level Config canonical: solo
|
||
// RuntimeEvent association. Future canonical fields post DC ratify + Ergon
|
||
// arkhe-noesis-attestation-types Cap 42+ ship:
|
||
//
|
||
// - `OitFeeSchedule: Arc<dyn arkhe_amis_server::OitFeeSchedule>` (post OCAFB)
|
||
// - Custom origin canonical para validator-restricted attestation
|
||
// - Pallet weights canonical desde benchmarking real
|
||
|
||
impl origin_chain_provenance::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
}
|
||
|
||
// ============================================================
|
||
// origin_chain_fees::Config — Phase 2.4 v0.0.21 wired
|
||
// ============================================================
|
||
//
|
||
// pallet-origin-fees scaffold canonical (DC `origin_chain_amis_fee_bridge_v1`
|
||
// OCAFB-1..6 sesión 3+ 6/7 firmas, ratify target 2026-06-21). Scaffold-level
|
||
// Config canonical v0.0.21: solo RuntimeEvent association. Future canonical
|
||
// fields post-OCAFB ratify + Mathi sub-crate ship:
|
||
//
|
||
// - `OitFeeSchedule: Arc<dyn arkhe_amis_server::OitFeeSchedule>` (post-OCAFB
|
||
// ratify swap canonical cross-workspace)
|
||
// - Pallet weights canonical desde benchmarking real (post-Phase 4 testnet)
|
||
// - Custom origin canonical para fee waiver scenarios (governance Phase 5)
|
||
|
||
impl origin_chain_fees::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
/// FIX-6 Stage 2a: la MISMA constante que alimenta la emisión (Index 13)
|
||
/// — pool-alimentación y pool-consumo apuntan a la misma cuenta og/subsy
|
||
/// (jamás re-declarar el literal: un typo divergiría las cuentas).
|
||
type SubsidyPalletId = EmissionSubsidyPalletId;
|
||
}
|
||
|
||
// ============================================================
|
||
// origin_chain_agent_identity::Config — Phase 2.7 v0.0.25 wired
|
||
// ============================================================
|
||
//
|
||
// pallet-agent-identity scaffold canonical (Phase 2.7 AGI DIDs Inmutable #41
|
||
// AGI Cross-Species Co-authorship). Scaffold-level Config canonical v0.0.25:
|
||
// solo RuntimeEvent association. Future canonical fields post-Phase 2.7 DC
|
||
// ratify pending:
|
||
//
|
||
// - `MaxAgentChainLen: Get<u32>` (BoundedVec bound canonical para agent_chain)
|
||
// - Custom origin canonical para Hybrid agent registration (governance Phase 5)
|
||
// - Pallet weights canonical desde benchmarking real (post-Phase 4 testnet)
|
||
|
||
impl origin_chain_agent_identity::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
}
|
||
|
||
// ============================================================
|
||
// origin_chain_governance::Config — Phase 5.1 v0.0.29 wired
|
||
// ============================================================
|
||
//
|
||
// pallet-origin-governance scaffold canonical (Phase 5.1 Foundation Treasury
|
||
// Governance CHN-4 AI-Driven Human-Guarded). Scaffold-level Config canonical
|
||
// v0.0.29: solo RuntimeEvent association. Future canonical fields post-Phase 5
|
||
// DC ratify:
|
||
//
|
||
// - `MinProposalStake: Get<u128>` (1,000 OGC mínimum canonical CHN-4 5.3)
|
||
// - `MaxVotingPeriodBlocks: Get<u64>` (14-day period canonical 5.4)
|
||
// - Custom origin canonical para Technical Council veto (5.5)
|
||
// - `IsGovernanceAdvisor: Trait` (5.6 — humans-only vote enforcement)
|
||
|
||
parameter_types! {
|
||
/// FIX-6: PalletId de la cuenta-tesorería de governance (vault, sin private
|
||
/// key, determinística). Tiene el balance real OGC; solo la governance (Root)
|
||
/// la drena vía treasury_disbursement. PRE-LAUNCH: el genesis mainnet debe
|
||
/// rutear la Foundation 250M a esta cuenta (hoy va a FNDT — follow-up).
|
||
pub const GovernanceTreasuryPalletId: frame_support::PalletId =
|
||
frame_support::PalletId(*b"og/gvtry");
|
||
}
|
||
|
||
impl origin_chain_governance::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
type Currency = crate::Balances;
|
||
type TreasuryPalletId = GovernanceTreasuryPalletId;
|
||
}
|
||
|
||
// ============================================================
|
||
// origin_chain_emission::Config — FIX-6 Stage 1 (audit V2-CA2)
|
||
// ============================================================
|
||
//
|
||
// En cada bloque mintea EmissionBlockReward y lo reparte: 70% al autor (el
|
||
// validador Aura), 20% al treasury (og/gvtry, la MISMA cuenta de governance),
|
||
// 10% al subsidy pool (og/subsy, proof-of-equity que financia el subsidio de
|
||
// hardware #16 — ortogonal a la suscripción, David 2026-06-10). Cierra "los
|
||
// validadores ganan 0 OGC". FindAuthor = el mapeo Aura→validador de session.
|
||
//
|
||
// BlockReward 10 OGC × ~5.256M bloques/año ≈ 52.6M OGC/año ≈ 5.26% inflación
|
||
// sobre el genesis de 1B (materializa la emisión del 40% Ecosystem BM V2).
|
||
// Stage 2 introduce pallet_staking NPoS sobre este substrate.
|
||
parameter_types! {
|
||
/// Recompensa por bloque: 10 OGC (~5% inflación anual).
|
||
pub const EmissionBlockReward: Balance = 10 * OGC;
|
||
/// 70% al autor (validador Aura).
|
||
pub const EmissionAuthorShareBps: u16 = 7_000;
|
||
/// 20% al treasury (el residual 10% va al subsidy pool).
|
||
pub const EmissionTreasuryShareBps: u16 = 2_000;
|
||
/// PalletId del subsidy pool (proof-of-equity, #16 anti-clasista).
|
||
pub const EmissionSubsidyPalletId: frame_support::PalletId =
|
||
frame_support::PalletId(*b"og/subsy");
|
||
}
|
||
|
||
impl origin_chain_emission::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
type Currency = crate::Balances;
|
||
/// Aura → validador account vía pallet_session (FindAccountFromAuthorIndex).
|
||
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Runtime, crate::Aura>;
|
||
type BlockReward = EmissionBlockReward;
|
||
type AuthorShareBps = EmissionAuthorShareBps;
|
||
type TreasuryShareBps = EmissionTreasuryShareBps;
|
||
// Reusa el MISMO vault de governance (og/gvtry) para el treasury.
|
||
type TreasuryPalletId = GovernanceTreasuryPalletId;
|
||
type SubsidyPalletId = EmissionSubsidyPalletId;
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_revive::Config — Phase 3 Slice 3.1 v0.0.39 wired
|
||
// ============================================================
|
||
//
|
||
// Smart contracts PolkaVM RISC-V WASM execution per SBS-5 ratificado
|
||
// (supersedes CHN-6 v1.0 → ink! v6 + Solidity vía revive compiler). Wired
|
||
// runtime Index 11 con associated types per Asset Hub Westend stable2509-3
|
||
// reference adaptado. pallet-revive 0.10.1 via git source polkadot-stable2509-3
|
||
// tag (post workspace bump Ship 1.5 v0.0.38 atómico).
|
||
//
|
||
// **Decisiones canonical Slice 3.1 SCAFFOLD interim** (refinement Phase 3.x maduración):
|
||
//
|
||
// - `Precompiles = ()`: empty tuple — sin custom precompiles canonical Slice 3.1.
|
||
// Phase 3.x añade ERC20 precompile (cross-asset compat) + custom Origin
|
||
// precompiles (provenance hooks + fees integration).
|
||
// - `FindAuthor = ()`: returns None canonical — sin pallet_authorship integration
|
||
// en Phase 1 PoA (Aura block author NO surfaced canonical via Authorship trait).
|
||
// Gas rebates al block author NO operativos en Slice 3.1 — acceptable en
|
||
// dev/testnet. Phase 4 testnet decide canonical: add pallet_authorship OR
|
||
// custom FindAuthor extracting de Aura digests pre-header inspection.
|
||
// - `AddressMapper = pallet_revive::AccountId32Mapper<Self>`: canonical para
|
||
// solochain — mapea AccountId32 ↔ H160 EVM addresses via BLAKE2b derivation.
|
||
//
|
||
// **OriginChainId 9_120_005**: EIP-155 unique canonical para Origin Metaverse.
|
||
// Pattern fecha-encoded (9=Sept simbólico inicio Genesis 2026, 12=Dec roadmap,
|
||
// 05=número simbólico David Herran founder). Previene replay attacks cross-chain.
|
||
|
||
parameter_types! {
|
||
/// Storage deposit canonical per byte de contract data stored.
|
||
/// Pattern Asset Hub canonical: 1 MILLI_OGC per byte = 10^15 base units.
|
||
/// Phase 3.x maduración refinement con Mathi OitFeeSchedule canonical.
|
||
/// Slice 3.1 SCAFFOLD initial estimate empirical-validated por
|
||
/// `__construct_runtime_integrity_test` pallet-revive 0.10.1 storage
|
||
/// size limit (formula derives max storage from DepositPerByte rate).
|
||
pub const ReviveDepositPerByte: Balance = MILLI_OGC;
|
||
|
||
/// Storage deposit canonical per storage item (key-value entry).
|
||
/// Pattern Asset Hub canonical: 1 OGC per item = 10^18 base units
|
||
/// (significantly higher than per-byte to economically gate canonical
|
||
/// storage item proliferation). Refunds canonical pro-rata via
|
||
/// `pallet-revive` design (refund-on-terminate canonical).
|
||
pub const ReviveDepositPerItem: Balance = OGC;
|
||
|
||
/// Code hash lockup deposit percentage canonical.
|
||
/// 30% canonical Asset Hub reference — locks 30% del storage deposit cuando
|
||
/// se instantiate desde un code hash, para protect code de unlikely deletion
|
||
/// mientras existen contract instances usándolo. Refunded canonical cuando
|
||
/// el último contract usando ese code es terminated.
|
||
pub ReviveCodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30);
|
||
}
|
||
|
||
impl pallet_revive::Config for Runtime {
|
||
// ── Runtime types (stable2509-3 pallet-revive 0.10.1 surface, 22 required types) ──
|
||
type RuntimeEvent = RuntimeEvent;
|
||
type RuntimeCall = RuntimeCall;
|
||
type RuntimeHoldReason = RuntimeHoldReason;
|
||
|
||
// ── Currency & Balance ─────────────────────────────────────
|
||
type Currency = crate::Balances;
|
||
type Time = crate::Timestamp;
|
||
/// WeightPrice canonical: Convert<Weight, Balance> via TransactionPayment.
|
||
/// pallet_transaction_payment::Pallet implementa Convert<Weight, BalanceOf>
|
||
/// per Asset Hub canonical reference pattern.
|
||
type WeightPrice = pallet_transaction_payment::Pallet<Runtime>;
|
||
|
||
// ── Storage & Deposit ──────────────────────────────────────
|
||
type DepositPerByte = ReviveDepositPerByte;
|
||
type DepositPerItem = ReviveDepositPerItem;
|
||
type CodeHashLockupDepositPercent = ReviveCodeHashLockupDepositPercent;
|
||
|
||
// ── EVM & Address Mapping ──────────────────────────────────
|
||
type AddressMapper = pallet_revive::AccountId32Mapper<Self>;
|
||
type ChainId = ConstU64<9_120_005>; // Origin Metaverse EIP-155 unique
|
||
type NativeToEthRatio = ConstU32<1_000_000>; // OGC 12 decimals → ETH 18 decimals
|
||
type AllowEVMBytecode = ConstBool<true>; // Solidity contracts canonical
|
||
/// EthGasEncoder canonical: gas ↔ balance conversion para EVM-style
|
||
/// transactions. Empty tuple `()` usa default canonical pallet-revive
|
||
/// para Slice 3.1 SCAFFOLD (1:1 mapping). Phase 3.x maduración custom.
|
||
type EthGasEncoder = ();
|
||
|
||
// ── Precompiles ────────────────────────────────────────────
|
||
// Slice 3.1 SCAFFOLD interim: empty tuple placeholder. Phase 3.x maduración.
|
||
type Precompiles = ();
|
||
|
||
// ── Execution Limits & Memory ──────────────────────────────
|
||
// pallet-revive 0.10.1 stable2509-3 integrity test formula canonical:
|
||
// storage_limit = (PVFMemory - RuntimeMemory) / 2
|
||
// max_storage_size = computed ~650 MB from BlockWeights + SetStorage cost
|
||
// Need PVFMemory > RuntimeMemory + 1.3 GB para pass integrity_test canonical.
|
||
// Asset Hub pattern: 128 MB runtime + 512 MB PVF NO works en 0.10.1 (limit
|
||
// would be 192 MB but max_storage 650 MB). Slice 3.1 SCAFFOLD bumps PVFMemory
|
||
// a 2 GB para satisfy integrity check (PVFMemory MEMORY-ONLY limit, no actual
|
||
// RAM allocation pre-validator load — Pi 5 8 GB RAM tier safe). Phase 3.x
|
||
// refinement post-real benchmarks.
|
||
type WeightInfo = pallet_revive::weights::SubstrateWeight<Self>;
|
||
type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>; // 128 MB runtime allocation
|
||
type PVFMemory = ConstU32<{ 2 * 1024 * 1024 * 1024 }>; // 2 GB validator PVF memory limit
|
||
|
||
// ── Access Control ─────────────────────────────────────────
|
||
type UploadOrigin = EnsureSigned<ChainAccountId>;
|
||
type InstantiateOrigin = EnsureSigned<ChainAccountId>;
|
||
|
||
// ── Authorship + Safety toggles ────────────────────────────
|
||
// pallet-revive 0.10.1 stable2509-3 NO expone DebugEnabled (added 0.12+).
|
||
// RuntimeOrigin NO expone direct (consumed transitively via RuntimeCall).
|
||
// FeeInfo NO expone (added 0.12+). MaxEthExtrinsicWeight NO expone (added 0.12+).
|
||
// GasScale NO expone (added 0.12+). DepositPerChildTrieItem NO expone (added 0.12+).
|
||
type FindAuthor = (); // returns None Slice 3.1 (sin pallet_authorship)
|
||
type UnsafeUnstableInterface = ConstBool<false>; // testnet-only feature gate
|
||
}
|
||
|
||
// ============================================================
|
||
// pallet_sudo::Config — FIX-5 governability (Root origin, audit V2-CA1)
|
||
// ============================================================
|
||
//
|
||
// La cadena no se gobernaba: las dispatchables admin de Governance (add/remove
|
||
// council, mark/unmark advisor, treasury_disbursement — todas `ensure_root`)
|
||
// eran no-invocables sin un Root origin, y la tesorería 250M quedaba congelada.
|
||
// pallet-sudo provee Root origin canonical vía una sudo key única.
|
||
//
|
||
// SUNSET canonical: la sudo key es interim (Foundation multisig humano, seteada
|
||
// en genesis). ANTES de mainnet se migra a governance real (pallet-collective +
|
||
// pallet-referenda) y se remueve sudo — la cadena se auto-gobierna sin Root.
|
||
impl pallet_sudo::Config for Runtime {
|
||
type RuntimeEvent = RuntimeEvent;
|
||
type RuntimeCall = RuntimeCall;
|
||
type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
|
||
}
|