From d6725e9a83ef17f2d39d4e4f5db49c3e19f3c76f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 23:16:46 +0000 Subject: [PATCH] build(deps): bump wasm-instrument from 0.2.0 to 0.4.0 Bumps [wasm-instrument](https://github.com/paritytech/wasm-instrument) from 0.2.0 to 0.4.0. - [Changelog](https://github.com/paritytech/wasm-instrument/blob/master/CHANGELOG.md) - [Commits](https://github.com/paritytech/wasm-instrument/compare/0.2.0...v0.4.0) The new version switches the per-block gas counter and the `memory.grow` charge helper from 32-bit to 64-bit arithmetic. Our call sites were adjusted accordingly: - `runtime/wasm/src/mapping.rs`: use the new `host_function::Injector` backend API for `gas_metering::inject`. - `runtime/wasm/src/gas_rules.rs`: implement the new `call_per_local_cost()` method, returning 0 so locals initialization remains free. - `runtime/wasm/src/module/instance.rs`: the injected `gas` host function now receives an `i64` cost argument instead of `i32`; update the Rust handler signature from `u32` to `u64`. The 64-bit arithmetic in the grow-counter helper also fixes an overflow that was previously under-charging gas for large `memory.grow` calls. In 0.2.0 the helper multiplied the page count by `gas_per_page` (~50.8M in our rules) using `I32Mul`, which wrapped mod 2^32 for any grow larger than ~84 pages (~5.25 MiB). 0.4.0 extends the page count to `i64` before the multiplication, so the full cost is charged. The two `yaml_parsing_v0_0_*` tests in `runtime/test/src/test.rs` pin exact `gas_used` totals. The YAML input `"x".repeat(10_000_001)` causes three large grow events, so each test reports exactly `3 * 2^32 = 12,884,901,888` more gas than before. Update the expected values to match the now-correct totals. Note for downstream: this is a semantic change in gas accounting for subgraph handlers that grow memory past ~5.25 MiB in a single call. Such handlers will consume more gas than they did on 0.2.0; this may warrant a release note or API-version gating, which is out of scope for this dependency bump. Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- runtime/test/src/test.rs | 4 ++-- runtime/wasm/Cargo.toml | 2 +- runtime/wasm/src/gas_rules.rs | 4 ++++ runtime/wasm/src/mapping.rs | 6 ++++-- runtime/wasm/src/module/instance.rs | 6 +++--- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db21e89c461..1e938c02693 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9165,9 +9165,9 @@ dependencies = [ [[package]] name = "wasm-instrument" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bca81f5279342b38b17d9acbf007a46ddeb73144e2bd5f0a21bfa9fc5d4ab3e" +checksum = "2a47ecb37b9734d1085eaa5ae1a81e60801fd8c28d4cabdd8aedb982021918bc" dependencies = [ "parity-wasm", ] diff --git a/runtime/test/src/test.rs b/runtime/test/src/test.rs index 985dc26ea8f..28f42ad53c5 100644 --- a/runtime/test/src/test.rs +++ b/runtime/test/src/test.rs @@ -1844,10 +1844,10 @@ async fn test_yaml_parsing(api_version: Version, gas_used: u64) { #[graph::test] async fn yaml_parsing_v0_0_4() { - test_yaml_parsing(API_VERSION_0_0_4, 1053927678771).await; + test_yaml_parsing(API_VERSION_0_0_4, 1066812580659).await; } #[graph::test] async fn yaml_parsing_v0_0_5() { - test_yaml_parsing(API_VERSION_0_0_5, 1053946160531).await; + test_yaml_parsing(API_VERSION_0_0_5, 1066831062419).await; } diff --git a/runtime/wasm/Cargo.toml b/runtime/wasm/Cargo.toml index 81c9f247688..abf96ddc0ff 100644 --- a/runtime/wasm/Cargo.toml +++ b/runtime/wasm/Cargo.toml @@ -14,7 +14,7 @@ anyhow = { workspace = true } never = "0.1" wasmtime.workspace = true -wasm-instrument = { version = "0.2.0", features = ["std", "sign_ext"] } +wasm-instrument = { version = "0.4.0", features = ["std", "sign_ext"] } # AssemblyScript uses sign extensions parity-wasm = { version = "0.45", features = ["std", "sign_ext"] } diff --git a/runtime/wasm/src/gas_rules.rs b/runtime/wasm/src/gas_rules.rs index 10717f92542..7a375f9e346 100644 --- a/runtime/wasm/src/gas_rules.rs +++ b/runtime/wasm/src/gas_rules.rs @@ -165,4 +165,8 @@ impl Rules for GasRules { MemoryGrowCost::Linear(gas_per_page) } + + fn call_per_local_cost(&self) -> u32 { + 0 + } } diff --git a/runtime/wasm/src/mapping.rs b/runtime/wasm/src/mapping.rs index 3c98bc8081d..c0d4bce52d7 100644 --- a/runtime/wasm/src/mapping.rs +++ b/runtime/wasm/src/mapping.rs @@ -302,8 +302,10 @@ impl ValidModule { name }); - let parity_module = wasm_instrument::gas_metering::inject(parity_module, &GasRules, "gas") - .map_err(|_| anyhow!("Failed to inject gas counter"))?; + let backend = wasm_instrument::gas_metering::host_function::Injector::new("gas", "gas"); + let parity_module = + wasm_instrument::gas_metering::inject(parity_module, backend, &GasRules) + .map_err(|_| anyhow!("Failed to inject gas counter"))?; let raw_module = parity_module.into_bytes()?; // We use Cranelift as a compilation engine. Cranelift is an optimizing compiler, but that diff --git a/runtime/wasm/src/module/instance.rs b/runtime/wasm/src/module/instance.rs index 02cfc5eb8d1..68472b0eae9 100644 --- a/runtime/wasm/src/module/instance.rs +++ b/runtime/wasm/src/module/instance.rs @@ -16,7 +16,7 @@ use graph::data_source::{MappingTrigger, TriggerWithHandler}; use graph::prelude::*; use graph::runtime::{ HostExportError, asc_new, - gas::{Gas, GasCounter, SaturatingInto}, + gas::{Gas, GasCounter}, }; use graph::{components::subgraph::MappingError, runtime::AscPtr}; @@ -576,7 +576,7 @@ pub(crate) fn build_linker( linker.func_wrap( "gas", "gas", - |mut caller: wasmtime::Caller<'_, WasmInstanceData>, gas_used: u32| -> anyhow::Result<()> { + |mut caller: wasmtime::Caller<'_, WasmInstanceData>, gas_used: u64| -> anyhow::Result<()> { // Gas metering has a relevant execution cost cost, being called tens of thousands // of times per handler, but it's not worth having a stopwatch section here because // the cost of measuring would be greater than the cost of `consume_host_fn`. Last @@ -584,7 +584,7 @@ pub(crate) fn build_linker( if let Err(e) = caller .data() .gas - .consume_host_fn_with_metrics(gas_used.saturating_into(), "gas") + .consume_host_fn_with_metrics(Gas::new(gas_used), "gas") { caller.data_mut().deterministic_host_trap = true; return Err(e.into());