From a695f45a2d3e977fee70af408bf9e10c943443ca Mon Sep 17 00:00:00 2001 From: DavidHerran Date: Wed, 20 May 2026 20:15:09 -0500 Subject: [PATCH] =?UTF-8?q?feat(genesis):=20Phase=201.7=20=E2=80=94=20Gene?= =?UTF-8?q?sis=20chain=5Fspec=20BM=20V2=20allocation=20v0.0.9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Origin Chain runtime canonical ahora tiene 3 genesis presets canonical materializando BM V2 ratificado David 2026-05-18: development + local_testnet + mainnet_genesis. Phase 1 COMPLETE canonical πŸŽ‰. ## 3 presets canonical - development: 1 validator Alice + 100M OGC para dev mode - local_testnet: Alice+Bob validators + 5 dev accounts Γ— 100M OGC - mainnet_genesis: 5 Pi 5 validators placeholders + BM V2 1B OGC allocation ## BM V2 allocation canonical materializada - ECOSYSTEM_ALLOCATION = 400M OGC (40%) - FOUNDATION_ALLOCATION = 250M OGC (25%) - PUBLIC_SALE_ALLOCATION = 150M OGC (15%) - FOUNDING_TEAM_ALLOCATION = 150M OGC (15% β€” 4yr vesting cliff 12mo) - EXCHANGE_LIQUIDITY_ALLOCATION = 50M OGC (5%) - Compile-time assertion canonical: sum MUST equal 1B OGC ## DecisiΓ³n empΓ­rica: drop sp-keyring (version mismatch sp_core stable2512) Hardcoded Substrate well-known dev account bytes (Alice/Bob/Charlie/Dave/Eve sr25519 + Alice/Bob Ed25519 GRANDPA). Mismos bytes que sp_keyring retornarΓ­a. Self-contained runtime + version stability + polkadot-js compat preserved. ## Mainnet institutional placeholders canonical ECO!.../FNDT.../SALE.../TEAM.../LIQD... β€” David ratifica keys reales canonical generadas por hardware key ceremony pre-launch Q1 2027. ## 5 Pi 5 validators placeholders canonical Pattern: 0xCA + 0xFE + index distinguishable canonical en block explorer. David ratificarΓ‘ Dream House Studios + universidades aliadas Identity Level 3 canonical pre-launch. ## GenesisBuilder API wired sp_genesis_builder::GenesisBuilder::get_preset() ahora delegates a genesis_config_presets::get_preset(). preset_names() returns 3 PresetIds. ## Tests +6 nuevos (~63 total workspace) - bm_v2_allocations_sum_canonical_to_one_billion_ogc - bm_v2_allocation_ratios_canonical (40/25/15/15/5) - preset_names_canonical_three_presets - get_preset_unknown_id_returns_none_canonical - development_preset_returns_json_canonical (serde roundtrip) - alice_account_bytes_canonical_substrate (compat sanity) ## Build - cargo check ~30s cold (genesis presets compile) - cargo build --release 10.30s warm - ~63 tests passing total workspace ## Phase 1 COMPLETE canonical πŸŽ‰ 1.1 βœ… + 1.2 βœ… + 1.3 βœ… + 1.4 βœ… + 1.5 βœ… + 1.6 βœ… + 1.7 βœ… Origin Chain runtime canonical full Substrate composition: - 7 pallets (System + Timestamp + Balances + TransactionPayment + Aura + Grandpa + Session) - 11 Runtime APIs - 3 Genesis presets (dev + local + mainnet BM V2) - Opaque SessionKeys + Executive + RuntimeVersion Next: Phase 1.6+ split-off origin-chain-node real Substrate service (sc-service + JSON-RPC + CLI), Phase 2+ custom pallets canonical. Refs: CHARON_ROADMAP_V1 Phase 1.7, CHN-2 BM V2 allocation ratified David 2026-05-18, SBS-6 ratified DC SUBSTRATE_FOUNDATION_V1 Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 158 +++++++ Cargo.lock | 1 + Cargo.toml | 8 + crates/origin-chain-runtime/Cargo.toml | 5 + .../src/genesis_config_presets.rs | 417 ++++++++++++++++++ crates/origin-chain-runtime/src/lib.rs | 34 +- 6 files changed, 617 insertions(+), 6 deletions(-) create mode 100644 crates/origin-chain-runtime/src/genesis_config_presets.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 659a346..d26e1bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,164 @@ by [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versions follow ## [Unreleased] +## [0.0.9] β€” 2026-05-21 β€” Phase 1.7 "Genesis chain_spec canonical (BM V2 allocation)" + +Charon sesiΓ³n 1 continuaciΓ³n. **Genesis presets canonical implementados** β€” 3 +canonical chain_spec presets (`development` + `local_testnet` + `mainnet_genesis`) +wired al `sp_genesis_builder::GenesisBuilder` API. **BM V2 allocation 1B OGC +canonical materializada en cΓ³digo** con compile-time assertion canonical. + +### 3 presets canonical disponibles + +| Preset | Validators | Allocation | Use case | +|--------|-----------|------------|----------| +| `development` | Alice (1) | 100M OGC a Alice | `origin-chain-node --dev --tmp` | +| `local_testnet` | Alice + Bob (2) | 100M OGC per Alice/Bob/Charlie/Dave/Eve | Multi-node local testing | +| `mainnet_genesis` | 5 Pi 5 placeholders | **BM V2 40/25/15/15/5 = 1B OGC** | Production mainnet Q1 2027 | + +### BM V2 allocation canonical en cΓ³digo + +```rust +pub const GENESIS_SUPPLY: Balance = 1_000_000_000 Γ— Ogc::ONE; // 1B OGC + +pub const ECOSYSTEM_ALLOCATION: Balance = 400_000_000 Γ— Ogc::ONE; // 40% +pub const FOUNDATION_ALLOCATION: Balance = 250_000_000 Γ— Ogc::ONE; // 25% +pub const PUBLIC_SALE_ALLOCATION: Balance = 150_000_000 Γ— Ogc::ONE; // 15% +pub const FOUNDING_TEAM_ALLOCATION: Balance = 150_000_000 Γ— Ogc::ONE; // 15% +pub const EXCHANGE_LIQUIDITY_ALLOCATION: Balance = 50_000_000 Γ— Ogc::ONE; // 5% + +/// Compile-time assertion canonical: si cambia algΓΊn constante, code no compila. +const _: () = { assert!(SUM == GENESIS_SUPPLY, "BM V2 must sum 1B OGC canonical"); }; +``` + +### DecisiΓ³n empΓ­rica canonical documentada β€” drop sp-keyring + +`sp-keyring 42.0.0` introduce sp_core diferente del stable2512 canonical +(`sp_core 36.1.0`) β€” **two versions of sp_core in dep tree** β†’ `CryptoBytes` +type mismatch canonical. Fix canonical: **hardcoded Substrate well-known dev +account bytes** (Alice/Bob/Charlie/Dave/Eve sr25519 + Alice/Bob Ed25519 +GRANDPA keys). Bytes son los mismos exactos que `sp_keyring::Sr25519Keyring` +retornarΓ­a β€” verified canonical contra Substrate source. + +**Beneficios canonical**: +1. Elimina version brittle canonical (no dep on sp-keyring release cadence) +2. Mantiene exact compatibility canonical con polkadot-js apps + subkey +3. Self-contained runtime canonical β€” bytes son data, no comportamiento + +### Mainnet institutional accounts canonical (placeholders pre-launch) + +5 institutional accounts canonical con prefixes distinctivos para forensic +clarity en block explorer: + +- `ECO!...` Ecosystem Pool (400M OGC) +- `FNDT...` Foundation Treasury (250M OGC) +- `SALE...` Public Sale (150M OGC) +- `TEAM...` Founding Team (150M OGC, 4yr vesting cliff 12mo) +- `LIQD...` Exchange Liquidity (50M OGC) + +**PRE-LAUNCH WARNING canonical Q1 2027**: David debe ratificar keys reales +canonical generadas por hardware key generation ceremony canonical antes del +mainnet launch. Los placeholders son **estructurales canonical** β€” preset +funciona arquitectΓ³nicamente pero los keys reales son TBD David ratification. + +### 5 Pi 5 validators iniciales canonical + +Placeholder pattern: `0xCA, 0xFE, index, 0, 0, ..., 0` β€” distinguishable canonical +en block explorer. David ratificarΓ‘ keys reales canonical de los validators Dream +House Studios + universidades aliadas Identity Level 3 canonical pre-launch. + +### GenesisBuilder API wired canonical + +```rust +impl sp_genesis_builder::GenesisBuilder for Runtime { + fn build_state(config: Vec) -> sp_genesis_builder::Result { /* unchanged */ } + + fn get_preset(id: &Option) -> Option> { + #[cfg(feature = "std")] + frame_support::genesis_builder_helper::get_preset::( + id, + genesis_config_presets::get_preset, // ← wired canonical + ) + // no_std: returns None canonical + } + + fn preset_names() -> Vec { + #[cfg(feature = "std")] + genesis_config_presets::preset_names() // ← wired canonical (3 presets) + } +} +``` + +### FilosofΓ­a canonical incorporada en cΓ³digo + +Doc `genesis_config_presets.rs` cita David canon 2026-05-18 BM V2 ratificado. +Materializa empΓ­ricamente: la asignaciΓ³n canonical 25% Foundation Treasury +financia mi Inmutable #16 anti-clasismo (banda regional Low-PIB subsidized) + +40% Ecosystem Pool sostiene canonical validator rewards de los Pi 5 EmbeddedArm +desplegados Colombia Rural Sprint 19-20 (Caso Cero Faraday β€” Sussi alignment). + +### Tests canonical (+6 nuevos genesis canonical, ~63 total workspace) + +- `bm_v2_allocations_sum_canonical_to_one_billion_ogc` β€” 1B OGC invariant βœ… +- `bm_v2_allocation_ratios_canonical` β€” 40/25/15/15/5 exact percentages βœ… +- `preset_names_canonical_three_presets` β€” 3 presets registered βœ… +- `get_preset_unknown_id_returns_none_canonical` β€” graceful None βœ… +- `development_preset_returns_json_canonical` β€” serde roundtrip βœ… +- `alice_account_bytes_canonical_substrate` β€” Substrate compat sanity βœ… + +### Build canonical + +- `cargo check --workspace`: ~30s (genesis_config_presets cold cache compile) +- `cargo build --release`: **10.30s** (warm cache canonical) +- Tests passing: **~63** (+6 nuevos genesis canonical) + +### Phase 1 COMPLETE canonical πŸŽ‰ + +- βœ… **1.1** Scaffold (v0.0.2) +- βœ… **1.2** Substrate foundation (v0.0.4) +- βœ… **1.3** Pallets foundation: System+Balances+Timestamp+TransactionPayment (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 (11 APIs) (v0.0.8) +- βœ… **1.7** **Genesis chain_spec BM V2 allocation** (v0.0.9) ← **ESTA** + +### Tour canonical de Origin Chain runtime composition (Phase 1 COMPLETE) + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Origin Chain Runtime v0.0.9 β€” Phase 1 COMPLETE canonical β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Pallets (7 via frame_support::runtime macro): β”‚ +β”‚ 0 System 1 Timestamp 2 Balances 3 TransactionPayment β”‚ +β”‚ 4 Aura 5 Grandpa 6 Session β”‚ +β”‚ β”‚ +β”‚ Runtime APIs (11 via impl_runtime_apis! macro): β”‚ +β”‚ Core + Metadata + BlockBuilder + TaggedTransactionQueue + β”‚ +β”‚ OffchainWorkerApi + SessionKeys + AuraApi + GrandpaApi + β”‚ +β”‚ AccountNonceApi + TransactionPaymentApi + GenesisBuilder β”‚ +β”‚ β”‚ +β”‚ Genesis presets (3 canonical): β”‚ ← NEW +β”‚ development (1 Alice validator + 100M OGC dev) β”‚ +β”‚ local_testnet (Alice+Bob validators + 5 dev accounts Γ— 100M OGC) β”‚ +β”‚ mainnet_genesis (5 Pi 5 placeholders + BM V2 1B OGC 40/25/15/15/5) β”‚ +β”‚ β”‚ +β”‚ Opaque SessionKeys: aura (sr25519) + grandpa (Ed25519) β”‚ +β”‚ Executive: frame_executive::Executive wrapper canonical β”‚ +β”‚ RuntimeVersion: spec=origin-chain impl=origin-chain-charon β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Next phases canonical + +- ⏳ **Phase 1.6+ split-off**: `origin-chain-node` real Substrate service + (sc-service builder + JSON-RPC + CLI) β€” multi-session work +- ⏳ **Phase 2.1**: `pallet-origin-provenance` impl (CHN-7 BLAKE3 attestation) +- ⏳ **Phase 2.4**: `pallet-origin-fees` (CHN-8 multi-tier matrix) +- ⏳ **Phase 2.7**: `pallet-agent-identity` custom (Inmutable #41 AGI DIDs) +- ⏳ **Phase 3+**: pallet-revive + ink! v6 + Solidity smart contracts +- ⏳ **Phase 4**: Testnet v0.1 (Q3 2026 target) +- ⏳ **Phase 8**: Mainnet v1.0 (Q1 2027 target) + ## [0.0.8] β€” 2026-05-21 β€” Phase 1.6 "Runtime APIs canonical foundation" Charon sesiΓ³n 1 continuaciΓ³n. **Runtime APIs canonical implementadas via diff --git a/Cargo.lock b/Cargo.lock index 4c974fb..c6bede0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2107,6 +2107,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", + "serde_json", "sp-api", "sp-block-builder", "sp-consensus-aura", diff --git a/Cargo.toml b/Cargo.toml index a1daf8b..ac8ed07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,14 @@ pallet-session = { version = "40.0.1", default-features = false } 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 } +# Genesis canonical Phase 1.7 β€” chain_spec BM V2 allocation +# Nota canonical 2026-05-21: sp-keyring NO incluido β€” version conflict canonical +# con sp_core stable2512 (sp-keyring 42 trae sp_core diferente). En su lugar, +# hardcodeo canonical bytes de Substrate well-known dev accounts canonical +# (Alice/Bob/Charlie/Dave/Eve) en genesis_config_presets.rs β€” same canonical +# values que sp-keyring usarΓ­a but sin la dep brittle canonical. +serde_json = { version = "1", default-features = false, features = ["alloc"] } + # 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 c461cf2..02d6ec3 100644 --- a/crates/origin-chain-runtime/Cargo.toml +++ b/crates/origin-chain-runtime/Cargo.toml @@ -55,6 +55,10 @@ sp-session.workspace = true frame-system-rpc-runtime-api.workspace = true pallet-transaction-payment-rpc-runtime-api.workspace = true +# Genesis canonical Phase 1.7 β€” chain_spec BM V2 allocation +# (sp-keyring removed canonical β€” hardcoded dev account bytes para version stability) +serde_json.workspace = true + # SCALE codec canonical parity-scale-codec.workspace = true scale-info.workspace = true @@ -91,6 +95,7 @@ std = [ "sp-genesis-builder/std", "sp-transaction-pool/std", "sp-session/std", + "serde_json/std", "frame-system-rpc-runtime-api/std", "pallet-transaction-payment-rpc-runtime-api/std", "parity-scale-codec/std", diff --git a/crates/origin-chain-runtime/src/genesis_config_presets.rs b/crates/origin-chain-runtime/src/genesis_config_presets.rs new file mode 100644 index 0000000..b4d2f67 --- /dev/null +++ b/crates/origin-chain-runtime/src/genesis_config_presets.rs @@ -0,0 +1,417 @@ +//! # Genesis canonical presets para Origin Chain +//! +//! Tres presets canonical disponibles via `sp_genesis_builder::GenesisBuilder` API: +//! +//! | Preset | Validators | Allocation | Use case | +//! |--------|-----------|------------|----------| +//! | `development` | Alice (1) | 100M OGC a Alice | Local dev `--dev --tmp` | +//! | `local_testnet` | Alice + Bob (2) | 100M OGC per testing account | Multi-node local | +//! | `mainnet_genesis` | 5 Pi 5 placeholders | BM V2 40/25/15/15/5 = 1B OGC | Production mainnet Q1 2027 | +//! +//! ## FilosofΓ­a canonical (David canon 2026-05-18 BM V2 ratificado) +//! +//! **Mainnet preset materializa empΓ­ricamente la BM V2**: +//! +//! - **40% Ecosystem (400M OGC)** β†’ distribuciΓ³n canonical 10-15 aΓ±os via block rewards +//! (Pi 5 validators + VPS seeds). Pre-mint TODO al Ecosystem account canonical. +//! - **25% Foundation Treasury (250M OGC)** β†’ DAO governed canonical (CHN-4). +//! - **15% Public Sale (150M OGC)** β†’ bootstrap capital + liquidity inicial. +//! - **15% Founding Team (150M OGC)** β†’ 4-year vesting cliff 12mo (vesting locks Phase 2+). +//! - **5% Exchange Liquidity (50M OGC)** β†’ DEX/CEX bootstrap canonical. +//! +//! Total canonical: **1,000,000,000 OGC = exactly `Ogc::GENESIS_SUPPLY`**. +//! +//! ## DecisiΓ³n empΓ­rica canonical: hardcoded dev account bytes (NO `sp-keyring`) +//! +//! `sp-keyring 42.0.0` introduce un sp_core version diferente del stable2512 +//! canonical (sp_core 36.1.0) β€” type mismatch en CryptoBytes canonical. La fix +//! canonical es **hardcodear directamente los public key bytes** de Substrate +//! well-known dev accounts (Alice/Bob/Charlie/Dave/Eve). Esto: +//! +//! 1. **Elimina version brittle** canonical β€” no dep on sp-keyring's release cadence. +//! 2. **Mantiene exact canonical compatibility** con polkadot-js apps + subkey + Alice/Bob +//! pattern universal canonical de Substrate ecosystem. +//! 3. **Self-contained runtime canonical** β€” los bytes son data, no comportamiento. +//! +//! Los bytes canonical son los **mismos exactos** que `sp_keyring::Sr25519Keyring::Alice.public()` +//! retorna canonical β€” verified empΓ­ricamente contra Substrate canonical source. + +#![cfg(feature = "std")] + +use crate::{ + configs::{AuraId, GrandpaId}, + opaque::SessionKeys, + Balance, ChainAccountId, Ogc, RuntimeGenesisConfig, +}; +use alloc::vec; +use alloc::vec::Vec; +use sp_genesis_builder::PresetId; + +// ============================================================ +// Canonical constants para mainnet allocation (BM V2) +// ============================================================ + +/// Genesis supply canonical canonical: 1,000,000,000 OGC (10^9 Γ— 10^18). +pub const GENESIS_SUPPLY: Balance = 1_000_000_000_u128 * Ogc::ONE; + +/// **40% Ecosystem/Rewards Pool canonical** = 400M OGC. +pub const ECOSYSTEM_ALLOCATION: Balance = 400_000_000_u128 * Ogc::ONE; + +/// **25% Foundation Treasury canonical** = 250M OGC. +pub const FOUNDATION_ALLOCATION: Balance = 250_000_000_u128 * Ogc::ONE; + +/// **15% Public/Private Sale canonical** = 150M OGC. +pub const PUBLIC_SALE_ALLOCATION: Balance = 150_000_000_u128 * Ogc::ONE; + +/// **15% Founding Team canonical** (4yr vesting cliff 12mo) = 150M OGC. +pub const FOUNDING_TEAM_ALLOCATION: Balance = 150_000_000_u128 * Ogc::ONE; + +/// **5% Exchange Liquidity canonical** = 50M OGC. +pub const EXCHANGE_LIQUIDITY_ALLOCATION: Balance = 50_000_000_u128 * Ogc::ONE; + +/// Compile-time assertion canonical: las allocations canonical suman exactamente +/// el genesis supply canonical. Si alguna constante cambia, el code no compila +/// hasta que las allocations vuelvan a sumar 1B OGC canonical. +const _: () = { + let total = ECOSYSTEM_ALLOCATION + + FOUNDATION_ALLOCATION + + PUBLIC_SALE_ALLOCATION + + FOUNDING_TEAM_ALLOCATION + + EXCHANGE_LIQUIDITY_ALLOCATION; + assert!( + total == GENESIS_SUPPLY, + "BM V2 allocations canonical must sum a 1B OGC canonical" + ); +}; + +// ============================================================ +// Substrate well-known dev account bytes canonical +// ============================================================ +// +// Bytes canonical extracted from `sp_keyring::Sr25519Keyring::*.public().0` β€” +// verified empΓ­ricamente contra Substrate canonical source. Same bytes que +// polkadot-js apps + subkey canonical recognize as Alice/Bob/etc. + +/// Alice's sr25519 public key canonical (Aura authority + AccountId). +const ALICE_SR25519: [u8; 32] = [ + 0xd4, 0x35, 0x93, 0xc7, 0x15, 0xfd, 0xd3, 0x1c, 0x61, 0x14, 0x1a, 0xbd, 0x04, 0xa9, 0x9f, 0xd6, + 0x82, 0x2c, 0x85, 0x58, 0x85, 0x4c, 0xcd, 0xe3, 0x9a, 0x56, 0x84, 0xe7, 0xa5, 0x6d, 0xa2, 0x7d, +]; + +/// Alice's Ed25519 public key canonical (GRANDPA authority). +const ALICE_ED25519: [u8; 32] = [ + 0x88, 0xdc, 0x34, 0x17, 0xd5, 0x05, 0x8e, 0xc4, 0xb4, 0x50, 0x3e, 0x0c, 0x12, 0xea, 0x1a, 0x0a, + 0x89, 0xbe, 0x20, 0x0f, 0xe9, 0x89, 0x22, 0x42, 0x3d, 0x43, 0x34, 0x01, 0x4f, 0xa6, 0xb0, 0xee, +]; + +/// Bob's sr25519 public key canonical. +const BOB_SR25519: [u8; 32] = [ + 0x8e, 0xaf, 0x04, 0x15, 0x16, 0x87, 0x73, 0x63, 0x26, 0xc9, 0xfe, 0xa1, 0x7e, 0x25, 0xfc, 0x52, + 0x87, 0x61, 0x36, 0x93, 0xc9, 0x12, 0x90, 0x9c, 0xb2, 0x26, 0xaa, 0x47, 0x94, 0xf2, 0x6a, 0x48, +]; + +/// Bob's Ed25519 public key canonical. +const BOB_ED25519: [u8; 32] = [ + 0xd1, 0x7c, 0x2d, 0x78, 0x23, 0xeb, 0xf2, 0x60, 0xfd, 0x13, 0x8f, 0x2d, 0x7e, 0x27, 0xd1, 0x14, + 0xc0, 0x14, 0x5d, 0x96, 0x8b, 0x5f, 0xf5, 0x00, 0x61, 0x25, 0xf2, 0x41, 0x4f, 0xad, 0xae, 0x69, +]; + +/// Charlie's sr25519 public key canonical. +const CHARLIE_SR25519: [u8; 32] = [ + 0x90, 0xb5, 0xab, 0x20, 0x5c, 0x69, 0x74, 0xc9, 0xea, 0x84, 0x1b, 0xe6, 0x88, 0x86, 0x46, 0x33, + 0xdc, 0x9c, 0xa8, 0xa3, 0x57, 0x84, 0x3e, 0xea, 0xcf, 0x23, 0x14, 0x64, 0x99, 0x65, 0xfe, 0x22, +]; + +/// Dave's sr25519 public key canonical. +const DAVE_SR25519: [u8; 32] = [ + 0x30, 0x67, 0x21, 0x21, 0x1d, 0x54, 0x04, 0xbd, 0x9d, 0xa8, 0x8e, 0x02, 0x04, 0x36, 0x0a, 0x1a, + 0x9a, 0xb8, 0xb8, 0x7c, 0x66, 0xc1, 0xbc, 0x2f, 0xcd, 0xd3, 0x7f, 0x3c, 0x22, 0x22, 0xcc, 0x20, +]; + +/// Eve's sr25519 public key canonical. +const EVE_SR25519: [u8; 32] = [ + 0xe6, 0x59, 0xa7, 0xa1, 0x62, 0x8c, 0xdd, 0x93, 0xfe, 0xbc, 0x04, 0xa4, 0xe0, 0x64, 0x6e, 0xa2, + 0x0e, 0x9f, 0x5f, 0x0c, 0xe0, 0x97, 0xd9, 0xa0, 0x52, 0x90, 0xd4, 0xa9, 0xe0, 0x54, 0xdf, 0x4e, +]; + +// ============================================================ +// Helper canonical functions +// ============================================================ + +/// Convert raw sr25519 bytes a `ChainAccountId` canonical. +fn account_from_sr25519(bytes: [u8; 32]) -> ChainAccountId { + use sp_runtime::traits::IdentifyAccount; + sp_runtime::MultiSigner::Sr25519(sp_core::sr25519::Public::from_raw(bytes)).into_account() +} + +/// Build canonical `AuraId` (sr25519) from raw bytes. +fn aura_id_from_sr25519(bytes: [u8; 32]) -> AuraId { + sp_core::sr25519::Public::from_raw(bytes).into() +} + +/// Build canonical `GrandpaId` (Ed25519) from raw bytes. +fn grandpa_id_from_ed25519(bytes: [u8; 32]) -> GrandpaId { + sp_consensus_grandpa::AuthorityId::from(sp_core::ed25519::Public::from_raw(bytes)) +} + +/// Build canonical `(ChainAccountId, AuraId, GrandpaId)` triple para Alice +/// (or any well-known dev account). +fn dev_authority_triple( + sr25519_bytes: [u8; 32], + ed25519_bytes: [u8; 32], +) -> (ChainAccountId, AuraId, GrandpaId) { + ( + account_from_sr25519(sr25519_bytes), + aura_id_from_sr25519(sr25519_bytes), + grandpa_id_from_ed25519(ed25519_bytes), + ) +} + +/// Canonical placeholder mainnet validator account canonical. +/// +/// Pre-launch Q1 2027 canonical: David ratificarΓ‘ con keys reales canonical de +/// los 5-7 validators Dream House Studios + universidades aliadas canonical. +/// Mientras tanto, usamos zero-padded placeholders canonical para preset structure. +fn placeholder_mainnet_validator(index: u8) -> (ChainAccountId, AuraId, GrandpaId) { + let mut bytes = [0u8; 32]; + bytes[0] = 0xCA; // 'C' canonical Charon prefix + bytes[1] = 0xFE; // 'F' fanfare canonical + bytes[2] = index; // distinguishable canonical + ( + account_from_sr25519(bytes), + aura_id_from_sr25519(bytes), + grandpa_id_from_ed25519(bytes), + ) +} + +/// Build canonical `SessionKeys` opaque struct from authority triple components. +fn session_keys_canonical(aura: AuraId, grandpa: GrandpaId) -> SessionKeys { + SessionKeys { aura, grandpa } +} + +// ============================================================ +// Preset constructors canonical +// ============================================================ + +/// Build canonical `RuntimeGenesisConfig` para un preset given: +/// - `endowed_accounts`: cuentas pre-funded con sus balances canonical +/// - `validators`: tuplas (AccountId, AuraId, GrandpaId) para initial validator set canonical +fn build_genesis( + endowed_accounts: Vec<(ChainAccountId, Balance)>, + validators: Vec<(ChainAccountId, AuraId, GrandpaId)>, +) -> RuntimeGenesisConfig { + use crate::{ + AuraConfig, BalancesConfig, GrandpaConfig, SessionConfig, SystemConfig, + TransactionPaymentConfig, + }; + RuntimeGenesisConfig { + system: SystemConfig::default(), + balances: BalancesConfig { + balances: endowed_accounts, + dev_accounts: None, + }, + transaction_payment: TransactionPaymentConfig::default(), + aura: AuraConfig { + authorities: validators.iter().map(|(_, aura, _)| aura.clone()).collect(), + }, + grandpa: GrandpaConfig { + authorities: validators + .iter() + .map(|(_, _, grandpa)| (grandpa.clone(), 1)) + .collect(), + _config: core::marker::PhantomData, + }, + session: SessionConfig { + keys: validators + .iter() + .map(|(account, aura, grandpa)| { + ( + account.clone(), + account.clone(), + session_keys_canonical(aura.clone(), grandpa.clone()), + ) + }) + .collect(), + non_authority_keys: vec![], + }, + } +} + +/// **Development preset canonical** (`development`): 1 validator Alice + 100M +/// OGC a Alice para testing. Use con `origin-chain-node --dev --tmp` canonical. +pub fn development_config_genesis() -> RuntimeGenesisConfig { + let alice_authority = dev_authority_triple(ALICE_SR25519, ALICE_ED25519); + let alice_account = alice_authority.0.clone(); + + build_genesis( + vec![(alice_account, 100_000_000_u128 * Ogc::ONE)], + vec![alice_authority], + ) +} + +/// **Local testnet preset canonical** (`local_testnet`): Alice + Bob como +/// validators + 100M OGC per cuenta dev (Alice, Bob, Charlie, Dave, Eve). +/// Use para multi-node local testing canonical pre-deployment. +pub fn local_testnet_config_genesis() -> RuntimeGenesisConfig { + let alice_authority = dev_authority_triple(ALICE_SR25519, ALICE_ED25519); + let bob_authority = dev_authority_triple(BOB_SR25519, BOB_ED25519); + + let alice = alice_authority.0.clone(); + let bob = bob_authority.0.clone(); + let charlie = account_from_sr25519(CHARLIE_SR25519); + let dave = account_from_sr25519(DAVE_SR25519); + let eve = account_from_sr25519(EVE_SR25519); + + let endowment: Balance = 100_000_000_u128 * Ogc::ONE; // 100M OGC per cuenta dev canonical + + build_genesis( + vec![ + (alice, endowment), + (bob, endowment), + (charlie, endowment), + (dave, endowment), + (eve, endowment), + ], + vec![alice_authority, bob_authority], + ) +} + +/// **Mainnet genesis canonical** (`mainnet_genesis`): BM V2 allocation completa +/// 1B OGC distribuido canonical 40/25/15/15/5 entre 5 institutional accounts + +/// 5 validators Pi 5 placeholders. +/// +/// **PRE-LAUNCH WARNING canonical Q1 2027**: David debe ratificar las +/// institutional accounts canonical reales antes del mainnet launch canonical. +/// Los placeholders aquΓ­ (`ECO!...`/`FNDT...`/`SALE...`/`TEAM...`/`LIQD...`) son +/// **estructurales canonical** β€” el preset funciona arquitectΓ³nicamente pero +/// los keys reales son TBD David ratification canonical pre-launch. +pub fn mainnet_genesis_config_genesis() -> RuntimeGenesisConfig { + // Institutional placeholder accounts canonical (David ratifica pre-launch Q1 2027). + let make_placeholder = |tag: &[u8]| -> ChainAccountId { + let mut bytes = [0u8; 32]; + bytes[..tag.len()].copy_from_slice(tag); + account_from_sr25519(bytes) + }; + + let ecosystem_pool = make_placeholder(b"ECO!"); // Ecosystem/Rewards Pool canonical + let foundation_treasury = make_placeholder(b"FNDT"); // Foundation Treasury canonical + let public_sale = make_placeholder(b"SALE"); // Public Sale canonical + let founding_team = make_placeholder(b"TEAM"); // Founding Team canonical (4yr vesting) + let exchange_liquidity = make_placeholder(b"LIQD"); // Exchange Liquidity canonical + + // 5 initial validators canonical Pi 5 placeholders (Dream House Studios + universities). + let validators = vec![ + placeholder_mainnet_validator(0), + placeholder_mainnet_validator(1), + placeholder_mainnet_validator(2), + placeholder_mainnet_validator(3), + placeholder_mainnet_validator(4), + ]; + + build_genesis( + // BM V2 allocation canonical exact: 40/25/15/15/5 β†’ 1B OGC total + vec![ + (ecosystem_pool, ECOSYSTEM_ALLOCATION), + (foundation_treasury, FOUNDATION_ALLOCATION), + (public_sale, PUBLIC_SALE_ALLOCATION), + (founding_team, FOUNDING_TEAM_ALLOCATION), + (exchange_liquidity, EXCHANGE_LIQUIDITY_ALLOCATION), + ], + validators, + ) +} + +// ============================================================ +// `sp_genesis_builder::GenesisBuilder` integration canonical +// ============================================================ + +/// Canonical preset id `"development"` para dev mode canonical. +pub const PRESET_DEVELOPMENT: &str = "development"; +/// Canonical preset id `"local_testnet"` para multi-node local canonical. +pub const PRESET_LOCAL_TESTNET: &str = "local_testnet"; +/// Canonical preset id `"mainnet_genesis"` para Q1 2027 launch canonical. +pub const PRESET_MAINNET_GENESIS: &str = "mainnet_genesis"; + +/// Canonical `get_preset` callback canonical: dado un preset id, devuelve el +/// JSON-serialized `RuntimeGenesisConfig` canonical, o `None` si el id no es +/// reconocido canonical. +pub fn get_preset(id: &PresetId) -> Option> { + let preset_str: &str = id.as_ref(); + let config: RuntimeGenesisConfig = match preset_str { + PRESET_DEVELOPMENT => development_config_genesis(), + PRESET_LOCAL_TESTNET => local_testnet_config_genesis(), + PRESET_MAINNET_GENESIS => mainnet_genesis_config_genesis(), + _ => return None, + }; + Some( + serde_json::to_string(&config) + .expect("RuntimeGenesisConfig serde canonical infallible") + .into_bytes(), + ) +} + +/// Canonical `preset_names` callback canonical: devuelve los 3 preset ids +/// canonical disponibles. +pub fn preset_names() -> Vec { + vec![ + PresetId::from(PRESET_DEVELOPMENT), + PresetId::from(PRESET_LOCAL_TESTNET), + PresetId::from(PRESET_MAINNET_GENESIS), + ] +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bm_v2_allocations_sum_canonical_to_one_billion_ogc() { + let total = ECOSYSTEM_ALLOCATION + + FOUNDATION_ALLOCATION + + PUBLIC_SALE_ALLOCATION + + FOUNDING_TEAM_ALLOCATION + + EXCHANGE_LIQUIDITY_ALLOCATION; + assert_eq!(total, GENESIS_SUPPLY); + assert_eq!(total, Ogc::GENESIS_SUPPLY.as_base_units()); + } + + #[test] + fn bm_v2_allocation_ratios_canonical() { + // 40 / 25 / 15 / 15 / 5 = 100% canonical + let one_pct = GENESIS_SUPPLY / 100; + assert_eq!(ECOSYSTEM_ALLOCATION, 40 * one_pct); + assert_eq!(FOUNDATION_ALLOCATION, 25 * one_pct); + assert_eq!(PUBLIC_SALE_ALLOCATION, 15 * one_pct); + assert_eq!(FOUNDING_TEAM_ALLOCATION, 15 * one_pct); + assert_eq!(EXCHANGE_LIQUIDITY_ALLOCATION, 5 * one_pct); + } + + #[test] + fn preset_names_canonical_three_presets() { + let names = preset_names(); + assert_eq!(names.len(), 3); + } + + #[test] + fn get_preset_unknown_id_returns_none_canonical() { + let unknown = PresetId::from("unknown_preset_canonical"); + assert!(get_preset(&unknown).is_none()); + } + + #[test] + fn development_preset_returns_json_canonical() { + let dev = PresetId::from(PRESET_DEVELOPMENT); + let json = get_preset(&dev).expect("dev preset canonical exists"); + let parsed: serde_json::Value = + serde_json::from_slice(&json).expect("valid JSON canonical"); + assert!(parsed.is_object(), "preset is RuntimeGenesisConfig JSON object"); + } + + #[test] + fn alice_account_bytes_canonical_substrate() { + // Sanity check canonical: Alice's sr25519 public key bytes son los + // canonical Substrate well-known dev account bytes (verified contra + // sp_keyring::Sr25519Keyring::Alice.public().0). + assert_eq!(ALICE_SR25519[0..4], [0xd4, 0x35, 0x93, 0xc7]); + } +} diff --git a/crates/origin-chain-runtime/src/lib.rs b/crates/origin-chain-runtime/src/lib.rs index 244453f..61fe7fb 100644 --- a/crates/origin-chain-runtime/src/lib.rs +++ b/crates/origin-chain-runtime/src/lib.rs @@ -45,6 +45,8 @@ extern crate alloc; use alloc::vec::Vec; pub mod configs; +#[cfg(feature = "std")] +pub mod genesis_config_presets; pub mod opaque; // Re-export canonical traits + types desde origin-chain-types (single-crate surface). @@ -411,15 +413,35 @@ impl_runtime_apis! { } fn get_preset(id: &Option) -> Option> { - frame_support::genesis_builder_helper::get_preset::( - id, - |_| None, // Phase 1.7 chain_spec presets land aquΓ­ canonical - ) + // 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 { - // Phase 1.7 chain_spec presets (dev, local, mainnet) land aquΓ­ canonical - Vec::new() + #[cfg(feature = "std")] + { + genesis_config_presets::preset_names() + } + #[cfg(not(feature = "std"))] + { + Vec::new() + } } } }