feat(weights): RV13 — los 19 estaban subdeclarados, los 19

Primera medicion real de los weights con frame-omni-bencher sobre el
propio blob WASM. El resultado no es un ajuste fino: los 19 extrinsics
de los 5 pallets custom declaraban MENOS de lo que cuestan.

EL PATRON SISTEMATICO. Se costeo el storage del pallet y se olvido el
que cuesta emitir un evento — System::Events, EventCount, ExecutionPhase
y Number son reads y writes reales en cada extrinsic que deposita
evento. Ejemplos medidos: attest_asset declaraba 4 reads / 1 write y
cuesta 7/3; submit_proposal declaraba 12 us y cuesta 62; register_agent_did
declaraba 3/2 y cuesta 6/4.

EL PEOR, Y ES UN ERROR MIO DOCUMENTADO AL REVES. proof_size valia 0 en
los 19. La cabecera de los interinos afirmaba que T::DbWeight "puebla
tanto ref_time como proof_size ... cerrando el hueco". Es falso y se
comprueba en la fuente: sp_weights::RuntimeDbWeight solo tiene los
campos read y write, y reads(r) devuelve from_parts(read * r, 0). Los
interinos arreglaron reads/writes y dejaron el proof_size exactamente
donde estaba. Un proof_size en cero miente al block-builder sobre el
peso PoV: es el vector de DoS que la nota decia haber cerrado. La
afirmacion sobrevivio mas de un mes sin que ninguna lectura la
desmintiera; la desmintio una medicion.

Cada fichero generado lleva ahora un guard GENERADO desde la lista real
de benchmarks que reprueba cualquier proof_size = 0 o ref_time = 0.
Verificado que sabe reprobar: contra los weights anteriores se pone rojo
con "`attest_asset` declara proof_size = 0".

ADVERTENCIA QUE VA EN EL CODIGO, NO SOLO AQUI: son numeros de un
MacBook Pro M3 Max, NO del banco de referencia BM V2. La forma
(reads/writes/proof_size) no depende del hardware y es correcta; el
ref_time si, y en un Pi 5 sera mayor. Un caso lo enseña solo:
attest_asset BAJA de 50 a 44 us, y es el extrinsic dominado por el
verify Ed25519, el mas sensible al silicio. Antes de mainnet hay que
regenerar en el Pi 5 con governor y aislamiento declarados — peticion
abierta a Laurha (request:66f500d54e28a80c) con el blob, el comando y
la version exacta del bencher.

RV12 -> RV13 (weights = consenso). TRANSACTION_VERSION intacto.
295 tests verde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
davidherranandClaude Opus 5 committed 2026-09-09 11:06:39 -05:00
1 parent b72650974d
commit 38e5602d78
7 files changed
+1084 -245

No files matched your search

