feat(bench): maquinaria FRAME v2 de benchmarking para los 5 pallets custom (RV 8→9)

Los 19 extrinsics de provenance/fees/agent-identity/emission/governance pasan de
weights placeholder `from_parts(10_000, 0)` (proof_size=0, sin contar reads/writes
de DB — vector de DoS real) a weights INTERIM hand-derived DB-aware vía el trait
`WeightInfo`. Cierra el mispricing de DoS en TODOS los extrinsics del chain.

Cada pallet gana:
- weights.rs: trait WeightInfo + SubstrateWeight<T> (DB-aware vía T::DbWeight) + impl ()
- benchmarking.rs: benchmarks FRAME v2, VERIFICADOS por impl_benchmark_test_suite!
  (19 benchmarks ejecutan+pasan en los mocks — cargo test --features runtime-benchmarks)
- Config: `type WeightInfo` + swap de los `#[pallet::weight]`

Runtime:
- define_benchmarks! con los 5 pallets + runtime API Benchmark (inerte sin la feature)
- WeightInfo cableado a SubstrateWeight<Runtime> en cada Config
- RUNTIME_VERSION 8→9 (weights = consenso-relevante: fee + llenado de bloque;
  las firmas de los extrinsics NO cambian ⇒ TRANSACTION_VERSION intacto)

3 bugs latentes cerrados (territorio virgen — el runtime NUNCA se compiló con
runtime-benchmarks; las dimensiones nuevas cazan lo que no se había visto):
- pallet-grandpa/try-runtime mal ubicado en la feature runtime-benchmarks (copy-paste
  erróneo: features ortogonales; NUNCA activaba los benchmarks de grandpa)
- feature runtime-benchmarks incompleta → E0046 en OriginFeeAdapter (métodos
  benchmark-gated de OnChargeTransaction) + pallet-staking
  (StakingUnchecked::migrate_to_direct_staker); ahora lista TODOS los pallets como
  un runtime de producción Substrate
- pallet-revive/runtime-benchmarks omitido a propósito (fixtures RISC-V/PolkaVM
  indisponibles; ReviveApi deferred, no benchmarkeado)

emission: mock extraído del `mod tests` inline a `pub mod mock` (reuso del test-suite,
sin duplicar el scaffold; los 15 tests existentes + el benchmark verdes).

GATED (documentado en el §Estado de cada weights.rs): la generación de números
CANÓNICOS por CLI requiere el node sc-service o omni-bencher+WASM (ambos bloqueados
hace sesiones). Los weights interinos son DB-aware/DoS-safe y regenerables de forma
mecánica cuando aterrice el HW de referencia (Pi5/VPS) — benchmarking.rs es la fuente
de verdad de la FORMA.

Verificado: 5 test-suites de pallet verdes (con y sin runtime-benchmarks) + runtime
compila en ambos modos + workspace sin regresión + 40 tests de runtime (incl. v9).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 4.8 committed 2026-07-07 22:48:26 -05:00
1 parent 0d56e0bcbf
commit c7fc6a88fc
29 files changed
+1206 -121

No files matched your search

