feat(session): Phase 1.5 — Session rotation 4h epochs canonical v0.0.7

Origin Chain runtime canonical ahora emite SessionEvent::NewSession cada 4
horas exactas per CHN-1 ratified. Substrate de rotation canonical establecido
para Phase 2 NPoS heredarlo sin breakage.

## Pallet añadido (per SBS-4)
- Index 6 Session (pallet_session 40.0.1) — validator session rotation per
  CHN-1 4h epochs. Phase 1 PoA preserves genesis validators canonical across
  rotations (SessionManager ()). Phase 2 NPoS introducira pallet_staking como
  SessionManager para rotation real per nominator stake + Pi 5 hardware tier
  weight.

## Configs canonical pallet_session
- SessionPeriod = BLOCK_HASH_COUNT (2400 bloques × 6s = 14400s = 4h exactas)
- SessionOffset = 0 (sesiones start at block 0)
- ValidatorId = ChainAccountId
- ValidatorIdOf = AccountIdIsValidatorId (custom identity converter Phase 1 PoA)
- ShouldEndSession/NextSessionRotation = PeriodicSessions<SessionPeriod, SessionOffset>
- SessionManager = () (preserves genesis Phase 1 PoA)
- SessionHandler = <opaque::SessionKeys as OpaqueKeys>::KeyTypeIdProviders
- Keys = opaque::SessionKeys (aura sr25519 + grandpa Ed25519)
- DisablingStrategy = () (Phase 2 NPoS introduce real slashing-based disable)

## Custom converter canonical
AccountIdIsValidatorId struct nueva — identity mapping AccountId → ValidatorId
Phase 1 PoA trivial. Phase 2 NPoS reemplazara con pallet_staking::StashOf<Self>
para real Stash/Controller separation canonical.

## Filosofía canonical
SessionPeriod = 4h es la frontera temporal canonical: cada 4h el chain
reflexiona on-chain quienes son los validators activos. Esta cadencia
institucional canonical es la minima necesaria para que Phase 2 NPoS pueda
evolucionar el set sin re-launching genesis. David canon 2026-05-14
materializado temporalmente.

## Build + tests
- cargo check 1.63s warm cache (pallet_session incremental)
- cargo build --release 7.70s warm cache clean
- ~57 tests passing (count preserved — session tests Phase 1.7 chain_spec)

## Decision empirica
pallet_session::Config::DisablingStrategy es nuevo stable2512 canonical (no
estaba en versiones anteriores). Phase 1 PoA: () preserva behavior original.
Phase 2 NPoS: UpToLimitWithReEnablingDisablingStrategy per CHN-3.

## Phase 1 progress
1.1 ✅ + 1.2 ✅ + 1.3 ✅ + 1.4 ✅ + 1.5 ✅ (esta). Next: 1.6 pallet_identity
Ed25519 DID + origin-chain-node real service.

7 pallets composed canonical:
- 0 System + 1 Timestamp + 2 Balances + 3 TransactionPayment
- 4 Aura + 5 Grandpa + 6 Session ← NEW
- Opaque SessionKeys consumed by pallet_session::Config::Keys ← NEW WIRE

Refs: CHARON_ROADMAP_V1 Phase 1.5, CHN-1 4h epoch rotation canonical, SBS-4
extended, arkhe-origin-chain commit pending

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 4.6 committed 2026-05-20 19:40:54 -05:00
1 parent 4988693d4b
commit 926650308c
7 files changed
+194 -1

No files matched your search

@@ -229,3 +229,78 @@ impl pallet_grandpa::Config for Runtime {
/// 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 = ();
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
}