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>
88 lines
4.1 KiB
Rust
88 lines
4.1 KiB
Rust
//! # Weights para `pallet-origin-provenance`
|
|
//!
|
|
//! ## Estado: INTERIM hand-derived (DB-aware, DoS-safe) — pendiente regeneración HW
|
|
//!
|
|
//! Estos weights son **derivados a mano de forma conservadora**, NO autogenerados
|
|
//! por `frame-benchmarking-cli` sobre hardware de referencia todavía. La razón es
|
|
//! infraestructural, no de diseño: generar los números canónicos requiere ejecutar
|
|
//! el loop `benchmark pallet`, que necesita **o** el node `sc-service` real
|
|
//! (bloqueado por el mismatch de API sc-*/sp-consensus del tag stable2509-3, ver
|
|
//! `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.
|
|
|
|
#![allow(unused_parens)]
|
|
#![allow(unused_imports)]
|
|
#![allow(clippy::unnecessary_cast)]
|
|
|
|
use core::marker::PhantomData;
|
|
use frame_support::{traits::Get, weights::constants::RocksDbWeight, weights::Weight};
|
|
|
|
/// Trait de weights para los extrinsics de `pallet-origin-provenance`.
|
|
pub trait WeightInfo {
|
|
/// Peso de `attest_asset` — decode postcard + 3-4 reads + verify Ed25519 + 1 write.
|
|
fn attest_asset() -> Weight;
|
|
/// Peso de `register_validator` (Root) — 1 write.
|
|
fn register_validator() -> Weight;
|
|
/// Peso de `revoke_validator` (Root) — 1 write (remove).
|
|
fn revoke_validator() -> Weight;
|
|
}
|
|
|
|
/// Weights para `pallet-origin-provenance` parametrizados por el `DbWeight` 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>);
|
|
|
|
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
|
fn attest_asset() -> Weight {
|
|
// Compute conservador: decode postcard (~115 bytes) + Ed25519 verify
|
|
// (dominante, ~50µs en HW de referencia) + BLAKE-hashing del dominio.
|
|
// Storage: contains_key(Attestations) + get(AuthorizedValidators) +
|
|
// block_hash(0) + block_number = 4 reads; insert(Attestations) = 1 write.
|
|
Weight::from_parts(50_000_000, 0)
|
|
.saturating_add(T::DbWeight::get().reads(4_u64))
|
|
.saturating_add(T::DbWeight::get().writes(1_u64))
|
|
}
|
|
|
|
fn register_validator() -> Weight {
|
|
// ensure_root (in-memory) + insert(AuthorizedValidators) = 1 write.
|
|
Weight::from_parts(8_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64))
|
|
}
|
|
|
|
fn revoke_validator() -> Weight {
|
|
// ensure_root (in-memory) + remove(AuthorizedValidators) = 1 write.
|
|
Weight::from_parts(8_000_000, 0).saturating_add(T::DbWeight::get().writes(1_u64))
|
|
}
|
|
}
|
|
|
|
/// Impl no-op para mocks / tests — usa `RocksDbWeight` directo (no requiere `T`).
|
|
impl WeightInfo for () {
|
|
fn attest_asset() -> Weight {
|
|
Weight::from_parts(50_000_000, 0)
|
|
.saturating_add(RocksDbWeight::get().reads(4_u64))
|
|
.saturating_add(RocksDbWeight::get().writes(1_u64))
|
|
}
|
|
|
|
fn register_validator() -> Weight {
|
|
Weight::from_parts(8_000_000, 0).saturating_add(RocksDbWeight::get().writes(1_u64))
|
|
}
|
|
|
|
fn revoke_validator() -> Weight {
|
|
Weight::from_parts(8_000_000, 0).saturating_add(RocksDbWeight::get().writes(1_u64))
|
|
}
|
|
}
|