From 4c6492ac3c56a3836ec3db8484b8e2e5d2ef2d16 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 09:09:17 +0200 Subject: [PATCH 01/15] Refactor ed25519_batch_verify gas cost --- packages/vm/src/environment.rs | 2 ++ packages/vm/src/imports.rs | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs index e30a0877e2..0d62419090 100644 --- a/packages/vm/src/environment.rs +++ b/packages/vm/src/environment.rs @@ -42,8 +42,10 @@ pub struct GasConfig { /// ed25519 signature verification cost pub ed25519_verify_cost: u64, /// ed25519 batch signature verification cost + /// This is charged per signature. pub ed25519_batch_verify_cost: u64, /// ed25519 batch signature verification cost (single public key) + /// This is charged per signature. pub ed25519_batch_verify_one_pubkey_cost: u64, /// bls12-381 aggregate cost per point (g1) pub bls12_381_aggregate_g1_per_point: u64, diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index ef86c276db..c2738cfdc8 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -728,12 +728,17 @@ pub fn do_ed25519_batch_verify< let signatures = decode_sections(&signatures); let public_keys = decode_sections(&public_keys); - let gas_cost = if public_keys.len() == 1 { + let gas_cost_per_sig = if public_keys.len() == 1 { data.gas_config.ed25519_batch_verify_one_pubkey_cost } else { data.gas_config.ed25519_batch_verify_cost - } * signatures.len() as u64; - let gas_info = GasInfo::with_cost(max(gas_cost, data.gas_config.ed25519_verify_cost)); + }; + let gas_info = GasInfo::with_cost(max( + // charge for each signature + gas_cost_per_sig * (signatures.len() as u64), + // but ensure we charge something even if there are no signatures + data.gas_config.ed25519_verify_cost, + )); process_gas_info(data, &mut store, gas_info)?; let result = ed25519_batch_verify(&mut OsRng, &messages, &signatures, &public_keys); let code = match result { From 7a6da5563a820e538290bf8c0d71d024240c2ad4 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 09:20:05 +0200 Subject: [PATCH 02/15] Fix typo --- packages/vm/src/imports.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index c2738cfdc8..dfde81a13e 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -253,7 +253,7 @@ const BLS12_381_AGGREGATE_SUCCESS: u32 = 0; /// Return code (error code) for success when hashing to the curve const BLS12_381_HASH_TO_CURVE_SUCCESS: u32 = 0; -/// Maximum size of continous points passed to aggregate functions +/// Maximum size of continuous points passed to aggregate functions const BLS12_381_MAX_AGGREGATE_SIZE: usize = 2 * MI; /// Maximum size of the message passed to the hash-to-curve functions From 58b23532f9d16ed090d56fcd796ccebfdddc70c1 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 12:53:18 +0200 Subject: [PATCH 03/15] Update gas cost of secp256 and ed25519 --- packages/vm/src/environment.rs | 59 +++++++++++++++++++++++----------- packages/vm/src/imports.rs | 8 ++--- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs index 0d62419090..816f35cd69 100644 --- a/packages/vm/src/environment.rs +++ b/packages/vm/src/environment.rs @@ -42,11 +42,9 @@ pub struct GasConfig { /// ed25519 signature verification cost pub ed25519_verify_cost: u64, /// ed25519 batch signature verification cost - /// This is charged per signature. - pub ed25519_batch_verify_cost: u64, + pub ed25519_batch_verify_cost: LinearGasCost, /// ed25519 batch signature verification cost (single public key) - /// This is charged per signature. - pub ed25519_batch_verify_one_pubkey_cost: u64, + pub ed25519_batch_verify_one_pubkey_cost: LinearGasCost, /// bls12-381 aggregate cost per point (g1) pub bls12_381_aggregate_g1_per_point: u64, /// bls12-381 aggregate cost per point (g2) @@ -67,20 +65,26 @@ impl Default for GasConfig { // Target is 10^12 per second (see GAS.md), i.e. 10^6 gas per ยต second. const GAS_PER_US: u64 = 1_000_000; Self { - // ~119 us in crypto benchmarks - secp256k1_verify_cost: 119 * GAS_PER_US, - // ~233 us in crypto benchmarks - secp256k1_recover_pubkey_cost: 233 * GAS_PER_US, - // ~374 us in crypto benchmarks - secp256r1_verify_cost: 374 * GAS_PER_US, - // ~834 us in crypto benchmarks - secp256r1_recover_pubkey_cost: 834 * GAS_PER_US, - // ~63 us in crypto benchmarks - ed25519_verify_cost: 63 * GAS_PER_US, - // Gas cost factors, relative to ed25519_verify cost - // From https://docs.rs/ed25519-zebra/2.2.0/ed25519_zebra/batch/index.html - ed25519_batch_verify_cost: 63 * GAS_PER_US / 2, - ed25519_batch_verify_one_pubkey_cost: 63 * GAS_PER_US / 4, + // ~96 us in crypto benchmarks + secp256k1_verify_cost: 96 * GAS_PER_US, + // ~194 us in crypto benchmarks + secp256k1_recover_pubkey_cost: 194 * GAS_PER_US, + // ~279 us in crypto benchmarks + secp256r1_verify_cost: 279 * GAS_PER_US, + // ~592 us in crypto benchmarks + secp256r1_recover_pubkey_cost: 592 * GAS_PER_US, + // ~35 us in crypto benchmarks + ed25519_verify_cost: 35 * GAS_PER_US, + // Calculated based on the benchmark results for `ed25519_batch_verify_{x}`. + ed25519_batch_verify_cost: LinearGasCost { + base: 24 * GAS_PER_US, + per_item: 21 * GAS_PER_US, + }, + // Calculated based on the benchmark results for `ed25519_batch_verify_one_pubkey_{x}`. + ed25519_batch_verify_one_pubkey_cost: LinearGasCost { + base: 36 * GAS_PER_US, + per_item: 10 * GAS_PER_US, + }, // just assume the production machines have more than 4 cores, so we can half that bls12_381_aggregate_g1_per_point: 16 * GAS_PER_US / 2, bls12_381_aggregate_g2_per_point: 33 * GAS_PER_US / 2, @@ -93,6 +97,25 @@ impl Default for GasConfig { } } +/// Linear gas cost model where the cost is linear in the number of items. +/// +/// To calculate it, you sample the cost for a few different amounts of items and fit a line to it. +/// Let `b` be that line of best fit. Then `base = b(0)` is the y-intercept and +/// `per_item = b(1) - b(0)` the slope. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct LinearGasCost { + /// This is a flat part of the cost, charged once per batch. + base: u64, + /// This is the cost per item in the batch. + per_item: u64, +} + +impl LinearGasCost { + pub fn total_cost(&self, items: u64) -> u64 { + self.base + self.per_item * items + } +} + /** context data **/ #[derive(Clone, PartialEq, Eq, Debug, Default)] diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index dfde81a13e..fc8307fbc7 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -728,14 +728,14 @@ pub fn do_ed25519_batch_verify< let signatures = decode_sections(&signatures); let public_keys = decode_sections(&public_keys); - let gas_cost_per_sig = if public_keys.len() == 1 { - data.gas_config.ed25519_batch_verify_one_pubkey_cost + let gas_cost = if public_keys.len() == 1 { + &data.gas_config.ed25519_batch_verify_one_pubkey_cost } else { - data.gas_config.ed25519_batch_verify_cost + &data.gas_config.ed25519_batch_verify_cost }; let gas_info = GasInfo::with_cost(max( // charge for each signature - gas_cost_per_sig * (signatures.len() as u64), + gas_cost.total_cost(signatures.len() as u64), // but ensure we charge something even if there are no signatures data.gas_config.ed25519_verify_cost, )); From 86fe644bed62456315bb1d2acbfd953c25eb1991 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 12:57:27 +0200 Subject: [PATCH 04/15] Update bls12_318 gas cost --- packages/vm/src/environment.rs | 34 +++++++++++++++++++--------------- packages/vm/src/imports.rs | 24 ++++++++++++++---------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs index 816f35cd69..2e174c6ca4 100644 --- a/packages/vm/src/environment.rs +++ b/packages/vm/src/environment.rs @@ -45,19 +45,16 @@ pub struct GasConfig { pub ed25519_batch_verify_cost: LinearGasCost, /// ed25519 batch signature verification cost (single public key) pub ed25519_batch_verify_one_pubkey_cost: LinearGasCost, - /// bls12-381 aggregate cost per point (g1) - pub bls12_381_aggregate_g1_per_point: u64, - /// bls12-381 aggregate cost per point (g2) - pub bls12_381_aggregate_g2_per_point: u64, + /// bls12-381 aggregate cost (g1) + pub bls12_381_aggregate_g1_cost: LinearGasCost, + /// bls12-381 aggregate cost (g2) + pub bls12_381_aggregate_g2_cost: LinearGasCost, /// bls12-381 hash to g1 cost pub bls12_381_hash_to_g1_cost: u64, /// bls12-381 hash to g2 cost pub bls12_381_hash_to_g2_cost: u64, /// bls12-381 pairing equality check cost - pub bls12_381_pairing_equality_cost: u64, - /// bls12-381 aggregated pairing equality check cost per point - /// (added on top of the base pairing equality check cost) - pub bls12_381_aggregated_pairing_equality_cost_per_pair: u64, + pub bls12_381_pairing_equality_cost: LinearGasCost, } impl Default for GasConfig { @@ -86,13 +83,20 @@ impl Default for GasConfig { per_item: 10 * GAS_PER_US, }, // just assume the production machines have more than 4 cores, so we can half that - bls12_381_aggregate_g1_per_point: 16 * GAS_PER_US / 2, - bls12_381_aggregate_g2_per_point: 33 * GAS_PER_US / 2, - bls12_381_hash_to_g1_cost: 324 * GAS_PER_US, - bls12_381_hash_to_g2_cost: 528 * GAS_PER_US, - // god i wish i was lying - bls12_381_pairing_equality_cost: 1038 * GAS_PER_US, - bls12_381_aggregated_pairing_equality_cost_per_pair: 108 * GAS_PER_US, + bls12_381_aggregate_g1_cost: LinearGasCost { + base: 136 * GAS_PER_US / 2, + per_item: 24 * GAS_PER_US / 2, + }, + bls12_381_aggregate_g2_cost: LinearGasCost { + base: 207 * GAS_PER_US / 2, + per_item: 49 * GAS_PER_US / 2, + }, + bls12_381_hash_to_g1_cost: 563 * GAS_PER_US, + bls12_381_hash_to_g2_cost: 871 * GAS_PER_US, + bls12_381_pairing_equality_cost: LinearGasCost { + base: 2281 * GAS_PER_US, + per_item: 163 * GAS_PER_US, + }, } } } diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index fc8307fbc7..506681f175 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -278,7 +278,9 @@ pub fn do_bls12_381_aggregate_g1< let estimated_point_count = (g1s.len() / BLS12_381_G1_POINT_LEN) as u64; let gas_info = GasInfo::with_cost( - data.gas_config.bls12_381_aggregate_g1_per_point * estimated_point_count, + data.gas_config + .bls12_381_aggregate_g1_cost + .total_cost(estimated_point_count), ); process_gas_info(data, &mut store, gas_info)?; @@ -322,7 +324,9 @@ pub fn do_bls12_381_aggregate_g2< let estimated_point_count = (g2s.len() / BLS12_381_G2_POINT_LEN) as u64; let gas_info = GasInfo::with_cost( - data.gas_config.bls12_381_aggregate_g2_per_point * estimated_point_count, + data.gas_config + .bls12_381_aggregate_g2_cost + .total_cost(estimated_point_count), ); process_gas_info(data, &mut store, gas_info)?; @@ -370,14 +374,14 @@ pub fn do_bls12_381_pairing_equality< let s = read_region(&memory, s_ptr, BLS12_381_G2_POINT_LEN)?; let estimated_point_count = (ps.len() / BLS12_381_G1_POINT_LEN) as u64; - let additional_cost = data - .gas_config - .bls12_381_aggregated_pairing_equality_cost_per_pair - // Add one since we do not include any pairs in the base benchmark, and we always need to add one for the `r` and `s` pair. - * (estimated_point_count + 1); - - let gas_info = - GasInfo::with_cost(data.gas_config.bls12_381_pairing_equality_cost + additional_cost); + + let gas_info = GasInfo::with_cost( + // Add one to the `estimated_point_count` since we do not include any pairs in the base + // benchmark, and we always need to add one for the `r` and `s` pair. + data.gas_config + .bls12_381_pairing_equality_cost + .total_cost(estimated_point_count + 1), + ); process_gas_info(data, &mut store, gas_info)?; let code = match bls12_381_pairing_equality(&ps, &qs, &r, &s) { From 12de355ec316927486f8be7adc52edc494745fad Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 13:17:32 +0200 Subject: [PATCH 05/15] Fix gas limit for crypto-verify --- contracts/crypto-verify/tests/integration.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/crypto-verify/tests/integration.rs b/contracts/crypto-verify/tests/integration.rs index 0c9c380b72..9107228305 100644 --- a/contracts/crypto-verify/tests/integration.rs +++ b/contracts/crypto-verify/tests/integration.rs @@ -21,7 +21,8 @@ use cosmwasm_std::{Binary, Response, Uint128}; use cosmwasm_vm::testing::{ - instantiate, mock_env, mock_info, mock_instance, query, MockApi, MockQuerier, MockStorage, + instantiate, mock_env, mock_info, mock_instance_with_gas_limit, query, MockApi, MockQuerier, + MockStorage, }; use cosmwasm_vm::{from_slice, Instance}; use hex_literal::hex; @@ -96,7 +97,7 @@ fn build_drand_message(round: u64, previous_signature: &[u8]) -> Vec { const DESERIALIZATION_LIMIT: usize = 20_000; fn setup() -> Instance { - let mut deps = mock_instance(WASM, &[]); + let mut deps = mock_instance_with_gas_limit(WASM, 10_000_000_000); let msg = InstantiateMsg {}; let info = mock_info(CREATOR, &[]); let res: Response = instantiate(&mut deps, mock_env(), info, msg).unwrap(); From 476112985262a71007dc778d9571e3b6926ce80b Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 14:49:06 +0200 Subject: [PATCH 06/15] Adjust wasm op gas cost --- packages/vm/src/instance.rs | 8 ++++---- packages/vm/src/wasm_backend/engine.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs index 08082d7ee8..14cad9eb85 100644 --- a/packages/vm/src/instance.rs +++ b/packages/vm/src/instance.rs @@ -914,7 +914,7 @@ mod tests { let report2 = instance.create_gas_report(); assert_eq!(report2.used_externally, 251); - assert_eq!(report2.used_internally, 8461548); + assert_eq!(report2.used_internally, 9589728); assert_eq!(report2.limit, LIMIT); assert_eq!( report2.remaining, @@ -1105,7 +1105,7 @@ mod tests { .unwrap(); let init_used = orig_gas - instance.get_gas_left(); - assert_eq!(init_used, 8461799); + assert_eq!(init_used, 9589979); } #[test] @@ -1130,7 +1130,7 @@ mod tests { .unwrap(); let execute_used = gas_before_execute - instance.get_gas_left(); - assert_eq!(execute_used, 11181706); + assert_eq!(execute_used, 12658786); } #[test] @@ -1173,6 +1173,6 @@ mod tests { ); let query_used = gas_before_query - instance.get_gas_left(); - assert_eq!(query_used, 7142556); + assert_eq!(query_used, 8094896); } } diff --git a/packages/vm/src/wasm_backend/engine.rs b/packages/vm/src/wasm_backend/engine.rs index 4cf58e6f88..7b2f6190a9 100644 --- a/packages/vm/src/wasm_backend/engine.rs +++ b/packages/vm/src/wasm_backend/engine.rs @@ -23,7 +23,7 @@ fn cost(_operator: &Operator) -> u64 { // In https://github.com/CosmWasm/cosmwasm/pull/1042 a profiler is developed to // identify runtime differences between different Wasm operation, but this is not yet // precise enough to derive insights from it. - 150 + 170 } /// Use Cranelift as the compiler backend if the feature is enabled From e50490c4199a234200a497219b27f071c3409f58 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 14:49:52 +0200 Subject: [PATCH 07/15] Document wasm gas changes and benchmark hardware --- docs/GAS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/GAS.md b/docs/GAS.md index 2a7b25caa2..873304e960 100644 --- a/docs/GAS.md +++ b/docs/GAS.md @@ -29,6 +29,18 @@ gas and took 15ms on our CI system. The ideal cost per operation for this system is `10**12 / (96837752 / (15 / 1000))`: 154. This is rounded to 150 for simplicity. +CosmWasm 2.1 update: All gas values were re-evaluated and adjusted to meet the 1 +Teragas/second target mentioned above. A rerun of the Argon2 test contract +consumed 5270718300 gas with the previous cost of 150, so the operation count +was `5270718300 / 150 = 35138122`. This took 6ms on our benchmark server, so the +new cost per operation is `10**12 / (35138122 / (6 / 1000))`: 171. This is +rounded to 170 for simplicity. + +Benchmarking system: + +- CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (4 cores, 8 threads) +- RAM: 32GB DDR4 2133 MHz + Each machine is different, we know that. But the above target helps us in multiple ways: From 2fad356dbccdd4c42cae10266f20f818d12fada8 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 14:50:58 +0200 Subject: [PATCH 08/15] Use more realistic humanize and canonicalize mock cost --- packages/vm/src/instance.rs | 4 ++-- packages/vm/src/testing/mock.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs index 14cad9eb85..4dfe1f00e5 100644 --- a/packages/vm/src/instance.rs +++ b/packages/vm/src/instance.rs @@ -914,7 +914,7 @@ mod tests { let report2 = instance.create_gas_report(); assert_eq!(report2.used_externally, 251); - assert_eq!(report2.used_internally, 9589728); + assert_eq!(report2.used_internally, 12109530); assert_eq!(report2.limit, LIMIT); assert_eq!( report2.remaining, @@ -1105,7 +1105,7 @@ mod tests { .unwrap(); let init_used = orig_gas - instance.get_gas_left(); - assert_eq!(init_used, 9589979); + assert_eq!(init_used, 12109781); } #[test] diff --git a/packages/vm/src/testing/mock.rs b/packages/vm/src/testing/mock.rs index fd5bdd1eb6..9260b69941 100644 --- a/packages/vm/src/testing/mock.rs +++ b/packages/vm/src/testing/mock.rs @@ -11,8 +11,13 @@ use crate::backend::unwrap_or_return_with_gas; use crate::{Backend, BackendApi, BackendError, BackendResult, GasInfo}; pub const MOCK_CONTRACT_ADDR: &str = "cosmwasmcontract"; // TODO: use correct address -const GAS_COST_HUMANIZE: u64 = 44; // TODO: these seem very low -const GAS_COST_CANONICALIZE: u64 = 55; +/// Default gas multiplier in wasmd. +/// See https://github.com/CosmWasm/wasmd/blob/v0.51.0/x/wasm/types/gas_register.go#L34 +const WASMD_GAS_MULTIPLIER: u64 = 140_000; +/// See https://github.com/CosmWasm/wasmd/blob/v0.51.0/x/wasm/keeper/api.go#L27 +const GAS_COST_HUMANIZE: u64 = 4 * WASMD_GAS_MULTIPLIER; +/// See https://github.com/CosmWasm/wasmd/blob/v0.51.0/x/wasm/keeper/api.go#L28 +const GAS_COST_CANONICALIZE: u64 = 5 * WASMD_GAS_MULTIPLIER; /// Default prefix used when creating Bech32 encoded address. const BECH32_PREFIX: &str = "cosmwasm"; From d2297aa1986650e86465e9794be94162d404a2ae Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 24 May 2024 14:59:12 +0200 Subject: [PATCH 09/15] Fix ed25519_batch gas calculation --- packages/vm/src/imports.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index 506681f175..575781cc73 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -1,6 +1,5 @@ //! Import implementations -use std::cmp::max; use std::marker::PhantomData; use cosmwasm_crypto::{ @@ -737,12 +736,7 @@ pub fn do_ed25519_batch_verify< } else { &data.gas_config.ed25519_batch_verify_cost }; - let gas_info = GasInfo::with_cost(max( - // charge for each signature - gas_cost.total_cost(signatures.len() as u64), - // but ensure we charge something even if there are no signatures - data.gas_config.ed25519_verify_cost, - )); + let gas_info = GasInfo::with_cost(gas_cost.total_cost(signatures.len() as u64)); process_gas_info(data, &mut store, gas_info)?; let result = ed25519_batch_verify(&mut OsRng, &messages, &signatures, &public_keys); let code = match result { From 685e87aa88a0dbc9cf756ab7864d7de925d47f03 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 27 May 2024 17:03:31 +0200 Subject: [PATCH 10/15] Fix bls pairing equality cost --- packages/vm/src/environment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs index 2e174c6ca4..d3e0a5b538 100644 --- a/packages/vm/src/environment.rs +++ b/packages/vm/src/environment.rs @@ -94,7 +94,7 @@ impl Default for GasConfig { bls12_381_hash_to_g1_cost: 563 * GAS_PER_US, bls12_381_hash_to_g2_cost: 871 * GAS_PER_US, bls12_381_pairing_equality_cost: LinearGasCost { - base: 2281 * GAS_PER_US, + base: 2112 * GAS_PER_US, per_item: 163 * GAS_PER_US, }, } From c989cc5915de279160a37a1d9e04ecbe488fba9b Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 27 May 2024 15:44:22 +0200 Subject: [PATCH 11/15] Fix docs how to run benchmarks --- packages/crypto/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/crypto/README.md b/packages/crypto/README.md index 180fcb07ab..3443bddac9 100644 --- a/packages/crypto/README.md +++ b/packages/crypto/README.md @@ -21,7 +21,7 @@ and [cosmwasm-std](`https://crates.io/crates/cosmwasm-std`) crates. ``` cd packages/crypto -cargo bench +cargo bench --features std ``` ## License From 7e8aaf9765c043876de209c1dbb5b064052cedc3 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 27 May 2024 15:54:48 +0200 Subject: [PATCH 12/15] Improve clarity on n vs. k --- packages/crypto/benches/main.rs | 14 ++++++++------ packages/vm/src/imports.rs | 9 +++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/crypto/benches/main.rs b/packages/crypto/benches/main.rs index a3af20d839..7d1d5850a3 100644 --- a/packages/crypto/benches/main.rs +++ b/packages/crypto/benches/main.rs @@ -157,12 +157,14 @@ where .map(|(secret_key, message)| *message * secret_key) .collect(); - for i in 1..=two_pow_max { - let num_points = 2_usize.pow(i); - let messages = &messages[..num_points]; - let keys = &public_keys[..num_points]; + for i in 0..=two_pow_max { + let n = 2_usize.pow(i); // the number of pairings on the left hand side + let k = n + 1; // the number of pairings in total + let messages: &[ark_ec::short_weierstrass::Affine] = + &messages[..n]; + let keys = &public_keys[..n]; let aggregated_signature: G2Affine = - signatures[..num_points].iter().sum::().into(); + signatures[..n].iter().sum::().into(); let serialized_pubkeys: Vec = keys .iter() @@ -187,7 +189,7 @@ where .serialize_compressed(&mut serialized_signature[..]) .unwrap(); - group.bench_function(format!("bls12_381_pairing_equality_{num_points}"), |b| { + group.bench_function(format!("bls12_381_pairing_equality_k={k}"), |b| { b.iter(|| { let is_valid = black_box(bls12_381_pairing_equality( &serialized_pubkeys, diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index 575781cc73..23e4ee6b46 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -372,14 +372,19 @@ pub fn do_bls12_381_pairing_equality< let r = read_region(&memory, r_ptr, BLS12_381_G1_POINT_LEN)?; let s = read_region(&memory, s_ptr, BLS12_381_G2_POINT_LEN)?; - let estimated_point_count = (ps.len() / BLS12_381_G1_POINT_LEN) as u64; + // The values here are only correct if ps and qs can be divided by the point size. + // They are good enough for gas since we error in `bls12_381_pairing_equality` if the inputs are + // not properly formatted. + let estimated_n = (ps.len() / BLS12_381_G1_POINT_LEN) as u64; + // The number of parings to compute (`n` on the left hand side and `k = n + 1` in total) + let estimated_k = estimated_n + 1; let gas_info = GasInfo::with_cost( // Add one to the `estimated_point_count` since we do not include any pairs in the base // benchmark, and we always need to add one for the `r` and `s` pair. data.gas_config .bls12_381_pairing_equality_cost - .total_cost(estimated_point_count + 1), + .total_cost(estimated_k), ); process_gas_info(data, &mut store, gas_info)?; From 089e9a6adb81dd5f8fc8aa599d93c9eeca68d01f Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 27 May 2024 17:01:04 +0200 Subject: [PATCH 13/15] Remove type --- packages/crypto/benches/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/crypto/benches/main.rs b/packages/crypto/benches/main.rs index 7d1d5850a3..afc64cbf13 100644 --- a/packages/crypto/benches/main.rs +++ b/packages/crypto/benches/main.rs @@ -160,8 +160,7 @@ where for i in 0..=two_pow_max { let n = 2_usize.pow(i); // the number of pairings on the left hand side let k = n + 1; // the number of pairings in total - let messages: &[ark_ec::short_weierstrass::Affine] = - &messages[..n]; + let messages = &messages[..n]; let keys = &public_keys[..n]; let aggregated_signature: G2Affine = signatures[..n].iter().sum::().into(); From cc2a777aac8e324fd3d45dd4aba20b7b9dcd9ede Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 27 May 2024 22:43:09 +0200 Subject: [PATCH 14/15] Remove obsolete comment --- packages/vm/src/imports.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index 23e4ee6b46..115cd5f33c 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -380,8 +380,6 @@ pub fn do_bls12_381_pairing_equality< let estimated_k = estimated_n + 1; let gas_info = GasInfo::with_cost( - // Add one to the `estimated_point_count` since we do not include any pairs in the base - // benchmark, and we always need to add one for the `r` and `s` pair. data.gas_config .bls12_381_pairing_equality_cost .total_cost(estimated_k), From ebbe2019943e0005631919a9e8e9b989da68f2cb Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Thu, 30 May 2024 12:54:12 +0200 Subject: [PATCH 15/15] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc946061db..a5fd2f8b48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,8 @@ and this project adheres to - cosmwasm-std: Deprecate "compact" serialization of `Binary`, `HexBinary`, `Checksum` ([#2125]) - cosmwasm-vm: Update wasmer to 4.3.1 ([#2147], [#2153]) +- cosmwasm-vm: Rebalance gas costs for cryptographic functions and wasm + instructions. ([#2152]) [#2044]: https://github.com/CosmWasm/cosmwasm/pull/2044 [#2051]: https://github.com/CosmWasm/cosmwasm/pull/2051 @@ -85,6 +87,7 @@ and this project adheres to [#2108]: https://github.com/CosmWasm/cosmwasm/pull/2108 [#2125]: https://github.com/CosmWasm/cosmwasm/pull/2125 [#2147]: https://github.com/CosmWasm/cosmwasm/pull/2147 +[#2152]: https://github.com/CosmWasm/cosmwasm/pull/2152 [#2153]: https://github.com/CosmWasm/cosmwasm/pull/2153 ## [2.0.1] - 2024-04-03