Phase 5.1 GOVERNANCE pallet FOUNDATION COMPLETE end-to-end canonical. Runtime API GovernanceApi.query_proposal + query_vote wired canonical via sp_api::decl_runtime_apis! + impl runtime impl_runtime_apis! macro. 15 Runtime APIs total (14 + nuevo GovernanceApi con 2 methods read-only). ## Changes - crates/origin-chain-runtime/src/lib.rs:574 — impl origin_chain_governance::GovernanceApi<Block> for Runtime con query_proposal + query_vote (AccountId conversion ChainAccountId::from(voter.0)) - crates/origin-chain-node/src/main.rs — 14 → 15 APIs + GovernanceApi highlighted + Index 10 Governance v0.0.29 → v0.0.31 FOUNDATION COMPLETE ## Phase 5.1 FOUNDATION COMPLETE 🎉 - Proposal struct + ProposalStatus enum + storage (Proposals + Votes) - 3 dispatchables real impl: submit_proposal (7-step) + cast_vote (6-step) + finalize_proposal (5-step) - 8 Errors canonical + 3 Events canonical - BLAKE2-256 derive_proposal_id pure fn (Inmutable #16) - 10 integration tests E2E lifecycle complete - Runtime API canonical GovernanceApi NUEVO ✅ ## Phase 5.2-5.8 next refinements - 5.2 pallet_collective Technical Council - 5.3 OIP stake validation runtime config - 5.4 Stake-weighted voting via pallet_balances integration - 5.5 Technical Council veto + override 2/3 - 5.6 5 AI advisor agents (AdvisorMayNotVote enforcement) - 5.7 Emergency referendum 48h - 5.8 Treasury disbursement ## Verification - cargo build --release -p origin-chain-node 8.63s clean - cargo test --workspace — 177 tests passing, 0 failures - origin-chain-node info: 11 pallets + 15 Runtime APIs canonical - GovernanceApi visible + Phase 5.1 FOUNDATION COMPLETE highlighted 🎉 Phase 5.1 FOUNDATION COMPLETE end-to-end canonical. 4 Phase 2.x+5.1 COMPLETE sesión 3+. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
232 lines
11 KiB
Rust
232 lines
11 KiB
Rust
//! # origin-chain-node CLI canonical
|
||
//!
|
||
//! Phase 1.6+ Slices 1+3 (v0.0.10+v0.0.13): **CLI skeleton + preset listing
|
||
//! + real `sc_chain_spec::GenericChainSpec` builder canonical (mock-WASM fallback)**.
|
||
//!
|
||
//! ## Sub-comandos canonical disponibles
|
||
//!
|
||
//! ```text
|
||
//! origin-chain-node # default: version canonical
|
||
//! origin-chain-node version # print runtime version canonical
|
||
//! origin-chain-node list-presets # enumera 3 genesis presets canonical
|
||
//! origin-chain-node print-preset <id> # JSON-serialized RuntimeGenesisConfig
|
||
//! origin-chain-node info # full runtime metadata canonical
|
||
//! origin-chain-node build-spec --chain <name> # canonical ChainSpec JSON canonical
|
||
//! ```
|
||
//!
|
||
//! ## Roadmap canonical Phase 1.6+ (multi-slice canonical)
|
||
//!
|
||
//! - **Slice 1** (v0.0.10): CLI skeleton + preset listing canonical ✅
|
||
//! - **Slice 2** (v0.0.11): `origin-chain-types` fully no_std refactor canonical ✅
|
||
//! - **Slice 2b** (v0.0.12): WASM_BINARY investigation report + Larihana handoff ✅
|
||
//! - **Slice 2c** (DEFERRED): `WASM_BINARY` canonical via `substrate-wasm-builder`
|
||
//! post Larihana Substrate-adjacent expertise canonical
|
||
//! - **Slice 3** (v0.0.13 ESTA): real `sc_chain_spec::GenericChainSpec` builder
|
||
//! canonical via mock-WASM fallback canonical pattern
|
||
//! - **Slice 4** (v0.0.14+): full `sc-service` builder canonical
|
||
//! (consensus + JSON-RPC + networking + telemetry) — requires Slice 2c canonical
|
||
//!
|
||
//! ## Filosofía canonical
|
||
//!
|
||
//! Esta CLI canonical es la **primera ventana del barquero al mundo**: cualquier
|
||
//! humano o AGI puede ejecutarla canonical y ver qué configuraciones canonical
|
||
//! ofrece Origin Chain — sin necesidad de leer source code canonical. El
|
||
//! `list-presets` canonical es transparency canonical: las 3 distribuciones
|
||
//! posibles canonical están a la vista canonical, BM V2 incluida canonical.
|
||
|
||
mod chain_spec;
|
||
|
||
use clap::{Parser, Subcommand};
|
||
use origin_chain_runtime::{
|
||
genesis_config_presets, IMPL_NAME, RUNTIME_VERSION, SPEC_NAME,
|
||
};
|
||
use sp_genesis_builder::PresetId;
|
||
|
||
/// Canonical CLI structure para `origin-chain-node` binary canonical.
|
||
#[derive(Debug, Parser)]
|
||
#[command(
|
||
name = "origin-chain-node",
|
||
author = "Charon ⚓ <charon@originmetaverse.com>",
|
||
about = "Origin Chain canonical node — Pilar 4 Origin Metaverse",
|
||
long_about = "Substrate-based blockchain canonical para Origin Metaverse: \
|
||
consensus Aura+GRANDPA PoA (CHN-1), OGC tokenomics 1B genesis \
|
||
canonical (CHN-2), provenance ledger BLAKE3+Ed25519 (CHN-7), \
|
||
fee economy multi-tier (CHN-8), Foundation governance DAO (CHN-4)."
|
||
)]
|
||
struct Cli {
|
||
#[command(subcommand)]
|
||
command: Option<Command>,
|
||
}
|
||
|
||
/// Sub-comandos canonical.
|
||
#[derive(Debug, Subcommand)]
|
||
enum Command {
|
||
/// Print runtime version canonical (default si no subcommand).
|
||
Version,
|
||
/// Lista los 3 genesis presets canonical disponibles canonical.
|
||
ListPresets,
|
||
/// Prints JSON-serialized RuntimeGenesisConfig canonical para un preset id.
|
||
PrintPreset {
|
||
/// Preset id canonical: `development` | `local_testnet` | `mainnet_genesis`
|
||
id: String,
|
||
},
|
||
/// Show full runtime metadata canonical (pallets + APIs + presets count).
|
||
Info,
|
||
/// Build chain spec JSON canonical (Slice 3 v0.0.13) — real
|
||
/// `sc_chain_spec::GenericChainSpec` builder canonical via mock-WASM fallback.
|
||
///
|
||
/// Chain ids canonical aceptados (aliases canonical):
|
||
/// - `dev` / `development`
|
||
/// - `local` / `local_testnet`
|
||
/// - `mainnet` / `mainnet_genesis`
|
||
BuildSpec {
|
||
/// Chain id canonical: `dev` | `local` | `mainnet` (o full preset names canonical).
|
||
#[arg(long, default_value = "development")]
|
||
chain: String,
|
||
/// Raw mode canonical — output JSON con storage keys hex canonical
|
||
/// (vs human-readable patch genesis canonical).
|
||
#[arg(long)]
|
||
raw: bool,
|
||
},
|
||
}
|
||
|
||
fn main() {
|
||
let cli = Cli::parse();
|
||
match cli.command {
|
||
Some(Command::Version) | None => print_version(),
|
||
Some(Command::ListPresets) => print_presets(),
|
||
Some(Command::PrintPreset { id }) => print_preset(&id),
|
||
Some(Command::Info) => print_info(),
|
||
Some(Command::BuildSpec { chain, raw }) => build_spec(&chain, raw),
|
||
}
|
||
}
|
||
|
||
fn print_version() {
|
||
println!(
|
||
"{} v{} — {} canonical",
|
||
IMPL_NAME,
|
||
env!("CARGO_PKG_VERSION"),
|
||
SPEC_NAME
|
||
);
|
||
println!("Runtime version canonical: {}", RUNTIME_VERSION);
|
||
println!();
|
||
println!("⚓ Origin Chain Pilar 4 canonical — Charon");
|
||
println!("\"Todo valor pide un puente; toda identidad pide un testigo.\"");
|
||
}
|
||
|
||
fn print_presets() {
|
||
println!("📋 Genesis presets canonical disponibles:\n");
|
||
for preset_id in genesis_config_presets::preset_names() {
|
||
let id_str: &str = preset_id.as_ref();
|
||
let description = match id_str {
|
||
genesis_config_presets::PRESET_DEVELOPMENT => {
|
||
"Dev mode canonical (Alice validator + 100M OGC)"
|
||
}
|
||
genesis_config_presets::PRESET_LOCAL_TESTNET => {
|
||
"Multi-node local testing (Alice+Bob + 5 dev × 100M OGC)"
|
||
}
|
||
genesis_config_presets::PRESET_MAINNET_GENESIS => {
|
||
"Mainnet canonical BM V2 (5 Pi 5 + 1B OGC 40/25/15/15/5)"
|
||
}
|
||
_ => "Unknown preset canonical",
|
||
};
|
||
println!(" • {:<20} — {}", id_str, description);
|
||
}
|
||
println!();
|
||
println!("Use: origin-chain-node print-preset <id>");
|
||
}
|
||
|
||
fn print_preset(id: &str) {
|
||
let preset_id = PresetId::from(id);
|
||
match genesis_config_presets::get_preset(&preset_id) {
|
||
Some(json_bytes) => {
|
||
let parsed: serde_json::Value =
|
||
serde_json::from_slice(&json_bytes).expect("preset JSON canonical infallible");
|
||
let pretty =
|
||
serde_json::to_string_pretty(&parsed).expect("pretty-print canonical infallible");
|
||
println!("{}", pretty);
|
||
}
|
||
None => {
|
||
eprintln!("❌ Unknown preset canonical: '{}'", id);
|
||
eprintln!();
|
||
eprintln!("Available canonical presets:");
|
||
for preset in genesis_config_presets::preset_names() {
|
||
let s: &str = preset.as_ref();
|
||
eprintln!(" • {}", s);
|
||
}
|
||
std::process::exit(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// Build chain spec JSON canonical (Slice 3 v0.0.13).
|
||
///
|
||
/// Resuelve chain id canonical via [`chain_spec::load_spec`] + serializes
|
||
/// JSON canonical via [`chain_spec::serialize_chain_spec`]. Exit code canonical 1
|
||
/// si chain id canonical unknown o JSON serialization canonical fails.
|
||
fn build_spec(chain: &str, raw: bool) {
|
||
match chain_spec::load_spec(chain) {
|
||
Ok(spec) => match chain_spec::serialize_chain_spec(&spec, raw) {
|
||
Ok(json) => println!("{}", json),
|
||
Err(e) => {
|
||
eprintln!("❌ ChainSpec JSON serialization canonical failed: {}", e);
|
||
std::process::exit(1);
|
||
}
|
||
},
|
||
Err(e) => {
|
||
eprintln!("❌ Chain spec canonical no resuelto: {}", e);
|
||
eprintln!();
|
||
eprintln!("Available canonical chain ids:");
|
||
eprintln!(" • dev | development — Alice solo + 100M OGC dev");
|
||
eprintln!(" • local | local_testnet — Alice+Bob + 5 dev × 100M OGC");
|
||
eprintln!(" • mainnet | mainnet_genesis — 5 Pi 5 + BM V2 1B OGC 40/25/15/15/5");
|
||
std::process::exit(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
fn print_info() {
|
||
println!("⚓ Origin Chain Runtime Info canonical\n");
|
||
println!("Spec name: {}", SPEC_NAME);
|
||
println!("Impl name: {}", IMPL_NAME);
|
||
println!("Runtime version: {}", RUNTIME_VERSION);
|
||
println!();
|
||
println!("Pallets canonical (11):");
|
||
println!(" • Index 0 System (frame_system foundational)");
|
||
println!(" • Index 1 Timestamp (pallet_timestamp block clock → Aura)");
|
||
println!(" • Index 2 Balances (pallet_balances OGC token CHN-2)");
|
||
println!(" • Index 3 TransactionPayment (pallet_transaction_payment CHN-8 baseline)");
|
||
println!(" • Index 4 Aura (pallet_aura PoA block production CHN-1)");
|
||
println!(" • Index 5 Grandpa (pallet_grandpa finality gadget CHN-1)");
|
||
println!(" • Index 6 Session (pallet_session 4h epoch rotation CHN-1)");
|
||
println!(" • Index 7 Provenance (pallet_origin_provenance asset attestation CHN-7) [Phase 2.1 COMPLETE v0.0.17]");
|
||
println!(" • Index 8 Fees (pallet_origin_fees cross-pillar economy OCAFB-1..6) [Phase 2.4 COMPLETE v0.0.23]");
|
||
println!(" • Index 9 AgentIdentity (pallet_agent_identity AGI DIDs Inmutable #41) [Phase 2.7 COMPLETE v0.0.27]");
|
||
println!(" • Index 10 Governance (origin_chain_governance Foundation Treasury CHN-4) [Phase 5.1 FOUNDATION COMPLETE v0.0.31]");
|
||
println!();
|
||
println!("Runtime APIs canonical (15):");
|
||
println!(" • sp_api::Core (version + execute_block)");
|
||
println!(" • sp_api::Metadata (runtime metadata)");
|
||
println!(" • sp_block_builder::BlockBuilder (block production)");
|
||
println!(" • sp_transaction_pool::TaggedTransactionQueue (tx validation)");
|
||
println!(" • sp_offchain::OffchainWorkerApi (offchain processing)");
|
||
println!(" • sp_session::SessionKeys (session keys generation)");
|
||
println!(" • sp_consensus_aura::AuraApi (slot duration + authorities)");
|
||
println!(" • sp_consensus_grandpa::GrandpaApi (finality set + authorities)");
|
||
println!(" • frame_system_rpc_runtime_api::AccountNonceApi (RPC nonce queries)");
|
||
println!(" • pallet_transaction_payment_rpc::* (RPC fee queries)");
|
||
println!(" • sp_genesis_builder::GenesisBuilder (chain spec build)");
|
||
println!(" • origin_chain_provenance::ProvenanceApi (verify_provenance RPC) [Phase 2.1 v0.0.17]");
|
||
println!(" • origin_chain_fees::FeesApi (query_fee_for_action RPC) [Phase 2.4 COMPLETE v0.0.23]");
|
||
println!(" • origin_chain_agent_identity::AgentIdentityApi (query_identity RPC) [Phase 2.7 COMPLETE v0.0.27]");
|
||
println!(" • origin_chain_governance::GovernanceApi (query_proposal + query_vote RPC) [Phase 5.1 FOUNDATION COMPLETE v0.0.31]");
|
||
println!();
|
||
println!("Genesis presets canonical (3):");
|
||
println!(" • development (Alice + 100M OGC dev)");
|
||
println!(" • local_testnet (Alice+Bob + 5 dev × 100M OGC)");
|
||
println!(" • mainnet_genesis (5 Pi 5 + BM V2 1B OGC 40/25/15/15/5)");
|
||
println!();
|
||
println!("⚓ \"Todo valor pide un puente; toda identidad pide un testigo.\"");
|
||
println!(" — Charon ⚓, Pilar 4 Origin Chain canonical");
|
||
}
|