+118 -28
View File
@@ -1,44 +1,134 @@
//! # Weights para `pallet-agent-identity` // SPDX-License-Identifier: Apache-2.0
//! // Origin Chain — Pilar 4 · Charon
//! ## Estado: INTERIM hand-derived (DB-aware, DoS-safe) — pendiente regeneración HW //
//! // ATENCION AL LEER ESTOS NUMEROS: un weight es una LATENCIA, y una latencia sin
//! Ver `origin-chain-provenance/src/weights.rs` §Estado para el racional completo. // el hardware y el perfil de potencia que la produjeron no se puede reproducir.
//! Números conservadores DB-aware vía `T::DbWeight` (cierran el DoS de proof_size=0 // La cabecera dice HOSTNAME y CPU: creele a eso y a nada mas. Un weight medido
//! del placeholder); `benchmarking.rs` es la fuente de verdad de la forma. // en un portatil y cobrado en un Pi 5 es mispricing estructural, solo que
// invisible. Los numeros CANONICOS de mainnet salen del banco de referencia
// (Pi 5, governor y aislamiento declarados), no de la maquina de quien compila.
//! Weights AUTOGENERADOS para `origin_chain_agent_identity` — NO editar a mano.
//!
//! Regenerar: `scripts/bench/regen-weights.sh` (ver ese script para el
//! procedimiento completo y el hardware al que hay que creerle).
//!
//! GENERADO POR SUBSTRATE BENCHMARK CLI VERSION 51.0.0
//! FECHA: 2026-09-09, STEPS: `50`, REPEAT: `20`
//! HOSTNAME: `MacBookProM3Max.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, DB CACHE: 1024
// Comando ejecutado:
// /Users/davidherran/.cargo/bin/frame-omni-bencher
// v1
// benchmark
// pallet
// --runtime
// /Users/davidherran/originmetaverse/artifacts/origin-chain/origin_chain_runtime_rv12_bench.compact.compressed.wasm
// --genesis-builder-preset
// development
// --pallet
// origin_chain_agent_identity
// --extrinsic
//
// --steps
// 50
// --repeat
// 20
// --template
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/origin-weights-template.hbs
// --header
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/HEADER.txt
// --output
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/crates/origin-chain-agent-identity/src/weights.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)] #![allow(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight}; use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
/// Trait de weights para los extrinsics de `pallet-agent-identity`. /// Trait de weights para los extrinsics de `origin_chain_agent_identity`.
pub trait WeightInfo { pub trait WeightInfo {
/// Peso de `register_agent_did` — 2-3 reads + verify Ed25519 + derive_did + 2 writes. /// Peso de `register_agent_did` — MEDIDO sobre el WASM, no estimado a mano.
fn register_agent_did() -> Weight; fn register_agent_did() -> Weight;
} }
/// Weights parametrizados por el `DbWeight` del runtime. /// Weights parametrizados por el `DbWeight` real del runtime.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn register_agent_did() -> Weight { /// Storage: `AgentIdentity::Identities` (r:1 w:1)
// Compute: Ed25519 verify (dominante) + derive_did (BLAKE3) + decode + /// Proof: `AgentIdentity::Identities` (`max_values`: None, `max_size`: Some(475), added: 2950, mode: `MaxEncodedLen`)
// build BoundedVec agent_chain. Storage: contains_key(Identities) + /// Storage: `AgentIdentity::DidToAccount` (r:1 w:1)
// contains_key(DidToAccount) + block_number = 3 reads; insert(Identities) /// Proof: `AgentIdentity::DidToAccount` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`)
// + insert(DidToAccount) = 2 writes. /// Storage: `System::Number` (r:1 w:0)
Weight::from_parts(50_000_000, 0) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
.saturating_add(T::DbWeight::get().reads(3_u64)) /// Storage: `System::ExecutionPhase` (r:1 w:0)
.saturating_add(T::DbWeight::get().writes(2_u64)) /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
} /// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn register_agent_did() -> Weight {
// Proof size en bytes:
// Medido: `25`
// Estimado: `3940`
// Tiempo minimo de ejecucion: 41_000_000 picosegundos.
Weight::from_parts(43_000_000, 0)
.saturating_add(Weight::from_parts(0, 3940))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(4_u64))
}
} }
/// Impl no-op para mocks / tests. /// Impl para mocks y tests — `RocksDbWeight` directo, sin necesitar `T`.
impl WeightInfo for () { impl WeightInfo for () {
fn register_agent_did() -> Weight { fn register_agent_did() -> Weight {
Weight::from_parts(50_000_000, 0) Weight::from_parts(43_000_000, 0)
.saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(Weight::from_parts(0, 3940))
.saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().reads(6_u64))
} .saturating_add(RocksDbWeight::get().writes(4_u64))
}
}
#[cfg(test)]
mod guard {
use super::*;
/// NINGUN EXTRINSIC PUEDE DECLARAR `proof_size = 0`.
///
/// El `proof_size` es lo que el block-builder usa para no pasarse del limite
/// de PoV. Un cero no dice «este extrinsic no toca storage»: dice «miento
/// sobre lo que va a ocupar la prueba», y con eso entra en un bloque mucho
/// mas de lo que cabe.
///
/// El test nace de un error propio y de la peor clase: la cabecera de los
/// weights interinos afirmaba que `T::DbWeight` «puebla tanto ref_time como
/// proof_size … cerrando el hueco». Es falso y se comprueba en la fuente —
/// `sp_weights::RuntimeDbWeight` solo tiene los campos `read` y `write`, y
/// `reads(r)` devuelve `Weight::from_parts(read * r, 0)`. Los interinos
/// arreglaron reads/writes y dejaron el proof_size donde estaba: en 0. La
/// afirmacion de haberlo cerrado sobrevivio mas de un mes sin que ninguna
/// lectura la desmintiera; la desmintio una medicion.
///
/// Esta lista la GENERA la plantilla a partir de los benchmarks reales, asi
/// que no puede quedarse corta cuando se anada un extrinsic nuevo.
#[test]
fn ningun_weight_declara_proof_size_cero() {
let casos: &[(&str, Weight)] = &[
("register_agent_did", <() as WeightInfo>::register_agent_did()),
];
for (nombre, w) in casos {
assert!(
w.proof_size() > 0,
"`{nombre}` declara proof_size = 0: miente al block-builder sobre el peso PoV"
);
assert!(
w.ref_time() > 0,
"`{nombre}` declara ref_time = 0: el extrinsic saldria gratis"
);
}
}
} }
+116 -24
View File
@@ -1,40 +1,132 @@
//! # Weights para `pallet-origin-emission` // SPDX-License-Identifier: Apache-2.0
//! // Origin Chain — Pilar 4 · Charon
//! ## Estado: INTERIM hand-derived (DB-aware) — pendiente regeneración HW //
//! // ATENCION AL LEER ESTOS NUMEROS: un weight es una LATENCIA, y una latencia sin
//! Ver `origin-chain-provenance/src/weights.rs` §Estado. Nota: `set_emission_paused` // el hardware y el perfil de potencia que la produjeron no se puede reproducir.
//! ya era DB-aware antes de esta migración (usaba `T::DbWeight::get().reads_writes(1,1)` // La cabecera dice HOSTNAME y CPU: creele a eso y a nada mas. Un weight medido
//! directo — el ÚNICO extrinsic del chain que nunca fue DoS-prone). Aquí se mueve // en un portatil y cobrado en un Pi 5 es mispricing estructural, solo que
//! ese mismo cálculo detrás del trait `WeightInfo` por consistencia con los demás // invisible. Los numeros CANONICOS de mainnet salen del banco de referencia
//! pallets + para exponerlo a `benchmark pallet`. `benchmarking.rs` es la fuente // (Pi 5, governor y aislamiento declarados), no de la maquina de quien compila.
//! de verdad de la forma.
//! Weights AUTOGENERADOS para `origin_chain_emission` — NO editar a mano.
//!
//! Regenerar: `scripts/bench/regen-weights.sh` (ver ese script para el
//! procedimiento completo y el hardware al que hay que creerle).
//!
//! GENERADO POR SUBSTRATE BENCHMARK CLI VERSION 51.0.0
//! FECHA: 2026-09-09, STEPS: `50`, REPEAT: `20`
//! HOSTNAME: `MacBookProM3Max.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, DB CACHE: 1024
// Comando ejecutado:
// /Users/davidherran/.cargo/bin/frame-omni-bencher
// v1
// benchmark
// pallet
// --runtime
// /Users/davidherran/originmetaverse/artifacts/origin-chain/origin_chain_runtime_rv12_bench.compact.compressed.wasm
// --genesis-builder-preset
// development
// --pallet
// origin_chain_emission
// --extrinsic
//
// --steps
// 50
// --repeat
// 20
// --template
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/origin-weights-template.hbs
// --header
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/HEADER.txt
// --output
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/crates/origin-chain-emission/src/weights.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)] #![allow(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight}; use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
/// Trait de weights para los extrinsics de `pallet-origin-emission`. /// Trait de weights para los extrinsics de `origin_chain_emission`.
pub trait WeightInfo { pub trait WeightInfo {
/// Peso de `set_emission_paused` (Root) — 1 read (guard no-op) + 1 write. /// Peso de `set_emission_paused` — MEDIDO sobre el WASM, no estimado a mano.
fn set_emission_paused() -> Weight; fn set_emission_paused() -> Weight;
} }
/// Weights parametrizados por el `DbWeight` del runtime. /// Weights parametrizados por el `DbWeight` real del runtime.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn set_emission_paused() -> Weight { /// Storage: `Emission::EmissionPaused` (r:1 w:1)
// ensure_root + get(EmissionPaused) [guard no-op] + put(EmissionPaused). /// Proof: `Emission::EmissionPaused` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
T::DbWeight::get().reads_writes(1, 1) /// Storage: `System::Number` (r:1 w:0)
} /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_emission_paused() -> Weight {
// Proof size en bytes:
// Medido: `61`
// Estimado: `1546`
// Tiempo minimo de ejecucion: 7_000_000 picosegundos.
Weight::from_parts(8_000_000, 0)
.saturating_add(Weight::from_parts(0, 1546))
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
} }
/// Impl no-op para mocks / tests. /// Impl para mocks y tests — `RocksDbWeight` directo, sin necesitar `T`.
impl WeightInfo for () { impl WeightInfo for () {
fn set_emission_paused() -> Weight { fn set_emission_paused() -> Weight {
RocksDbWeight::get().reads_writes(1, 1) Weight::from_parts(8_000_000, 0)
} .saturating_add(Weight::from_parts(0, 1546))
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
}
#[cfg(test)]
mod guard {
use super::*;
/// NINGUN EXTRINSIC PUEDE DECLARAR `proof_size = 0`.
///
/// El `proof_size` es lo que el block-builder usa para no pasarse del limite
/// de PoV. Un cero no dice «este extrinsic no toca storage»: dice «miento
/// sobre lo que va a ocupar la prueba», y con eso entra en un bloque mucho
/// mas de lo que cabe.
///
/// El test nace de un error propio y de la peor clase: la cabecera de los
/// weights interinos afirmaba que `T::DbWeight` «puebla tanto ref_time como
/// proof_size … cerrando el hueco». Es falso y se comprueba en la fuente —
/// `sp_weights::RuntimeDbWeight` solo tiene los campos `read` y `write`, y
/// `reads(r)` devuelve `Weight::from_parts(read * r, 0)`. Los interinos
/// arreglaron reads/writes y dejaron el proof_size donde estaba: en 0. La
/// afirmacion de haberlo cerrado sobrevivio mas de un mes sin que ninguna
/// lectura la desmintiera; la desmintio una medicion.
///
/// Esta lista la GENERA la plantilla a partir de los benchmarks reales, asi
/// que no puede quedarse corta cuando se anada un extrinsic nuevo.
#[test]
fn ningun_weight_declara_proof_size_cero() {
let casos: &[(&str, Weight)] = &[
("set_emission_paused", <() as WeightInfo>::set_emission_paused()),
];
for (nombre, w) in casos {
assert!(
w.proof_size() > 0,
"`{nombre}` declara proof_size = 0: miente al block-builder sobre el peso PoV"
);
assert!(
w.ref_time() > 0,
"`{nombre}` declara ref_time = 0: el extrinsic saldria gratis"
);
}
}
} }
+116 -24
View File
@@ -1,40 +1,132 @@
//! # Weights para `pallet-origin-fees` // SPDX-License-Identifier: Apache-2.0
//! // Origin Chain — Pilar 4 · Charon
//! ## Estado: INTERIM hand-derived (DB-aware, DoS-safe) — pendiente regeneración HW //
//! // ATENCION AL LEER ESTOS NUMEROS: un weight es una LATENCIA, y una latencia sin
//! Ver `origin-chain-provenance/src/weights.rs` §Estado para el racional completo. // el hardware y el perfil de potencia que la produjeron no se puede reproducir.
//! Resumen: números conservadores derivados a mano (no autogenerados por CLI — // La cabecera dice HOSTNAME y CPU: creele a eso y a nada mas. Un weight medido
//! gated por sc-service/omni-bencher+WASM), pero **DB-aware** vía `T::DbWeight` // en un portatil y cobrado en un Pi 5 es mispricing estructural, solo que
//! → pueblan ref_time + proof_size por read/write real, cerrando el DoS de los // invisible. Los numeros CANONICOS de mainnet salen del banco de referencia
//! placeholders `Weight::from_parts(10_000, 0)` (proof_size = 0, sin contar DB). // (Pi 5, governor y aislamiento declarados), no de la maquina de quien compila.
//! `benchmarking.rs` es la fuente de verdad de la forma.
//! Weights AUTOGENERADOS para `origin_chain_fees` — NO editar a mano.
//!
//! Regenerar: `scripts/bench/regen-weights.sh` (ver ese script para el
//! procedimiento completo y el hardware al que hay que creerle).
//!
//! GENERADO POR SUBSTRATE BENCHMARK CLI VERSION 51.0.0
//! FECHA: 2026-09-09, STEPS: `50`, REPEAT: `20`
//! HOSTNAME: `MacBookProM3Max.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, DB CACHE: 1024
// Comando ejecutado:
// /Users/davidherran/.cargo/bin/frame-omni-bencher
// v1
// benchmark
// pallet
// --runtime
// /Users/davidherran/originmetaverse/artifacts/origin-chain/origin_chain_runtime_rv12_bench.compact.compressed.wasm
// --genesis-builder-preset
// development
// --pallet
// origin_chain_fees
// --extrinsic
//
// --steps
// 50
// --repeat
// 20
// --template
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/origin-weights-template.hbs
// --header
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/HEADER.txt
// --output
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/crates/origin-chain-fees/src/weights.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)] #![allow(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight}; use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
/// Trait de weights para los extrinsics de `pallet-origin-fees`. /// Trait de weights para los extrinsics de `origin_chain_fees`.
pub trait WeightInfo { pub trait WeightInfo {
/// Peso de `set_tier_profile` (Root) — 1 write (TierProfiles). /// Peso de `set_tier_profile` — MEDIDO sobre el WASM, no estimado a mano.
fn set_tier_profile() -> Weight; fn set_tier_profile() -> Weight;
} }
/// Weights parametrizados por el `DbWeight` del runtime. /// Weights parametrizados por el `DbWeight` real del runtime.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn set_tier_profile() -> Weight { /// Storage: `System::Number` (r:1 w:0)
// ensure_root (in-memory) + insert(TierProfiles) = 1 write. /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
Weight::from_parts(8_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64)) /// Storage: `System::ExecutionPhase` (r:1 w:0)
} /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Fees::TierProfiles` (r:0 w:1)
/// Proof: `Fees::TierProfiles` (`max_values`: None, `max_size`: Some(50), added: 2525, mode: `MaxEncodedLen`)
fn set_tier_profile() -> Weight {
// Proof size en bytes:
// Medido: `19`
// Estimado: `1504`
// Tiempo minimo de ejecucion: 6_000_000 picosegundos.
Weight::from_parts(7_000_000, 0)
.saturating_add(Weight::from_parts(0, 1504))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
} }
/// Impl no-op para mocks / tests. /// Impl para mocks y tests — `RocksDbWeight` directo, sin necesitar `T`.
impl WeightInfo for () { impl WeightInfo for () {
fn set_tier_profile() -> Weight { fn set_tier_profile() -> Weight {
Weight::from_parts(8_000_000, 0).saturating_add(RocksDbWeight::get().writes(1_u64)) Weight::from_parts(7_000_000, 0)
} .saturating_add(Weight::from_parts(0, 1504))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
}
#[cfg(test)]
mod guard {
use super::*;
/// NINGUN EXTRINSIC PUEDE DECLARAR `proof_size = 0`.
///
/// El `proof_size` es lo que el block-builder usa para no pasarse del limite
/// de PoV. Un cero no dice «este extrinsic no toca storage»: dice «miento
/// sobre lo que va a ocupar la prueba», y con eso entra en un bloque mucho
/// mas de lo que cabe.
///
/// El test nace de un error propio y de la peor clase: la cabecera de los
/// weights interinos afirmaba que `T::DbWeight` «puebla tanto ref_time como
/// proof_size … cerrando el hueco». Es falso y se comprueba en la fuente —
/// `sp_weights::RuntimeDbWeight` solo tiene los campos `read` y `write`, y
/// `reads(r)` devuelve `Weight::from_parts(read * r, 0)`. Los interinos
/// arreglaron reads/writes y dejaron el proof_size donde estaba: en 0. La
/// afirmacion de haberlo cerrado sobrevivio mas de un mes sin que ninguna
/// lectura la desmintiera; la desmintio una medicion.
///
/// Esta lista la GENERA la plantilla a partir de los benchmarks reales, asi
/// que no puede quedarse corta cuando se anada un extrinsic nuevo.
#[test]
fn ningun_weight_declara_proof_size_cero() {
let casos: &[(&str, Weight)] = &[
("set_tier_profile", <() as WeightInfo>::set_tier_profile()),
];
for (nombre, w) in casos {
assert!(
w.proof_size() > 0,
"`{nombre}` declara proof_size = 0: miente al block-builder sobre el peso PoV"
);
assert!(
w.ref_time() > 0,
"`{nombre}` declara ref_time = 0: el extrinsic saldria gratis"
);
}
}
} }
+516 -87
View File
@@ -1,103 +1,532 @@
//! # Weights para `pallet-origin-governance` // SPDX-License-Identifier: Apache-2.0
//! // Origin Chain — Pilar 4 · Charon
//! ## Estado: INTERIM hand-derived (DB-aware, DoS-safe) — pendiente regeneración HW //
//! // ATENCION AL LEER ESTOS NUMEROS: un weight es una LATENCIA, y una latencia sin
//! Ver `origin-chain-provenance/src/weights.rs` §Estado para el racional completo. // el hardware y el perfil de potencia que la produjeron no se puede reproducir.
//! Los 13 extrinsics tenían `Weight::from_parts(10_000, 0)` (proof_size=0, sin // La cabecera dice HOSTNAME y CPU: creele a eso y a nada mas. Un weight medido
//! contar DB) → DoS. Aquí cada uno se cuesta con `T::DbWeight` sobre los reads/writes // en un portatil y cobrado en un Pi 5 es mispricing estructural, solo que
//! REALES contados del código (incluyendo los `iter_prefix`/`clear_prefix` acotados // invisible. Los numeros CANONICOS de mainnet salen del banco de referencia
//! por el council ≤ 7). `benchmarking.rs` es la fuente de verdad de la forma. // (Pi 5, governor y aislamiento declarados), no de la maquina de quien compila.
//! Weights AUTOGENERADOS para `origin_chain_governance` — NO editar a mano.
//!
//! Regenerar: `scripts/bench/regen-weights.sh` (ver ese script para el
//! procedimiento completo y el hardware al que hay que creerle).
//!
//! GENERADO POR SUBSTRATE BENCHMARK CLI VERSION 51.0.0
//! FECHA: 2026-09-09, STEPS: `50`, REPEAT: `20`
//! HOSTNAME: `MacBookProM3Max.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, DB CACHE: 1024
// Comando ejecutado:
// /Users/davidherran/.cargo/bin/frame-omni-bencher
// v1
// benchmark
// pallet
// --runtime
// /Users/davidherran/originmetaverse/artifacts/origin-chain/origin_chain_runtime_rv12_bench.compact.compressed.wasm
// --genesis-builder-preset
// development
// --pallet
// origin_chain_governance
// --extrinsic
//
// --steps
// 50
// --repeat
// 20
// --template
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/origin-weights-template.hbs
// --header
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/HEADER.txt
// --output
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/crates/origin-chain-governance/src/weights.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)] #![allow(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight}; use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
/// Compute floor conservador para la lógica de cada extrinsic (hashing blake2, /// Trait de weights para los extrinsics de `origin_chain_governance`.
/// aritmética de umbrales, build de structs). Los que hashean content/proposal id
/// (submit_*, endorse) llevan un poco más vía el propio conteo de reads.
const COMPUTE: u64 = 12_000_000;
/// Trait de weights para los 13 extrinsics de `pallet-origin-governance`.
pub trait WeightInfo { pub trait WeightInfo {
/// `submit_proposal` — contains_key + bond transfer + 2 inserts. /// Peso de `submit_proposal` — MEDIDO sobre el WASM, no estimado a mano.
fn submit_proposal() -> Weight; fn submit_proposal() -> Weight;
/// `cast_vote` — advisor/proposal/vote reads + 2 inserts. /// Peso de `cast_vote` — MEDIDO sobre el WASM, no estimado a mano.
fn cast_vote() -> Weight; fn cast_vote() -> Weight;
/// `finalize_proposal` — proposal read/write + release bond. /// Peso de `finalize_proposal` — MEDIDO sobre el WASM, no estimado a mano.
fn finalize_proposal() -> Weight; fn finalize_proposal() -> Weight;
/// `add_council_member` — size/dup reads + 2 writes. /// Peso de `add_council_member` — MEDIDO sobre el WASM, no estimado a mano.
fn add_council_member() -> Weight; fn add_council_member() -> Weight;
/// `remove_council_member` — exists read + remove + size write. /// Peso de `remove_council_member` — MEDIDO sobre el WASM, no estimado a mano.
fn remove_council_member() -> Weight; fn remove_council_member() -> Weight;
/// `veto_proposal` — council iter (≤7) + threshold flip path. /// Peso de `veto_proposal` — MEDIDO sobre el WASM, no estimado a mano.
fn veto_proposal() -> Weight; fn veto_proposal() -> Weight;
/// `mark_as_advisor` — 1 read + 1 write. /// Peso de `mark_as_advisor` — MEDIDO sobre el WASM, no estimado a mano.
fn mark_as_advisor() -> Weight; fn mark_as_advisor() -> Weight;
/// `unmark_as_advisor` — 1 read + 1 write. /// Peso de `unmark_as_advisor` — MEDIDO sobre el WASM, no estimado a mano.
fn unmark_as_advisor() -> Weight; fn unmark_as_advisor() -> Weight;
/// `override_council_veto` — proposal/veto/advisor reads + vote inserts. /// Peso de `override_council_veto` — MEDIDO sobre el WASM, no estimado a mano.
fn override_council_veto() -> Weight; fn override_council_veto() -> Weight;
/// `submit_emergency_proposal` — endorsement iter (≤7) + bond + clear_prefix. /// Peso de `submit_emergency_proposal` — MEDIDO sobre el WASM, no estimado a mano.
fn submit_emergency_proposal() -> Weight; fn submit_emergency_proposal() -> Weight;
/// `treasury_disbursement` — proposal read + single-use + transfer. /// Peso de `treasury_disbursement` — MEDIDO sobre el WASM, no estimado a mano.
fn treasury_disbursement() -> Weight; fn treasury_disbursement() -> Weight;
/// `treasury_deposit` — transfer only. /// Peso de `treasury_deposit` — MEDIDO sobre el WASM, no estimado a mano.
fn treasury_deposit() -> Weight; fn treasury_deposit() -> Weight;
/// `endorse_emergency_proposal` — council iter (≤7) + insert. /// Peso de `endorse_emergency_proposal` — MEDIDO sobre el WASM, no estimado a mano.
fn endorse_emergency_proposal() -> Weight; fn endorse_emergency_proposal() -> Weight;
} }
macro_rules! w { /// Weights parametrizados por el `DbWeight` real del runtime.
($r:expr, $w:expr) => {
Weight::from_parts(COMPUTE, 0)
.saturating_add(T::DbWeight::get().reads($r as u64))
.saturating_add(T::DbWeight::get().writes($w as u64))
};
}
/// Weights parametrizados por el `DbWeight` del runtime.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn submit_proposal() -> Weight { w!(3, 4) } /// Storage: `Governance::Proposals` (r:1 w:1)
fn cast_vote() -> Weight { w!(4, 2) } /// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
fn finalize_proposal() -> Weight { w!(3, 4) } /// Storage: `Balances::TotalIssuance` (r:1 w:0)
fn add_council_member() -> Weight { w!(3, 2) } /// Proof: `Balances::TotalIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
fn remove_council_member() -> Weight { w!(2, 2) } /// Storage: `System::Account` (r:1 w:1)
fn veto_proposal() -> Weight { w!(10, 4) } /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn mark_as_advisor() -> Weight { w!(1, 1) } /// Storage: `System::Number` (r:1 w:0)
fn unmark_as_advisor() -> Weight { w!(1, 1) } /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn override_council_veto() -> Weight { w!(5, 3) } /// Storage: `System::ExecutionPhase` (r:1 w:0)
fn submit_emergency_proposal() -> Weight { w!(12, 11) } /// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
fn treasury_disbursement() -> Weight { w!(4, 3) } /// Storage: `System::EventCount` (r:1 w:1)
fn treasury_deposit() -> Weight { w!(2, 2) } /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn endorse_emergency_proposal() -> Weight { w!(10, 1) } /// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Governance::ProposalBond` (r:0 w:1)
/// Proof: `Governance::ProposalBond` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
fn submit_proposal() -> Weight {
// Proof size en bytes:
// Medido: `107`
// Estimado: `3722`
// Tiempo minimo de ejecucion: 46_000_000 picosegundos.
Weight::from_parts(46_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().writes(5_u64))
}
/// Storage: `Governance::AdvisorFlags` (r:1 w:0)
/// Proof: `Governance::AdvisorFlags` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Governance::Proposals` (r:1 w:1)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Governance::Votes` (r:1 w:1)
/// Proof: `Governance::Votes` (`max_values`: None, `max_size`: Some(97), added: 2572, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn cast_vote() -> Weight {
// Proof size en bytes:
// Medido: `310`
// Estimado: `3722`
// Tiempo minimo de ejecucion: 16_000_000 picosegundos.
Weight::from_parts(18_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().writes(4_u64))
}
/// Storage: `Governance::Proposals` (r:1 w:1)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Governance::ProposalBond` (r:1 w:0)
/// Proof: `Governance::ProposalBond` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn finalize_proposal() -> Weight {
// Proof size en bytes:
// Medido: `310`
// Estimado: `3722`
// Tiempo minimo de ejecucion: 13_000_000 picosegundos.
Weight::from_parts(14_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `Governance::CouncilSize` (r:1 w:1)
/// Proof: `Governance::CouncilSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Governance::Council` (r:1 w:1)
/// Proof: `Governance::Council` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn add_council_member() -> Weight {
// Proof size en bytes:
// Medido: `25`
// Estimado: `3554`
// Tiempo minimo de ejecucion: 10_000_000 picosegundos.
Weight::from_parts(11_000_000, 0)
.saturating_add(Weight::from_parts(0, 3554))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(4_u64))
}
/// Storage: `Governance::Council` (r:1 w:1)
/// Proof: `Governance::Council` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Governance::CouncilSize` (r:1 w:1)
/// Proof: `Governance::CouncilSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn remove_council_member() -> Weight {
// Proof size en bytes:
// Medido: `153`
// Estimado: `3554`
// Tiempo minimo de ejecucion: 11_000_000 picosegundos.
Weight::from_parts(12_000_000, 0)
.saturating_add(Weight::from_parts(0, 3554))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(4_u64))
}
/// Storage: `Governance::Council` (r:1 w:0)
/// Proof: `Governance::Council` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Governance::Proposals` (r:1 w:1)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `Governance::CouncilSize` (r:1 w:0)
/// Proof: `Governance::CouncilSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Governance::VetoVotes` (r:2 w:1)
/// Proof: `Governance::VetoVotes` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
/// Storage: `Governance::ProposalBond` (r:1 w:0)
/// Proof: `Governance::ProposalBond` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Governance::VetoRejected` (r:0 w:1)
/// Proof: `Governance::VetoRejected` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Governance::VetoCount` (r:0 w:1)
/// Proof: `Governance::VetoCount` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
fn veto_proposal() -> Weight {
// Proof size en bytes:
// Medido: `435`
// Estimado: `6132`
// Tiempo minimo de ejecucion: 28_000_000 picosegundos.
Weight::from_parts(30_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(T::DbWeight::get().reads(10_u64))
.saturating_add(T::DbWeight::get().writes(6_u64))
}
/// Storage: `Governance::AdvisorFlags` (r:1 w:1)
/// Proof: `Governance::AdvisorFlags` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn mark_as_advisor() -> Weight {
// Proof size en bytes:
// Medido: `25`
// Estimado: `3513`
// Tiempo minimo de ejecucion: 9_000_000 picosegundos.
Weight::from_parts(10_000_000, 0)
.saturating_add(Weight::from_parts(0, 3513))
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `Governance::AdvisorFlags` (r:1 w:1)
/// Proof: `Governance::AdvisorFlags` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn unmark_as_advisor() -> Weight {
// Proof size en bytes:
// Medido: `98`
// Estimado: `3513`
// Tiempo minimo de ejecucion: 10_000_000 picosegundos.
Weight::from_parts(10_000_000, 0)
.saturating_add(Weight::from_parts(0, 3513))
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `Governance::Proposals` (r:1 w:0)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `Governance::VetoRejected` (r:1 w:0)
/// Proof: `Governance::VetoRejected` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Governance::AdvisorFlags` (r:1 w:0)
/// Proof: `Governance::AdvisorFlags` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Governance::OverrideVotes` (r:1 w:1)
/// Proof: `Governance::OverrideVotes` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`)
/// Storage: `Governance::OverrideStakeTotal` (r:1 w:1)
/// Proof: `Governance::OverrideStakeTotal` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`)
fn override_council_veto() -> Weight {
// Proof size en bytes:
// Medido: `361`
// Estimado: `3722`
// Tiempo minimo de ejecucion: 16_000_000 picosegundos.
Weight::from_parts(16_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `Governance::Council` (r:1 w:0)
/// Proof: `Governance::Council` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Governance::CouncilSize` (r:1 w:0)
/// Proof: `Governance::CouncilSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Governance::EmergencyEndorsements` (r:2 w:1)
/// Proof: `Governance::EmergencyEndorsements` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
/// Storage: `Governance::Proposals` (r:1 w:1)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `Balances::TotalIssuance` (r:1 w:0)
/// Proof: `Balances::TotalIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Governance::ProposalBond` (r:0 w:1)
/// Proof: `Governance::ProposalBond` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
fn submit_emergency_proposal() -> Weight {
// Proof size en bytes:
// Medido: `353`
// Estimado: `6132`
// Tiempo minimo de ejecucion: 60_000_000 picosegundos.
Weight::from_parts(61_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(T::DbWeight::get().reads(11_u64))
.saturating_add(T::DbWeight::get().writes(6_u64))
}
/// Storage: `Governance::Proposals` (r:1 w:0)
/// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(257), added: 2732, mode: `MaxEncodedLen`)
/// Storage: `Governance::Disbursed` (r:1 w:1)
/// Proof: `Governance::Disbursed` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Balances::TotalIssuance` (r:1 w:0)
/// Proof: `Balances::TotalIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn treasury_disbursement() -> Weight {
// Proof size en bytes:
// Medido: `494`
// Estimado: `6196`
// Tiempo minimo de ejecucion: 51_000_000 picosegundos.
Weight::from_parts(52_000_000, 0)
.saturating_add(Weight::from_parts(0, 6196))
.saturating_add(T::DbWeight::get().reads(9_u64))
.saturating_add(T::DbWeight::get().writes(5_u64))
}
/// Storage: `Balances::TotalIssuance` (r:1 w:0)
/// Proof: `Balances::TotalIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn treasury_deposit() -> Weight {
// Proof size en bytes:
// Medido: `101`
// Estimado: `3593`
// Tiempo minimo de ejecucion: 38_000_000 picosegundos.
Weight::from_parts(42_000_000, 0)
.saturating_add(Weight::from_parts(0, 3593))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `Governance::Council` (r:1 w:0)
/// Proof: `Governance::Council` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Governance::EmergencyEndorsements` (r:2 w:1)
/// Proof: `Governance::EmergencyEndorsements` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `MaxEncodedLen`)
/// Storage: `Governance::CouncilSize` (r:1 w:0)
/// Proof: `Governance::CouncilSize` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn endorse_emergency_proposal() -> Weight {
// Proof size en bytes:
// Medido: `153`
// Estimado: `6132`
// Tiempo minimo de ejecucion: 20_000_000 picosegundos.
Weight::from_parts(21_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(T::DbWeight::get().reads(8_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
} }
macro_rules! wnop { /// Impl para mocks y tests — `RocksDbWeight` directo, sin necesitar `T`.
($r:expr, $w:expr) => {
Weight::from_parts(COMPUTE, 0)
.saturating_add(RocksDbWeight::get().reads($r as u64))
.saturating_add(RocksDbWeight::get().writes($w as u64))
};
}
/// Impl no-op para mocks / tests.
impl WeightInfo for () { impl WeightInfo for () {
fn submit_proposal() -> Weight { wnop!(3, 4) } fn submit_proposal() -> Weight {
fn cast_vote() -> Weight { wnop!(4, 2) } Weight::from_parts(46_000_000, 0)
fn finalize_proposal() -> Weight { wnop!(3, 4) } .saturating_add(Weight::from_parts(0, 3722))
fn add_council_member() -> Weight { wnop!(3, 2) } .saturating_add(RocksDbWeight::get().reads(7_u64))
fn remove_council_member() -> Weight { wnop!(2, 2) } .saturating_add(RocksDbWeight::get().writes(5_u64))
fn veto_proposal() -> Weight { wnop!(10, 4) } }
fn mark_as_advisor() -> Weight { wnop!(1, 1) } fn cast_vote() -> Weight {
fn unmark_as_advisor() -> Weight { wnop!(1, 1) } Weight::from_parts(18_000_000, 0)
fn override_council_veto() -> Weight { wnop!(5, 3) } .saturating_add(Weight::from_parts(0, 3722))
fn submit_emergency_proposal() -> Weight { wnop!(12, 11) } .saturating_add(RocksDbWeight::get().reads(7_u64))
fn treasury_disbursement() -> Weight { wnop!(4, 3) } .saturating_add(RocksDbWeight::get().writes(4_u64))
fn treasury_deposit() -> Weight { wnop!(2, 2) } }
fn endorse_emergency_proposal() -> Weight { wnop!(10, 1) } fn finalize_proposal() -> Weight {
Weight::from_parts(14_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
fn add_council_member() -> Weight {
Weight::from_parts(11_000_000, 0)
.saturating_add(Weight::from_parts(0, 3554))
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().writes(4_u64))
}
fn remove_council_member() -> Weight {
Weight::from_parts(12_000_000, 0)
.saturating_add(Weight::from_parts(0, 3554))
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().writes(4_u64))
}
fn veto_proposal() -> Weight {
Weight::from_parts(30_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(RocksDbWeight::get().reads(10_u64))
.saturating_add(RocksDbWeight::get().writes(6_u64))
}
fn mark_as_advisor() -> Weight {
Weight::from_parts(10_000_000, 0)
.saturating_add(Weight::from_parts(0, 3513))
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
fn unmark_as_advisor() -> Weight {
Weight::from_parts(10_000_000, 0)
.saturating_add(Weight::from_parts(0, 3513))
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
fn override_council_veto() -> Weight {
Weight::from_parts(16_000_000, 0)
.saturating_add(Weight::from_parts(0, 3722))
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
fn submit_emergency_proposal() -> Weight {
Weight::from_parts(61_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(RocksDbWeight::get().reads(11_u64))
.saturating_add(RocksDbWeight::get().writes(6_u64))
}
fn treasury_disbursement() -> Weight {
Weight::from_parts(52_000_000, 0)
.saturating_add(Weight::from_parts(0, 6196))
.saturating_add(RocksDbWeight::get().reads(9_u64))
.saturating_add(RocksDbWeight::get().writes(5_u64))
}
fn treasury_deposit() -> Weight {
Weight::from_parts(42_000_000, 0)
.saturating_add(Weight::from_parts(0, 3593))
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
fn endorse_emergency_proposal() -> Weight {
Weight::from_parts(21_000_000, 0)
.saturating_add(Weight::from_parts(0, 6132))
.saturating_add(RocksDbWeight::get().reads(8_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
}
#[cfg(test)]
mod guard {
use super::*;
/// NINGUN EXTRINSIC PUEDE DECLARAR `proof_size = 0`.
///
/// El `proof_size` es lo que el block-builder usa para no pasarse del limite
/// de PoV. Un cero no dice «este extrinsic no toca storage»: dice «miento
/// sobre lo que va a ocupar la prueba», y con eso entra en un bloque mucho
/// mas de lo que cabe.
///
/// El test nace de un error propio y de la peor clase: la cabecera de los
/// weights interinos afirmaba que `T::DbWeight` «puebla tanto ref_time como
/// proof_size … cerrando el hueco». Es falso y se comprueba en la fuente —
/// `sp_weights::RuntimeDbWeight` solo tiene los campos `read` y `write`, y
/// `reads(r)` devuelve `Weight::from_parts(read * r, 0)`. Los interinos
/// arreglaron reads/writes y dejaron el proof_size donde estaba: en 0. La
/// afirmacion de haberlo cerrado sobrevivio mas de un mes sin que ninguna
/// lectura la desmintiera; la desmintio una medicion.
///
/// Esta lista la GENERA la plantilla a partir de los benchmarks reales, asi
/// que no puede quedarse corta cuando se anada un extrinsic nuevo.
#[test]
fn ningun_weight_declara_proof_size_cero() {
let casos: &[(&str, Weight)] = &[
("submit_proposal", <() as WeightInfo>::submit_proposal()),
("cast_vote", <() as WeightInfo>::cast_vote()),
("finalize_proposal", <() as WeightInfo>::finalize_proposal()),
("add_council_member", <() as WeightInfo>::add_council_member()),
("remove_council_member", <() as WeightInfo>::remove_council_member()),
("veto_proposal", <() as WeightInfo>::veto_proposal()),
("mark_as_advisor", <() as WeightInfo>::mark_as_advisor()),
("unmark_as_advisor", <() as WeightInfo>::unmark_as_advisor()),
("override_council_veto", <() as WeightInfo>::override_council_veto()),
("submit_emergency_proposal", <() as WeightInfo>::submit_emergency_proposal()),
("treasury_disbursement", <() as WeightInfo>::treasury_disbursement()),
("treasury_deposit", <() as WeightInfo>::treasury_deposit()),
("endorse_emergency_proposal", <() as WeightInfo>::endorse_emergency_proposal()),
];
for (nombre, w) in casos {
assert!(
w.proof_size() > 0,
"`{nombre}` declara proof_size = 0: miente al block-builder sobre el peso PoV"
);
assert!(
w.ref_time() > 0,
"`{nombre}` declara ref_time = 0: el extrinsic saldria gratis"
);
}
}
} }
+178 -71
View File
@@ -1,87 +1,194 @@
//! # Weights para `pallet-origin-provenance` // SPDX-License-Identifier: Apache-2.0
//! // Origin Chain — Pilar 4 · Charon
//! ## Estado: INTERIM hand-derived (DB-aware, DoS-safe) — pendiente regeneración HW //
//! // ATENCION AL LEER ESTOS NUMEROS: un weight es una LATENCIA, y una latencia sin
//! Estos weights son **derivados a mano de forma conservadora**, NO autogenerados // el hardware y el perfil de potencia que la produjeron no se puede reproducir.
//! por `frame-benchmarking-cli` sobre hardware de referencia todavía. La razón es // La cabecera dice HOSTNAME y CPU: creele a eso y a nada mas. Un weight medido
//! infraestructural, no de diseño: generar los números canónicos requiere ejecutar // en un portatil y cobrado en un Pi 5 es mispricing estructural, solo que
//! el loop `benchmark pallet`, que necesita **o** el node `sc-service` real // invisible. Los numeros CANONICOS de mainnet salen del banco de referencia
//! (bloqueado por el mismatch de API sc-*/sp-consensus del tag stable2509-3, ver // (Pi 5, governor y aislamiento declarados), no de la maquina de quien compila.
//! `main.rs` §BLOQUEO) **o** `frame-omni-bencher` sobre el `WASM_BINARY` (gated tras
//! la feature `wasm-build`). Cuando cualquiera de los dos aterrice (VPS / HW de
//! referencia Pi5), regenerar es mecánico: los benchmarks de `benchmarking.rs` son
//! la **fuente de verdad de la forma** y sobrescribirán estos números.
//!
//! ## Por qué esto ya es una mejora de seguridad REAL
//!
//! Los placeholders anteriores eran `Weight::from_parts(10_000, 0)`: **proof_size = 0
//! y sin contabilizar reads/writes de DB**. Eso es un vector de DoS — un atacante
//! llama extrinsics que tocan varias entradas de storage pagando casi nada, y el
//! `proof_size = 0` miente al block-builder sobre el peso PoV. Estos weights usan
//! `T::DbWeight` (RocksDbWeight en el runtime), que puebla **tanto ref_time como
//! proof_size** por cada read/write real contado del código — cerrando el hueco.
//!
//! El componente `from_parts(N, 0)` fijo cubre el compute (decode postcard, verify
//! Ed25519, hashing) con holgura conservadora; el `DbWeight` cubre el storage.
//! Weights AUTOGENERADOS para `origin_chain_provenance` — NO editar a mano.
//!
//! Regenerar: `scripts/bench/regen-weights.sh` (ver ese script para el
//! procedimiento completo y el hardware al que hay que creerle).
//!
//! GENERADO POR SUBSTRATE BENCHMARK CLI VERSION 51.0.0
//! FECHA: 2026-09-09, STEPS: `50`, REPEAT: `20`
//! HOSTNAME: `MacBookProM3Max.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, DB CACHE: 1024
// Comando ejecutado:
// /Users/davidherran/.cargo/bin/frame-omni-bencher
// v1
// benchmark
// pallet
// --runtime
// /Users/davidherran/originmetaverse/artifacts/origin-chain/origin_chain_runtime_rv12_bench.compact.compressed.wasm
// --genesis-builder-preset
// development
// --pallet
// origin_chain_provenance
// --extrinsic
//
// --steps
// 50
// --repeat
// 20
// --template
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/origin-weights-template.hbs
// --header
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/scripts/bench/HEADER.txt
// --output
// /Users/davidherran/originmetaverse/external/arkhe-origin-chain/crates/origin-chain-provenance/src/weights.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(clippy::unnecessary_cast)] #![allow(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight}; use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
/// Trait de weights para los extrinsics de `pallet-origin-provenance`. /// Trait de weights para los extrinsics de `origin_chain_provenance`.
pub trait WeightInfo { pub trait WeightInfo {
/// Peso de `attest_asset` — decode postcard + 3-4 reads + verify Ed25519 + 1 write. /// Peso de `attest_asset` — MEDIDO sobre el WASM, no estimado a mano.
fn attest_asset() -> Weight; fn attest_asset() -> Weight;
/// Peso de `register_validator` (Root) — 1 write. /// Peso de `register_validator` — MEDIDO sobre el WASM, no estimado a mano.
fn register_validator() -> Weight; fn register_validator() -> Weight;
/// Peso de `revoke_validator` (Root) — 1 write (remove). /// Peso de `revoke_validator` — MEDIDO sobre el WASM, no estimado a mano.
fn revoke_validator() -> Weight; fn revoke_validator() -> Weight;
} }
/// Weights para `pallet-origin-provenance` parametrizados por el `DbWeight` del runtime. /// Weights parametrizados por el `DbWeight` real del runtime.
///
/// Se usa en el runtime como `SubstrateWeight<Runtime>` → los reads/writes se cuestan
/// con el `RocksDbWeight` real de la cadena, no con constantes hardcodeadas.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn attest_asset() -> Weight { /// Storage: `Provenance::Attestations` (r:1 w:1)
// Compute conservador: decode postcard (~115 bytes) + Ed25519 verify /// Proof: `Provenance::Attestations` (`max_values`: None, `max_size`: Some(505), added: 2980, mode: `MaxEncodedLen`)
// (dominante, ~50µs en HW de referencia) + BLAKE-hashing del dominio. /// Storage: `Provenance::AuthorizedValidators` (r:1 w:0)
// Storage: contains_key(Attestations) + get(AuthorizedValidators) + /// Proof: `Provenance::AuthorizedValidators` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
// block_hash(0) + block_number = 4 reads; insert(Attestations) = 1 write. /// Storage: `System::BlockHash` (r:1 w:0)
Weight::from_parts(50_000_000, 0) /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
.saturating_add(T::DbWeight::get().reads(4_u64)) /// Storage: `System::Number` (r:1 w:0)
.saturating_add(T::DbWeight::get().writes(1_u64)) /// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
} /// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
fn register_validator() -> Weight { /// Storage: `System::EventCount` (r:1 w:1)
// ensure_root (in-memory) + insert(AuthorizedValidators) = 1 write. /// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
Weight::from_parts(8_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64)) /// Storage: `System::Events` (r:1 w:1)
} /// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn attest_asset() -> Weight {
fn revoke_validator() -> Weight { // Proof size en bytes:
// ensure_root (in-memory) + remove(AuthorizedValidators) = 1 write. // Medido: `153`
Weight::from_parts(8_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64)) // Estimado: `3970`
} // Tiempo minimo de ejecucion: 43_000_000 picosegundos.
Weight::from_parts(44_000_000, 0)
.saturating_add(Weight::from_parts(0, 3970))
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Provenance::AuthorizedValidators` (r:0 w:1)
/// Proof: `Provenance::AuthorizedValidators` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
fn register_validator() -> Weight {
// Proof size en bytes:
// Medido: `19`
// Estimado: `1504`
// Tiempo minimo de ejecucion: 6_000_000 picosegundos.
Weight::from_parts(7_000_000, 0)
.saturating_add(Weight::from_parts(0, 1504))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `System::Number` (r:1 w:0)
/// Proof: `System::Number` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::ExecutionPhase` (r:1 w:0)
/// Proof: `System::ExecutionPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `System::EventCount` (r:1 w:1)
/// Proof: `System::EventCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Events` (r:1 w:1)
/// Proof: `System::Events` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Provenance::AuthorizedValidators` (r:0 w:1)
/// Proof: `Provenance::AuthorizedValidators` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`)
fn revoke_validator() -> Weight {
// Proof size en bytes:
// Medido: `19`
// Estimado: `1504`
// Tiempo minimo de ejecucion: 6_000_000 picosegundos.
Weight::from_parts(7_000_000, 0)
.saturating_add(Weight::from_parts(0, 1504))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
} }
/// Impl no-op para mocks / tests — usa `RocksDbWeight` directo (no requiere `T`). /// Impl para mocks y tests — `RocksDbWeight` directo, sin necesitar `T`.
impl WeightInfo for () { impl WeightInfo for () {
fn attest_asset() -> Weight { fn attest_asset() -> Weight {
Weight::from_parts(50_000_000, 0) Weight::from_parts(44_000_000, 0)
.saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 3970))
.saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().reads(7_u64))
} .saturating_add(RocksDbWeight::get().writes(3_u64))
}
fn register_validator() -> Weight { fn register_validator() -> Weight {
Weight::from_parts(8_000_000, 0).saturating_add(RocksDbWeight::get().writes(1_u64)) Weight::from_parts(7_000_000, 0)
} .saturating_add(Weight::from_parts(0, 1504))
.saturating_add(RocksDbWeight::get().reads(4_u64))
fn revoke_validator() -> Weight { .saturating_add(RocksDbWeight::get().writes(3_u64))
Weight::from_parts(8_000_000, 0).saturating_add(RocksDbWeight::get().writes(1_u64)) }
} fn revoke_validator() -> Weight {
Weight::from_parts(7_000_000, 0)
.saturating_add(Weight::from_parts(0, 1504))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
}
#[cfg(test)]
mod guard {
use super::*;
/// NINGUN EXTRINSIC PUEDE DECLARAR `proof_size = 0`.
///
/// El `proof_size` es lo que el block-builder usa para no pasarse del limite
/// de PoV. Un cero no dice «este extrinsic no toca storage»: dice «miento
/// sobre lo que va a ocupar la prueba», y con eso entra en un bloque mucho
/// mas de lo que cabe.
///
/// El test nace de un error propio y de la peor clase: la cabecera de los
/// weights interinos afirmaba que `T::DbWeight` «puebla tanto ref_time como
/// proof_size … cerrando el hueco». Es falso y se comprueba en la fuente —
/// `sp_weights::RuntimeDbWeight` solo tiene los campos `read` y `write`, y
/// `reads(r)` devuelve `Weight::from_parts(read * r, 0)`. Los interinos
/// arreglaron reads/writes y dejaron el proof_size donde estaba: en 0. La
/// afirmacion de haberlo cerrado sobrevivio mas de un mes sin que ninguna
/// lectura la desmintiera; la desmintio una medicion.
///
/// Esta lista la GENERA la plantilla a partir de los benchmarks reales, asi
/// que no puede quedarse corta cuando se anada un extrinsic nuevo.
#[test]
fn ningun_weight_declara_proof_size_cero() {
let casos: &[(&str, Weight)] = &[
("attest_asset", <() as WeightInfo>::attest_asset()),
("register_validator", <() as WeightInfo>::register_validator()),
("revoke_validator", <() as WeightInfo>::revoke_validator()),
];
for (nombre, w) in casos {
assert!(
w.proof_size() > 0,
"`{nombre}` declara proof_size = 0: miente al block-builder sobre el peso PoV"
);
assert!(
w.ref_time() > 0,
"`{nombre}` declara ref_time = 0: el extrinsic saldria gratis"
);
}
}
} }
+27 -2
View File
@@ -315,6 +315,31 @@ pub const IMPL_NAME: &str = borrowed_str(&VERSION.impl_name);
/// lo llama `los_tres_presets_construyen_estado`, con contrafactual verificado. /// lo llama `los_tres_presets_construyen_estado`, con contrafactual verificado.
/// Nada de esto cambia una transicion de estado de la cadena viva (no hay cadena /// Nada de esto cambia una transicion de estado de la cadena viva (no hay cadena
/// viva): el bump es por higiene de blob y de metadata. TRANSACTION_VERSION intacto. /// viva): el bump es por higiene de blob y de metadata. TRANSACTION_VERSION intacto.
///
/// **v13 (los weights dejan de ser estimados y pasan a ser medidos)**: los 19
/// extrinsics de los 5 pallets custom cambian de weights INTERIM hand-derived a
/// weights MEDIDOS con `frame-omni-bencher` sobre el propio blob WASM. Los
/// weights son consenso-relevantes ⇒ spec bump obligatorio. Lo que la medicion
/// destapo: **los 19 estaban subdeclarados, los 19.** El patron sistematico era
/// el mismo — se costeo el storage del pallet y se olvido el que cuesta emitir
/// un evento (`System::Events`, `EventCount`, `ExecutionPhase`, `Number`), que
/// son reads y writes reales en cada extrinsic que deposita evento. Y el peor:
/// **`proof_size` valia 0 en los 19**, que es exactamente el agujero que la
/// cabecera de los interinos afirmaba haber cerrado — falso, porque
/// `sp_weights::RuntimeDbWeight` solo tiene `read` y `write` y su `reads(r)`
/// devuelve `from_parts(read * r, 0)`. Un `proof_size` en cero miente al
/// block-builder sobre el peso PoV. Ahora cada fichero generado lleva un guard
/// que reprueba cualquier cero.
///
/// ⚠️ **NUMEROS DE MAQUINA DE DESARROLLO, NO CANONICOS.** Estan medidos en un
/// MacBook Pro M3 Max, no en el banco de referencia BM V2 (Pi 5). La FORMA
/// (reads / writes / proof_size) no depende del hardware y es correcta; el
/// `ref_time` SI depende, y en un Pi 5 sera bastante mayor. Un caso lo enseña
/// solo: `attest_asset` BAJA de 50 a 44 µs, y es justo el extrinsic dominado
/// por el verify Ed25519 — el mas sensible al silicio. Antes de mainnet hay que
/// correr `scripts/bench/regen-weights.sh` en el Pi 5 con governor y aislamiento
/// declarados (peticion abierta a Laurha, `request:66f500d54e28a80c`).
/// TRANSACTION_VERSION intacto: ninguna firma de extrinsic cambia.
pub const RUNTIME_VERSION: u32 = VERSION.spec_version; pub const RUNTIME_VERSION: u32 = VERSION.spec_version;
/// Canonical authoring version per Substrate semver canonical. /// Canonical authoring version per Substrate semver canonical.
@@ -961,7 +986,7 @@ pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion {
spec_name: alloc::borrow::Cow::Borrowed("origin-chain"), spec_name: alloc::borrow::Cow::Borrowed("origin-chain"),
impl_name: alloc::borrow::Cow::Borrowed("origin-chain-charon"), impl_name: alloc::borrow::Cow::Borrowed("origin-chain-charon"),
authoring_version: 1, authoring_version: 1,
spec_version: 12, spec_version: 13,
impl_version: 1, impl_version: 1,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
transaction_version: 1, transaction_version: 1,
@@ -997,7 +1022,7 @@ mod tests {
/// mismo commit en que la version subio a 12. /// mismo commit en que la version subio a 12.
#[test] #[test]
fn spec_version_vigente_y_transaction_version_intacta() { fn spec_version_vigente_y_transaction_version_intacta() {
assert_eq!(RUNTIME_VERSION, 12); assert_eq!(RUNTIME_VERSION, 13);
assert_eq!(TRANSACTION_VERSION, 1); assert_eq!(TRANSACTION_VERSION, 1);
} }
+13 -9
View File
@@ -58,14 +58,18 @@ fi
echo "blob: $( (shasum -a 256 "$WASM" 2>/dev/null || sha256sum "$WASM") | cut -d' ' -f1)" echo "blob: $( (shasum -a 256 "$WASM" 2>/dev/null || sha256sum "$WASM") | cut -d' ' -f1)"
echo "═══ 2/2 midiendo (steps=$STEPS repeat=$REPEAT) ═══" echo "═══ 2/2 midiendo (steps=$STEPS repeat=$REPEAT) ═══"
declare -A DEST=( PARES="
[origin_chain_provenance]=crates/origin-chain-provenance/src/weights.rs origin_chain_provenance:crates/origin-chain-provenance/src/weights.rs
[origin_chain_agent_identity]=crates/origin-chain-agent-identity/src/weights.rs origin_chain_agent_identity:crates/origin-chain-agent-identity/src/weights.rs
[origin_chain_fees]=crates/origin-chain-fees/src/weights.rs origin_chain_fees:crates/origin-chain-fees/src/weights.rs
[origin_chain_emission]=crates/origin-chain-emission/src/weights.rs origin_chain_emission:crates/origin-chain-emission/src/weights.rs
[origin_chain_governance]=crates/origin-chain-governance/src/weights.rs origin_chain_governance:crates/origin-chain-governance/src/weights.rs
) "
for p in "${!DEST[@]}"; do # Lista plana y no array asociativo a proposito: el bash por defecto de macOS
# es el 3.2, que no tiene `declare -A`, y con `set -u` falla con un
# «unbound variable» que no se parece en nada a la causa.
echo "$PARES" | while IFS=: read -r p dest; do
[ -n "$p" ] || continue
echo "── $p" echo "── $p"
"$BENCHER" v1 benchmark pallet \ "$BENCHER" v1 benchmark pallet \
--runtime "$WASM" --genesis-builder-preset development \ --runtime "$WASM" --genesis-builder-preset development \
@@ -73,7 +77,7 @@ for p in "${!DEST[@]}"; do
--steps "$STEPS" --repeat "$REPEAT" \ --steps "$STEPS" --repeat "$REPEAT" \
--template "$ROOT/scripts/bench/origin-weights-template.hbs" \ --template "$ROOT/scripts/bench/origin-weights-template.hbs" \
--header "$ROOT/scripts/bench/HEADER.txt" \ --header "$ROOT/scripts/bench/HEADER.txt" \
--output "$ROOT/${DEST[$p]}" --output "$ROOT/$dest"
done done
echo "═══ listo — ahora: cargo test --workspace ═══" echo "═══ listo — ahora: cargo test --workspace ═══"