feat(genesis): Phase 1.7 — Genesis chain_spec BM V2 allocation v0.0.9
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 <noreply@anthropic.com>
This commit is contained in:
1 parent
4286b8d9e8
commit
a695f45a2d
6 files changed
+617
-6
No files matched your search
+158
@@ -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<Block> for Runtime {
|
||||
fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result { /* unchanged */ }
|
||||
|
||||
fn get_preset(id: &Option<PresetId>) -> Option<Vec<u8>> {
|
||||
#[cfg(feature = "std")]
|
||||
frame_support::genesis_builder_helper::get_preset::<RuntimeGenesisConfig>(
|
||||
id,
|
||||
genesis_config_presets::get_preset, // ← wired canonical
|
||||
)
|
||||
// no_std: returns None canonical
|
||||
}
|
||||
|
||||
fn preset_names() -> Vec<PresetId> {
|
||||
#[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
|
||||
|
||||
Generated
+1
@@ -2107,6 +2107,7 @@ dependencies = [
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-consensus-aura",
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Vec<u8>> {
|
||||
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<PresetId> {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@@ -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<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
|
||||
)
|
||||
// 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::<RuntimeGenesisConfig>(
|
||||
id,
|
||||
genesis_config_presets::get_preset,
|
||||
)
|
||||
}
|
||||
#[cfg(not(feature = "std"))]
|
||||
{
|
||||
let _ = id;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user