+26 -13
View File
@@ -40,6 +40,14 @@
pub use pallet::*;
/// Weights canonical (INTERIM hand-derived DB-aware — ver `weights.rs` §Estado).
pub mod weights;
pub use weights::WeightInfo;
/// Benchmarks canonical (FRAME v2) — solo bajo `runtime-benchmarks`.
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
/// Re-export canonical types desde origin-chain-types para consumers.
pub use origin_chain_types::{ProposalId, Vote, VoteStance};
@@ -124,6 +132,8 @@ pub mod pallet {
use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::traits::{AccountIdConversion, SaturatedConversion};
// Trait de weights en scope para resolver `T::WeightInfo::<method>()`.
use crate::weights::WeightInfo;
/// ProposalStatus canonical — proposal lifecycle stages canonical.
#[derive(
@@ -246,6 +256,9 @@ pub mod pallet {
/// tesorería no depende de una llave humana custodiable.
#[pallet::constant]
type TreasuryPalletId: Get<PalletId>;
/// Weight information canonical para los extrinsics de este pallet.
type WeightInfo: crate::weights::WeightInfo;
}
/// Pallet definition canonical.
@@ -623,7 +636,7 @@ pub mod pallet {
/// 7-step canonical flow: ensure_signed + validate_stake + derive_id +
/// collision_check + build + insert + emit.
#[pallet::call_index(0)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::submit_proposal())]
pub fn submit_proposal(
origin: OriginFor<T>,
title_hash: [u8; 32],
@@ -683,7 +696,7 @@ pub mod pallet {
/// CHN-4 5.4 canonical: `cast_vote` real dispatchable canonical.
#[pallet::call_index(1)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::cast_vote())]
pub fn cast_vote(
origin: OriginFor<T>,
proposal_id: ProposalId,
@@ -746,7 +759,7 @@ pub mod pallet {
/// CHN-4 canonical: `finalize_proposal` real dispatchable canonical.
#[pallet::call_index(2)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::finalize_proposal())]
pub fn finalize_proposal(
origin: OriginFor<T>,
proposal_id: ProposalId,
@@ -799,7 +812,7 @@ pub mod pallet {
/// 6-step canonical flow: ensure_root + size_check + no_duplicate + build +
/// insert + emit.
#[pallet::call_index(3)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::add_council_member())]
pub fn add_council_member(
origin: OriginFor<T>,
account: T::AccountId,
@@ -843,7 +856,7 @@ pub mod pallet {
///
/// 5-step canonical flow: ensure_root + validate_exists + remove + decrement + emit.
#[pallet::call_index(4)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::remove_council_member())]
pub fn remove_council_member(
origin: OriginFor<T>,
account: T::AccountId,
@@ -880,7 +893,7 @@ pub mod pallet {
/// 7. Check threshold canonical: if count >= required → flip status to Rejected
/// + emit ProposalVetoed canonical; else emit CouncilVetoVoteCast canonical
#[pallet::call_index(5)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::veto_proposal())]
pub fn veto_proposal(
origin: OriginFor<T>,
proposal_id: ProposalId,
@@ -964,7 +977,7 @@ pub mod pallet {
/// Sentinel). Advisor canonical NO puede votar — humans-only vote canonical
/// non-negotiable per CHN-4 + Inmutable #41.
#[pallet::call_index(6)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::mark_as_advisor())]
pub fn mark_as_advisor(
origin: OriginFor<T>,
account: T::AccountId,
@@ -981,7 +994,7 @@ pub mod pallet {
/// CHN-4 5.6 v0.0.34 canonical: `unmark_as_advisor` Phase 5.6 dispatchable.
#[pallet::call_index(7)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::unmark_as_advisor())]
pub fn unmark_as_advisor(
origin: OriginFor<T>,
account: T::AccountId,
@@ -1012,7 +1025,7 @@ pub mod pallet {
/// 6. Insert vote + increment total stake
/// 7. Check threshold canonical 4/5: if >= → flip to Approved + emit CouncilVetoOverridden
#[pallet::call_index(8)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::override_council_veto())]
pub fn override_council_veto(
origin: OriginFor<T>,
proposal_id: ProposalId,
@@ -1084,7 +1097,7 @@ pub mod pallet {
/// canonical 5/7 council pre-approval flow (gather signatures via separate
/// dispatchable y luego promote canonical).
#[pallet::call_index(9)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::submit_emergency_proposal())]
pub fn submit_emergency_proposal(
origin: OriginFor<T>,
title_hash: [u8; 32],
@@ -1179,7 +1192,7 @@ pub mod pallet {
/// 5. (Phase 5.9+ refinement canonical: transfer via pallet_balances integration)
/// 6. Emit TreasuryDisbursed canonical
#[pallet::call_index(10)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::treasury_disbursement())]
pub fn treasury_disbursement(
origin: OriginFor<T>,
proposal_id: ProposalId,
@@ -1233,7 +1246,7 @@ pub mod pallet {
/// canonical (BM V2 250M OGC Foundation allocation). Real Phase 5.9+ refinement
/// canonical: replace canonical via Genesis storage canonical config.
#[pallet::call_index(11)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::treasury_deposit())]
pub fn treasury_deposit(origin: OriginFor<T>, amount: u128) -> DispatchResult {
// FIX-6: donación REAL a la tesorería — el caller transfiere `amount`
// de su propio balance a la cuenta-tesorería. Cualquiera puede fondear
@@ -1251,7 +1264,7 @@ pub mod pallet {
/// reemplaza el gate 5/7 TAUTOLÓGICO anterior (que dejaba a UN solo miembro
/// fast-trackear a 48h).
#[pallet::call_index(12)]
#[pallet::weight(Weight::from_parts(10_000, 0))]
#[pallet::weight(T::WeightInfo::endorse_emergency_proposal())]
pub fn endorse_emergency_proposal(
origin: OriginFor<T>,
title_hash: [u8; 32],