From a47dde8acf5b31652d3c64660af5ba6844e16012 Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:23:49 -0800 Subject: [PATCH 01/98] fix(nns): Fix for a particular locked neuron (#3311) A neuron was locked, which logged `Inflight commands: { 17912780790050115461: NeuronInFlightCommand { timestamp: 1728911670, command: Some( Spawn( NeuronId { id: 17912780790050115461, }, ), ), }, }` We identified the account as: https://dashboard.internetcomputer.org/account/9765cc69bd6580023bee8fa8280fb630977b9f850da49d73cddcb99512272abb And the neuron can be seen here: https://dashboard.internetcomputer.org/neuron/17912780790050115461 As can be seen, no ICP was minted, but the neuron's cached stake was set and maturity was cleared. The fix is to mint the ICP and unlock the neuron. Fix to prevent this from happening in the future is here: https://github.com/dfinity/ic/pull/3226 --- rs/nns/governance/canister/canister.rs | 15 ++++++ rs/nns/governance/src/governance.rs | 61 ++++++++++++++++++++++ rs/nns/governance/tests/governance.rs | 72 +++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/rs/nns/governance/canister/canister.rs b/rs/nns/governance/canister/canister.rs index 0d343ebe194..5659a616e23 100644 --- a/rs/nns/governance/canister/canister.rs +++ b/rs/nns/governance/canister/canister.rs @@ -167,6 +167,9 @@ fn schedule_timers() { // TODO(NNS1-3446): Delete. (This only needs to be run once, but can safely be run multiple times). schedule_backfill_voting_power_refreshed_timestamps(Duration::from_secs(0)); + + // Schedule the fix for the locked neuron + schedule_locked_spawning_neuron_fix(); } // Seeding interval seeks to find a balance between the need for rng secrecy, and @@ -325,6 +328,18 @@ fn schedule_vote_processing() { }); } +// TODO(NNS1-3526): Remove this method once it is released. +fn schedule_locked_spawning_neuron_fix() { + ic_cdk_timers::set_timer(Duration::from_secs(0), || { + spawn(async { + governance_mut() + .fix_locked_spawn_neuron() + .await + .expect("Failed to fix locked neuron"); + }); + }); +} + struct CanisterEnv { rng: Option, time_warp: GovTimeWarp, diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index d5829c24be5..cb774266a2b 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -7060,6 +7060,67 @@ impl Governance { self.heap_data.spawning_neurons = Some(false); } + // TODO(NNS1-3526): Remove this method once it is released. + pub async fn fix_locked_spawn_neuron(&mut self) -> Result<(), GovernanceError> { + // ID of neuron that was locked when trying to spawn it due to ledger upgrade. + // Neuron's state was updated, but the ledger transaction did not finish. + const TARGETED_LOCK_TIMESTAMP: u64 = 1728911670; + + let id = 17912780790050115461; + let neuron_id = NeuronId { id }; + + let now_seconds = self.env.now(); + + match self.heap_data.in_flight_commands.get(&id) { + None => { + return Ok(()); + } + Some(existing_lock) => { + let NeuronInFlightCommand { + timestamp, + command: _, + } = existing_lock; + + // We check the exact timestamp so that new locks couldn't trigger this condition + // which would allow that neuron to repeatedly mint under the right conditions. + if *timestamp != TARGETED_LOCK_TIMESTAMP { + return Ok(()); + } + } + }; + + let (neuron_stake, subaccount) = self.with_neuron(&neuron_id, |neuron| { + let neuron_stake = neuron.cached_neuron_stake_e8s; + let subaccount = neuron.subaccount(); + (neuron_stake, subaccount) + })?; + + // Mint the ICP + match self + .ledger + .transfer_funds( + neuron_stake, + 0, // Minting transfer don't pay a fee. + None, + neuron_subaccount(subaccount), + now_seconds, + ) + .await + { + Ok(_) => { + self.heap_data.in_flight_commands.remove(&id); + Ok(()) + } + Err(error) => Err(GovernanceError::new_with_message( + ErrorType::Unavailable, + format!( + "Error fixing locked neuron: {:?}. Ledger update failed with err: {:?}.", + neuron_id, error + ), + )), + } + } + /// Return `true` if rewards should be distributed, `false` otherwise fn should_distribute_rewards(&self) -> bool { let latest_distribution_nominal_end_timestamp_seconds = diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index e62a2d89de3..c87cf0268d8 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -136,7 +136,10 @@ use std::{ #[cfg(feature = "tla")] use ic_nns_governance::governance::tla::{check_traces as tla_check_traces, TLA_TRACES_LKEY}; -use ic_nns_governance::storage::reset_stable_memory; +use ic_nns_governance::{ + pb::v1::governance::{neuron_in_flight_command, NeuronInFlightCommand}, + storage::reset_stable_memory, +}; #[cfg(feature = "tla")] use tla_instrumentation_proc_macros::with_tla_trace_check; @@ -14912,3 +14915,70 @@ impl CMC for StubCMC { unimplemented!() } } + +// TODO(NNS1-3526): Remove after deployed and confirmed fix +#[test] +fn test_locked_neuron_is_unlocked_and_icp_is_minted() { + let epoch = DEFAULT_TEST_START_TIMESTAMP_SECONDS + (20 * ONE_YEAR_SECONDS); + let neuron_id = 17912780790050115461; + let mut nns = NNSBuilder::new() + .set_start_time(epoch) + .add_neuron( + NeuronBuilder::new(neuron_id, 1_200_000, PrincipalId::new_user_test_id(42)) + .set_dissolve_state(Some(DissolveState::WhenDissolvedTimestampSeconds(epoch))), + ) + .create(); + + nns.governance.heap_data.in_flight_commands.insert( + neuron_id, + NeuronInFlightCommand { + timestamp: 1728911670, + command: Some(neuron_in_flight_command::Command::Spawn(NeuronId { + id: neuron_id, + })), + }, + ); + + // B/c of how this test is setup, the neuron will have stake. + // We just want to make sure it can only incrase once. + assert_eq!( + nns.get_account_balance(nns.get_neuron_account_id(neuron_id)), + 1_200_000 + ); + + nns.governance + .fix_locked_spawn_neuron() + .now_or_never() + .unwrap() + .expect("Failed to fix locked spawn neuron"); + + assert_eq!(nns.governance.heap_data.in_flight_commands.len(), 0); + assert_eq!( + nns.get_account_balance(nns.get_neuron_account_id(neuron_id)), + 1_200_000 * 2 + ); + + // Nothing happens if you call it again with a differnt lock time. + nns.governance.heap_data.in_flight_commands.insert( + neuron_id, + NeuronInFlightCommand { + timestamp: 1728911671, + command: Some(neuron_in_flight_command::Command::Spawn(NeuronId { + id: neuron_id, + })), + }, + ); + nns.governance + .fix_locked_spawn_neuron() + .now_or_never() + .unwrap() + .expect("Failed to fix locked spawn neuron"); + + // Lock is not cleared b/c we didn't target that lock + assert_eq!(nns.governance.heap_data.in_flight_commands.len(), 1); + // Balance doesn't change this time. + assert_eq!( + nns.get_account_balance(nns.get_neuron_account_id(neuron_id)), + 1_200_000 * 2 + ); +} From ea0222cc29b890a12b7b8364b6473533ad121568 Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:39:16 -0800 Subject: [PATCH 02/98] refactor(nns): Change Root interface crate to use ic-cdk (#3306) --- Cargo.lock | 2 -- rs/nns/handlers/root/interface/BUILD.bazel | 2 -- rs/nns/handlers/root/interface/Cargo.toml | 2 -- rs/nns/handlers/root/interface/src/client.rs | 17 +++++++++-------- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee7494c9f2e..6f0f534c2cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10416,8 +10416,6 @@ version = "0.1.0" dependencies = [ "async-trait", "candid", - "dfn_candid", - "dfn_core", "ic-base-types", "ic-cdk 0.16.0", "ic-nervous-system-clients", diff --git a/rs/nns/handlers/root/interface/BUILD.bazel b/rs/nns/handlers/root/interface/BUILD.bazel index f53e8c3f2a6..f567f6c99f3 100644 --- a/rs/nns/handlers/root/interface/BUILD.bazel +++ b/rs/nns/handlers/root/interface/BUILD.bazel @@ -6,8 +6,6 @@ DEPENDENCIES = [ # Keep sorted. "//rs/nervous_system/clients", "//rs/nns/constants", - "//rs/rust_canisters/dfn_candid", - "//rs/rust_canisters/dfn_core", "//rs/types/base_types", "@crate_index//:candid", "@crate_index//:ic-cdk", diff --git a/rs/nns/handlers/root/interface/Cargo.toml b/rs/nns/handlers/root/interface/Cargo.toml index 4771015fc9c..1cdfcb55352 100644 --- a/rs/nns/handlers/root/interface/Cargo.toml +++ b/rs/nns/handlers/root/interface/Cargo.toml @@ -6,8 +6,6 @@ edition = "2021" [dependencies] async-trait = { workspace = true } candid = { workspace = true } -dfn_candid = { path = "../../../../rust_canisters/dfn_candid" } -dfn_core = { path = "../../../../rust_canisters/dfn_core" } ic-base-types = { path = "../../../../types/base_types" } ic-cdk = { workspace = true } ic-nervous-system-clients = { path = "../../../../nervous_system/clients" } diff --git a/rs/nns/handlers/root/interface/src/client.rs b/rs/nns/handlers/root/interface/src/client.rs index 09d556152c0..50707e62002 100644 --- a/rs/nns/handlers/root/interface/src/client.rs +++ b/rs/nns/handlers/root/interface/src/client.rs @@ -3,9 +3,8 @@ use crate::{ ChangeCanisterControllersResponse, ChangeCanisterControllersResult, }; use async_trait::async_trait; -use dfn_candid::candid_one; -use dfn_core::call; use ic_base_types::PrincipalId; +use ic_cdk::call; use ic_nervous_system_clients::{ canister_id_record::CanisterIdRecord, canister_status::{ @@ -44,12 +43,13 @@ impl NnsRootCanisterClient for NnsRootCanisterClientImpl { change_canister_controllers_request: ChangeCanisterControllersRequest, ) -> Result, String)> { call( - ROOT_CANISTER_ID, + ROOT_CANISTER_ID.get().0, "change_canister_controllers", - candid_one, - change_canister_controllers_request, + (change_canister_controllers_request,), ) .await + .map(|(response,): (ChangeCanisterControllersResponse,)| response) + .map_err(|(code, message)| (Some(code as i32), message)) } async fn canister_status( @@ -57,12 +57,13 @@ impl NnsRootCanisterClient for NnsRootCanisterClientImpl { canister_id_record: CanisterIdRecord, ) -> Result, String)> { call( - ROOT_CANISTER_ID, + ROOT_CANISTER_ID.get().0, "canister_status", - candid_one, - canister_id_record, + (canister_id_record,), ) .await + .map(|(response,): (CanisterStatusResult,)| response) + .map_err(|(code, message)| (Some(code as i32), message)) } } From a18576a759ec221ec37d7b0cff17a81941127f61 Mon Sep 17 00:00:00 2001 From: jasonz-dfinity <133917836+jasonz-dfinity@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:26:19 -0800 Subject: [PATCH 03/98] feat(nns): Make neuron migration to stable memory reversible (#3344) We are about to migrate neurons from heap memory to stable memory. If anything goes wrong, we'd like to reverse the migration by setting their target location from `Stable` to `Heap`. Previously the `adjust_neuron_storage` procedure only looks at the neurons in the heap, and therefore it can only move neurons from heap memory to stable memory if the target location is different from where they are. In order to make the reverse migration possible, we look at the neurons in the stable memory during `adjust_neuron_storage`. Testing: ` //rs/nns/integration_tests:integration_tests_test_src/governance_migrations` still passes (which fails if `schedule_adjust_neurons_storage` is commented out) --- rs/nns/governance/canister/canister.rs | 20 +++---- rs/nns/governance/src/governance.rs | 8 ++- rs/nns/governance/src/neuron_store.rs | 59 ++----------------- .../src/neuron_store/neuron_store_tests.rs | 59 +++++++++---------- 4 files changed, 46 insertions(+), 100 deletions(-) diff --git a/rs/nns/governance/canister/canister.rs b/rs/nns/governance/canister/canister.rs index 5659a616e23..27aebf8d450 100644 --- a/rs/nns/governance/canister/canister.rs +++ b/rs/nns/governance/canister/canister.rs @@ -158,7 +158,7 @@ fn set_governance(gov: Governance) { fn schedule_timers() { schedule_seeding(Duration::from_nanos(0)); - schedule_adjust_neurons_storage(Duration::from_nanos(0), NeuronIdProto { id: 0 }); + schedule_adjust_neurons_storage(Duration::from_nanos(0), Bound::Unbounded); schedule_prune_following(Duration::from_secs(0), Bound::Unbounded); schedule_spawn_neurons(); schedule_unstake_maturity_of_dissolved_neurons(); @@ -280,19 +280,15 @@ const ADJUST_NEURON_STORAGE_BATCH_INTERVAL: Duration = Duration::from_secs(5); // id. const ADJUST_NEURON_STORAGE_ROUND_INTERVAL: Duration = Duration::from_secs(3600); -fn schedule_adjust_neurons_storage(delay: Duration, start_neuron_id: NeuronIdProto) { +fn schedule_adjust_neurons_storage(delay: Duration, next: Bound) { ic_cdk_timers::set_timer(delay, move || { - let next_neuron_id = governance_mut().batch_adjust_neurons_storage(start_neuron_id); - match next_neuron_id { - Some(next_neuron_id) => schedule_adjust_neurons_storage( - ADJUST_NEURON_STORAGE_BATCH_INTERVAL, - next_neuron_id, - ), - None => schedule_adjust_neurons_storage( - ADJUST_NEURON_STORAGE_ROUND_INTERVAL, - NeuronIdProto { id: 0 }, - ), + let next = governance_mut().batch_adjust_neurons_storage(next); + let next_delay = if next == Bound::Unbounded { + ADJUST_NEURON_STORAGE_ROUND_INTERVAL + } else { + ADJUST_NEURON_STORAGE_BATCH_INTERVAL }; + schedule_adjust_neurons_storage(next_delay, next); }); } diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index cb774266a2b..f34f522b23c 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -7345,9 +7345,11 @@ impl Governance { }) } - pub fn batch_adjust_neurons_storage(&mut self, start_neuron_id: NeuronId) -> Option { - self.neuron_store - .batch_adjust_neurons_storage(start_neuron_id) + pub fn batch_adjust_neurons_storage( + &mut self, + next: std::ops::Bound, + ) -> std::ops::Bound { + self.neuron_store.batch_adjust_neurons_storage(next) } /// Recompute cached metrics once per day diff --git a/rs/nns/governance/src/neuron_store.rs b/rs/nns/governance/src/neuron_store.rs index 41cd5eaba12..dfbb49d773e 100644 --- a/rs/nns/governance/src/neuron_store.rs +++ b/rs/nns/governance/src/neuron_store.rs @@ -624,68 +624,17 @@ impl NeuronStore { /// Adjusts the storage location of neurons, since active neurons might become inactive due to /// passage of time. - pub fn batch_adjust_neurons_storage(&mut self, start_neuron_id: NeuronId) -> Option { - static BATCH_SIZE_FOR_MOVING_NEURONS: usize = 200; - + pub fn batch_adjust_neurons_storage(&mut self, next: Bound) -> Bound { #[cfg(target_arch = "wasm32")] static MAX_NUM_INSTRUCTIONS_PER_BATCH: u64 = 1_000_000_000; #[cfg(target_arch = "wasm32")] - let max_instructions_reached = - || ic_cdk::api::instruction_counter() >= MAX_NUM_INSTRUCTIONS_PER_BATCH; + let carry_on = || ic_cdk::api::instruction_counter() < MAX_NUM_INSTRUCTIONS_PER_BATCH; #[cfg(not(target_arch = "wasm32"))] - let max_instructions_reached = || false; - - self.adjust_neuron_storage_with_max_instructions( - start_neuron_id, - BATCH_SIZE_FOR_MOVING_NEURONS, - max_instructions_reached, - ) - } - - fn adjust_neuron_storage_with_max_instructions( - &mut self, - start_neuron_id: NeuronId, - max_batch_size: usize, - max_instructions_reached: impl Fn() -> bool, - ) -> Option { - // We currently only move neurons from heap to stable storage, since it's impossible to have - // active neurons in stable storage. In the future, we might need to move neurons from - // stable storage to heap as a rollback mechanism, but it is not implemented here yet. - let neuron_ids: Vec<_> = self - .heap_neurons - .range(start_neuron_id.id..) - .take(max_batch_size) - .map(|(id, _)| NeuronId { id: *id }) - .collect(); - // We know it is the last batch if the number of neurons is less than the batch size. - let is_last_batch = neuron_ids.len() < max_batch_size; - - if neuron_ids.is_empty() { - return None; - } + let carry_on = || true; - let mut next_neuron_id = Some(start_neuron_id); - - for neuron_id in neuron_ids { - if max_instructions_reached() { - // We don't need to look at the `is_last_batch` because at least one neuron is - // skipped due to instruction limit. - return next_neuron_id; - } - - // We don't modify the neuron, but the below just makes sure that the neuron is in the - // appropriate storage location given its state and the current time. - let _ = self.with_neuron_mut(&neuron_id, |_| {}); - next_neuron_id = neuron_id.next(); - } - - if is_last_batch { - None - } else { - next_neuron_id - } + groom_some_neurons(self, |_| {}, next, carry_on) } fn remove_neuron_from_indexes(&mut self, neuron: &Neuron) { diff --git a/rs/nns/governance/src/neuron_store/neuron_store_tests.rs b/rs/nns/governance/src/neuron_store/neuron_store_tests.rs index cc62bdc363e..879c1019e2d 100644 --- a/rs/nns/governance/src/neuron_store/neuron_store_tests.rs +++ b/rs/nns/governance/src/neuron_store/neuron_store_tests.rs @@ -944,30 +944,20 @@ fn test_batch_adjust_neurons_storage() { warp_time_to_make_neuron_inactive(&mut neuron_store); // Step 1.5: define a lambda which always returns false, for checking instructions. - let always_false = || false; + let always_true = || true; // Step 1.6: make sure the counts of neurons in heap and stable are expected. assert_eq!(neuron_store.heap_neuron_store_len(), 10); assert_eq!(neuron_store.stable_neuron_store_len(), 0); - // Step 2: adjust the storage of neurons for the first 6 neurons and verifies the counts. Since - // the first 5 neurons are active because of their stake, only 1 neuron is moved. - let next_neuron_id = neuron_store.adjust_neuron_storage_with_max_instructions( - NeuronId { id: 0 }, - 6, - always_false, + // Step 2: adjust the storage of neurons and verifies the counts. + let next_neuron_id = groom_some_neurons( + &mut neuron_store, + |_| {}, + Bound::Excluded(NeuronId { id: 0 }), + always_true, ); - assert_eq!(next_neuron_id, Some(NeuronId { id: 7 })); - assert_eq!(neuron_store.heap_neuron_store_len(), 9); - assert_eq!(neuron_store.stable_neuron_store_len(), 1); - - // Step 3: adjust the storage of neurons for the rest of 4 neurons and verifies the counts. - let next_neuron_id = neuron_store.adjust_neuron_storage_with_max_instructions( - NeuronId { id: 7 }, - 6, - always_false, - ); - assert_eq!(next_neuron_id, None); + assert_eq!(next_neuron_id, Bound::Unbounded); assert_eq!(neuron_store.heap_neuron_store_len(), 5); assert_eq!(neuron_store.stable_neuron_store_len(), 5); } @@ -995,26 +985,35 @@ fn test_batch_adjust_neurons_storage_exceeds_instructions_limit() { assert_eq!(neuron_store.heap_neuron_store_len(), 5); assert_eq!(neuron_store.stable_neuron_store_len(), 0); - // Step 2: adjust the storage of neurons for the first 10 neurons, however, the instruction - // limit checker returns true for the 4th time it's called, allowing moving only 3 neurons. + // Step 2: adjust the storage of neurons for the first 10 neurons, however, the `carry_on` + // returns false for the 3rd time it's called, allowing `groom_some_neurons` continue 2 times, + // moving only 3 neurons. let counter = Cell::new(0); - let next_neuron_id = - neuron_store.adjust_neuron_storage_with_max_instructions(NeuronId { id: 0 }, 10, || { + let next_neuron_id = groom_some_neurons( + &mut neuron_store, + |_| {}, + Bound::Excluded(NeuronId { id: 0 }), + || { counter.set(counter.get() + 1); - counter.get() > 3 - }); - assert_eq!(next_neuron_id, Some(NeuronId { id: 4 })); + counter.get() <= 2 + }, + ); + assert_eq!(next_neuron_id, Bound::Excluded(NeuronId { id: 3 })); assert_eq!(neuron_store.heap_neuron_store_len(), 2); assert_eq!(neuron_store.stable_neuron_store_len(), 3); // Step 3: adjust the storage of neurons for the rest of 4 neurons and verifies the counts. let counter = Cell::new(0); - let next_neuron_id = - neuron_store.adjust_neuron_storage_with_max_instructions(NeuronId { id: 4 }, 10, || { + let next_neuron_id = groom_some_neurons( + &mut neuron_store, + |_| {}, + Bound::Excluded(NeuronId { id: 3 }), + || { counter.set(counter.get() + 1); - counter.get() > 3 - }); - assert_eq!(next_neuron_id, None); + counter.get() <= 2 + }, + ); + assert_eq!(next_neuron_id, Bound::Unbounded); assert_eq!(neuron_store.heap_neuron_store_len(), 0); assert_eq!(neuron_store.stable_neuron_store_len(), 5); } From 3f4397cf562443a220b88121af920bc1a385c836 Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:47:06 -0800 Subject: [PATCH 04/98] fix(nns): Fix maturity for neurons that temporarily fail to spawn (#3323) A previous pull request sets the maturity to the modulated amount, when it should be set to the original amount so that modulation is not applied more than once. --------- Co-authored-by: oggy-dfin <89794951+oggy-dfin@users.noreply.github.com> --- rs/nns/governance/src/governance.rs | 6 +- rs/nns/governance/tests/fake.rs | 50 ++++++++++- rs/nns/governance/tests/governance.rs | 121 ++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 5 deletions(-) diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index f34f522b23c..945cd736477 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -6946,11 +6946,11 @@ impl Governance { .with_neuron(&neuron_id, |neuron| neuron.clone()) .expect("Neuron should exist, just found in list"); - let maturity = neuron.maturity_e8s_equivalent; + let original_maturity = neuron.maturity_e8s_equivalent; let subaccount = neuron.subaccount(); let neuron_stake: u64 = match apply_maturity_modulation( - maturity, + original_maturity, maturity_modulation, ) { Ok(neuron_stake) => neuron_stake, @@ -7019,7 +7019,7 @@ impl Governance { error, ); match self.with_neuron_mut(&neuron_id, |neuron| { - neuron.maturity_e8s_equivalent = neuron_stake; + neuron.maturity_e8s_equivalent = original_maturity; neuron.cached_neuron_stake_e8s = 0; neuron.spawn_at_timestamp_seconds = original_spawn_at_timestamp_seconds; diff --git a/rs/nns/governance/tests/fake.rs b/rs/nns/governance/tests/fake.rs index c5b4fffa5ca..6917631dddf 100644 --- a/rs/nns/governance/tests/fake.rs +++ b/rs/nns/governance/tests/fake.rs @@ -105,6 +105,7 @@ impl Default for FakeState { /// advanced, and ledger accounts manipulated. pub struct FakeDriver { pub state: Arc>, + pub error_on_next_ledger_call: Arc>>, } /// Create a default mock driver. @@ -112,6 +113,7 @@ impl Default for FakeDriver { fn default() -> Self { Self { state: Arc::new(Mutex::new(Default::default())), + error_on_next_ledger_call: Arc::new(Mutex::new(None)), } } } @@ -181,6 +183,7 @@ impl FakeDriver { pub fn get_fake_env(&self) -> Box { Box::new(FakeDriver { state: Arc::clone(&self.state), + error_on_next_ledger_call: Arc::clone(&self.error_on_next_ledger_call), }) } @@ -188,12 +191,14 @@ impl FakeDriver { pub fn get_fake_ledger(&self) -> Box { Box::new(FakeDriver { state: Arc::clone(&self.state), + error_on_next_ledger_call: Arc::clone(&self.error_on_next_ledger_call), }) } pub fn get_fake_cmc(&self) -> Box { Box::new(FakeDriver { state: Arc::clone(&self.state), + error_on_next_ledger_call: Arc::clone(&self.error_on_next_ledger_call), }) } @@ -241,6 +246,13 @@ impl FakeDriver { num_accounts ); } + + pub fn fail_next_ledger_call(&self) { + self.error_on_next_ledger_call + .lock() + .unwrap() + .replace(NervousSystemError::new()); + } } #[async_trait] @@ -276,6 +288,18 @@ impl IcpLedger for FakeDriver { ])) ); + if let Some(err) = self.error_on_next_ledger_call.lock().unwrap().take() { + println!("Failing the ledger transfer because we were instructed to fail the next ledger call"); + tla_log_response!( + Destination::new("ledger"), + tla::TlaValue::Variant { + tag: "Fail".to_string(), + value: Box::new(tla::TlaValue::Constant("UNIT".to_string())) + } + ); + return Err(err); + } + let accounts = &mut self.state.try_lock().unwrap().accounts; let from_e8s = accounts @@ -286,6 +310,13 @@ impl IcpLedger for FakeDriver { if !is_minting_operation { if *from_e8s < requested_e8s { + tla_log_response!( + Destination::new("ledger"), + tla::TlaValue::Variant { + tag: "Fail".to_string(), + value: Box::new(tla::TlaValue::Constant("UNIT".to_string())) + } + ); return Err(NervousSystemError::new_with_message(format!( "Insufficient funds. Available {} requested {}", *from_e8s, requested_e8s @@ -307,6 +338,10 @@ impl IcpLedger for FakeDriver { } async fn total_supply(&self) -> Result { + if let Some(err) = self.error_on_next_ledger_call.lock().unwrap().take() { + return Err(err); + } + Ok(self.get_supply()) } @@ -314,8 +349,6 @@ impl IcpLedger for FakeDriver { &self, account: AccountIdentifier, ) -> Result { - let accounts = &mut self.state.try_lock().unwrap().accounts; - tla_log_request!( "WaitForBalanceQuery", Destination::new("ledger"), @@ -326,6 +359,19 @@ impl IcpLedger for FakeDriver { )])) ); + if let Some(err) = self.error_on_next_ledger_call.lock().unwrap().take() { + tla_log_response!( + Destination::new("ledger"), + tla::TlaValue::Variant { + tag: "Fail".to_string(), + value: Box::new(tla::TlaValue::Constant("UNIT".to_string())), + } + ); + return Err(err); + } + + let accounts = &mut self.state.try_lock().unwrap().accounts; + let account_e8s = accounts.get(&account).unwrap_or(&0); tla_log_response!( Destination::new("ledger"), diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index c87cf0268d8..e77a5f19802 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -6233,6 +6233,127 @@ fn test_neuron_spawn_with_subaccount() { assert_eq!(child_neuron.maturity_e8s_equivalent, 0); } +#[test] +fn test_maturity_correctly_reset_if_spawn_fails() { + let from = *TEST_NEURON_1_OWNER_PRINCIPAL; + // Compute the subaccount to which the transfer would have been made + let nonce = 1234u64; + + let block_height = 543212234; + let dissolve_delay_seconds = MIN_DISSOLVE_DELAY_FOR_VOTE_ELIGIBILITY_SECONDS; + let neuron_stake_e8s = 1_000_000_000; + + let (mut driver, mut gov, id, _) = governance_with_staked_neuron( + dissolve_delay_seconds, + neuron_stake_e8s, + block_height, + from, + nonce, + ); + run_periodic_tasks_often_enough_to_update_maturity_modulation(&mut gov); + + let now = driver.now(); + assert_eq!( + gov.with_neuron(&id, |neuron| neuron + .get_neuron_info(gov.voting_power_economics(), now, *RANDOM_PRINCIPAL_ID) + .state()) + .unwrap(), + NeuronState::NotDissolving + ); + + // Artificially set the neuron's maturity to sufficient value + let parent_maturity_e8s_equivalent: u64 = 123_456_789; + assert!( + parent_maturity_e8s_equivalent + > NetworkEconomics::with_default_values().neuron_minimum_stake_e8s + ); + gov.with_neuron_mut(&id, |neuron| { + neuron.maturity_e8s_equivalent = parent_maturity_e8s_equivalent; + }) + .expect("Neuron did not exist"); + + // Advance the time so that we can check that the spawned neuron has the age + // and the right creation timestamp + driver.advance_time_by(1); + + // Nonce used for spawn (given as input). + let nonce_spawn = driver.random_u64().expect("Could not get random number"); + + let child_controller = *TEST_NEURON_2_OWNER_PRINCIPAL; + + let child_nid = gov + .spawn_neuron( + &id, + &from, + &Spawn { + new_controller: Some(child_controller), + nonce: Some(nonce_spawn), + percentage_to_spawn: None, + }, + ) + .unwrap(); + + let creation_timestamp = driver.now(); + + // We should now have 2 neurons. + assert_eq!(gov.neuron_store.len(), 2); + // And we should have one ledger accounts. + driver.assert_num_neuron_accounts_exist(1); + + // Running periodic tasks shouldn't cause the ICP to be minted. + gov.maybe_spawn_neurons().now_or_never().unwrap(); + driver.assert_num_neuron_accounts_exist(1); + + let parent_neuron = gov + .with_neuron(&id, |neuron| neuron.clone()) + .expect("The parent neuron is missing"); + // Maturity on the parent neuron should be reset. + assert_eq!(parent_neuron.maturity_e8s_equivalent, 0); + + // Advance the time by one week, should cause the neuron's ICP + // to be minted. + driver.advance_time_by(7 * 86400); + driver.fail_next_ledger_call(); + + gov.maybe_spawn_neurons().now_or_never().unwrap(); + + //Driver should fail to finish spawning neurons now (i.e. minting) b/c ledger returns error + + driver.assert_num_neuron_accounts_exist(1); + + let child_neuron = gov + .get_full_neuron(&child_nid, &child_controller) + .expect("The child neuron is missing"); + + assert_eq!(child_neuron.created_timestamp_seconds, creation_timestamp); + assert_eq!(child_neuron.aging_since_timestamp_seconds, u64::MAX); + assert_eq!(child_neuron.spawn_at_timestamp_seconds, Some(1730737555)); + assert_eq!( + child_neuron.dissolve_state, + Some(DissolveState::WhenDissolvedTimestampSeconds( + creation_timestamp + + gov + .heap_data + .economics + .as_ref() + .unwrap() + .neuron_spawn_dissolve_delay_seconds + )) + ); + assert_eq!(child_neuron.kyc_verified, true); + assert_eq!(child_neuron.cached_neuron_stake_e8s, 0); + // We expect maturity modulation of 100 basis points, which is 1%, because of the + // result returned from FakeDriver when pretending to be CMC. + assert_eq!( + gov.heap_data + .cached_daily_maturity_modulation_basis_points + .unwrap(), + 100 + ); + // The value here should be reset to the original value, without being modulated. + assert_eq!(child_neuron.maturity_e8s_equivalent, 123_456_789); +} + /// Checks that: /// * Specifying a percentage_to_spawn different from 100 lead to the proper fractional maturity /// to be spawned. From 21c5e93de63d1a13df218e6890f919cc5ec3b44b Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Tue, 7 Jan 2025 10:57:32 +0100 Subject: [PATCH 05/98] feat(PocketIC): optionally check caller when retrieving ingress status (#3341) This PR extends the PocketIC functionality of retrieving ingress status with an optional caller: if provided and if a corresponding read state request for the status of the same update call signed by that specified caller was rejected because the update call was submitted by a different caller, then an error is returned. To distinguish between the ingress status not being available and forbidden due to the new error condition introduced by this PR, a new enumeration `IngressStatusResult` is introduced in the PocketIC library. --- packages/pocket-ic/CHANGELOG.md | 2 +- packages/pocket-ic/src/common/rest.rs | 6 ++ packages/pocket-ic/src/lib.rs | 17 ++- packages/pocket-ic/src/nonblocking.rs | 112 ++++++++++++++------ packages/pocket-ic/tests/tests.rs | 92 ++++++++++++++-- rs/pocket_ic_server/CHANGELOG.md | 2 + rs/pocket_ic_server/src/pocket_ic.rs | 48 ++++++--- rs/pocket_ic_server/src/state_api/routes.rs | 28 ++++- rs/pocket_ic_server/src/state_api/state.rs | 4 + rs/state_machine_tests/src/lib.rs | 5 + 10 files changed, 248 insertions(+), 68 deletions(-) diff --git a/packages/pocket-ic/CHANGELOG.md b/packages/pocket-ic/CHANGELOG.md index 1bf0fe02b18..80f45471327 100644 --- a/packages/pocket-ic/CHANGELOG.md +++ b/packages/pocket-ic/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - The function `PocketIcBuilder::with_bitcoind_addrs` to specify multiple addresses and ports at which `bitcoind` processes are listening. - The function `PocketIc::query_call_with_effective_principal` for making generic query calls (including management canister query calls). -- The function `PocketIc::ingress_status` to fetch the status of an update call submitted through an ingress message (`None` means that the status is unknown yet). +- The function `PocketIc::ingress_status` to fetch the status of an update call submitted through an ingress message. - The function `PocketIc::await_call_no_ticks` to await the status of an update call (submitted through an ingress message) becoming known without triggering round execution (round execution must be triggered separarely, e.g., on a "live" instance or by separate PocketIC library calls). diff --git a/packages/pocket-ic/src/common/rest.rs b/packages/pocket-ic/src/common/rest.rs index b33c5f54a6f..a99c2241db5 100644 --- a/packages/pocket-ic/src/common/rest.rs +++ b/packages/pocket-ic/src/common/rest.rs @@ -122,6 +122,12 @@ pub struct RawMessageId { pub message_id: Vec, } +#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] +pub struct RawIngressStatusArgs { + pub raw_message_id: RawMessageId, + pub raw_caller: Option, +} + #[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] pub enum RawSubmitIngressResult { Ok(RawMessageId), diff --git a/packages/pocket-ic/src/lib.rs b/packages/pocket-ic/src/lib.rs index e647de89523..393be384e36 100644 --- a/packages/pocket-ic/src/lib.rs +++ b/packages/pocket-ic/src/lib.rs @@ -681,9 +681,10 @@ impl PocketIc { pub fn ingress_status( &self, message_id: RawMessageId, - ) -> Option> { + caller: Option, + ) -> IngressStatusResult { let runtime = self.runtime.clone(); - runtime.block_on(async { self.pocket_ic.ingress_status(message_id).await }) + runtime.block_on(async { self.pocket_ic.ingress_status(message_id, caller).await }) } /// Await an update call submitted previously by `submit_call` or `submit_call_with_effective_principal`. @@ -1525,6 +1526,18 @@ pub enum CallError { UserError(UserError), } +/// This enum describes the result of retrieving ingress status. +/// The `IngressStatusResult::Forbidden` variant is produced +/// if an optional caller is provided and a corresponding read state request +/// for the status of the same update call signed by that specified caller +/// was rejected because the update call was submitted by a different caller. +#[derive(Debug, Serialize, Deserialize)] +pub enum IngressStatusResult { + NotAvailable, + Forbidden(String), + Success(Result), +} + /// This struct describes the different types that executing a WASM function in /// a canister can produce. #[derive(PartialOrd, Ord, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/packages/pocket-ic/src/nonblocking.rs b/packages/pocket-ic/src/nonblocking.rs index 9f7fbcdb13e..80d119bdf46 100644 --- a/packages/pocket-ic/src/nonblocking.rs +++ b/packages/pocket-ic/src/nonblocking.rs @@ -3,9 +3,10 @@ use crate::common::rest::{ CreateHttpGatewayResponse, CreateInstanceResponse, ExtendedSubnetConfigSet, HttpGatewayBackend, HttpGatewayConfig, HttpGatewayInfo, HttpsConfig, InstanceConfig, InstanceId, MockCanisterHttpResponse, RawAddCycles, RawCanisterCall, RawCanisterHttpRequest, RawCanisterId, - RawCanisterResult, RawCycles, RawEffectivePrincipal, RawMessageId, RawMockCanisterHttpResponse, - RawPrincipalId, RawSetStableMemory, RawStableMemory, RawSubmitIngressResult, RawSubnetId, - RawTime, RawVerifyCanisterSigArg, RawWasmResult, SubnetId, Topology, + RawCanisterResult, RawCycles, RawEffectivePrincipal, RawIngressStatusArgs, RawMessageId, + RawMockCanisterHttpResponse, RawPrincipalId, RawSetStableMemory, RawStableMemory, + RawSubmitIngressResult, RawSubnetId, RawTime, RawVerifyCanisterSigArg, RawWasmResult, SubnetId, + Topology, }; use crate::management_canister::{ CanisterId, CanisterIdRecord, CanisterInstallMode, CanisterInstallModeUpgradeInner, @@ -16,7 +17,7 @@ use crate::management_canister::{ TakeCanisterSnapshotArgs, UpdateSettingsArgs, UploadChunkArgs, UploadChunkResult, }; pub use crate::DefaultEffectiveCanisterIdError; -use crate::{CallError, PocketIcBuilder, UserError, WasmResult}; +use crate::{CallError, IngressStatusResult, PocketIcBuilder, UserError, WasmResult}; use backoff::backoff::Backoff; use backoff::{ExponentialBackoff, ExponentialBackoffBuilder}; use candid::{ @@ -599,17 +600,31 @@ impl PocketIc { /// or a round has been executed due to a separate PocketIC library call. pub async fn ingress_status( &self, - message_id: RawMessageId, - ) -> Option> { + raw_message_id: RawMessageId, + caller: Option, + ) -> IngressStatusResult { let endpoint = "read/ingress_status"; - let result: Option = self.post(endpoint, message_id).await; - result.map(|result| match result { - RawCanisterResult::Ok(raw_wasm_result) => match raw_wasm_result { - RawWasmResult::Reply(data) => Ok(WasmResult::Reply(data)), - RawWasmResult::Reject(text) => Ok(WasmResult::Reject(text)), - }, - RawCanisterResult::Err(user_error) => Err(user_error), - }) + let raw_ingress_status_args = RawIngressStatusArgs { + raw_message_id, + raw_caller: caller.map(|caller| caller.into()), + }; + match self.try_post(endpoint, raw_ingress_status_args).await { + Ok(None) => IngressStatusResult::NotAvailable, + Ok(Some(raw_result)) => { + let result = match raw_result { + RawCanisterResult::Ok(raw_wasm_result) => match raw_wasm_result { + RawWasmResult::Reply(data) => Ok(WasmResult::Reply(data)), + RawWasmResult::Reject(text) => Ok(WasmResult::Reject(text)), + }, + RawCanisterResult::Err(user_error) => Err(user_error), + }; + IngressStatusResult::Success(result) + } + Err((status, message)) => { + assert_eq!(status, StatusCode::FORBIDDEN, "HTTP error code {} for PocketIc::ingress_status is not StatusCode::FORBIDDEN. This is a bug!", status); + IngressStatusResult::Forbidden(message) + } + } } /// Await an update call submitted previously by `submit_call` or `submit_call_with_effective_principal`. @@ -625,7 +640,9 @@ impl PocketIc { .with_multiplier(2.0) .build(); loop { - if let Some(ingress_status) = self.ingress_status(message_id.clone()).await { + if let IngressStatusResult::Success(ingress_status) = + self.ingress_status(message_id.clone(), None).await + { break ingress_status; } tokio::time::sleep(retry_policy.next_backoff().unwrap()).await; @@ -1361,12 +1378,29 @@ impl PocketIc { self.request(HttpMethod::Post, endpoint, body).await } + async fn try_post( + &self, + endpoint: &str, + body: B, + ) -> Result { + self.try_request(HttpMethod::Post, endpoint, body).await + } + async fn request( &self, http_method: HttpMethod, endpoint: &str, body: B, ) -> T { + self.try_request(http_method, endpoint, body).await.unwrap() + } + + async fn try_request( + &self, + http_method: HttpMethod, + endpoint: &str, + body: B, + ) -> Result { // we may have to try several times if the instance is busy let start = std::time::SystemTime::now(); loop { @@ -1377,9 +1411,10 @@ impl PocketIc { HttpMethod::Post => reqwest_client.post(url).json(&body), }; let result = builder.send().await.expect("HTTP failure"); + let status = result.status(); match ApiResponse::<_>::from_response(result).await { - ApiResponse::Success(t) => break t, - ApiResponse::Error { message } => panic!("{}", message), + ApiResponse::Success(t) => break Ok(t), + ApiResponse::Error { message } => break Err((status, message)), ApiResponse::Busy { state_label, op_id } => { debug!( "instance_id={} Instance is busy (with a different computation): state_label: {}, op_id: {}", @@ -1404,24 +1439,31 @@ impl PocketIc { .send() .await .expect("HTTP failure"); - match ApiResponse::<_>::from_response(result).await { - ApiResponse::Error { message } => { - debug!("Polling has not succeeded yet: {}", message) - } - ApiResponse::Success(t) => { - return t; - } - ApiResponse::Started { state_label, op_id } => { - warn!( - "instance_id={} unexpected Started({} {})", - self.instance_id, state_label, op_id - ); - } - ApiResponse::Busy { state_label, op_id } => { - warn!( - "instance_id={} unexpected Busy({} {})", - self.instance_id, state_label, op_id - ); + if result.status() == reqwest::StatusCode::NOT_FOUND { + let message = + String::from_utf8(result.bytes().await.unwrap().to_vec()).unwrap(); + debug!("Polling has not succeeded yet: {}", message); + } else { + let status = result.status(); + match ApiResponse::<_>::from_response(result).await { + ApiResponse::Error { message } => { + return Err((status, message)); + } + ApiResponse::Success(t) => { + return Ok(t); + } + ApiResponse::Started { state_label, op_id } => { + warn!( + "instance_id={} unexpected Started({} {})", + self.instance_id, state_label, op_id + ); + } + ApiResponse::Busy { state_label, op_id } => { + warn!( + "instance_id={} unexpected Busy({} {})", + self.instance_id, state_label, op_id + ); + } } } if let Some(max_request_time_ms) = self.max_request_time_ms { diff --git a/packages/pocket-ic/tests/tests.rs b/packages/pocket-ic/tests/tests.rs index 56389585740..295ed91d115 100644 --- a/packages/pocket-ic/tests/tests.rs +++ b/packages/pocket-ic/tests/tests.rs @@ -1,4 +1,7 @@ use candid::{decode_one, encode_one, CandidType, Decode, Deserialize, Encode, Principal}; +use ic_certification::Label; +use ic_transport_types::Envelope; +use ic_transport_types::EnvelopeContent::ReadState; use pocket_ic::management_canister::{ CanisterId, CanisterIdRecord, CanisterInstallMode, CanisterSettings, EcdsaPublicKeyResult, HttpRequestResult, ProvisionalCreateCanisterWithCyclesArgs, SchnorrAlgorithm, @@ -9,11 +12,12 @@ use pocket_ic::{ BlobCompression, CanisterHttpReply, CanisterHttpResponse, MockCanisterHttpResponse, RawEffectivePrincipal, SubnetKind, }, - query_candid, update_candid, DefaultEffectiveCanisterIdError, ErrorCode, PocketIc, - PocketIcBuilder, WasmResult, + query_candid, update_candid, DefaultEffectiveCanisterIdError, ErrorCode, IngressStatusResult, + PocketIc, PocketIcBuilder, WasmResult, }; #[cfg(unix)] use reqwest::blocking::Client; +use serde::Serialize; use sha2::{Digest, Sha256}; use std::{io::Read, time::SystemTime}; @@ -2009,25 +2013,91 @@ fn ingress_status() { pic.add_cycles(canister_id, INIT_CYCLES); pic.install_canister(canister_id, test_canister_wasm(), vec![], None); + let caller = Principal::from_slice(&[0xFF; 29]); let msg_id = pic - .submit_call( - canister_id, - Principal::anonymous(), - "whoami", - encode_one(()).unwrap(), - ) + .submit_call(canister_id, caller, "whoami", encode_one(()).unwrap()) .unwrap(); - assert!(pic.ingress_status(msg_id.clone()).is_none()); + match pic.ingress_status(msg_id.clone(), None) { + IngressStatusResult::NotAvailable => (), + status => panic!("Unexpected ingress status: {:?}", status), + } + + // since the ingress status is not available, any caller can attempt to retrieve it + match pic.ingress_status(msg_id.clone(), Some(Principal::anonymous())) { + IngressStatusResult::NotAvailable => (), + status => panic!("Unexpected ingress status: {:?}", status), + } pic.tick(); - let ingress_status = pic.ingress_status(msg_id).unwrap().unwrap(); - let principal = match ingress_status { + let reply = match pic.ingress_status(msg_id.clone(), None) { + IngressStatusResult::Success(result) => result.unwrap(), + status => panic!("Unexpected ingress status: {:?}", status), + }; + let principal = match reply { WasmResult::Reply(data) => Decode!(&data, String).unwrap(), WasmResult::Reject(err) => panic!("Unexpected reject: {}", err), }; assert_eq!(principal, canister_id.to_string()); + + // now that the ingress status is available, the caller must match + let expected_err = "The user tries to access Request ID not signed by the caller."; + match pic.ingress_status(msg_id.clone(), Some(Principal::anonymous())) { + IngressStatusResult::Forbidden(msg) => assert_eq!(msg, expected_err,), + status => panic!("Unexpected ingress status: {:?}", status), + } + + // confirm the behavior of read state requests + let resp = read_state_request_status(&pic, canister_id, msg_id.message_id.as_slice()); + assert_eq!(resp.status(), reqwest::StatusCode::FORBIDDEN); + assert_eq!( + String::from_utf8(resp.bytes().unwrap().to_vec()).unwrap(), + expected_err + ); +} + +fn read_state_request_status( + pic: &PocketIc, + canister_id: Principal, + msg_id: &[u8], +) -> reqwest::blocking::Response { + let path = vec!["request_status".into(), Label::from_bytes(msg_id)]; + let paths = vec![path.clone()]; + let content = ReadState { + ingress_expiry: pic + .get_time() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .unwrap() + .as_nanos() as u64 + + 240_000_000_000, + sender: Principal::anonymous(), + paths, + }; + let envelope = Envelope { + content: std::borrow::Cow::Borrowed(&content), + sender_pubkey: None, + sender_sig: None, + sender_delegation: None, + }; + + let mut serialized_bytes = Vec::new(); + let mut serializer = serde_cbor::Serializer::new(&mut serialized_bytes); + serializer.self_describe().unwrap(); + envelope.serialize(&mut serializer).unwrap(); + + let endpoint = format!( + "instances/{}/api/v2/canister/{}/read_state", + pic.instance_id(), + canister_id.to_text() + ); + let client = reqwest::blocking::Client::new(); + client + .post(pic.get_server_url().join(&endpoint).unwrap()) + .header(reqwest::header::CONTENT_TYPE, "application/cbor") + .body(serialized_bytes) + .send() + .unwrap() } #[test] diff --git a/rs/pocket_ic_server/CHANGELOG.md b/rs/pocket_ic_server/CHANGELOG.md index 43ec593bfc2..ab99557c7a6 100644 --- a/rs/pocket_ic_server/CHANGELOG.md +++ b/rs/pocket_ic_server/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - New endpoint `/instances//read/ingress_status` to fetch the status of an update call submitted through an ingress message. + If an optional caller is provided and a corresponding read state request for the status of the same update call + signed by that specified caller was rejected because the update call was submitted by a different caller, then an error is returned. ### Fixed - Canisters created via `provisional_create_canister_with_cycles` with the management canister ID as the effective canister ID diff --git a/rs/pocket_ic_server/src/pocket_ic.rs b/rs/pocket_ic_server/src/pocket_ic.rs index dfac250784c..f0f98d27ff5 100644 --- a/rs/pocket_ic_server/src/pocket_ic.rs +++ b/rs/pocket_ic_server/src/pocket_ic.rs @@ -1711,29 +1711,49 @@ impl Operation for ExecuteIngressMessage { } #[derive(Clone, Debug)] -pub struct IngressMessageStatus(pub MessageId); +pub struct IngressMessageStatus { + pub message_id: MessageId, + pub caller: Option, +} impl Operation for IngressMessageStatus { fn compute(&self, pic: &mut PocketIc) -> OpOut { - let subnet = route(pic, self.0.effective_principal.clone(), false); + let subnet = route(pic, self.message_id.effective_principal.clone(), false); match subnet { - Ok(subnet) => match subnet.ingress_status(&self.0.msg_id) { - IngressStatus::Known { - state: IngressState::Completed(result), - .. - } => Ok(result).into(), - IngressStatus::Known { - state: IngressState::Failed(error), - .. - } => Err(error).into(), - _ => OpOut::NoOutput, - }, + Ok(subnet) => { + if let Some(caller) = self.caller { + if let Some(actual_caller) = subnet.ingress_caller(&self.message_id.msg_id) { + if caller != actual_caller.get().0 { + return OpOut::Error(PocketIcError::Forbidden( + "The user tries to access Request ID not signed by the caller." + .to_string(), + )); + } + } + } + match subnet.ingress_status(&self.message_id.msg_id) { + IngressStatus::Known { + state: IngressState::Completed(result), + .. + } => Ok(result).into(), + IngressStatus::Known { + state: IngressState::Failed(error), + .. + } => Err(error).into(), + _ => OpOut::NoOutput, + } + } Err(e) => OpOut::Error(PocketIcError::BadIngressMessage(e)), } } fn id(&self) -> OpId { - OpId(format!("ingress_status_{}", self.0.msg_id)) + OpId(format!( + "ingress_status({},{:?},{:?})", + self.message_id.msg_id, + self.message_id.effective_principal, + self.caller.map(|caller| caller.to_string()) + )) } } diff --git a/rs/pocket_ic_server/src/state_api/routes.rs b/rs/pocket_ic_server/src/state_api/routes.rs index 5b04216cdc2..add5a1e0d39 100644 --- a/rs/pocket_ic_server/src/state_api/routes.rs +++ b/rs/pocket_ic_server/src/state_api/routes.rs @@ -38,8 +38,8 @@ use ic_types::{CanisterId, SubnetId}; use pocket_ic::common::rest::{ self, ApiResponse, AutoProgressConfig, ExtendedSubnetConfigSet, HttpGatewayConfig, HttpGatewayDetails, InstanceConfig, MockCanisterHttpResponse, RawAddCycles, RawCanisterCall, - RawCanisterHttpRequest, RawCanisterId, RawCanisterResult, RawCycles, RawMessageId, - RawMockCanisterHttpResponse, RawPrincipalId, RawSetStableMemory, RawStableMemory, + RawCanisterHttpRequest, RawCanisterId, RawCanisterResult, RawCycles, RawIngressStatusArgs, + RawMessageId, RawMockCanisterHttpResponse, RawPrincipalId, RawSetStableMemory, RawStableMemory, RawSubmitIngressResult, RawSubnetId, RawTime, RawWasmResult, Topology, }; use pocket_ic::WasmResult; @@ -312,6 +312,12 @@ impl> FromOpOut for T { async fn from(value: OpOut) -> (StatusCode, ApiResponse) { // match errors explicitly to make sure they have a 4xx status code match value { + OpOut::Error(PocketIcError::Forbidden(msg)) => ( + StatusCode::FORBIDDEN, + ApiResponse::Error { + message: msg.to_string(), + }, + ), OpOut::Error(e) => ( StatusCode::BAD_REQUEST, ApiResponse::Error { @@ -894,6 +900,13 @@ async fn op_out_to_response(op_out: OpOut) -> Response { )), ) .into_response(), + OpOut::Error(PocketIcError::Forbidden(msg)) => ( + StatusCode::FORBIDDEN, + Json(ApiResponse::<()>::Error { + message: msg.to_string(), + }), + ) + .into_response(), opout @ OpOut::Error(_) => ( StatusCode::BAD_REQUEST, Json(ApiResponse::<()>::Error { @@ -1032,12 +1045,17 @@ pub async fn handler_ingress_status( State(AppState { api_state, .. }): State, Path(instance_id): Path, headers: HeaderMap, - extract::Json(raw_message_id): extract::Json, + extract::Json(raw_ingress_status_args): extract::Json, ) -> (StatusCode, Json>>) { let timeout = timeout_or_default(headers); - match crate::pocket_ic::MessageId::try_from(raw_message_id) { + match crate::pocket_ic::MessageId::try_from(raw_ingress_status_args.raw_message_id) { Ok(message_id) => { - let ingress_op = IngressMessageStatus(message_id); + let ingress_op = IngressMessageStatus { + message_id, + caller: raw_ingress_status_args + .raw_caller + .map(|caller| caller.into()), + }; let (code, response) = run_operation(api_state, instance_id, timeout, ingress_op).await; (code, Json(response)) } diff --git a/rs/pocket_ic_server/src/state_api/state.rs b/rs/pocket_ic_server/src/state_api/state.rs index f3d7a2311be..703e63ffd36 100644 --- a/rs/pocket_ic_server/src/state_api/state.rs +++ b/rs/pocket_ic_server/src/state_api/state.rs @@ -255,6 +255,7 @@ pub enum PocketIcError { InvalidMockCanisterHttpResponses((usize, usize)), InvalidRejectCode(u64), SettingTimeIntoPast((u64, u64)), + Forbidden(String), } impl From> for OpOut { @@ -328,6 +329,9 @@ impl std::fmt::Debug for OpOut { OpOut::Error(PocketIcError::SettingTimeIntoPast((current, set))) => { write!(f, "SettingTimeIntoPast(current={},set={})", current, set) } + OpOut::Error(PocketIcError::Forbidden(msg)) => { + write!(f, "Forbidden({})", msg) + } OpOut::Bytes(bytes) => write!(f, "Bytes({})", base64::encode(bytes)), OpOut::StableMemBytes(bytes) => write!(f, "StableMemory({})", base64::encode(bytes)), OpOut::MaybeSubnetId(Some(subnet_id)) => write!(f, "SubnetId({})", subnet_id), diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index 7122e6df144..6578db7c5c7 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -3238,6 +3238,11 @@ impl StateMachine { (self.ingress_history_reader.get_latest_status())(msg_id) } + /// Returns the caller of the ingress message with the specified ID if available. + pub fn ingress_caller(&self, msg_id: &MessageId) -> Option { + self.get_latest_state().get_ingress_status(msg_id).user_id() + } + /// Starts the canister with the specified ID. pub fn start_canister(&self, canister_id: CanisterId) -> Result { self.start_canister_as(PrincipalId::new_anonymous(), canister_id) From c741e349451edf0c9792149ad439bb32a0161371 Mon Sep 17 00:00:00 2001 From: maciejdfinity <122265298+maciejdfinity@users.noreply.github.com> Date: Tue, 7 Jan 2025 11:49:58 +0100 Subject: [PATCH 06/98] feat: ICRC-ledger: FI-1439: Implement V4 for ICRC ledger - migrate balances to stable structures (#2901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This version of the ledger migrates the balances stored by the ledger from heap to stable memory stable structures. This allows the ledger to store more data (heap memory is limited to 4GB) and reduces the number of instructions used during the upgrades - there is no need to serialize and deserialize the balances stored in heap memory. Since we are no longer limited by the heap size, the logic for trimming balances and related init/upgrade arguments (`maximum_number_of_accounts`, `accounts_overflow_trim_quantity`) were removed. The migration to stable structures is performed during the upgrade and, if 200B instruction limit is reached, using timer invocations after the upgrade. If timer invocations are used by the migration, the ledger is unavailable for transfers and approvals until migration is finished. The migration status can be checked by checking the value of the `ledger_stable_upgrade_migration_steps` metric and calling the `is_ledger_ready` endpoint. The metric will increase at roughly 1s intervals until the migration is finished. The canister logs will also contain some information about the number of migrated allowances and balances (e.g. "Migration partially done. Scheduling the next part. Number of elements migrated: allowances: 0 expirations: 0 balances: 7657..."). If migration is not progressing and the ledger is not ready, the ledger can still be downgraded to the previous version. After migration is finished and `is_ledger_ready` returns true, it is no longer possible to downgrade the ledger to the previous version . --------- Co-authored-by: Mathias Björkqvist --- WORKSPACE.bazel | 8 + mainnet-canister-revisions.json | 16 ++ .../src/scheduler/mod.rs | 2 - .../common/ledger_canister_core/src/ledger.rs | 29 +++- rs/ledger_suite/icp/ledger/tests/tests.rs | 1 + rs/ledger_suite/icrc1/index-ng/tests/tests.rs | 1 - rs/ledger_suite/icrc1/ledger/BUILD.bazel | 8 + .../ledger/canbench_results/canbench_u256.yml | 32 ++-- .../ledger/canbench_results/canbench_u64.yml | 32 ++-- rs/ledger_suite/icrc1/ledger/ledger.did | 3 - .../icrc1/ledger/src/benches/mod.rs | 10 +- rs/ledger_suite/icrc1/ledger/src/lib.rs | 140 ++++++++++----- rs/ledger_suite/icrc1/ledger/src/main.rs | 30 +++- rs/ledger_suite/icrc1/ledger/src/tests.rs | 2 - rs/ledger_suite/icrc1/ledger/tests/tests.rs | 153 +++++++++++++---- .../tests/golden_state_upgrade_downgrade.rs | 21 +-- .../icrc1/tests/upgrade_downgrade.rs | 14 +- rs/ledger_suite/tests/sm-tests/src/lib.rs | 160 +++++++++++++++--- 18 files changed, 494 insertions(+), 168 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index dd128089dd9..09c62d8bd34 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -26,9 +26,13 @@ canisters( "sns-wasm": "sns-wasm-canister.wasm.gz", "ck_btc_archive": "ic-icrc1-archive.wasm.gz", "ck_btc_ledger": "ic-icrc1-ledger.wasm.gz", + "ck_btc_ledger_v1": "ic-icrc1-ledger.wasm.gz", + "ck_btc_ledger_v2": "ic-icrc1-ledger.wasm.gz", "ck_btc_index": "ic-icrc1-index-ng.wasm.gz", "ck_eth_archive": "ic-icrc1-archive-u256.wasm.gz", "ck_eth_ledger": "ic-icrc1-ledger-u256.wasm.gz", + "ck_eth_ledger_v1": "ic-icrc1-ledger-u256.wasm.gz", + "ck_eth_ledger_v2": "ic-icrc1-ledger-u256.wasm.gz", "ck_eth_index": "ic-icrc1-index-ng-u256.wasm.gz", "sns_root": "sns-root-canister.wasm.gz", "sns_governance": "sns-governance-canister.wasm.gz", @@ -52,9 +56,13 @@ canisters( "sns-wasm": "mainnet_nns_sns-wasm-canister", "ck_btc_archive": "mainnet_ckbtc_ic-icrc1-archive", "ck_btc_ledger": "mainnet_ckbtc_ic-icrc1-ledger", + "ck_btc_ledger_v1": "mainnet_ckbtc_ic-icrc1-ledger-v1", + "ck_btc_ledger_v2": "mainnet_ckbtc_ic-icrc1-ledger-v2", "ck_btc_index": "mainnet_ckbtc-index-ng", "ck_eth_archive": "mainnet_cketh_ic-icrc1-archive-u256", "ck_eth_ledger": "mainnet_cketh_ic-icrc1-ledger-u256", + "ck_eth_ledger_v1": "mainnet_cketh_ic-icrc1-ledger-u256-v1", + "ck_eth_ledger_v2": "mainnet_cketh_ic-icrc1-ledger-u256-v2", "ck_eth_index": "mainnet_cketh-index-ng", "sns_root": "mainnet_sns-root-canister", "sns_governance": "mainnet_sns-governance-canister", diff --git a/mainnet-canister-revisions.json b/mainnet-canister-revisions.json index f044f082ec7..f940ecf64b1 100644 --- a/mainnet-canister-revisions.json +++ b/mainnet-canister-revisions.json @@ -15,6 +15,14 @@ "rev": "2190613d3b5bcd9b74c382b22d151580b8ac271a", "sha256": "25071c2c55ad4571293e00d8e277f442aec7aed88109743ac52df3125209ff45" }, + "ck_btc_ledger_v1": { + "rev": "d4ee25b0865e89d3eaac13a60f0016d5e3296b31", + "sha256": "a170bfdce5d66e751a3cc03747cb0f06b450af500e75e15976ec08a3f5691f4c" + }, + "ck_btc_ledger_v2": { + "rev": "e54d3fa34ded227c885d04e64505fa4b5d564743", + "sha256": "3d808fa63a3d8ebd4510c0400aa078e99a31afaa0515f0b68778f929ce4b2a46" + }, "ck_eth_archive": { "rev": "2190613d3b5bcd9b74c382b22d151580b8ac271a", "sha256": "2d25f7831894100d48aa9043c65e87c293487523f0958c15760027d004fbbda9" @@ -27,6 +35,14 @@ "rev": "2190613d3b5bcd9b74c382b22d151580b8ac271a", "sha256": "9637743e1215a4db376a62ee807a0986faf20833be2b332df09b3d5dbdd7339e" }, + "ck_eth_ledger_v1": { + "rev": "d4ee25b0865e89d3eaac13a60f0016d5e3296b31", + "sha256": "e6072806ae22868ee09c07923d093b1b0b687dba540d22cfc1e1a5392bfcca46" + }, + "ck_eth_ledger_v2": { + "rev": "e54d3fa34ded227c885d04e64505fa4b5d564743", + "sha256": "98a7b7391608dc4a554d6964bad24157b6aaf890a05bbaad3fcc92033d9c7b02" + }, "cycles-minting": { "rev": "ee52ab3056cf5f39b09b08de70bdd20485c8b2dc", "sha256": "bbb8995cb749ba9e2c721ff507f5e5313f32e69b1adf3df20e3901ed56a70b42" diff --git a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs index 8848c70062a..af80736d513 100644 --- a/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs +++ b/rs/ethereum/ledger-suite-orchestrator/src/scheduler/mod.rs @@ -932,8 +932,6 @@ fn icrc1_ledger_init_arg( ), max_memo_length: Some(MAX_MEMO_LENGTH), feature_flags: Some(ICRC2_FEATURE), - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, } } diff --git a/rs/ledger_suite/common/ledger_canister_core/src/ledger.rs b/rs/ledger_suite/common/ledger_canister_core/src/ledger.rs index c8190e968e0..30e9d972a98 100644 --- a/rs/ledger_suite/common/ledger_canister_core/src/ledger.rs +++ b/rs/ledger_suite/common/ledger_canister_core/src/ledger.rs @@ -208,6 +208,7 @@ pub enum TransferError { const APPROVE_PRUNE_LIMIT: usize = 100; /// Adds a new block with the specified transaction to the ledger. +/// Trim balances if necessary. pub fn apply_transaction( ledger: &mut L, transaction: L::Transaction, @@ -217,6 +218,22 @@ pub fn apply_transaction( where L: LedgerData, L::BalancesStore: InspectableBalancesStore, +{ + let result = apply_transaction_no_trimming(ledger, transaction, now, effective_fee); + trim_balances(ledger, now); + result +} + +/// Adds a new block with the specified transaction to the ledger. +/// Do not perform any balance trimming. +pub fn apply_transaction_no_trimming( + ledger: &mut L, + transaction: L::Transaction, + now: TimeStamp, + effective_fee: L::Tokens, +) -> Result<(BlockIndex, HashOf), TransferError> +where + L: LedgerData, { let num_pruned = purge_old_transactions(ledger, now); @@ -301,6 +318,16 @@ where transaction_hash: tx_hash, }); } + + Ok((height, ledger.blockchain().last_hash.unwrap())) +} + +/// Trim balances. Can be used e.g. if the ledger is low on heap memory. +fn trim_balances(ledger: &mut L, now: TimeStamp) +where + L: LedgerData, + L::BalancesStore: InspectableBalancesStore, +{ let effective_max_number_of_accounts = ledger.max_number_of_accounts() + ledger.accounts_overflow_trim_quantity() - 1; @@ -331,8 +358,6 @@ where )) .unwrap(); } - - Ok((height, ledger.blockchain().last_hash.unwrap())) } /// Finds the archive canister that contains the block with the specified height. diff --git a/rs/ledger_suite/icp/ledger/tests/tests.rs b/rs/ledger_suite/icp/ledger/tests/tests.rs index b3362beb36a..4b7573de082 100644 --- a/rs/ledger_suite/icp/ledger/tests/tests.rs +++ b/rs/ledger_suite/icp/ledger/tests/tests.rs @@ -1250,6 +1250,7 @@ fn test_upgrade_serialization() { upgrade_args, minter, false, + false, ); } diff --git a/rs/ledger_suite/icrc1/index-ng/tests/tests.rs b/rs/ledger_suite/icrc1/index-ng/tests/tests.rs index 9edffa62dde..6a1bb3e35f9 100644 --- a/rs/ledger_suite/icrc1/index-ng/tests/tests.rs +++ b/rs/ledger_suite/icrc1/index-ng/tests/tests.rs @@ -55,7 +55,6 @@ fn upgrade_ledger( change_fee_collector, max_memo_length: None, feature_flags: None, - accounts_overflow_trim_quantity: None, change_archive_options: None, })); env.upgrade_canister(ledger_id, ledger_wasm(), Encode!(&args).unwrap()) diff --git a/rs/ledger_suite/icrc1/ledger/BUILD.bazel b/rs/ledger_suite/icrc1/ledger/BUILD.bazel index 3a283db1377..afaec0a3b60 100644 --- a/rs/ledger_suite/icrc1/ledger/BUILD.bazel +++ b/rs/ledger_suite/icrc1/ledger/BUILD.bazel @@ -278,14 +278,22 @@ rust_test( "//rs/ledger_suite/icrc1/archive:archive_canister" + name_suffix + ".wasm.gz", "//rs/ledger_suite/icrc1/ledger:ledger_canister_icrc3_compatible_data_certificate", "//rs/universal_canister/impl:universal_canister.wasm.gz", + "@mainnet_ckbtc_ic-icrc1-ledger-v1//file", + "@mainnet_ckbtc_ic-icrc1-ledger-v2//file", "@mainnet_ckbtc_ic-icrc1-ledger//file", + "@mainnet_cketh_ic-icrc1-ledger-u256-v1//file", + "@mainnet_cketh_ic-icrc1-ledger-u256-v2//file", "@mainnet_cketh_ic-icrc1-ledger-u256//file", "@mainnet_ic-icrc1-ledger//file", ], env = { "CARGO_MANIFEST_DIR": "rs/ledger_suite/icrc1/ledger", "CKBTC_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_ckbtc_ic-icrc1-ledger//file)", + "CKBTC_IC_ICRC1_LEDGER_V1_VERSION_WASM_PATH": "$(rootpath @mainnet_ckbtc_ic-icrc1-ledger-v1//file)", + "CKBTC_IC_ICRC1_LEDGER_V2_VERSION_WASM_PATH": "$(rootpath @mainnet_ckbtc_ic-icrc1-ledger-v2//file)", "CKETH_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_cketh_ic-icrc1-ledger-u256//file)", + "CKETH_IC_ICRC1_LEDGER_V1_VERSION_WASM_PATH": "$(rootpath @mainnet_cketh_ic-icrc1-ledger-u256-v1//file)", + "CKETH_IC_ICRC1_LEDGER_V2_VERSION_WASM_PATH": "$(rootpath @mainnet_cketh_ic-icrc1-ledger-u256-v2//file)", "IC_ICRC1_ARCHIVE_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/archive:archive_canister" + name_suffix + ".wasm.gz)", "IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_ic-icrc1-ledger//file)", "IC_ICRC1_LEDGER_ICRC3_COMPATIBLE_DATA_CERTIFICATE_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/ledger:ledger_canister_icrc3_compatible_data_certificate)", diff --git a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml index 77770b0cfb7..4fe24655c4a 100644 --- a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml +++ b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml @@ -1,42 +1,42 @@ benches: bench_icrc1_transfers: total: - instructions: 6398923208 - heap_increase: 227 + instructions: 13798815361 + heap_increase: 172 stable_memory_increase: 128 scopes: before_upgrade: - instructions: 5790054103 - heap_increase: 71 + instructions: 13630531777 + heap_increase: 43 stable_memory_increase: 0 post_upgrade: - instructions: 424320009 - heap_increase: 27 + instructions: 118601062 + heap_increase: 0 stable_memory_increase: 0 pre_upgrade: - instructions: 184546072 + instructions: 49679478 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 608867671 - heap_increase: 156 + instructions: 168282130 + heap_increase: 129 stable_memory_increase: 128 bench_upgrade_baseline: total: - instructions: 8755062 + instructions: 8684974 heap_increase: 258 - stable_memory_increase: 129 + stable_memory_increase: 128 scopes: post_upgrade: - instructions: 8627524 + instructions: 8606422 heap_increase: 129 stable_memory_increase: 0 pre_upgrade: - instructions: 125131 + instructions: 76145 heap_increase: 129 - stable_memory_increase: 129 + stable_memory_increase: 128 upgrade: - instructions: 8754373 + instructions: 8684285 heap_increase: 258 - stable_memory_increase: 129 + stable_memory_increase: 128 version: 0.1.7 diff --git a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml index 22fe755925c..7e7164f34e5 100644 --- a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml +++ b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml @@ -1,42 +1,42 @@ benches: bench_icrc1_transfers: total: - instructions: 5926738616 - heap_increase: 214 + instructions: 13237283790 + heap_increase: 171 stable_memory_increase: 128 scopes: before_upgrade: - instructions: 5341274673 - heap_increase: 64 + instructions: 13068913917 + heap_increase: 42 stable_memory_increase: 0 post_upgrade: - instructions: 406888378 - heap_increase: 21 + instructions: 118797275 + heap_increase: 0 stable_memory_increase: 0 pre_upgrade: - instructions: 178572258 + instructions: 49569466 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 585462226 - heap_increase: 150 + instructions: 168368331 + heap_increase: 129 stable_memory_increase: 128 bench_upgrade_baseline: total: - instructions: 8758206 + instructions: 8686052 heap_increase: 258 - stable_memory_increase: 129 + stable_memory_increase: 128 scopes: post_upgrade: - instructions: 8627876 + instructions: 8606533 heap_increase: 129 stable_memory_increase: 0 pre_upgrade: - instructions: 127923 + instructions: 77112 heap_increase: 129 - stable_memory_increase: 129 + stable_memory_increase: 128 upgrade: - instructions: 8757517 + instructions: 8685363 heap_increase: 258 - stable_memory_increase: 129 + stable_memory_increase: 128 version: 0.1.7 diff --git a/rs/ledger_suite/icrc1/ledger/ledger.did b/rs/ledger_suite/icrc1/ledger/ledger.did index dece15d9bba..b3a6c474c35 100644 --- a/rs/ledger_suite/icrc1/ledger/ledger.did +++ b/rs/ledger_suite/icrc1/ledger/ledger.did @@ -107,8 +107,6 @@ type InitArgs = record { metadata : vec record { text; MetadataValue }; initial_balances : vec record { Account; nat }; feature_flags : opt FeatureFlags; - maximum_number_of_accounts : opt nat64; - accounts_overflow_trim_quantity : opt nat64; archive_options : record { num_blocks_to_archive : nat64; max_transactions_per_response : opt nat64; @@ -144,7 +142,6 @@ type UpgradeArgs = record { change_fee_collector : opt ChangeFeeCollector; max_memo_length : opt nat16; feature_flags : opt FeatureFlags; - accounts_overflow_trim_quantity: opt nat64; change_archive_options : opt ChangeArchiveOptions; }; diff --git a/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs b/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs index f99196d8c27..68d36334239 100644 --- a/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs +++ b/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs @@ -1,10 +1,8 @@ -use crate::{execute_transfer_not_async, post_upgrade, pre_upgrade, Access, Tokens}; +use crate::{balances_len, execute_transfer_not_async, post_upgrade, pre_upgrade, Tokens}; use assert_matches::assert_matches; use candid::{Nat, Principal}; use ic_canister_log::Sink; -use ic_ledger_canister_core::ledger::{ - blocks_to_archive, remove_archived_blocks, LedgerAccess, LedgerContext, -}; +use ic_ledger_canister_core::ledger::{blocks_to_archive, remove_archived_blocks, LedgerAccess}; use ic_ledger_core::block::BlockIndex; use icrc_ledger_types::icrc1::account::Account; use icrc_ledger_types::icrc1::transfer::TransferArg; @@ -42,9 +40,7 @@ pub fn icrc1_transfer( } fn assert_has_num_balances(num_balances: u32) { - Access::with_ledger(|ledger| { - assert_eq!(ledger.balances().store.len() as u32, num_balances); - }); + assert_eq!(balances_len() as u32, num_balances); } pub fn max_length_principal(index: u32) -> Principal { diff --git a/rs/ledger_suite/icrc1/ledger/src/lib.rs b/rs/ledger_suite/icrc1/ledger/src/lib.rs index c1c5839db3e..ee7d2fc00bf 100644 --- a/rs/ledger_suite/icrc1/ledger/src/lib.rs +++ b/rs/ledger_suite/icrc1/ledger/src/lib.rs @@ -22,9 +22,12 @@ use ic_ledger_canister_core::runtime::Runtime; use ic_ledger_canister_core::{ archive::ArchiveCanisterWasm, blockchain::Blockchain, - ledger::{apply_transaction, block_locations, LedgerContext, LedgerData, TransactionInfo}, + ledger::{ + apply_transaction_no_trimming, block_locations, LedgerContext, LedgerData, TransactionInfo, + }, range_utils, }; +use ic_ledger_core::balances::BalancesStore; use ic_ledger_core::{ approvals::{Allowance, AllowanceTable, AllowancesData}, balances::Balances, @@ -59,11 +62,9 @@ use std::ops::DerefMut; use std::time::Duration; const TRANSACTION_WINDOW: Duration = Duration::from_secs(24 * 60 * 60); -const MAX_ACCOUNTS: usize = 28_000_000; /// The maximum number of transactions the ledger should return for a single /// get_transactions request. const MAX_TRANSACTIONS_PER_REQUEST: usize = 2_000; -const ACCOUNTS_OVERFLOW_TRIM_QUANTITY: usize = 100_000; const MAX_TRANSACTIONS_IN_WINDOW: usize = 3_000_000; const MAX_TRANSACTIONS_TO_PURGE: usize = 100_000; #[allow(dead_code)] @@ -82,11 +83,12 @@ pub type Tokens = ic_icrc1_tokens_u256::U256; /// We have the following ledger versions: /// * 0 - the whole ledger state is stored on the heap. /// * 1 - the allowances are stored in stable structures. +/// * 2 - the balances are stored in stable structures. #[cfg(not(feature = "next-ledger-version"))] -pub const LEDGER_VERSION: u64 = 1; +pub const LEDGER_VERSION: u64 = 2; #[cfg(feature = "next-ledger-version")] -pub const LEDGER_VERSION: u64 = 2; +pub const LEDGER_VERSION: u64 = 3; #[derive(Clone, Debug)] pub struct Icrc1ArchiveWasm; @@ -179,8 +181,6 @@ impl InitArgsBuilder { }, max_memo_length: None, feature_flags: None, - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, }) } @@ -263,8 +263,6 @@ pub struct InitArgs { pub archive_options: ArchiveOptions, pub max_memo_length: Option, pub feature_flags: Option, - pub maximum_number_of_accounts: Option, - pub accounts_overflow_trim_quantity: Option, } #[derive(Clone, Eq, PartialEq, Debug, CandidType, Deserialize)] @@ -340,8 +338,6 @@ pub struct UpgradeArgs { #[serde(default, skip_serializing_if = "Option::is_none")] pub feature_flags: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub accounts_overflow_trim_quantity: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] pub change_archive_options: Option, } @@ -499,6 +495,7 @@ pub enum LedgerArgument { const UPGRADES_MEMORY_ID: MemoryId = MemoryId::new(0); const ALLOWANCES_MEMORY_ID: MemoryId = MemoryId::new(1); const ALLOWANCES_EXPIRATIONS_MEMORY_ID: MemoryId = MemoryId::new(2); +const BALANCES_MEMORY_ID: MemoryId = MemoryId::new(3); thread_local! { static MEMORY_MANAGER: RefCell> = RefCell::new( @@ -520,12 +517,17 @@ thread_local! { #[allow(clippy::type_complexity)] pub static ALLOWANCES_EXPIRATIONS_MEMORY: RefCell>> = MEMORY_MANAGER.with(|memory_manager| RefCell::new(StableBTreeMap::init(memory_manager.borrow().get(ALLOWANCES_EXPIRATIONS_MEMORY_ID)))); + + // account -> tokens - map storing ledger balances. + pub static BALANCES_MEMORY: RefCell>> = + MEMORY_MANAGER.with(|memory_manager| RefCell::new(StableBTreeMap::init(memory_manager.borrow().get(BALANCES_MEMORY_ID)))); } #[derive(Copy, Clone, Serialize, Deserialize, Debug)] pub enum LedgerField { Allowances, AllowancesExpirations, + Balances, } #[derive(Copy, Clone, Serialize, Deserialize, Debug)] @@ -540,11 +542,15 @@ impl Default for LedgerState { } } +type StableLedgerBalances = Balances; + #[derive(Debug, Deserialize, Serialize)] #[serde(bound = "")] pub struct Ledger { balances: LedgerBalances, #[serde(default)] + stable_balances: StableLedgerBalances, + #[serde(default)] approvals: LedgerAllowances, #[serde(default)] stable_approvals: AllowanceTable, @@ -569,23 +575,17 @@ pub struct Ledger { #[serde(default)] feature_flags: FeatureFlags, - #[serde(default = "default_maximum_number_of_accounts")] + // DEPRECATED + #[serde(default)] maximum_number_of_accounts: usize, - #[serde(default = "default_accounts_overflow_trim_quantity")] + // DEPRECATED + #[serde(default)] accounts_overflow_trim_quantity: usize, #[serde(default = "default_ledger_version")] pub ledger_version: u64, } -fn default_maximum_number_of_accounts() -> usize { - MAX_ACCOUNTS -} - -fn default_accounts_overflow_trim_quantity() -> usize { - ACCOUNTS_OVERFLOW_TRIM_QUANTITY -} - fn default_ledger_version() -> u64 { LEDGER_VERSION } @@ -630,8 +630,6 @@ impl Ledger { fee_collector_account, max_memo_length, feature_flags, - maximum_number_of_accounts, - accounts_overflow_trim_quantity, }: InitArgs, now: TimeStamp, ) -> Self { @@ -643,6 +641,7 @@ impl Ledger { } let mut ledger = Self { balances: LedgerBalances::default(), + stable_balances: StableLedgerBalances::default(), approvals: Default::default(), stable_approvals: Default::default(), blockchain: Blockchain::new_with_archive(archive_options), @@ -665,14 +664,8 @@ impl Ledger { .collect(), max_memo_length: max_memo_length.unwrap_or(DEFAULT_MAX_MEMO_LENGTH), feature_flags: feature_flags.unwrap_or_default(), - maximum_number_of_accounts: maximum_number_of_accounts - .unwrap_or_else(|| MAX_ACCOUNTS.try_into().unwrap()) - .try_into() - .unwrap(), - accounts_overflow_trim_quantity: accounts_overflow_trim_quantity - .unwrap_or_else(|| ACCOUNTS_OVERFLOW_TRIM_QUANTITY.try_into().unwrap()) - .try_into() - .unwrap(), + maximum_number_of_accounts: 0, + accounts_overflow_trim_quantity: 0, ledger_version: LEDGER_VERSION, }; @@ -684,12 +677,14 @@ impl Ledger { ) }); let mint = Transaction::mint(account, amount, Some(now), None); - apply_transaction(&mut ledger, mint, now, Tokens::ZERO).unwrap_or_else(|err| { - panic!( - "failed to mint {} tokens to {}: {:?}", - balance, account, err - ) - }); + apply_transaction_no_trimming(&mut ledger, mint, now, Tokens::ZERO).unwrap_or_else( + |err| { + panic!( + "failed to mint {} tokens to {}: {:?}", + balance, account, err + ) + }, + ); } ledger @@ -719,25 +714,39 @@ impl Ledger { } } + pub fn migrate_one_balance(&mut self) -> bool { + match self.balances.store.pop_first() { + Some((account, tokens)) => { + self.stable_balances.credit(&account, tokens); + true + } + None => false, + } + } + pub fn clear_arrivals(&mut self) { self.approvals.allowances_data.clear_arrivals(); } + + pub fn copy_token_pool(&mut self) { + self.stable_balances.token_pool = self.balances.token_pool; + } } impl LedgerContext for Ledger { type AccountId = Account; type AllowancesData = StableAllowancesData; - type BalancesStore = BTreeMap; + type BalancesStore = StableBalances; type Tokens = Tokens; fn balances(&self) -> &Balances { panic_if_not_ready(); - &self.balances + &self.stable_balances } fn balances_mut(&mut self) -> &mut Balances { panic_if_not_ready(); - &mut self.balances + &mut self.stable_balances } fn approvals(&self) -> &AllowanceTable { @@ -904,10 +913,6 @@ impl Ledger { } self.feature_flags = feature_flags; } - if let Some(accounts_overflow_trim_quantity) = args.accounts_overflow_trim_quantity { - self.accounts_overflow_trim_quantity = - accounts_overflow_trim_quantity.try_into().unwrap(); - } if let Some(change_archive_options) = args.change_archive_options { let mut maybe_archive = self.blockchain.archive.write().expect( "BUG: should be unreachable since upgrade has exclusive write access to the ledger", @@ -1149,6 +1154,16 @@ pub fn clear_stable_allowance_data() { }); } +pub fn clear_stable_balances_data() { + BALANCES_MEMORY.with_borrow_mut(|balances| { + balances.clear_new(); + }); +} + +pub fn balances_len() -> u64 { + BALANCES_MEMORY.with_borrow(|balances| balances.len()) +} + #[derive(Serialize, Deserialize, Debug, Default)] pub struct StableAllowancesData {} @@ -1247,3 +1262,40 @@ impl AllowancesData for StableAllowancesData { panic!("The method `clear_arrivals` should not be called for StableAllowancesData") } } + +#[derive(Serialize, Deserialize, Debug, Default, PartialEq)] +pub struct StableBalances {} + +impl BalancesStore for StableBalances { + type AccountId = Account; + type Tokens = Tokens; + + fn get_balance(&self, k: &Account) -> Option { + BALANCES_MEMORY.with_borrow(|balances| balances.get(k)) + } + + fn update(&mut self, k: Account, mut f: F) -> Result + where + F: FnMut(Option<&Tokens>) -> Result, + { + let entry = BALANCES_MEMORY.with_borrow(|balances| balances.get(&k)); + match entry { + Some(v) => { + let new_v = f(Some(&v))?; + if new_v != Tokens::ZERO { + BALANCES_MEMORY.with_borrow_mut(|balances| balances.insert(k, new_v)); + } else { + BALANCES_MEMORY.with_borrow_mut(|balances| balances.remove(&k)); + } + Ok(new_v) + } + None => { + let new_v = f(None)?; + if new_v != Tokens::ZERO { + BALANCES_MEMORY.with_borrow_mut(|balances| balances.insert(k, new_v)); + } + Ok(new_v) + } + } + } +} diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 507224c7732..18643abf59e 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -16,12 +16,12 @@ use ic_icrc1::{ Operation, Transaction, }; use ic_icrc1_ledger::{ - clear_stable_allowance_data, is_ready, ledger_state, panic_if_not_ready, set_ledger_state, - LEDGER_VERSION, UPGRADES_MEMORY, + balances_len, clear_stable_allowance_data, clear_stable_balances_data, is_ready, ledger_state, + panic_if_not_ready, set_ledger_state, LEDGER_VERSION, UPGRADES_MEMORY, }; use ic_icrc1_ledger::{InitArgs, Ledger, LedgerArgument, LedgerField, LedgerState}; use ic_ledger_canister_core::ledger::{ - apply_transaction, archive_blocks, LedgerAccess, LedgerContext, LedgerData, + apply_transaction_no_trimming, archive_blocks, LedgerAccess, LedgerContext, LedgerData, TransferError as CoreTransferError, }; use ic_ledger_canister_core::runtime::heap_memory_size_bytes; @@ -238,6 +238,14 @@ fn post_upgrade(args: Option) { PRE_UPGRADE_INSTRUCTIONS_CONSUMED.with(|n| *n.borrow_mut() = pre_upgrade_instructions_consumed); + if upgrade_from_version < 2 { + set_ledger_state(LedgerState::Migrating(LedgerField::Balances)); + log_message(format!("Upgrading from version {upgrade_from_version} which does not store balances in stable structures, clearing stable balances data.").as_str()); + clear_stable_balances_data(); + Access::with_ledger_mut(|ledger| { + ledger.copy_token_pool(); + }); + } if upgrade_from_version == 0 { set_ledger_state(LedgerState::Migrating(LedgerField::Allowances)); log_message("Upgrading from version 0 which does not use stable structures, clearing stable allowance data."); @@ -263,6 +271,7 @@ fn migrate_next_part(instruction_limit: u64) { STABLE_UPGRADE_MIGRATION_STEPS.with(|n| *n.borrow_mut() += 1); let mut migrated_allowances = 0; let mut migrated_expirations = 0; + let mut migrated_balances = 0; log_message("Migrating part of the ledger state."); @@ -285,6 +294,13 @@ fn migrate_next_part(instruction_limit: u64) { LedgerField::AllowancesExpirations => { if ledger.migrate_one_expiration() { migrated_expirations += 1; + } else { + set_ledger_state(LedgerState::Migrating(LedgerField::Balances)); + } + } + LedgerField::Balances => { + if ledger.migrate_one_balance() { + migrated_balances += 1; } else { set_ledger_state(LedgerState::Ready); } @@ -292,7 +308,7 @@ fn migrate_next_part(instruction_limit: u64) { } } let instructions_migration = instruction_counter() - instructions_migration_start; - let msg = format!("Number of elements migrated: allowances: {migrated_allowances} expirations: {migrated_expirations}. Migration step instructions: {instructions_migration}, total instructions used in message: {}." , + let msg = format!("Number of elements migrated: allowances: {migrated_allowances} expirations: {migrated_expirations} balances: {migrated_balances}. Migration step instructions: {instructions_migration}, total instructions used in message: {}." , instruction_counter()); if !is_ready() { log_message( @@ -404,7 +420,7 @@ fn encode_metrics(w: &mut ic_metrics_encoder::MetricsEncoder>) -> std::i )?; w.encode_gauge( "ledger_balance_store_entries", - ledger.balances().store.len() as f64, + balances_len() as f64, "Total number of accounts in the balance store.", )?; } @@ -654,7 +670,7 @@ fn execute_transfer_not_async( ) }; - let (block_idx, _) = apply_transaction(ledger, tx, now, effective_fee)?; + let (block_idx, _) = apply_transaction_no_trimming(ledger, tx, now, effective_fee)?; Ok(block_idx) }) } @@ -853,7 +869,7 @@ async fn icrc2_approve(arg: ApproveArgs) -> Result { memo: arg.memo, }; - let (block_idx, _) = apply_transaction(ledger, tx, now, expected_fee_tokens) + let (block_idx, _) = apply_transaction_no_trimming(ledger, tx, now, expected_fee_tokens) .map_err(convert_transfer_error) .map_err(|err| { let err: ApproveError = match err.try_into() { diff --git a/rs/ledger_suite/icrc1/ledger/src/tests.rs b/rs/ledger_suite/icrc1/ledger/src/tests.rs index ca5634b81d4..5b177a13dbc 100644 --- a/rs/ledger_suite/icrc1/ledger/src/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/src/tests.rs @@ -85,8 +85,6 @@ fn default_init_args() -> InitArgs { }, max_memo_length: None, feature_flags: None, - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, } } diff --git a/rs/ledger_suite/icrc1/ledger/tests/tests.rs b/rs/ledger_suite/icrc1/ledger/tests/tests.rs index dd0caf85769..e3b0fee8020 100644 --- a/rs/ledger_suite/icrc1/ledger/tests/tests.rs +++ b/rs/ledger_suite/icrc1/ledger/tests/tests.rs @@ -77,16 +77,52 @@ fn ledger_mainnet_wasm() -> Vec { mainnet_wasm } +fn ledger_mainnet_v2_wasm() -> Vec { + #[cfg(not(feature = "u256-tokens"))] + let mainnet_wasm = ledger_mainnet_v2_u64_wasm(); + #[cfg(feature = "u256-tokens")] + let mainnet_wasm = ledger_mainnet_v2_u256_wasm(); + mainnet_wasm +} + +fn ledger_mainnet_v1_wasm() -> Vec { + #[cfg(not(feature = "u256-tokens"))] + let mainnet_wasm = ledger_mainnet_v1_u64_wasm(); + #[cfg(feature = "u256-tokens")] + let mainnet_wasm = ledger_mainnet_v1_u256_wasm(); + mainnet_wasm +} + fn ledger_mainnet_u64_wasm() -> Vec { std::fs::read(std::env::var("CKBTC_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH").unwrap()) .unwrap() } +#[cfg(not(feature = "u256-tokens"))] +fn ledger_mainnet_v2_u64_wasm() -> Vec { + std::fs::read(std::env::var("CKBTC_IC_ICRC1_LEDGER_V2_VERSION_WASM_PATH").unwrap()).unwrap() +} + +#[cfg(not(feature = "u256-tokens"))] +fn ledger_mainnet_v1_u64_wasm() -> Vec { + std::fs::read(std::env::var("CKBTC_IC_ICRC1_LEDGER_V1_VERSION_WASM_PATH").unwrap()).unwrap() +} + fn ledger_mainnet_u256_wasm() -> Vec { std::fs::read(std::env::var("CKETH_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH").unwrap()) .unwrap() } +#[cfg(feature = "u256-tokens")] +fn ledger_mainnet_v2_u256_wasm() -> Vec { + std::fs::read(std::env::var("CKETH_IC_ICRC1_LEDGER_V2_VERSION_WASM_PATH").unwrap()).unwrap() +} + +#[cfg(feature = "u256-tokens")] +fn ledger_mainnet_v1_u256_wasm() -> Vec { + std::fs::read(std::env::var("CKETH_IC_ICRC1_LEDGER_V1_VERSION_WASM_PATH").unwrap()).unwrap() +} + fn ledger_wasm() -> Vec { ic_test_utilities_load_wasm::load_wasm( std::env::var("CARGO_MANIFEST_DIR").unwrap(), @@ -153,8 +189,6 @@ fn encode_init_args(args: ic_ledger_suite_state_machine_tests::InitArgs) -> Ledg }, max_memo_length: None, feature_flags: args.feature_flags, - maximum_number_of_accounts: args.maximum_number_of_accounts, - accounts_overflow_trim_quantity: args.accounts_overflow_trim_quantity, }) } @@ -390,11 +424,6 @@ fn test_transfer_from_burn() { ic_ledger_suite_state_machine_tests::test_transfer_from_burn(ledger_wasm(), encode_init_args); } -#[test] -fn test_balances_overflow() { - ic_ledger_suite_state_machine_tests::test_balances_overflow(ledger_wasm(), encode_init_args); -} - #[test] fn test_archive_controllers() { ic_ledger_suite_state_machine_tests::test_archive_controllers(ledger_wasm()); @@ -438,7 +467,16 @@ fn test_block_transformation() { } #[test] -fn icrc1_test_upgrade_serialization() { +fn icrc1_test_upgrade_serialization_from_mainnet() { + icrc1_test_upgrade_serialization(ledger_mainnet_wasm()); +} + +#[test] +fn icrc1_test_upgrade_serialization_from_v2() { + icrc1_test_upgrade_serialization(ledger_mainnet_v2_wasm()); +} + +fn icrc1_test_upgrade_serialization(ledger_mainnet_wasm: Vec) { let minter = Arc::new(minter_identity()); let builder = LedgerInitArgsBuilder::with_symbol_and_name(TOKEN_SYMBOL, TOKEN_NAME) .with_minting_account(minter.sender().unwrap()) @@ -446,18 +484,18 @@ fn icrc1_test_upgrade_serialization() { let init_args = Encode!(&LedgerArgument::Init(builder.build())).unwrap(); let upgrade_args = Encode!(&LedgerArgument::Upgrade(None)).unwrap(); ic_ledger_suite_state_machine_tests::test_upgrade_serialization::( - ledger_mainnet_wasm(), + ledger_mainnet_wasm, ledger_wasm(), init_args, upgrade_args, minter, true, + true, ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_multi_step_migration() { +fn icrc1_test_multi_step_migration_from_mainnet() { ic_ledger_suite_state_machine_tests::icrc1_test_multi_step_migration( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -465,6 +503,15 @@ fn icrc1_test_multi_step_migration() { ); } +#[test] +fn icrc1_test_multi_step_migration_from_v2() { + ic_ledger_suite_state_machine_tests::icrc1_test_multi_step_migration( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + ); +} + #[test] fn icrc1_test_downgrade_from_incompatible_version() { ic_ledger_suite_state_machine_tests::test_downgrade_from_incompatible_version( @@ -472,13 +519,12 @@ fn icrc1_test_downgrade_from_incompatible_version() { ledger_wasm_nextledgerversion(), ledger_wasm(), encode_init_args, - true, + false, ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_stable_migration_endpoints_disabled() { +fn icrc1_test_stable_migration_endpoints_disabled_from_mainnet() { ic_ledger_suite_state_machine_tests::icrc1_test_stable_migration_endpoints_disabled( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -487,9 +533,18 @@ fn icrc1_test_stable_migration_endpoints_disabled() { ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_incomplete_migration() { +fn icrc1_test_stable_migration_endpoints_disabled_from_v2() { + ic_ledger_suite_state_machine_tests::icrc1_test_stable_migration_endpoints_disabled( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + vec![], + ); +} + +#[test] +fn icrc1_test_incomplete_migration_from_mainnet() { ic_ledger_suite_state_machine_tests::test_incomplete_migration( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -497,9 +552,17 @@ fn icrc1_test_incomplete_migration() { ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_incomplete_migration_to_current() { +fn icrc1_test_incomplete_migration_from_v2() { + ic_ledger_suite_state_machine_tests::test_incomplete_migration( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + ); +} + +#[test] +fn icrc1_test_incomplete_migration_to_current_from_mainnet() { ic_ledger_suite_state_machine_tests::test_incomplete_migration_to_current( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -507,9 +570,17 @@ fn icrc1_test_incomplete_migration_to_current() { ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_migration_resumes_from_frozen() { +fn icrc1_test_incomplete_migration_to_current_from_v2() { + ic_ledger_suite_state_machine_tests::test_incomplete_migration_to_current( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + ); +} + +#[test] +fn icrc1_test_migration_resumes_from_frozen_from_mainnet() { ic_ledger_suite_state_machine_tests::test_migration_resumes_from_frozen( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -517,9 +588,17 @@ fn icrc1_test_migration_resumes_from_frozen() { ); } -#[ignore] // TODO: Re-enable as part of FI-1440 #[test] -fn icrc1_test_metrics_while_migrating() { +fn icrc1_test_migration_resumes_from_frozen_from_v2() { + ic_ledger_suite_state_machine_tests::test_migration_resumes_from_frozen( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + ); +} + +#[test] +fn icrc1_test_metrics_while_migrating_from_mainnet() { ic_ledger_suite_state_machine_tests::test_metrics_while_migrating( ledger_mainnet_wasm(), ledger_wasm_lowupgradeinstructionlimits(), @@ -527,6 +606,24 @@ fn icrc1_test_metrics_while_migrating() { ); } +#[test] +fn icrc1_test_metrics_while_migrating_from_v2() { + ic_ledger_suite_state_machine_tests::test_metrics_while_migrating( + ledger_mainnet_v2_wasm(), + ledger_wasm_lowupgradeinstructionlimits(), + encode_init_args, + ); +} + +#[test] +fn icrc1_test_upgrade_from_v1_not_possible() { + ic_ledger_suite_state_machine_tests::test_upgrade_from_v1_not_possible( + ledger_mainnet_v1_wasm(), + ledger_wasm(), + encode_init_args, + ); +} + mod metrics { use crate::{encode_init_args, encode_upgrade_args, ledger_wasm}; use ic_ledger_suite_state_machine_tests::metrics::LedgerSuiteType; @@ -638,8 +735,6 @@ fn test_icrc2_feature_flag_doesnt_disable_icrc2_endpoints() { }, max_memo_length: None, feature_flags: Some(FeatureFlags { icrc2: false }), - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, })) .unwrap(); let ledger_id = env @@ -814,8 +909,6 @@ fn test_icrc3_get_archives() { }, max_memo_length: None, feature_flags: None, - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, }); let args = Encode!(&args).unwrap(); let ledger_id = env @@ -891,8 +984,6 @@ fn test_icrc3_get_blocks() { }, max_memo_length: None, feature_flags: None, - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, }); let args = Encode!(&args).unwrap(); let ledger_id = env @@ -1167,8 +1258,6 @@ fn test_icrc3_get_blocks_number_of_blocks_limit() { }, max_memo_length: None, feature_flags: None, - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, }); let args = Encode!(&args).unwrap(); @@ -1603,8 +1692,6 @@ mod verify_written_blocks { }, max_memo_length: None, feature_flags: Some(FeatureFlags { icrc2: true }), - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, }); let args = Encode!(&ledger_arg_init).unwrap(); @@ -1821,8 +1908,6 @@ mod incompatible_token_type_upgrade { }, max_memo_length: None, feature_flags: Some(FeatureFlags { icrc2: false }), - maximum_number_of_accounts: None, - accounts_overflow_trim_quantity: None, })) .unwrap() } diff --git a/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs index 7b97715f99d..bfa0c0d13f3 100644 --- a/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -14,7 +14,7 @@ use ic_ledger_suite_state_machine_tests::{ wait_ledger_ready, TransactionGenerationParameters, }; use ic_nns_test_utils_golden_nns_state::new_state_machine_with_golden_fiduciary_state_or_panic; -use ic_state_machine_tests::{StateMachine, UserError}; +use ic_state_machine_tests::{ErrorCode, StateMachine, UserError}; use icrc_ledger_types::icrc1::account::Account; use lazy_static::lazy_static; use std::str::FromStr; @@ -351,18 +351,19 @@ impl LedgerSuiteConfig { // Upgrade each canister twice to exercise pre-upgrade self.upgrade_index_or_panic(state_machine, &self.mainnet_wasms.index_wasm); self.upgrade_index_or_panic(state_machine, &self.mainnet_wasms.index_wasm); - self.upgrade_ledger( - state_machine, - &self.mainnet_wasms.ledger_wasm, - ExpectMigration::No, - ) - .expect("should downgrade to mainnet ledger version"); - self.upgrade_ledger( + match self.upgrade_ledger( state_machine, &self.mainnet_wasms.ledger_wasm, ExpectMigration::No, - ) - .expect("should downgrade to mainnet ledger version"); + ) { + Ok(_) => { + panic!("should not successfully downgrade ledger"); + } + Err(user_error) => user_error.assert_contains( + ErrorCode::CanisterCalledTrap, + "Trying to downgrade from incompatible version", + ), + } self.upgrade_archives_or_panic(state_machine, &self.mainnet_wasms.archive_wasm); self.upgrade_archives_or_panic(state_machine, &self.mainnet_wasms.archive_wasm); } diff --git a/rs/ledger_suite/icrc1/tests/upgrade_downgrade.rs b/rs/ledger_suite/icrc1/tests/upgrade_downgrade.rs index db8191ea320..d44725258db 100644 --- a/rs/ledger_suite/icrc1/tests/upgrade_downgrade.rs +++ b/rs/ledger_suite/icrc1/tests/upgrade_downgrade.rs @@ -77,12 +77,20 @@ fn should_upgrade_and_downgrade_ledger_canister_suite() { ) .unwrap(); - env.upgrade_canister( + match env.upgrade_canister( ledger_id, ledger_mainnet_wasm(), Encode!(&ledger_upgrade_arg).unwrap(), - ) - .unwrap(); + ) { + Ok(_) => { + panic!("Upgrade to mainnet should fail!") + } + Err(e) => { + assert!(e + .description() + .contains("Trying to downgrade from incompatible version")) + } + }; } fn default_archive_options() -> ArchiveOptions { diff --git a/rs/ledger_suite/tests/sm-tests/src/lib.rs b/rs/ledger_suite/tests/sm-tests/src/lib.rs index 466270172c6..c38b394251a 100644 --- a/rs/ledger_suite/tests/sm-tests/src/lib.rs +++ b/rs/ledger_suite/tests/sm-tests/src/lib.rs @@ -2413,6 +2413,7 @@ pub fn test_upgrade_serialization( upgrade_args: Vec, minter: Arc, verify_blocks: bool, + mainnet_on_prev_version: bool, ) where Tokens: TokensType + Default + std::fmt::Display + From, { @@ -2470,20 +2471,33 @@ pub fn test_upgrade_serialization( }; // Test if the old serialized approvals and balances are correctly deserialized - // TODO: Expected migration steps should be 1 again in FI-1440. - // test_upgrade(ledger_wasm_current.clone(), 1); + let expected_steps = if mainnet_on_prev_version { 1 } else { 0 }; + test_upgrade(ledger_wasm_current.clone(), expected_steps); // Test the new wasm serialization test_upgrade(ledger_wasm_current.clone(), 0); // Test deserializing from memory manager test_upgrade(ledger_wasm_current.clone(), 0); - // Downgrade to mainnet should succeed since they are both the same version wrt. - // migration to stable structures. - env.upgrade_canister( + // Downgrade to mainnet if possible. + match env.upgrade_canister( ledger_id, ledger_wasm_mainnet.clone(), Encode!(&LedgerArgument::Upgrade(None)).unwrap(), - ) - .expect("Downgrading to mainnet should succeed"); + ) { + Ok(_) => { + if mainnet_on_prev_version { + panic!("Upgrade from future ledger version should fail!") + } + } + Err(e) => { + if mainnet_on_prev_version { + assert!(e + .description() + .contains("Trying to downgrade from incompatible version")) + } else { + panic!("Upgrade to mainnet should succeed!") + } + } + }; if verify_blocks { // This will also verify the ledger blocks. // The current implementation of the InMemoryLedger cannot get blocks @@ -2524,7 +2538,7 @@ pub fn icrc1_test_multi_step_migration( }, ]; let mut initial_balances = vec![]; - let all_accounts = [accounts.clone(), additional_accounts.clone()].concat(); + let mut all_accounts = [accounts.clone(), additional_accounts.clone()].concat(); for (index, account) in all_accounts.iter().enumerate() { initial_balances.push((*account, 10_000_000u64 + index as u64)); } @@ -2564,6 +2578,11 @@ pub fn icrc1_test_multi_step_migration( )); } } + for i in 7..7 + 30 { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, accounts[0], to, 100).expect("failed to transfer funds"); + all_accounts.push(to); + } let mut balances = BTreeMap::new(); for account in &all_accounts { balances.insert(account, Nat::from(balance_of(&env, canister_id, *account))); @@ -2579,7 +2598,7 @@ pub fn icrc1_test_multi_step_migration( ) .unwrap(); - wait_ledger_ready(&env, canister_id, 10); + wait_ledger_ready(&env, canister_id, 20); let stable_upgrade_migration_steps = parse_metric(&env, canister_id, "ledger_stable_upgrade_migration_steps"); @@ -2748,6 +2767,11 @@ pub fn icrc1_test_stable_migration_endpoints_disabled( send_approval(&env, canister_id, account.owner, &approve_args).expect("approval failed"); } + for i in 2..30 { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, account, to, 100).expect("failed to transfer funds"); + } + env.upgrade_canister( canister_id, ledger_wasm_current_lowinstructionlimits, @@ -2807,7 +2831,7 @@ pub fn icrc1_test_stable_migration_endpoints_disabled( test_endpoint(endpoint_name, args, true); } - wait_ledger_ready(&env, canister_id, 10); + wait_ledger_ready(&env, canister_id, 20); test_endpoint("icrc1_transfer", Encode!(&transfer_args).unwrap(), false); test_endpoint("icrc2_approve", Encode!(&approve_args).unwrap(), false); @@ -2842,8 +2866,10 @@ pub fn test_incomplete_migration( ); const APPROVE_AMOUNT: u64 = 150_000; + const TRANSFER_AMOUNT: u64 = 100; const NUM_APPROVALS: u64 = 20; + const NUM_TRANSFERS: u64 = 30; let send_approvals = || { for i in 2..2 + NUM_APPROVALS { @@ -2856,6 +2882,12 @@ pub fn test_incomplete_migration( send_approvals(); + for i in 2..2 + NUM_TRANSFERS { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, account, to, TRANSFER_AMOUNT + FEE) + .expect("failed to transfer funds"); + } + let check_approvals = |non_zero_from: u64| { for i in 2..2 + NUM_APPROVALS { let allowance = Account::get_allowance( @@ -2872,8 +2904,23 @@ pub fn test_incomplete_migration( assert_eq!(allowance.allowance, expected_allowance); } }; - + let check_balances = |non_zero_from: u64| { + for i in 2..2 + NUM_TRANSFERS { + let balance = balance_of( + &env, + canister_id, + Account::from(PrincipalId::new_user_test_id(i).0), + ); + let expected_balance = if i < non_zero_from { + Nat::from(0u64) + } else { + Nat::from(TRANSFER_AMOUNT + FEE) + }; + assert_eq!(balance, expected_balance); + } + }; check_approvals(2); + check_balances(2); env.upgrade_canister( canister_id, @@ -2906,9 +2953,12 @@ pub fn test_incomplete_migration( let spender = Account::from(PrincipalId::new_user_test_id(i).0); let approve_args = default_approve_args(spender, 0); send_approval(&env, canister_id, account.owner, &approve_args).expect("approval failed"); + transfer(&env, canister_id, spender, account, TRANSFER_AMOUNT) + .expect("failed to transfer funds"); } check_approvals(5); + check_balances(5); env.upgrade_canister( canister_id, @@ -2919,6 +2969,7 @@ pub fn test_incomplete_migration( wait_ledger_ready(&env, canister_id, 20); check_approvals(5); + check_balances(5); } pub fn test_incomplete_migration_to_current( @@ -2939,8 +2990,10 @@ pub fn test_incomplete_migration_to_current( ); const APPROVE_AMOUNT: u64 = 150_000; + const TRANSFER_AMOUNT: u64 = 100; const NUM_APPROVALS: u64 = 20; + const NUM_TRANSFERS: u64 = 30; let send_approvals = || { for i in 2..2 + NUM_APPROVALS { @@ -2953,7 +3006,13 @@ pub fn test_incomplete_migration_to_current( send_approvals(); - let check_approvals = |non_zero_from: u64| { + for i in 2..2 + NUM_TRANSFERS { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, account, to, TRANSFER_AMOUNT + i) + .expect("failed to transfer funds"); + } + + let check_approvals = || { for i in 2..2 + NUM_APPROVALS { let allowance = Account::get_allowance( &env, @@ -2961,16 +3020,22 @@ pub fn test_incomplete_migration_to_current( account, Account::from(PrincipalId::new_user_test_id(i).0), ); - let expected_allowance = if i < non_zero_from { - Nat::from(0u64) - } else { - Nat::from(APPROVE_AMOUNT) - }; - assert_eq!(allowance.allowance, expected_allowance); + assert_eq!(allowance.allowance, Nat::from(APPROVE_AMOUNT)); + } + }; + let check_balances = || { + for i in 2..2 + NUM_TRANSFERS { + let balance = balance_of( + &env, + canister_id, + Account::from(PrincipalId::new_user_test_id(i).0), + ); + assert_eq!(balance, Nat::from(TRANSFER_AMOUNT + i)); } }; - check_approvals(2); + check_approvals(); + check_balances(); env.upgrade_canister( canister_id, @@ -2997,7 +3062,8 @@ pub fn test_incomplete_migration_to_current( .unwrap(); wait_ledger_ready(&env, canister_id, 20); - check_approvals(2); + check_approvals(); + check_balances(); } pub fn test_migration_resumes_from_frozen( @@ -3028,7 +3094,10 @@ pub fn test_migration_resumes_from_frozen( .unwrap(); const APPROVE_AMOUNT: u64 = 150_000; + const TRANSFER_AMOUNT: u64 = 100; + const NUM_APPROVALS: u64 = 20; + const NUM_TRANSFERS: u64 = 30; let send_approvals = || { for i in 2..2 + NUM_APPROVALS { @@ -3041,6 +3110,12 @@ pub fn test_migration_resumes_from_frozen( send_approvals(); + for i in 2..2 + NUM_TRANSFERS { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, account, to, TRANSFER_AMOUNT + i) + .expect("failed to transfer funds"); + } + let check_approvals = || { for i in 2..2 + NUM_APPROVALS { let allowance = Account::get_allowance( @@ -3052,8 +3127,19 @@ pub fn test_migration_resumes_from_frozen( assert_eq!(allowance.allowance, Nat::from(APPROVE_AMOUNT)); } }; + let check_balances = || { + for i in 2..2 + NUM_TRANSFERS { + let balance = balance_of( + &env, + canister_id, + Account::from(PrincipalId::new_user_test_id(i).0), + ); + assert_eq!(balance, Nat::from(TRANSFER_AMOUNT + i)); + } + }; check_approvals(); + check_balances(); env.upgrade_canister( canister_id, @@ -3099,6 +3185,7 @@ pub fn test_migration_resumes_from_frozen( assert!(!is_ledger_ready()); wait_ledger_ready(&env, canister_id, 20); check_approvals(); + check_balances(); } pub fn test_metrics_while_migrating( @@ -3124,6 +3211,11 @@ pub fn test_metrics_while_migrating( send_approval(&env, canister_id, account.owner, &approve_args).expect("approval failed"); } + for i in 2..30 { + let to = Account::from(PrincipalId::new_user_test_id(i).0); + transfer(&env, canister_id, account, to, 100).expect("failed to transfer funds"); + } + env.upgrade_canister( canister_id, ledger_wasm_current_lowinstructionlimits, @@ -3154,7 +3246,7 @@ pub fn test_metrics_while_migrating( .expect("failed to decode is_ledger_ready response"); assert!(!is_ledger_ready); - wait_ledger_ready(&env, canister_id, 10); + wait_ledger_ready(&env, canister_id, 20); let metrics = retrieve_metrics(&env, canister_id); assert!( @@ -3171,6 +3263,32 @@ pub fn test_metrics_while_migrating( ); } +pub fn test_upgrade_from_v1_not_possible( + ledger_wasm_mainnet_v1: Vec, + ledger_wasm_current: Vec, + encode_init_args: fn(InitArgs) -> T, +) where + T: CandidType, +{ + // Setup ledger with v1 state that does not use UPGRADES_MEMORY. + let (env, canister_id) = setup(ledger_wasm_mainnet_v1, encode_init_args, vec![]); + + match env.upgrade_canister( + canister_id, + ledger_wasm_current, + Encode!(&LedgerArgument::Upgrade(None)).unwrap(), + ) { + Ok(_) => { + panic!("Upgrade from V1 should fail!") + } + Err(e) => { + assert!(e + .description() + .contains("Cannot upgrade from scratch stable memory, please upgrade to memory manager first.")); + } + }; +} + pub fn default_approve_args(spender: impl Into, amount: u64) -> ApproveArgs { ApproveArgs { from_subaccount: None, From 0cd1ac662285eb45d5552e84ef871da3fa6f3523 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Tue, 7 Jan 2025 06:08:14 -0600 Subject: [PATCH 07/98] chore: Update ic-agent and ic-agent's reverse dependencies to v0.39 (#3282) I created this PR by following these instructions from @nathanosdev: > The following crates should use version 3.0.2: > 1. `ic-response-verification` > 2. `ic-certification` > 3. `ic-certificate-verification` > 4. `ic-http-certification` > 5. `ic-cbor` > > I recommend just setting them to `3` in `Cargo.toml` and `^3.0.2` in `external_crates.bzl` so they can be updated more easily in the future. That's how it's setup in `ic-http-gateway` too. > And `ic-http-gateway` can be set to version `0.1.0`. The git tag reference can be removed now. I also updated `ic-agent` to 0.39 because that is the version of `ic-agent` that `ic-http-gateway` v0.1.0 depends on. In doing so, I also updated `ic-utils` and `ic-transport-types`. I also moved the `ic-http-gateway` dependency to the workspace-level `Cargo.toml`. It seems like there were a number of breaking changes in these crates, so I also went through and fixed all the code that became broken. --------- Co-authored-by: IDX GitLab Automation --- Cargo.Bazel.Fuzzing.json.lock | 2796 ++++++----------- Cargo.Bazel.Fuzzing.toml.lock | 318 +- Cargo.Bazel.json.lock | 2796 ++++++----------- Cargo.Bazel.toml.lock | 316 +- Cargo.lock | 2339 +++++++------- Cargo.toml | 23 +- bazel/external_crates.bzl | 31 +- packages/ic-signature-verification/Cargo.toml | 2 +- .../certificate_issuer/src/check.rs | 23 +- .../certificate_issuer/src/main.rs | 10 +- .../fuzz/fuzz_targets/execute_call_service.rs | 10 +- .../tracing/jaeger_exporter/src/lib.rs | 13 +- rs/nervous_system/agent/src/agent_impl.rs | 5 +- rs/pocket_ic_server/Cargo.toml | 2 +- rs/pocket_ic_server/src/state_api/state.rs | 3 +- rs/pocket_ic_server/tests/test.rs | 19 +- .../BUILD.bazel | 1 + .../Cargo.toml | 1 + .../src/canister_access.rs | 4 +- .../icp/tests/system_tests/common/utils.rs | 5 +- rs/rosetta-api/icrc1/src/main.rs | 9 +- .../icrc1/tests/common/local_replica.rs | 6 +- .../api_bn_decentralization_test.rs | 18 +- .../integration_test_common/src/lib.rs | 46 +- .../rate_limit_canister_test.rs | 152 +- rs/tests/driver/src/util.rs | 16 +- .../general_execution_tests/nns_shielding.rs | 6 +- .../wasm_chunk_store.rs | 2 +- 28 files changed, 3663 insertions(+), 5309 deletions(-) diff --git a/Cargo.Bazel.Fuzzing.json.lock b/Cargo.Bazel.Fuzzing.json.lock index 0b136744a8b..0d2fc0a35cd 100644 --- a/Cargo.Bazel.Fuzzing.json.lock +++ b/Cargo.Bazel.Fuzzing.json.lock @@ -1,5 +1,5 @@ { - "checksum": "07235e2434b10c31e76bd9a0241a6cacdfce000dd6c4c568fbdbee7b0ef6d7ab", + "checksum": "e904ebd5eba74e59f5c8c82f9170ceb30c11cb23b89e7edc0f00a0b3bade57c1", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -537,7 +537,7 @@ "target": "regex_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -969,7 +969,7 @@ "target": "regex_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -1646,7 +1646,7 @@ "target": "schemars" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -2674,7 +2674,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -2772,7 +2772,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -3123,7 +3123,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -3284,6 +3284,62 @@ ], "license_file": "LICENSE-APACHE" }, + "async-channel 1.9.0": { + "name": "async-channel", + "version": "1.9.0", + "package_url": "https://github.com/smol-rs/async-channel", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/async-channel/1.9.0/download", + "sha256": "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" + } + }, + "targets": [ + { + "Library": { + "crate_name": "async_channel", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "async_channel", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "concurrent-queue 2.5.0", + "target": "concurrent_queue" + }, + { + "id": "event-listener 2.5.3", + "target": "event_listener" + }, + { + "id": "futures-core 0.3.31", + "target": "futures_core" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.9.0" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "async-channel 2.3.1": { "name": "async-channel", "version": "2.3.1", @@ -4103,6 +4159,54 @@ ], "license_file": "LICENSE-APACHE" }, + "async-watch 0.3.1": { + "name": "async-watch", + "version": "0.3.1", + "package_url": "https://github.com/cynecx/async-watch", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/async-watch/0.3.1/download", + "sha256": "a078faf4e27c0c6cc0efb20e5da59dcccc04968ebf2801d8e0b2195124cdcdb2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "async_watch", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "async_watch", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "event-listener 2.5.3", + "target": "event_listener" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.3.1" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "async-web-client 0.6.2": { "name": "async-web-client", "version": "0.6.2", @@ -4545,7 +4649,7 @@ "target": "pin_project_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -4808,7 +4912,7 @@ "target": "pin_project_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -5802,7 +5906,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6028,7 +6132,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6720,7 +6824,7 @@ "target": "secp256k1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6836,7 +6940,7 @@ "target": "secp256k1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde", "alias": "actual_serde" } @@ -7297,7 +7401,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -7357,7 +7461,7 @@ "alias": "internals" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -7476,7 +7580,7 @@ "target": "log" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -7531,7 +7635,7 @@ "target": "bitcoin" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -8739,7 +8843,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -9045,7 +9149,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -9326,7 +9430,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -9558,14 +9662,14 @@ ], "license_file": null }, - "cached 0.47.0": { + "cached 0.49.2": { "name": "cached", - "version": "0.47.0", + "version": "0.49.2", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.47.0/download", - "sha256": "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" + "url": "https://static.crates.io/crates/cached/0.49.2/download", + "sha256": "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" } }, "targets": [ @@ -9587,26 +9691,8 @@ "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "ahash", - "cached_proc_macro", - "cached_proc_macro_types", - "default", - "proc_macro" - ], - "selects": {} - }, "deps": { "common": [ - { - "id": "ahash 0.8.11", - "target": "ahash" - }, - { - "id": "cached_proc_macro_types 0.1.0", - "target": "cached_proc_macro_types" - }, { "id": "hashbrown 0.14.5", "target": "hashbrown" @@ -9627,16 +9713,7 @@ "selects": {} }, "edition": "2018", - "proc_macro_deps": { - "common": [ - { - "id": "cached_proc_macro 0.18.1", - "target": "cached_proc_macro" - } - ], - "selects": {} - }, - "version": "0.47.0" + "version": "0.49.2" }, "license": "MIT", "license_ids": [ @@ -9644,14 +9721,14 @@ ], "license_file": "LICENSE" }, - "cached 0.49.2": { + "cached 0.52.0": { "name": "cached", - "version": "0.49.2", + "version": "0.52.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.49.2/download", - "sha256": "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" + "url": "https://static.crates.io/crates/cached/0.52.0/download", + "sha256": "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" } }, "targets": [ @@ -9673,8 +9750,18 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "ahash" + ], + "selects": {} + }, "deps": { "common": [ + { + "id": "ahash 0.8.11", + "target": "ahash" + }, { "id": "hashbrown 0.14.5", "target": "hashbrown" @@ -9695,7 +9782,7 @@ "selects": {} }, "edition": "2018", - "version": "0.49.2" + "version": "0.52.0" }, "license": "MIT", "license_ids": [ @@ -9703,14 +9790,14 @@ ], "license_file": "LICENSE" }, - "cached 0.52.0": { + "cached 0.54.0": { "name": "cached", - "version": "0.52.0", + "version": "0.54.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.52.0/download", - "sha256": "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" + "url": "https://static.crates.io/crates/cached/0.54.0/download", + "sha256": "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" } }, "targets": [ @@ -9734,7 +9821,11 @@ ], "crate_features": { "common": [ - "ahash" + "ahash", + "cached_proc_macro", + "cached_proc_macro_types", + "default", + "proc_macro" ], "selects": {} }, @@ -9745,12 +9836,12 @@ "target": "ahash" }, { - "id": "hashbrown 0.14.5", - "target": "hashbrown" + "id": "cached_proc_macro_types 0.1.1", + "target": "cached_proc_macro_types" }, { - "id": "instant 0.1.12", - "target": "instant" + "id": "hashbrown 0.14.5", + "target": "hashbrown" }, { "id": "once_cell 1.19.0", @@ -9759,12 +9850,25 @@ { "id": "thiserror 1.0.68", "target": "thiserror" + }, + { + "id": "web-time 1.1.0", + "target": "web_time" } ], "selects": {} }, "edition": "2018", - "version": "0.52.0" + "proc_macro_deps": { + "common": [ + { + "id": "cached_proc_macro 0.23.0", + "target": "cached_proc_macro" + } + ], + "selects": {} + }, + "version": "0.54.0" }, "license": "MIT", "license_ids": [ @@ -9772,14 +9876,14 @@ ], "license_file": "LICENSE" }, - "cached_proc_macro 0.18.1": { + "cached_proc_macro 0.23.0": { "name": "cached_proc_macro", - "version": "0.18.1", + "version": "0.23.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached_proc_macro/0.18.1/download", - "sha256": "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" + "url": "https://static.crates.io/crates/cached_proc_macro/0.23.0/download", + "sha256": "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" } }, "targets": [ @@ -9804,7 +9908,7 @@ "deps": { "common": [ { - "id": "darling 0.14.4", + "id": "darling 0.20.10", "target": "darling" }, { @@ -9816,29 +9920,29 @@ "target": "quote" }, { - "id": "syn 1.0.109", + "id": "syn 2.0.87", "target": "syn" } ], "selects": {} }, "edition": "2018", - "version": "0.18.1" + "version": "0.23.0" }, "license": "MIT", "license_ids": [ "MIT" ], - "license_file": null + "license_file": "LICENSE" }, - "cached_proc_macro_types 0.1.0": { + "cached_proc_macro_types 0.1.1": { "name": "cached_proc_macro_types", - "version": "0.1.0", + "version": "0.1.1", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached_proc_macro_types/0.1.0/download", - "sha256": "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" + "url": "https://static.crates.io/crates/cached_proc_macro_types/0.1.1/download", + "sha256": "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" } }, "targets": [ @@ -9861,13 +9965,13 @@ "**" ], "edition": "2018", - "version": "0.1.0" + "version": "0.1.1" }, "license": "MIT", "license_ids": [ "MIT" ], - "license_file": null + "license_file": "LICENSE" }, "camino 1.1.6": { "name": "camino", @@ -9924,7 +10028,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -10028,7 +10132,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10099,7 +10203,7 @@ "target": "ic_cdk" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -10257,7 +10361,7 @@ "target": "pretty" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10528,7 +10632,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -10594,7 +10698,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10973,7 +11077,7 @@ "target": "regex_syntax" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -11624,7 +11728,7 @@ "target": "num_traits" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -11876,7 +11980,7 @@ "target": "ciborium_ll" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -12822,7 +12926,7 @@ "target": "reqwest" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -13151,7 +13255,7 @@ "target": "pretty_assertions" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -14033,7 +14137,7 @@ "target": "log" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -14092,7 +14196,7 @@ "target": "bitcoin_private" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -14313,7 +14417,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -14323,7 +14427,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -14668,7 +14772,7 @@ "target": "cranelift_bitset" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -14678,7 +14782,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -15083,7 +15187,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -15109,7 +15213,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -16405,7 +16509,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -16917,77 +17021,14 @@ ], "license_file": "LICENSE" }, - "darling 0.14.4": { - "name": "darling", - "version": "0.14.4", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling/0.14.4/download", - "sha256": "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" - } - }, - "targets": [ - { - "Library": { - "crate_name": "darling", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "suggestions" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "darling_core 0.14.4", - "target": "darling_core" - } - ], - "selects": {} - }, - "edition": "2018", - "proc_macro_deps": { - "common": [ - { - "id": "darling_macro 0.14.4", - "target": "darling_macro" - } - ], - "selects": {} - }, - "version": "0.14.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling 0.20.3": { + "darling 0.20.10": { "name": "darling", - "version": "0.20.3", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling/0.20.3/download", - "sha256": "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" + "url": "https://static.crates.io/crates/darling/0.20.10/download", + "sha256": "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" } }, "targets": [ @@ -17019,23 +17060,23 @@ "deps": { "common": [ { - "id": "darling_core 0.20.3", + "id": "darling_core 0.20.10", "target": "darling_core" } ], "selects": {} }, - "edition": "2018", + "edition": "2021", "proc_macro_deps": { "common": [ { - "id": "darling_macro 0.20.3", + "id": "darling_macro 0.20.10", "target": "darling_macro" } ], "selects": {} }, - "version": "0.20.3" + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -17117,14 +17158,14 @@ ], "license_file": "LICENSE" }, - "darling_core 0.14.4": { + "darling_core 0.20.10": { "name": "darling_core", - "version": "0.14.4", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_core/0.14.4/download", - "sha256": "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" + "url": "https://static.crates.io/crates/darling_core/0.20.10/download", + "sha256": "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" } }, "targets": [ @@ -17172,18 +17213,18 @@ "target": "quote" }, { - "id": "strsim 0.10.0", + "id": "strsim 0.11.1", "target": "strsim" }, { - "id": "syn 1.0.109", + "id": "syn 2.0.87", "target": "syn" } ], "selects": {} }, - "edition": "2018", - "version": "0.14.4" + "edition": "2021", + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -17191,20 +17232,20 @@ ], "license_file": "LICENSE" }, - "darling_core 0.20.3": { - "name": "darling_core", - "version": "0.20.3", + "darling_macro 0.13.4": { + "name": "darling_macro", + "version": "0.13.4", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_core/0.20.3/download", - "sha256": "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" + "url": "https://static.crates.io/crates/darling_macro/0.13.4/download", + "sha256": "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" } }, "targets": [ { - "Library": { - "crate_name": "darling_core", + "ProcMacro": { + "crate_name": "darling_macro", "crate_root": "src/lib.rs", "srcs": { "allow_empty": true, @@ -17215,49 +17256,30 @@ } } ], - "library_target_name": "darling_core", + "library_target_name": "darling_macro", "common_attrs": { "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "strsim", - "suggestions" - ], - "selects": {} - }, "deps": { "common": [ { - "id": "fnv 1.0.7", - "target": "fnv" - }, - { - "id": "ident_case 1.0.1", - "target": "ident_case" - }, - { - "id": "proc-macro2 1.0.89", - "target": "proc_macro2" + "id": "darling_core 0.13.4", + "target": "darling_core" }, { "id": "quote 1.0.37", "target": "quote" }, { - "id": "strsim 0.10.0", - "target": "strsim" - }, - { - "id": "syn 2.0.87", + "id": "syn 1.0.109", "target": "syn" } ], "selects": {} }, "edition": "2018", - "version": "0.20.3" + "version": "0.13.4" }, "license": "MIT", "license_ids": [ @@ -17265,14 +17287,14 @@ ], "license_file": "LICENSE" }, - "darling_macro 0.13.4": { + "darling_macro 0.20.10": { "name": "darling_macro", - "version": "0.13.4", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.13.4/download", - "sha256": "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" + "url": "https://static.crates.io/crates/darling_macro/0.20.10/download", + "sha256": "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" } }, "targets": [ @@ -17297,117 +17319,7 @@ "deps": { "common": [ { - "id": "darling_core 0.13.4", - "target": "darling_core" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "syn 1.0.109", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.13.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling_macro 0.14.4": { - "name": "darling_macro", - "version": "0.14.4", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.14.4/download", - "sha256": "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "darling_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "darling_core 0.14.4", - "target": "darling_core" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "syn 1.0.109", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.14.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling_macro 0.20.3": { - "name": "darling_macro", - "version": "0.20.3", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.20.3/download", - "sha256": "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "darling_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "darling_core 0.20.3", + "id": "darling_core 0.20.10", "target": "darling_core" }, { @@ -17421,8 +17333,8 @@ ], "selects": {} }, - "edition": "2018", - "version": "0.20.3" + "edition": "2021", + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -18809,7 +18721,7 @@ "target": "hyper_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { @@ -18825,11 +18737,11 @@ "target": "ic_canister_log" }, { - "id": "ic-canister-sig-creation 1.0.1", + "id": "ic-canister-sig-creation 1.1.0", "target": "ic_canister_sig_creation" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { @@ -18841,11 +18753,11 @@ "target": "ic_cdk_timers" }, { - "id": "ic-certificate-verification 2.6.0", + "id": "ic-certificate-verification 3.0.2", "target": "ic_certificate_verification" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -18853,11 +18765,11 @@ "target": "ic_certified_map" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-http-gateway 0.0.0", + "id": "ic-http-gateway 0.1.0", "target": "ic_http_gateway" }, { @@ -18865,7 +18777,7 @@ "target": "ic_metrics_encoder" }, { - "id": "ic-response-verification 2.6.0", + "id": "ic-response-verification 3.0.2", "target": "ic_response_verification" }, { @@ -18881,11 +18793,11 @@ "target": "ic_test_state_machine_client" }, { - "id": "ic-transport-types 0.37.1", + "id": "ic-transport-types 0.39.2", "target": "ic_transport_types" }, { - "id": "ic-utils 0.37.0", + "id": "ic-utils 0.39.2", "target": "ic_utils" }, { @@ -19118,7 +19030,7 @@ "target": "opentelemetry_prometheus" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -19359,7 +19271,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -20344,7 +20256,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -20429,6 +20341,7 @@ "common": [ "alloc", "arithmetic", + "default", "der", "digest", "hazmat", @@ -20596,7 +20509,7 @@ "target": "rand_core" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -20915,6 +20828,7 @@ "common": [ "alloc", "arithmetic", + "default", "digest", "ff", "group", @@ -21789,7 +21703,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -22102,7 +22016,7 @@ "target": "once_cell" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22192,7 +22106,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22481,7 +22395,7 @@ "target": "rlp" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22562,7 +22476,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -22578,14 +22492,14 @@ ], "license_file": "LICENSE-APACHE" }, - "event-listener 4.0.3": { + "event-listener 2.5.3": { "name": "event-listener", - "version": "4.0.3", + "version": "2.5.3", "package_url": "https://github.com/smol-rs/event-listener", "repository": { "Http": { - "url": "https://static.crates.io/crates/event-listener/4.0.3/download", - "sha256": "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" + "url": "https://static.crates.io/crates/event-listener/2.5.3/download", + "sha256": "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" } }, "targets": [ @@ -22607,221 +22521,8 @@ "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "parking", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "concurrent-queue 2.5.0", - "target": "concurrent_queue" - }, - { - "id": "pin-project-lite 0.2.13", - "target": "pin_project_lite" - } - ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-apple-ios": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-apple-ios-sim": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-fuchsia": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-linux-android": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-pc-windows-msvc": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-unknown-nixos-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "aarch64-unknown-nto-qnx710": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "arm-unknown-linux-gnueabi": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "armv7-linux-androideabi": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "armv7-unknown-linux-gnueabi": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "i686-apple-darwin": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "i686-linux-android": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "i686-pc-windows-msvc": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "i686-unknown-freebsd": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "i686-unknown-linux-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "powerpc-unknown-linux-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "riscv32imc-unknown-none-elf": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "riscv64gc-unknown-none-elf": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "s390x-unknown-linux-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "thumbv7em-none-eabi": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "thumbv8m.main-none-eabi": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-apple-darwin": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-apple-ios": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-fuchsia": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-linux-android": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-unknown-freebsd": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ], - "x86_64-unknown-none": [ - { - "id": "parking 2.1.1", - "target": "parking" - } - ] - } - }, - "edition": "2021", - "version": "4.0.3" + "edition": "2018", + "version": "2.5.3" }, "license": "Apache-2.0 OR MIT", "license_ids": [ @@ -22830,14 +22531,266 @@ ], "license_file": "LICENSE-APACHE" }, - "event-listener 5.3.1": { + "event-listener 4.0.3": { "name": "event-listener", - "version": "5.3.1", + "version": "4.0.3", "package_url": "https://github.com/smol-rs/event-listener", "repository": { "Http": { - "url": "https://static.crates.io/crates/event-listener/5.3.1/download", - "sha256": "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" + "url": "https://static.crates.io/crates/event-listener/4.0.3/download", + "sha256": "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" + } + }, + "targets": [ + { + "Library": { + "crate_name": "event_listener", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "event_listener", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "parking", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "concurrent-queue 2.5.0", + "target": "concurrent_queue" + }, + { + "id": "pin-project-lite 0.2.13", + "target": "pin_project_lite" + } + ], + "selects": { + "aarch64-apple-darwin": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-apple-ios": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-apple-ios-sim": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-fuchsia": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-linux-android": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-pc-windows-msvc": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-unknown-linux-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-unknown-nixos-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "aarch64-unknown-nto-qnx710": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "arm-unknown-linux-gnueabi": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "armv7-linux-androideabi": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "armv7-unknown-linux-gnueabi": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "i686-apple-darwin": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "i686-linux-android": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "i686-pc-windows-msvc": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "i686-unknown-freebsd": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "i686-unknown-linux-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "powerpc-unknown-linux-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "riscv32imc-unknown-none-elf": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "riscv64gc-unknown-none-elf": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "s390x-unknown-linux-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "thumbv7em-none-eabi": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "thumbv8m.main-none-eabi": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-apple-darwin": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-apple-ios": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-fuchsia": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-linux-android": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-pc-windows-msvc": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-unknown-freebsd": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-unknown-linux-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-unknown-nixos-gnu": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ], + "x86_64-unknown-none": [ + { + "id": "parking 2.1.1", + "target": "parking" + } + ] + } + }, + "edition": "2021", + "version": "4.0.3" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "event-listener 5.3.1": { + "name": "event-listener", + "version": "5.3.1", + "package_url": "https://github.com/smol-rs/event-listener", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/event-listener/5.3.1/download", + "sha256": "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" } }, "targets": [ @@ -23247,7 +23200,7 @@ "target": "num_bigint" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -26568,7 +26521,7 @@ "target": "allocator_api2" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -27219,7 +27172,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -28282,62 +28235,6 @@ ], "license_file": "LICENSE" }, - "http-body-to-bytes 0.2.0": { - "name": "http-body-to-bytes", - "version": "0.2.0", - "package_url": "https://github.com/bk-rs/http-body-ext", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/http-body-to-bytes/0.2.0/download", - "sha256": "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" - } - }, - "targets": [ - { - "Library": { - "crate_name": "http_body_to_bytes", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "http_body_to_bytes", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bytes 1.9.0", - "target": "bytes" - }, - { - "id": "http-body 1.0.1", - "target": "http_body" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.0" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, "http-body-util 0.1.2": { "name": "http-body-util", "version": "0.1.2", @@ -28638,7 +28535,7 @@ "target": "humantime" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -29878,14 +29775,14 @@ ], "license_file": "LICENSE-APACHE" }, - "ic-agent 0.37.1": { + "ic-agent 0.39.2": { "name": "ic-agent", - "version": "0.37.1", + "version": "0.39.2", "package_url": "https://github.com/dfinity/agent-rs", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-agent/0.37.1/download", - "sha256": "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" + "url": "https://static.crates.io/crates/ic-agent/0.39.2/download", + "sha256": "1ba408987ca48fc3eee6a613e760d076a9046cccbbb5ba29efbada339ab28ed9" } }, "targets": [ @@ -29910,19 +29807,29 @@ "crate_features": { "common": [ "default", - "experimental_sync_call", - "hyper", "pem", - "reqwest" + "ring" ], "selects": {} }, "deps": { "common": [ + { + "id": "arc-swap 1.7.1", + "target": "arc_swap" + }, + { + "id": "async-channel 1.9.0", + "target": "async_channel" + }, { "id": "async-lock 3.3.0", "target": "async_lock" }, + { + "id": "async-watch 0.3.1", + "target": "async_watch" + }, { "id": "backoff 0.4.0", "target": "backoff" @@ -29935,10 +29842,22 @@ "id": "candid 0.10.10", "target": "candid" }, + { + "id": "der 0.7.8", + "target": "der" + }, + { + "id": "ecdsa 0.16.9", + "target": "ecdsa" + }, { "id": "ed25519-consensus 2.1.0", "target": "ed25519_consensus" }, + { + "id": "elliptic-curve 0.13.8", + "target": "elliptic_curve" + }, { "id": "futures-util 0.3.31", "target": "futures_util" @@ -29956,15 +29875,11 @@ "target": "http_body" }, { - "id": "hyper 1.5.1", - "target": "hyper" - }, - { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-transport-types 0.37.1", + "id": "ic-transport-types 0.39.2", "target": "ic_transport_types" }, { @@ -30012,7 +29927,7 @@ "target": "sec1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -30032,732 +29947,32 @@ "target": "simple_asn1" }, { - "id": "thiserror 1.0.68", + "id": "stop-token 0.7.0", + "target": "stop_token" + }, + { + "id": "thiserror 2.0.3", "target": "thiserror" }, { "id": "time 0.3.36", "target": "time" }, + { + "id": "tower-service 0.3.3", + "target": "tower_service" + }, { "id": "url 2.5.3", "target": "url" } ], "selects": { - "aarch64-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-apple-ios": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-apple-ios-sim": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-fuchsia": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-nixos-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-nto-qnx710": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "arm-unknown-linux-gnueabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "armv7-linux-androideabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "armv7-unknown-linux-gnueabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], "cfg(not(target_family = \"wasm\"))": [ - { - "id": "rustls-webpki 0.102.8", - "target": "webpki" - }, { "id": "tokio 1.42.0", "target": "tokio" } - ], - "i686-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-unknown-freebsd": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "powerpc-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "riscv32imc-unknown-none-elf": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "riscv64gc-unknown-none-elf": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "s390x-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "thumbv7em-none-eabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "thumbv8m.main-none-eabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-apple-ios": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-fuchsia": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-freebsd": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-none": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } ] } }, @@ -30765,13 +29980,17 @@ "proc_macro_deps": { "common": [ { - "id": "serde_repr 0.1.16", + "id": "async-trait 0.1.83", + "target": "async_trait" + }, + { + "id": "serde_repr 0.1.19", "target": "serde_repr" } ], "selects": {} }, - "version": "0.37.1" + "version": "0.39.2" }, "license": "Apache-2.0", "license_ids": [ @@ -30953,7 +30172,7 @@ "target": "scopeguard" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31095,7 +30314,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31146,7 +30365,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -31161,14 +30380,16 @@ ], "license_file": "LICENSE" }, - "ic-canister-sig-creation 1.0.1": { + "ic-canister-sig-creation 1.1.0": { "name": "ic-canister-sig-creation", - "version": "1.0.1", + "version": "1.1.0", "package_url": "https://github.com/dfinity/ic-canister-sig-creation", "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-canister-sig-creation/1.0.1/download", - "sha256": "5d1fc58d747480967a25810d8a90d460e7e9ea4c669ab0286541a148736513f9" + "Git": { + "remote": "https://github.com/dfinity/ic-canister-sig-creation", + "commitish": { + "Rev": "7f9e931954637526295269155881207f6c832d6d" + } } }, "targets": [ @@ -31201,15 +30422,15 @@ "target": "hex" }, { - "id": "ic-cdk 0.14.1", + "id": "ic-cdk 0.17.0", "target": "ic_cdk" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { @@ -31217,7 +30438,7 @@ "target": "lazy_static" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31233,14 +30454,14 @@ "target": "sha2" }, { - "id": "thiserror 1.0.68", + "id": "thiserror 2.0.3", "target": "thiserror" } ], "selects": {} }, "edition": "2021", - "version": "1.0.1" + "version": "1.1.0" }, "license": "Apache-2.0", "license_ids": [ @@ -31248,14 +30469,14 @@ ], "license_file": "LICENSE" }, - "ic-cbor 2.6.0": { + "ic-cbor 3.0.2": { "name": "ic-cbor", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-cbor/2.6.0/download", - "sha256": "02b0e48b4166c891e79d624f3a184b4a7c145d307576872d9a46dedb8c73ea8f" + "url": "https://static.crates.io/crates/ic-cbor/3.0.2/download", + "sha256": "5500d6e85bc2ca8ea8aaed16cb84811882589244831a2fd8eefe02e90b3006c6" } }, "targets": [ @@ -31284,7 +30505,7 @@ "target": "candid" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -31303,7 +30524,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -31351,7 +30572,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31379,74 +30600,6 @@ ], "license_file": "LICENSE" }, - "ic-cdk 0.14.1": { - "name": "ic-cdk", - "version": "0.14.1", - "package_url": "https://github.com/dfinity/cdk-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-cdk/0.14.1/download", - "sha256": "9cff1a3c3db565e3384c9c9d6d676b0a3f89a0886f4f787294d9c946d844369f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ic_cdk", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ic_cdk", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "candid 0.10.10", - "target": "candid" - }, - { - "id": "ic0 0.23.0", - "target": "ic0" - }, - { - "id": "serde 1.0.214", - "target": "serde" - }, - { - "id": "serde_bytes 0.11.15", - "target": "serde_bytes" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "ic-cdk-macros 0.14.0", - "target": "ic_cdk_macros" - } - ], - "selects": {} - }, - "version": "0.14.1" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE" - }, "ic-cdk 0.16.0": { "name": "ic-cdk", "version": "0.16.0", @@ -31487,7 +30640,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31555,7 +30708,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31627,7 +30780,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31694,7 +30847,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31717,73 +30870,6 @@ ], "license_file": "LICENSE" }, - "ic-cdk-macros 0.14.0": { - "name": "ic-cdk-macros", - "version": "0.14.0", - "package_url": "https://github.com/dfinity/cdk-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-cdk-macros/0.14.0/download", - "sha256": "01dc6bc425ec048d6ac4137c7c0f2cfbd6f8b0be8efc568feae2b265f566117c" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "ic_cdk_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ic_cdk_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "candid 0.10.10", - "target": "candid" - }, - { - "id": "proc-macro2 1.0.89", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "serde 1.0.214", - "target": "serde" - }, - { - "id": "serde_tokenstream 0.2.1", - "target": "serde_tokenstream" - }, - { - "id": "syn 2.0.87", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.14.0" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE" - }, "ic-cdk-macros 0.16.0": { "name": "ic-cdk-macros", "version": "0.16.0", @@ -31828,7 +30914,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31895,7 +30981,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31962,7 +31048,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31985,14 +31071,14 @@ ], "license_file": "LICENSE" }, - "ic-certificate-verification 2.6.0": { + "ic-certificate-verification 3.0.2": { "name": "ic-certificate-verification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-certificate-verification/2.6.0/download", - "sha256": "586e09b06a93d930f6a33f5f909bb11d2e4a06be3635dd5da1eb0e6554b7dae4" + "url": "https://static.crates.io/crates/ic-certificate-verification/3.0.2/download", + "sha256": "2daec653eb7895b5549cdf58d871985711c03cf5e389f7800a970f4f42dc0897" } }, "targets": [ @@ -32017,7 +31103,7 @@ "deps": { "common": [ { - "id": "cached 0.47.0", + "id": "cached 0.54.0", "target": "cached" }, { @@ -32025,11 +31111,11 @@ "target": "candid" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -32064,7 +31150,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32116,7 +31202,7 @@ "target": "hex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32139,6 +31225,72 @@ ], "license_file": "LICENSE" }, + "ic-certification 3.0.2": { + "name": "ic-certification", + "version": "3.0.2", + "package_url": "https://github.com/dfinity/response-verification", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ic-certification/3.0.2/download", + "sha256": "9eae40f26fcac9c141cad54d9aa5f423efffde78ac371057c53d275ebbcad443" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic_certification", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_certification", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "serde" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_bytes 0.11.15", + "target": "serde_bytes" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "3.0.2" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "ic-certified-map 0.3.4": { "name": "ic-certified-map", "version": "0.3.4", @@ -32171,7 +31323,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32194,14 +31346,14 @@ ], "license_file": "LICENSE" }, - "ic-http-certification 2.6.0": { + "ic-http-certification 3.0.2": { "name": "ic-http-certification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-http-certification/2.6.0/download", - "sha256": "ff0b97e949845039149dc5e7ea6a7c12ee4333bb402e37bc507904643c7b3e41" + "url": "https://static.crates.io/crates/ic-http-certification/3.0.2/download", + "sha256": "479941fca8e68c2267cddf686d34ed6fb491168667ff259c08a3d65d28bd26d2" } }, "targets": [ @@ -32225,26 +31377,34 @@ ], "deps": { "common": [ + { + "id": "base64 0.22.1", + "target": "base64" + }, { "id": "candid 0.10.10", "target": "candid" }, { - "id": "http 0.2.12", + "id": "http 1.2.0", "target": "http" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, + { + "id": "serde_cbor 0.11.2", + "target": "serde_cbor" + }, { "id": "thiserror 1.0.68", "target": "thiserror" @@ -32257,7 +31417,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32265,17 +31425,14 @@ ], "license_file": "LICENSE" }, - "ic-http-gateway 0.0.0": { + "ic-http-gateway 0.1.0": { "name": "ic-http-gateway", - "version": "0.0.0", + "version": "0.1.0", "package_url": "https://github.com/dfinity/http-gateway", "repository": { - "Git": { - "remote": "https://github.com/dfinity/http-gateway", - "commitish": { - "Rev": "3be26b5a2c71bf56e05b910951c1935a1ac550c4" - }, - "strip_prefix": "packages/ic-http-gateway" + "Http": { + "url": "https://static.crates.io/crates/ic-http-gateway/0.1.0/download", + "sha256": "8e8b30a8ff19af1a7dc64b1dbe1a38f1b60c7eea566e2049f755ce3bace0e630" } }, "targets": [ @@ -32324,19 +31481,19 @@ "target": "http_body_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-response-verification 2.6.0", + "id": "ic-response-verification 3.0.2", "target": "ic_response_verification" }, { - "id": "ic-utils 0.37.0", + "id": "ic-utils 0.39.2", "target": "ic_utils" }, { @@ -32347,7 +31504,7 @@ "selects": {} }, "edition": "2021", - "version": "0.0.0" + "version": "0.1.0" }, "license": "Apache-2.0", "license_ids": [ @@ -32393,14 +31550,14 @@ ], "license_file": "LICENSE" }, - "ic-representation-independent-hash 2.6.0": { + "ic-representation-independent-hash 3.0.2": { "name": "ic-representation-independent-hash", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-representation-independent-hash/2.6.0/download", - "sha256": "08ae59483e377cd9aad94ec339ed1d2583b0d5929cab989328dac2d853b2f570" + "url": "https://static.crates.io/crates/ic-representation-independent-hash/3.0.2/download", + "sha256": "3643f12824280580d31e47d380f1be23abee29944a1430c3ed22b164ac8e68db" } }, "targets": [ @@ -32436,7 +31593,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32444,14 +31601,14 @@ ], "license_file": null }, - "ic-response-verification 2.6.0": { + "ic-response-verification 3.0.2": { "name": "ic-response-verification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-response-verification/2.6.0/download", - "sha256": "2bef02ef84189d61a7d39889b7e9a3ae212d45c3df293513f7b2568027fd08a8" + "url": "https://static.crates.io/crates/ic-response-verification/3.0.2/download", + "sha256": "2b97514fada84797baf61a6a29f1c71695798c2628cb6013d97a5dd6ecc26df7" } }, "targets": [ @@ -32476,7 +31633,7 @@ "deps": { "common": [ { - "id": "base64 0.21.4", + "id": "base64 0.22.1", "target": "base64" }, { @@ -32492,27 +31649,27 @@ "target": "hex" }, { - "id": "http 0.2.12", + "id": "http 1.2.0", "target": "http" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { - "id": "ic-certificate-verification 2.6.0", + "id": "ic-certificate-verification 3.0.2", "target": "ic_certificate_verification" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { @@ -32543,7 +31700,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32706,7 +31863,7 @@ "target": "ciborium" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32773,7 +31930,7 @@ "target": "leb128" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32795,7 +31952,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_repr 0.1.16", + "id": "serde_repr 0.1.19", "target": "serde_repr" } ], @@ -32809,14 +31966,102 @@ ], "license_file": null }, - "ic-utils 0.37.0": { + "ic-transport-types 0.39.2": { + "name": "ic-transport-types", + "version": "0.39.2", + "package_url": "https://github.com/dfinity/agent-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ic-transport-types/0.39.2/download", + "sha256": "21e2418868dd5857d2a5bac3f1cb6de1aecf2316d380997ef842aec3d8a79d4e" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic_transport_types", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_transport_types", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "candid 0.10.10", + "target": "candid" + }, + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "ic-certification 3.0.2", + "target": "ic_certification" + }, + { + "id": "leb128 0.2.5", + "target": "leb128" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_bytes 0.11.15", + "target": "serde_bytes" + }, + { + "id": "serde_cbor 0.11.2", + "target": "serde_cbor" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + }, + { + "id": "thiserror 2.0.3", + "target": "thiserror" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "serde_repr 0.1.19", + "target": "serde_repr" + } + ], + "selects": {} + }, + "version": "0.39.2" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": null + }, + "ic-utils 0.39.2": { "name": "ic-utils", - "version": "0.37.0", + "version": "0.39.2", "package_url": "https://github.com/dfinity/agent-rs", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-utils/0.37.0/download", - "sha256": "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" + "url": "https://static.crates.io/crates/ic-utils/0.39.2/download", + "sha256": "e1fb9c35ef4976a71d37f3ebf73ee43bb52b360be60d91d3a77f74fbc875dda4" } }, "targets": [ @@ -32855,7 +32100,7 @@ "target": "futures_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { @@ -32867,7 +32112,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32883,7 +32128,7 @@ "target": "strum" }, { - "id": "thiserror 1.0.68", + "id": "thiserror 2.0.3", "target": "thiserror" }, { @@ -32911,7 +32156,7 @@ ], "selects": {} }, - "version": "0.37.0" + "version": "0.39.2" }, "license": "Apache-2.0", "license_ids": [ @@ -33141,7 +32386,7 @@ "target": "rustc_demangle" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -33204,7 +32449,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -33479,7 +32724,7 @@ "target": "data_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -33545,7 +32790,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -34817,7 +34062,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35069,7 +34314,7 @@ "target": "hashbrown" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35647,7 +34892,7 @@ "target": "rustls_pki_types" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -35717,7 +34962,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35867,7 +35112,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35922,7 +35167,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -36076,7 +35321,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36576,7 +35821,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36636,7 +35881,7 @@ "target": "pest" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -36781,7 +36026,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36845,7 +36090,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -37022,7 +36267,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -37312,7 +36557,7 @@ "target": "secrecy" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -37407,7 +36652,7 @@ "target": "k8s_openapi" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -40276,8 +39521,6 @@ ], "crate_features": { "common": [ - "max_level_off", - "release_max_level_off", "std" ], "selects": {} @@ -41266,7 +40509,7 @@ "target": "memchr" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -41902,7 +41145,7 @@ "target": "rustls_pemfile" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -43431,7 +42674,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -43520,7 +42763,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -44303,7 +43546,7 @@ "target": "num_traits" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -44408,7 +43651,7 @@ "target": "rand" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -46160,7 +45403,7 @@ "target": "opentelemetry_proto" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -46384,7 +45627,7 @@ "target": "opentelemetry" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -46951,14 +46194,14 @@ ], "license_file": "LICENSE" }, - "opentelemetry_sdk 0.27.0": { + "opentelemetry_sdk 0.27.1": { "name": "opentelemetry_sdk", - "version": "0.27.0", + "version": "0.27.1", "package_url": "https://github.com/open-telemetry/opentelemetry-rust", "repository": { "Http": { - "url": "https://static.crates.io/crates/opentelemetry_sdk/0.27.0/download", - "sha256": "27b742c1cae4693792cc564e58d75a2a0ba29421a34a85b50da92efa89ecb2bc" + "url": "https://static.crates.io/crates/opentelemetry_sdk/0.27.1/download", + "sha256": "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" } }, "targets": [ @@ -47017,10 +46260,6 @@ "id": "glob 0.3.1", "target": "glob" }, - { - "id": "once_cell 1.19.0", - "target": "once_cell" - }, { "id": "opentelemetry 0.27.0", "target": "opentelemetry" @@ -47066,7 +46305,7 @@ ], "selects": {} }, - "version": "0.27.0" + "version": "0.27.1" }, "license": "Apache-2.0", "license_ids": [ @@ -47502,7 +46741,7 @@ "target": "byte_slice_cast" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -50021,7 +49260,7 @@ "target": "schemars" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -50357,7 +49596,7 @@ "target": "embedded_io" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -51337,7 +50576,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -56584,7 +55823,7 @@ "target": "http" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -57734,7 +56973,7 @@ "target": "mime_guess" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -60922,7 +60161,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -62408,7 +61647,7 @@ "target": "ring" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -63064,104 +62303,7 @@ "ring", "std" ], - "selects": { - "aarch64-apple-darwin": [ - "default" - ], - "aarch64-apple-ios": [ - "default" - ], - "aarch64-apple-ios-sim": [ - "default" - ], - "aarch64-fuchsia": [ - "default" - ], - "aarch64-linux-android": [ - "default" - ], - "aarch64-pc-windows-msvc": [ - "default" - ], - "aarch64-unknown-linux-gnu": [ - "default" - ], - "aarch64-unknown-nixos-gnu": [ - "default" - ], - "aarch64-unknown-nto-qnx710": [ - "default" - ], - "arm-unknown-linux-gnueabi": [ - "default" - ], - "armv7-linux-androideabi": [ - "default" - ], - "armv7-unknown-linux-gnueabi": [ - "default" - ], - "i686-apple-darwin": [ - "default" - ], - "i686-linux-android": [ - "default" - ], - "i686-pc-windows-msvc": [ - "default" - ], - "i686-unknown-freebsd": [ - "default" - ], - "i686-unknown-linux-gnu": [ - "default" - ], - "powerpc-unknown-linux-gnu": [ - "default" - ], - "riscv32imc-unknown-none-elf": [ - "default" - ], - "riscv64gc-unknown-none-elf": [ - "default" - ], - "s390x-unknown-linux-gnu": [ - "default" - ], - "thumbv7em-none-eabi": [ - "default" - ], - "thumbv8m.main-none-eabi": [ - "default" - ], - "x86_64-apple-darwin": [ - "default" - ], - "x86_64-apple-ios": [ - "default" - ], - "x86_64-fuchsia": [ - "default" - ], - "x86_64-linux-android": [ - "default" - ], - "x86_64-pc-windows-msvc": [ - "default" - ], - "x86_64-unknown-freebsd": [ - "default" - ], - "x86_64-unknown-linux-gnu": [ - "default" - ], - "x86_64-unknown-nixos-gnu": [ - "default" - ], - "x86_64-unknown-none": [ - "default" - ] - } + "selects": {} }, "deps": { "common": [ @@ -63660,7 +62802,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -64191,7 +63333,7 @@ "target": "secp256k1_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -64262,7 +63404,7 @@ "target": "secp256k1_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -64634,7 +63776,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -64978,7 +64120,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65002,14 +64144,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde 1.0.214": { + "serde 1.0.217": { "name": "serde", - "version": "1.0.214", + "version": "1.0.217", "package_url": "https://github.com/serde-rs/serde", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde/1.0.214/download", - "sha256": "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" + "url": "https://static.crates.io/crates/serde/1.0.217/download", + "sha256": "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" } }, "targets": [ @@ -65057,7 +64199,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "build_script_build" } ], @@ -65067,13 +64209,13 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], "selects": {} }, - "version": "1.0.214" + "version": "1.0.217" }, "build_script_attrs": { "compile_data_glob": [ @@ -65130,7 +64272,7 @@ "target": "hex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65181,7 +64323,7 @@ "target": "ordered_float" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65232,7 +64374,7 @@ "target": "js_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65290,7 +64432,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65349,7 +64491,7 @@ "target": "half" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65365,14 +64507,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde_derive 1.0.214": { + "serde_derive 1.0.217": { "name": "serde_derive", - "version": "1.0.214", + "version": "1.0.217", "package_url": "https://github.com/serde-rs/serde", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde_derive/1.0.214/download", - "sha256": "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" + "url": "https://static.crates.io/crates/serde_derive/1.0.217/download", + "sha256": "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" } }, "targets": [ @@ -65418,7 +64560,7 @@ "selects": {} }, "edition": "2015", - "version": "1.0.214" + "version": "1.0.217" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -65550,7 +64692,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65614,7 +64756,7 @@ "target": "itoa" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65666,7 +64808,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65722,7 +64864,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65738,14 +64880,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde_repr 0.1.16": { + "serde_repr 0.1.19": { "name": "serde_repr", - "version": "0.1.16", + "version": "0.1.19", "package_url": "https://github.com/dtolnay/serde-repr", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde_repr/0.1.16/download", - "sha256": "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" + "url": "https://static.crates.io/crates/serde_repr/0.1.19/download", + "sha256": "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" } }, "targets": [ @@ -65785,7 +64927,7 @@ "selects": {} }, "edition": "2021", - "version": "0.1.16" + "version": "0.1.19" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -65830,7 +64972,7 @@ "target": "proc_macro2" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65889,7 +65031,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65952,7 +65094,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -66008,7 +65150,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -66079,7 +65221,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -66196,7 +65338,7 @@ "deps": { "common": [ { - "id": "darling 0.20.3", + "id": "darling 0.20.10", "target": "darling" }, { @@ -66264,7 +65406,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -66328,7 +65470,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -67896,7 +67038,7 @@ "target": "erased_serde" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -68235,7 +67377,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -69009,6 +68151,66 @@ ], "license_file": "LICENSE-APACHE" }, + "stop-token 0.7.0": { + "name": "stop-token", + "version": "0.7.0", + "package_url": "https://github.com/async-rs/stop-token", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/stop-token/0.7.0/download", + "sha256": "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "stop_token", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "stop_token", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "async-channel 1.9.0", + "target": "async_channel" + }, + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "futures-core 0.3.31", + "target": "futures_core" + }, + { + "id": "pin-project-lite 0.2.13", + "target": "pin_project_lite" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.7.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": null + }, "str_stack 0.1.0": { "name": "str_stack", "version": "0.1.0", @@ -69108,7 +68310,7 @@ "target": "precomputed_hash" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -71029,7 +70231,7 @@ "target": "rand" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -73077,7 +72279,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -74235,7 +73437,7 @@ "target": "pin_project" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -74655,7 +73857,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -76300,7 +75502,7 @@ "target": "opentelemetry" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -76378,7 +75580,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -76429,7 +75631,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -76584,7 +75786,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -78146,7 +77348,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -78447,7 +77649,7 @@ "target": "getrandom" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -78683,7 +77885,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -79215,7 +78417,7 @@ "target": "scoped_tls" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -80166,7 +79368,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80243,7 +79445,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80321,7 +79523,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80564,7 +79766,7 @@ "target": "rayon" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -80833,7 +80035,7 @@ "target": "paste" }, { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" }, { @@ -81274,7 +80476,7 @@ "target": "postcard" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -81304,7 +80506,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -85010,7 +84212,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -85032,7 +84234,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -85250,7 +84452,7 @@ "target": "data_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -87710,27 +86912,27 @@ "hyper-rustls 0.27.3", "hyper-socks2 0.9.1", "hyper-util 0.1.10", - "ic-agent 0.37.1", + "ic-agent 0.39.2", "ic-bn-lib 0.1.0", "ic-btc-interface 0.2.2", "ic-canister-log 0.2.0", - "ic-canister-sig-creation 1.0.1", - "ic-cbor 2.6.0", + "ic-canister-sig-creation 1.1.0", + "ic-cbor 3.0.2", "ic-cdk 0.16.0", "ic-cdk-macros 0.9.0", "ic-cdk-timers 0.11.0", - "ic-certificate-verification 2.6.0", - "ic-certification 2.6.0", + "ic-certificate-verification 3.0.2", + "ic-certification 3.0.2", "ic-certified-map 0.3.4", - "ic-http-certification 2.6.0", - "ic-http-gateway 0.0.0", + "ic-http-certification 3.0.2", + "ic-http-gateway 0.1.0", "ic-metrics-encoder 1.1.1", - "ic-response-verification 2.6.0", + "ic-response-verification 3.0.2", "ic-sha3 1.0.0", "ic-stable-structures 0.6.5", "ic-test-state-machine-client 3.0.1", - "ic-transport-types 0.37.1", - "ic-utils 0.37.0", + "ic-transport-types 0.39.2", + "ic-utils 0.39.2", "ic-verify-bls-signature 0.6.0", "ic-wasm 0.8.4", "ic-xrc-types 1.2.0", @@ -87790,7 +86992,7 @@ "opentelemetry 0.27.0", "opentelemetry-otlp 0.27.0", "opentelemetry-prometheus 0.13.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "p256 0.13.2", "pairing 0.23.0", "parking_lot 0.12.1", @@ -87854,7 +87056,7 @@ "scraper 0.17.1", "secp256k1 0.22.2", "semver 1.0.22", - "serde 1.0.214", + "serde 1.0.217", "serde-bytes-repr 0.1.5", "serde_bytes 0.11.15", "serde_cbor 0.11.2", diff --git a/Cargo.Bazel.Fuzzing.toml.lock b/Cargo.Bazel.Fuzzing.toml.lock index 2031cd4ec12..44f13247684 100644 --- a/Cargo.Bazel.Fuzzing.toml.lock +++ b/Cargo.Bazel.Fuzzing.toml.lock @@ -570,6 +570,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-channel" version = "2.3.1" @@ -723,6 +734,15 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "async-watch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a078faf4e27c0c6cc0efb20e5da59dcccc04968ebf2801d8e0b2195124cdcdb2" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-web-client" version = "0.6.2" @@ -1342,7 +1362,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel", + "async-channel 2.3.1", "async-task", "futures-io", "futures-lite", @@ -1610,13 +1630,10 @@ checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" [[package]] name = "cached" -version = "0.47.0" +version = "0.49.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" +checksum = "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" dependencies = [ - "ahash 0.8.11", - "cached_proc_macro", - "cached_proc_macro_types", "hashbrown 0.14.5", "instant", "once_cell", @@ -1625,10 +1642,11 @@ dependencies = [ [[package]] name = "cached" -version = "0.49.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" +checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" dependencies = [ + "ahash 0.8.11", "hashbrown 0.14.5", "instant", "once_cell", @@ -1637,34 +1655,36 @@ dependencies = [ [[package]] name = "cached" -version = "0.52.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" +checksum = "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" dependencies = [ "ahash 0.8.11", + "cached_proc_macro", + "cached_proc_macro_types", "hashbrown 0.14.5", - "instant", "once_cell", "thiserror 1.0.68", + "web-time", ] [[package]] name = "cached_proc_macro" -version = "0.18.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" dependencies = [ - "darling 0.14.4", + "darling 0.20.10", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "camino" @@ -2720,22 +2740,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -2754,29 +2764,15 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", + "strsim 0.11.1", "syn 2.0.87", ] @@ -2793,22 +2789,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.10", "quote", "syn 2.0.87", ] @@ -3094,7 +3079,7 @@ dependencies = [ "ic-cdk-macros 0.9.0", "ic-cdk-timers", "ic-certificate-verification", - "ic-certification", + "ic-certification 3.0.2", "ic-certified-map", "ic-http-certification", "ic-http-gateway", @@ -3103,7 +3088,7 @@ dependencies = [ "ic-sha3", "ic-stable-structures", "ic-test-state-machine-client", - "ic-transport-types", + "ic-transport-types 0.39.2", "ic-utils", "ic-verify-bls-signature 0.6.0", "ic-wasm", @@ -3164,7 +3149,7 @@ dependencies = [ "opentelemetry 0.27.0", "opentelemetry-otlp", "opentelemetry-prometheus 0.13.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "p256", "pairing", "parking_lot 0.12.1", @@ -3792,6 +3777,12 @@ dependencies = [ "serde", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "event-listener" version = "4.0.3" @@ -4685,17 +4676,6 @@ dependencies = [ "http 1.2.0", ] -[[package]] -name = "http-body-to-bytes" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" -dependencies = [ - "bytes", - "http-body 1.0.1", - "http-body-util", -] - [[package]] name = "http-body-util" version = "0.1.2" @@ -4919,26 +4899,28 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.37.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" +checksum = "1ba408987ca48fc3eee6a613e760d076a9046cccbbb5ba29efbada339ab28ed9" dependencies = [ + "arc-swap", + "async-channel 1.9.0", "async-lock", + "async-trait", + "async-watch", "backoff", "cached 0.52.0", "candid", + "der", + "ecdsa", "ed25519-consensus", + "elliptic-curve", "futures-util", "hex", "http 1.2.0", "http-body 1.0.1", - "http-body-to-bytes", - "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", - "hyper-util", - "ic-certification", - "ic-transport-types", + "ic-certification 3.0.2", + "ic-transport-types 0.39.2", "ic-verify-bls-signature 0.5.0", "k256", "leb128", @@ -4949,7 +4931,6 @@ dependencies = [ "rangemap", "reqwest 0.12.9", "ring 0.17.7", - "rustls-webpki 0.102.8", "sec1", "serde", "serde_bytes", @@ -4957,10 +4938,11 @@ dependencies = [ "serde_repr", "sha2 0.10.8", "simple_asn1", - "thiserror 1.0.68", + "stop-token", + "thiserror 2.0.3", "time", "tokio", - "tower 0.4.13", + "tower-service", "url", ] @@ -5051,31 +5033,30 @@ dependencies = [ [[package]] name = "ic-canister-sig-creation" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1fc58d747480967a25810d8a90d460e7e9ea4c669ab0286541a148736513f9" +version = "1.1.0" +source = "git+https://github.com/dfinity/ic-canister-sig-creation?rev=7f9e931954637526295269155881207f6c832d6d#7f9e931954637526295269155881207f6c832d6d" dependencies = [ "candid", "hex", - "ic-cdk 0.14.1", - "ic-certification", + "ic-cdk 0.17.0", + "ic-certification 3.0.2", "ic-representation-independent-hash", "lazy_static", "serde", "serde_bytes", "serde_cbor", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 2.0.3", ] [[package]] name = "ic-cbor" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b0e48b4166c891e79d624f3a184b4a7c145d307576872d9a46dedb8c73ea8f" +checksum = "5500d6e85bc2ca8ea8aaed16cb84811882589244831a2fd8eefe02e90b3006c6" dependencies = [ "candid", - "ic-certification", + "ic-certification 3.0.2", "leb128", "nom", "thiserror 1.0.68", @@ -5094,19 +5075,6 @@ dependencies = [ "serde_bytes", ] -[[package]] -name = "ic-cdk" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cff1a3c3db565e3384c9c9d6d676b0a3f89a0886f4f787294d9c946d844369f" -dependencies = [ - "candid", - "ic-cdk-macros 0.14.0", - "ic0 0.23.0", - "serde", - "serde_bytes", -] - [[package]] name = "ic-cdk" version = "0.16.0" @@ -5161,20 +5129,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ic-cdk-macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01dc6bc425ec048d6ac4137c7c0f2cfbd6f8b0be8efc568feae2b265f566117c" -dependencies = [ - "candid", - "proc-macro2", - "quote", - "serde", - "serde_tokenstream 0.2.1", - "syn 2.0.87", -] - [[package]] name = "ic-cdk-macros" version = "0.16.0" @@ -5219,14 +5173,14 @@ dependencies = [ [[package]] name = "ic-certificate-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586e09b06a93d930f6a33f5f909bb11d2e4a06be3635dd5da1eb0e6554b7dae4" +checksum = "2daec653eb7895b5549cdf58d871985711c03cf5e389f7800a970f4f42dc0897" dependencies = [ - "cached 0.47.0", + "cached 0.54.0", "candid", "ic-cbor", - "ic-certification", + "ic-certification 3.0.2", "lazy_static", "leb128", "miracl_core_bls12381", @@ -5248,6 +5202,18 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ic-certification" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eae40f26fcac9c141cad54d9aa5f423efffde78ac371057c53d275ebbcad443" +dependencies = [ + "hex", + "serde", + "serde_bytes", + "sha2 0.10.8", +] + [[package]] name = "ic-certified-map" version = "0.3.4" @@ -5261,23 +5227,26 @@ dependencies = [ [[package]] name = "ic-http-certification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0b97e949845039149dc5e7ea6a7c12ee4333bb402e37bc507904643c7b3e41" +checksum = "479941fca8e68c2267cddf686d34ed6fb491168667ff259c08a3d65d28bd26d2" dependencies = [ + "base64 0.22.1", "candid", - "http 0.2.12", - "ic-certification", + "http 1.2.0", + "ic-certification 3.0.2", "ic-representation-independent-hash", "serde", + "serde_cbor", "thiserror 1.0.68", "urlencoding", ] [[package]] name = "ic-http-gateway" -version = "0.0.0" -source = "git+https://github.com/dfinity/http-gateway?tag=0.1.0-b0#3be26b5a2c71bf56e05b910951c1935a1ac550c4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8b30a8ff19af1a7dc64b1dbe1a38f1b60c7eea566e2049f755ce3bace0e630" dependencies = [ "bytes", "candid", @@ -5300,9 +5269,9 @@ checksum = "8b5c7628eac357aecda461130f8074468be5aa4d258a002032d82d817f79f1f8" [[package]] name = "ic-representation-independent-hash" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ae59483e377cd9aad94ec339ed1d2583b0d5929cab989328dac2d853b2f570" +checksum = "3643f12824280580d31e47d380f1be23abee29944a1430c3ed22b164ac8e68db" dependencies = [ "leb128", "sha2 0.10.8", @@ -5310,18 +5279,18 @@ dependencies = [ [[package]] name = "ic-response-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef02ef84189d61a7d39889b7e9a3ae212d45c3df293513f7b2568027fd08a8" +checksum = "2b97514fada84797baf61a6a29f1c71695798c2628cb6013d97a5dd6ecc26df7" dependencies = [ - "base64 0.21.4", + "base64 0.22.1", "candid", "flate2", "hex", - "http 0.2.12", + "http 1.2.0", "ic-cbor", "ic-certificate-verification", - "ic-certification", + "ic-certification 3.0.2", "ic-http-certification", "ic-representation-independent-hash", "leb128", @@ -5370,7 +5339,7 @@ checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" dependencies = [ "candid", "hex", - "ic-certification", + "ic-certification 2.6.0", "leb128", "serde", "serde_bytes", @@ -5379,11 +5348,29 @@ dependencies = [ "thiserror 1.0.68", ] +[[package]] +name = "ic-transport-types" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e2418868dd5857d2a5bac3f1cb6de1aecf2316d380997ef842aec3d8a79d4e" +dependencies = [ + "candid", + "hex", + "ic-certification 3.0.2", + "leb128", + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "sha2 0.10.8", + "thiserror 2.0.3", +] + [[package]] name = "ic-utils" -version = "0.37.0" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" +checksum = "e1fb9c35ef4976a71d37f3ebf73ee43bb52b360be60d91d3a77f74fbc875dda4" dependencies = [ "async-trait", "candid", @@ -5396,7 +5383,7 @@ dependencies = [ "sha2 0.10.8", "strum 0.26.3", "strum_macros 0.26.4", - "thiserror 1.0.68", + "thiserror 2.0.3", "time", "tokio", ] @@ -7479,7 +7466,7 @@ dependencies = [ "http 1.2.0", "opentelemetry 0.27.0", "opentelemetry-proto", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "prost 0.13.3", "thiserror 1.0.68", "tokio", @@ -7520,7 +7507,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" dependencies = [ "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "prost 0.13.3", "tonic", ] @@ -7627,16 +7614,15 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b742c1cae4693792cc564e58d75a2a0ba29421a34a85b50da92efa89ecb2bc" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" dependencies = [ "async-trait", "futures-channel", "futures-executor", "futures-util", "glob", - "once_cell", "opentelemetry 0.27.0", "percent-encoding", "rand 0.8.5", @@ -8140,8 +8126,8 @@ dependencies = [ "base64 0.13.1", "candid", "hex", - "ic-certification", - "ic-transport-types", + "ic-certification 2.6.0", + "ic-transport-types 0.37.1", "reqwest 0.12.9", "schemars", "serde", @@ -10022,9 +10008,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -10082,9 +10068,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -10149,9 +10135,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", @@ -10237,7 +10223,7 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.87", @@ -10675,6 +10661,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if 1.0.0", + "futures-core", + "pin-project-lite", +] + [[package]] name = "str_stack" version = "0.1.0" @@ -11767,7 +11765,7 @@ dependencies = [ "js-sys", "once_cell", "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "smallvec", "tracing", "tracing-core", diff --git a/Cargo.Bazel.json.lock b/Cargo.Bazel.json.lock index 7ab2407edb1..648b81a729a 100644 --- a/Cargo.Bazel.json.lock +++ b/Cargo.Bazel.json.lock @@ -1,5 +1,5 @@ { - "checksum": "51797bc8949c18c1a9fe4968fbc724d1f4f9237d74378b46b77f7c36a0fd2369", + "checksum": "4b1ad87a35d894e5bb253c5e0257cf4fbd0b0e806bc40273165b04099062b55d", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -537,7 +537,7 @@ "target": "regex_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -973,7 +973,7 @@ "target": "regex_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -1650,7 +1650,7 @@ "target": "schemars" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -2678,7 +2678,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -2776,7 +2776,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -3127,7 +3127,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -3288,6 +3288,62 @@ ], "license_file": "LICENSE-APACHE" }, + "async-channel 1.9.0": { + "name": "async-channel", + "version": "1.9.0", + "package_url": "https://github.com/smol-rs/async-channel", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/async-channel/1.9.0/download", + "sha256": "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" + } + }, + "targets": [ + { + "Library": { + "crate_name": "async_channel", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "async_channel", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "concurrent-queue 2.5.0", + "target": "concurrent_queue" + }, + { + "id": "event-listener 2.5.3", + "target": "event_listener" + }, + { + "id": "futures-core 0.3.31", + "target": "futures_core" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.9.0" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "async-channel 2.3.1": { "name": "async-channel", "version": "2.3.1", @@ -4107,6 +4163,54 @@ ], "license_file": "LICENSE-APACHE" }, + "async-watch 0.3.1": { + "name": "async-watch", + "version": "0.3.1", + "package_url": "https://github.com/cynecx/async-watch", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/async-watch/0.3.1/download", + "sha256": "a078faf4e27c0c6cc0efb20e5da59dcccc04968ebf2801d8e0b2195124cdcdb2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "async_watch", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "async_watch", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "event-listener 2.5.3", + "target": "event_listener" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.3.1" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "async-web-client 0.6.2": { "name": "async-web-client", "version": "0.6.2", @@ -4549,7 +4653,7 @@ "target": "pin_project_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -4812,7 +4916,7 @@ "target": "pin_project_lite" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -5803,7 +5907,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6029,7 +6133,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6700,7 +6804,7 @@ "target": "secp256k1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -6795,7 +6899,7 @@ "target": "secp256k1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde", "alias": "actual_serde" } @@ -7214,7 +7318,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -7274,7 +7378,7 @@ "alias": "internals" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -7393,7 +7497,7 @@ "target": "log" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -7448,7 +7552,7 @@ "target": "bitcoin" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -8656,7 +8760,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -8962,7 +9066,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -9243,7 +9347,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -9475,14 +9579,14 @@ ], "license_file": null }, - "cached 0.47.0": { + "cached 0.49.2": { "name": "cached", - "version": "0.47.0", + "version": "0.49.2", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.47.0/download", - "sha256": "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" + "url": "https://static.crates.io/crates/cached/0.49.2/download", + "sha256": "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" } }, "targets": [ @@ -9504,26 +9608,8 @@ "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "ahash", - "cached_proc_macro", - "cached_proc_macro_types", - "default", - "proc_macro" - ], - "selects": {} - }, "deps": { "common": [ - { - "id": "ahash 0.8.11", - "target": "ahash" - }, - { - "id": "cached_proc_macro_types 0.1.0", - "target": "cached_proc_macro_types" - }, { "id": "hashbrown 0.14.5", "target": "hashbrown" @@ -9544,16 +9630,7 @@ "selects": {} }, "edition": "2018", - "proc_macro_deps": { - "common": [ - { - "id": "cached_proc_macro 0.18.1", - "target": "cached_proc_macro" - } - ], - "selects": {} - }, - "version": "0.47.0" + "version": "0.49.2" }, "license": "MIT", "license_ids": [ @@ -9561,14 +9638,14 @@ ], "license_file": "LICENSE" }, - "cached 0.49.2": { + "cached 0.52.0": { "name": "cached", - "version": "0.49.2", + "version": "0.52.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.49.2/download", - "sha256": "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" + "url": "https://static.crates.io/crates/cached/0.52.0/download", + "sha256": "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" } }, "targets": [ @@ -9590,8 +9667,18 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "ahash" + ], + "selects": {} + }, "deps": { "common": [ + { + "id": "ahash 0.8.11", + "target": "ahash" + }, { "id": "hashbrown 0.14.5", "target": "hashbrown" @@ -9612,7 +9699,7 @@ "selects": {} }, "edition": "2018", - "version": "0.49.2" + "version": "0.52.0" }, "license": "MIT", "license_ids": [ @@ -9620,14 +9707,14 @@ ], "license_file": "LICENSE" }, - "cached 0.52.0": { + "cached 0.54.0": { "name": "cached", - "version": "0.52.0", + "version": "0.54.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached/0.52.0/download", - "sha256": "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" + "url": "https://static.crates.io/crates/cached/0.54.0/download", + "sha256": "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" } }, "targets": [ @@ -9651,7 +9738,11 @@ ], "crate_features": { "common": [ - "ahash" + "ahash", + "cached_proc_macro", + "cached_proc_macro_types", + "default", + "proc_macro" ], "selects": {} }, @@ -9662,12 +9753,12 @@ "target": "ahash" }, { - "id": "hashbrown 0.14.5", - "target": "hashbrown" + "id": "cached_proc_macro_types 0.1.1", + "target": "cached_proc_macro_types" }, { - "id": "instant 0.1.12", - "target": "instant" + "id": "hashbrown 0.14.5", + "target": "hashbrown" }, { "id": "once_cell 1.19.0", @@ -9676,12 +9767,25 @@ { "id": "thiserror 1.0.68", "target": "thiserror" + }, + { + "id": "web-time 1.1.0", + "target": "web_time" } ], "selects": {} }, "edition": "2018", - "version": "0.52.0" + "proc_macro_deps": { + "common": [ + { + "id": "cached_proc_macro 0.23.0", + "target": "cached_proc_macro" + } + ], + "selects": {} + }, + "version": "0.54.0" }, "license": "MIT", "license_ids": [ @@ -9689,14 +9793,14 @@ ], "license_file": "LICENSE" }, - "cached_proc_macro 0.18.1": { + "cached_proc_macro 0.23.0": { "name": "cached_proc_macro", - "version": "0.18.1", + "version": "0.23.0", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached_proc_macro/0.18.1/download", - "sha256": "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" + "url": "https://static.crates.io/crates/cached_proc_macro/0.23.0/download", + "sha256": "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" } }, "targets": [ @@ -9721,7 +9825,7 @@ "deps": { "common": [ { - "id": "darling 0.14.4", + "id": "darling 0.20.10", "target": "darling" }, { @@ -9733,29 +9837,29 @@ "target": "quote" }, { - "id": "syn 1.0.109", + "id": "syn 2.0.87", "target": "syn" } ], "selects": {} }, "edition": "2018", - "version": "0.18.1" + "version": "0.23.0" }, "license": "MIT", "license_ids": [ "MIT" ], - "license_file": null + "license_file": "LICENSE" }, - "cached_proc_macro_types 0.1.0": { + "cached_proc_macro_types 0.1.1": { "name": "cached_proc_macro_types", - "version": "0.1.0", + "version": "0.1.1", "package_url": "https://github.com/jaemk/cached", "repository": { "Http": { - "url": "https://static.crates.io/crates/cached_proc_macro_types/0.1.0/download", - "sha256": "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" + "url": "https://static.crates.io/crates/cached_proc_macro_types/0.1.1/download", + "sha256": "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" } }, "targets": [ @@ -9778,13 +9882,13 @@ "**" ], "edition": "2018", - "version": "0.1.0" + "version": "0.1.1" }, "license": "MIT", "license_ids": [ "MIT" ], - "license_file": null + "license_file": "LICENSE" }, "camino 1.1.6": { "name": "camino", @@ -9841,7 +9945,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -9945,7 +10049,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10016,7 +10120,7 @@ "target": "ic_cdk" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -10174,7 +10278,7 @@ "target": "pretty" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10424,7 +10528,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -10490,7 +10594,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -10869,7 +10973,7 @@ "target": "regex_syntax" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -11520,7 +11624,7 @@ "target": "num_traits" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -11772,7 +11876,7 @@ "target": "ciborium_ll" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -12718,7 +12822,7 @@ "target": "reqwest" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -13047,7 +13151,7 @@ "target": "pretty_assertions" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -13861,7 +13965,7 @@ "target": "log" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -13920,7 +14024,7 @@ "target": "bitcoin_private" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -14141,7 +14245,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -14151,7 +14255,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -14496,7 +14600,7 @@ "target": "cranelift_bitset" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -14506,7 +14610,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -14911,7 +15015,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -14937,7 +15041,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -16233,7 +16337,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -16745,77 +16849,14 @@ ], "license_file": "LICENSE" }, - "darling 0.14.4": { - "name": "darling", - "version": "0.14.4", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling/0.14.4/download", - "sha256": "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" - } - }, - "targets": [ - { - "Library": { - "crate_name": "darling", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "suggestions" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "darling_core 0.14.4", - "target": "darling_core" - } - ], - "selects": {} - }, - "edition": "2018", - "proc_macro_deps": { - "common": [ - { - "id": "darling_macro 0.14.4", - "target": "darling_macro" - } - ], - "selects": {} - }, - "version": "0.14.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling 0.20.3": { + "darling 0.20.10": { "name": "darling", - "version": "0.20.3", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling/0.20.3/download", - "sha256": "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" + "url": "https://static.crates.io/crates/darling/0.20.10/download", + "sha256": "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" } }, "targets": [ @@ -16847,23 +16888,23 @@ "deps": { "common": [ { - "id": "darling_core 0.20.3", + "id": "darling_core 0.20.10", "target": "darling_core" } ], "selects": {} }, - "edition": "2018", + "edition": "2021", "proc_macro_deps": { "common": [ { - "id": "darling_macro 0.20.3", + "id": "darling_macro 0.20.10", "target": "darling_macro" } ], "selects": {} }, - "version": "0.20.3" + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -16945,14 +16986,14 @@ ], "license_file": "LICENSE" }, - "darling_core 0.14.4": { + "darling_core 0.20.10": { "name": "darling_core", - "version": "0.14.4", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_core/0.14.4/download", - "sha256": "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" + "url": "https://static.crates.io/crates/darling_core/0.20.10/download", + "sha256": "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" } }, "targets": [ @@ -17000,18 +17041,18 @@ "target": "quote" }, { - "id": "strsim 0.10.0", + "id": "strsim 0.11.1", "target": "strsim" }, { - "id": "syn 1.0.109", + "id": "syn 2.0.87", "target": "syn" } ], "selects": {} }, - "edition": "2018", - "version": "0.14.4" + "edition": "2021", + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -17019,20 +17060,20 @@ ], "license_file": "LICENSE" }, - "darling_core 0.20.3": { - "name": "darling_core", - "version": "0.20.3", + "darling_macro 0.13.4": { + "name": "darling_macro", + "version": "0.13.4", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_core/0.20.3/download", - "sha256": "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" + "url": "https://static.crates.io/crates/darling_macro/0.13.4/download", + "sha256": "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" } }, "targets": [ { - "Library": { - "crate_name": "darling_core", + "ProcMacro": { + "crate_name": "darling_macro", "crate_root": "src/lib.rs", "srcs": { "allow_empty": true, @@ -17043,49 +17084,30 @@ } } ], - "library_target_name": "darling_core", + "library_target_name": "darling_macro", "common_attrs": { "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "strsim", - "suggestions" - ], - "selects": {} - }, "deps": { "common": [ { - "id": "fnv 1.0.7", - "target": "fnv" - }, - { - "id": "ident_case 1.0.1", - "target": "ident_case" - }, - { - "id": "proc-macro2 1.0.89", - "target": "proc_macro2" + "id": "darling_core 0.13.4", + "target": "darling_core" }, { "id": "quote 1.0.37", "target": "quote" }, { - "id": "strsim 0.10.0", - "target": "strsim" - }, - { - "id": "syn 2.0.87", + "id": "syn 1.0.109", "target": "syn" } ], "selects": {} }, "edition": "2018", - "version": "0.20.3" + "version": "0.13.4" }, "license": "MIT", "license_ids": [ @@ -17093,14 +17115,14 @@ ], "license_file": "LICENSE" }, - "darling_macro 0.13.4": { + "darling_macro 0.20.10": { "name": "darling_macro", - "version": "0.13.4", + "version": "0.20.10", "package_url": "https://github.com/TedDriggs/darling", "repository": { "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.13.4/download", - "sha256": "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" + "url": "https://static.crates.io/crates/darling_macro/0.20.10/download", + "sha256": "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" } }, "targets": [ @@ -17125,117 +17147,7 @@ "deps": { "common": [ { - "id": "darling_core 0.13.4", - "target": "darling_core" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "syn 1.0.109", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.13.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling_macro 0.14.4": { - "name": "darling_macro", - "version": "0.14.4", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.14.4/download", - "sha256": "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "darling_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "darling_core 0.14.4", - "target": "darling_core" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "syn 1.0.109", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.14.4" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "darling_macro 0.20.3": { - "name": "darling_macro", - "version": "0.20.3", - "package_url": "https://github.com/TedDriggs/darling", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/darling_macro/0.20.3/download", - "sha256": "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "darling_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "darling_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "darling_core 0.20.3", + "id": "darling_core 0.20.10", "target": "darling_core" }, { @@ -17249,8 +17161,8 @@ ], "selects": {} }, - "edition": "2018", - "version": "0.20.3" + "edition": "2021", + "version": "0.20.10" }, "license": "MIT", "license_ids": [ @@ -18637,7 +18549,7 @@ "target": "hyper_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { @@ -18653,11 +18565,11 @@ "target": "ic_canister_log" }, { - "id": "ic-canister-sig-creation 1.0.1", + "id": "ic-canister-sig-creation 1.1.0", "target": "ic_canister_sig_creation" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { @@ -18669,11 +18581,11 @@ "target": "ic_cdk_timers" }, { - "id": "ic-certificate-verification 2.6.0", + "id": "ic-certificate-verification 3.0.2", "target": "ic_certificate_verification" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -18681,11 +18593,11 @@ "target": "ic_certified_map" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-http-gateway 0.0.0", + "id": "ic-http-gateway 0.1.0", "target": "ic_http_gateway" }, { @@ -18693,7 +18605,7 @@ "target": "ic_metrics_encoder" }, { - "id": "ic-response-verification 2.6.0", + "id": "ic-response-verification 3.0.2", "target": "ic_response_verification" }, { @@ -18709,11 +18621,11 @@ "target": "ic_test_state_machine_client" }, { - "id": "ic-transport-types 0.37.1", + "id": "ic-transport-types 0.39.2", "target": "ic_transport_types" }, { - "id": "ic-utils 0.37.0", + "id": "ic-utils 0.39.0", "target": "ic_utils" }, { @@ -18946,7 +18858,7 @@ "target": "opentelemetry_prometheus" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -19187,7 +19099,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -20172,7 +20084,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -20257,6 +20169,7 @@ "common": [ "alloc", "arithmetic", + "default", "der", "digest", "hazmat", @@ -20424,7 +20337,7 @@ "target": "rand_core" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -20743,6 +20656,7 @@ "common": [ "alloc", "arithmetic", + "default", "digest", "ff", "group", @@ -21633,7 +21547,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -21954,7 +21868,7 @@ "target": "once_cell" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22044,7 +21958,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22332,7 +22246,7 @@ "target": "rlp" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -22413,7 +22327,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -22429,14 +22343,14 @@ ], "license_file": "LICENSE-APACHE" }, - "event-listener 4.0.3": { + "event-listener 2.5.3": { "name": "event-listener", - "version": "4.0.3", + "version": "2.5.3", "package_url": "https://github.com/smol-rs/event-listener", "repository": { "Http": { - "url": "https://static.crates.io/crates/event-listener/4.0.3/download", - "sha256": "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" + "url": "https://static.crates.io/crates/event-listener/2.5.3/download", + "sha256": "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" } }, "targets": [ @@ -22458,221 +22372,8 @@ "compile_data_glob": [ "**" ], - "crate_features": { - "common": [ - "parking", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "concurrent-queue 2.5.0", - "target": "concurrent_queue" - }, - { - "id": "pin-project-lite 0.2.13", - "target": "pin_project_lite" - } - ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-apple-ios": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-apple-ios-sim": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-fuchsia": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-linux-android": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-pc-windows-msvc": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-unknown-nixos-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "aarch64-unknown-nto-qnx710": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "arm-unknown-linux-gnueabi": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "armv7-linux-androideabi": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "armv7-unknown-linux-gnueabi": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "i686-apple-darwin": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "i686-linux-android": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "i686-pc-windows-msvc": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "i686-unknown-freebsd": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "i686-unknown-linux-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "powerpc-unknown-linux-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "riscv32imc-unknown-none-elf": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "riscv64gc-unknown-none-elf": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "s390x-unknown-linux-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "thumbv7em-none-eabi": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "thumbv8m.main-none-eabi": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-apple-darwin": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-apple-ios": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-fuchsia": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-linux-android": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-unknown-freebsd": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ], - "x86_64-unknown-none": [ - { - "id": "parking 2.1.0", - "target": "parking" - } - ] - } - }, - "edition": "2021", - "version": "4.0.3" + "edition": "2018", + "version": "2.5.3" }, "license": "Apache-2.0 OR MIT", "license_ids": [ @@ -22681,14 +22382,266 @@ ], "license_file": "LICENSE-APACHE" }, - "event-listener 5.3.1": { + "event-listener 4.0.3": { "name": "event-listener", - "version": "5.3.1", + "version": "4.0.3", "package_url": "https://github.com/smol-rs/event-listener", "repository": { "Http": { - "url": "https://static.crates.io/crates/event-listener/5.3.1/download", - "sha256": "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" + "url": "https://static.crates.io/crates/event-listener/4.0.3/download", + "sha256": "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" + } + }, + "targets": [ + { + "Library": { + "crate_name": "event_listener", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "event_listener", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "parking", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "concurrent-queue 2.5.0", + "target": "concurrent_queue" + }, + { + "id": "pin-project-lite 0.2.13", + "target": "pin_project_lite" + } + ], + "selects": { + "aarch64-apple-darwin": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-apple-ios": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-apple-ios-sim": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-fuchsia": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-linux-android": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-pc-windows-msvc": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-unknown-linux-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-unknown-nixos-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "aarch64-unknown-nto-qnx710": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "arm-unknown-linux-gnueabi": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "armv7-linux-androideabi": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "armv7-unknown-linux-gnueabi": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "i686-apple-darwin": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "i686-linux-android": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "i686-pc-windows-msvc": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "i686-unknown-freebsd": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "i686-unknown-linux-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "powerpc-unknown-linux-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "riscv32imc-unknown-none-elf": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "riscv64gc-unknown-none-elf": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "s390x-unknown-linux-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "thumbv7em-none-eabi": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "thumbv8m.main-none-eabi": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-apple-darwin": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-apple-ios": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-fuchsia": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-linux-android": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-pc-windows-msvc": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-unknown-freebsd": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-unknown-linux-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-unknown-nixos-gnu": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ], + "x86_64-unknown-none": [ + { + "id": "parking 2.1.0", + "target": "parking" + } + ] + } + }, + "edition": "2021", + "version": "4.0.3" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "event-listener 5.3.1": { + "name": "event-listener", + "version": "5.3.1", + "package_url": "https://github.com/smol-rs/event-listener", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/event-listener/5.3.1/download", + "sha256": "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" } }, "targets": [ @@ -23098,7 +23051,7 @@ "target": "num_bigint" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -26419,7 +26372,7 @@ "target": "allocator_api2" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -27074,7 +27027,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -28137,62 +28090,6 @@ ], "license_file": "LICENSE" }, - "http-body-to-bytes 0.2.0": { - "name": "http-body-to-bytes", - "version": "0.2.0", - "package_url": "https://github.com/bk-rs/http-body-ext", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/http-body-to-bytes/0.2.0/download", - "sha256": "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" - } - }, - "targets": [ - { - "Library": { - "crate_name": "http_body_to_bytes", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "http_body_to_bytes", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bytes 1.9.0", - "target": "bytes" - }, - { - "id": "http-body 1.0.1", - "target": "http_body" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.0" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, "http-body-util 0.1.2": { "name": "http-body-util", "version": "0.1.2", @@ -28493,7 +28390,7 @@ "target": "humantime" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -29733,14 +29630,14 @@ ], "license_file": "LICENSE-APACHE" }, - "ic-agent 0.37.1": { + "ic-agent 0.39.2": { "name": "ic-agent", - "version": "0.37.1", + "version": "0.39.2", "package_url": "https://github.com/dfinity/agent-rs", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-agent/0.37.1/download", - "sha256": "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" + "url": "https://static.crates.io/crates/ic-agent/0.39.2/download", + "sha256": "1ba408987ca48fc3eee6a613e760d076a9046cccbbb5ba29efbada339ab28ed9" } }, "targets": [ @@ -29765,19 +29662,29 @@ "crate_features": { "common": [ "default", - "experimental_sync_call", - "hyper", "pem", - "reqwest" + "ring" ], "selects": {} }, "deps": { "common": [ + { + "id": "arc-swap 1.7.1", + "target": "arc_swap" + }, + { + "id": "async-channel 1.9.0", + "target": "async_channel" + }, { "id": "async-lock 3.3.0", "target": "async_lock" }, + { + "id": "async-watch 0.3.1", + "target": "async_watch" + }, { "id": "backoff 0.4.0", "target": "backoff" @@ -29790,10 +29697,22 @@ "id": "candid 0.10.10", "target": "candid" }, + { + "id": "der 0.7.7", + "target": "der" + }, + { + "id": "ecdsa 0.16.9", + "target": "ecdsa" + }, { "id": "ed25519-consensus 2.1.0", "target": "ed25519_consensus" }, + { + "id": "elliptic-curve 0.13.8", + "target": "elliptic_curve" + }, { "id": "futures-util 0.3.31", "target": "futures_util" @@ -29811,15 +29730,11 @@ "target": "http_body" }, { - "id": "hyper 1.5.1", - "target": "hyper" - }, - { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-transport-types 0.37.1", + "id": "ic-transport-types 0.39.2", "target": "ic_transport_types" }, { @@ -29867,7 +29782,7 @@ "target": "sec1" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -29887,732 +29802,32 @@ "target": "simple_asn1" }, { - "id": "thiserror 1.0.68", + "id": "stop-token 0.7.0", + "target": "stop_token" + }, + { + "id": "thiserror 2.0.3", "target": "thiserror" }, { "id": "time 0.3.36", "target": "time" }, + { + "id": "tower-service 0.3.3", + "target": "tower_service" + }, { "id": "url 2.5.3", "target": "url" } ], "selects": { - "aarch64-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-apple-ios": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-apple-ios-sim": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-fuchsia": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-nixos-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "aarch64-unknown-nto-qnx710": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "arm-unknown-linux-gnueabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "armv7-linux-androideabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "armv7-unknown-linux-gnueabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], "cfg(not(target_family = \"wasm\"))": [ - { - "id": "rustls-webpki 0.102.8", - "target": "webpki" - }, { "id": "tokio 1.42.0", "target": "tokio" } - ], - "i686-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-unknown-freebsd": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "i686-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "powerpc-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "riscv32imc-unknown-none-elf": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "riscv64gc-unknown-none-elf": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "s390x-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "thumbv7em-none-eabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "thumbv8m.main-none-eabi": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-apple-darwin": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-apple-ios": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-fuchsia": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-linux-android": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-freebsd": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } - ], - "x86_64-unknown-none": [ - { - "id": "http-body-to-bytes 0.2.0", - "target": "http_body_to_bytes" - }, - { - "id": "http-body-util 0.1.2", - "target": "http_body_util" - }, - { - "id": "hyper-rustls 0.27.3", - "target": "hyper_rustls" - }, - { - "id": "hyper-util 0.1.10", - "target": "hyper_util" - }, - { - "id": "tower 0.4.13", - "target": "tower" - } ] } }, @@ -30620,13 +29835,17 @@ "proc_macro_deps": { "common": [ { - "id": "serde_repr 0.1.14", + "id": "async-trait 0.1.83", + "target": "async_trait" + }, + { + "id": "serde_repr 0.1.19", "target": "serde_repr" } ], "selects": {} }, - "version": "0.37.1" + "version": "0.39.2" }, "license": "Apache-2.0", "license_ids": [ @@ -30808,7 +30027,7 @@ "target": "scopeguard" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -30950,7 +30169,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31001,7 +30220,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -31016,14 +30235,16 @@ ], "license_file": "LICENSE" }, - "ic-canister-sig-creation 1.0.1": { + "ic-canister-sig-creation 1.1.0": { "name": "ic-canister-sig-creation", - "version": "1.0.1", + "version": "1.1.0", "package_url": "https://github.com/dfinity/ic-canister-sig-creation", "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-canister-sig-creation/1.0.1/download", - "sha256": "5d1fc58d747480967a25810d8a90d460e7e9ea4c669ab0286541a148736513f9" + "Git": { + "remote": "https://github.com/dfinity/ic-canister-sig-creation", + "commitish": { + "Rev": "7f9e931954637526295269155881207f6c832d6d" + } } }, "targets": [ @@ -31056,15 +30277,15 @@ "target": "hex" }, { - "id": "ic-cdk 0.14.1", + "id": "ic-cdk 0.17.0", "target": "ic_cdk" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { @@ -31072,7 +30293,7 @@ "target": "lazy_static" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31088,14 +30309,14 @@ "target": "sha2" }, { - "id": "thiserror 1.0.68", + "id": "thiserror 2.0.3", "target": "thiserror" } ], "selects": {} }, "edition": "2021", - "version": "1.0.1" + "version": "1.1.0" }, "license": "Apache-2.0", "license_ids": [ @@ -31103,14 +30324,14 @@ ], "license_file": "LICENSE" }, - "ic-cbor 2.6.0": { + "ic-cbor 3.0.2": { "name": "ic-cbor", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-cbor/2.6.0/download", - "sha256": "02b0e48b4166c891e79d624f3a184b4a7c145d307576872d9a46dedb8c73ea8f" + "url": "https://static.crates.io/crates/ic-cbor/3.0.2/download", + "sha256": "5500d6e85bc2ca8ea8aaed16cb84811882589244831a2fd8eefe02e90b3006c6" } }, "targets": [ @@ -31139,7 +30360,7 @@ "target": "candid" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -31158,7 +30379,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -31206,7 +30427,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31234,74 +30455,6 @@ ], "license_file": "LICENSE" }, - "ic-cdk 0.14.1": { - "name": "ic-cdk", - "version": "0.14.1", - "package_url": "https://github.com/dfinity/cdk-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-cdk/0.14.1/download", - "sha256": "9cff1a3c3db565e3384c9c9d6d676b0a3f89a0886f4f787294d9c946d844369f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ic_cdk", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ic_cdk", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "candid 0.10.10", - "target": "candid" - }, - { - "id": "ic0 0.23.0", - "target": "ic0" - }, - { - "id": "serde 1.0.214", - "target": "serde" - }, - { - "id": "serde_bytes 0.11.15", - "target": "serde_bytes" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "ic-cdk-macros 0.14.0", - "target": "ic_cdk_macros" - } - ], - "selects": {} - }, - "version": "0.14.1" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE" - }, "ic-cdk 0.16.0": { "name": "ic-cdk", "version": "0.16.0", @@ -31342,7 +30495,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31410,7 +30563,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31482,7 +30635,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31549,7 +30702,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31572,73 +30725,6 @@ ], "license_file": "LICENSE" }, - "ic-cdk-macros 0.14.0": { - "name": "ic-cdk-macros", - "version": "0.14.0", - "package_url": "https://github.com/dfinity/cdk-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ic-cdk-macros/0.14.0/download", - "sha256": "01dc6bc425ec048d6ac4137c7c0f2cfbd6f8b0be8efc568feae2b265f566117c" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "ic_cdk_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ic_cdk_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "candid 0.10.10", - "target": "candid" - }, - { - "id": "proc-macro2 1.0.89", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.37", - "target": "quote" - }, - { - "id": "serde 1.0.214", - "target": "serde" - }, - { - "id": "serde_tokenstream 0.2.1", - "target": "serde_tokenstream" - }, - { - "id": "syn 2.0.87", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.14.0" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE" - }, "ic-cdk-macros 0.16.0": { "name": "ic-cdk-macros", "version": "0.16.0", @@ -31683,7 +30769,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31750,7 +30836,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31817,7 +30903,7 @@ "target": "ic0" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31840,14 +30926,14 @@ ], "license_file": "LICENSE" }, - "ic-certificate-verification 2.6.0": { + "ic-certificate-verification 3.0.2": { "name": "ic-certificate-verification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-certificate-verification/2.6.0/download", - "sha256": "586e09b06a93d930f6a33f5f909bb11d2e4a06be3635dd5da1eb0e6554b7dae4" + "url": "https://static.crates.io/crates/ic-certificate-verification/3.0.2/download", + "sha256": "2daec653eb7895b5549cdf58d871985711c03cf5e389f7800a970f4f42dc0897" } }, "targets": [ @@ -31872,7 +30958,7 @@ "deps": { "common": [ { - "id": "cached 0.47.0", + "id": "cached 0.54.0", "target": "cached" }, { @@ -31880,11 +30966,11 @@ "target": "candid" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { @@ -31919,7 +31005,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -31971,7 +31057,7 @@ "target": "hex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -31994,6 +31080,72 @@ ], "license_file": "LICENSE" }, + "ic-certification 3.0.2": { + "name": "ic-certification", + "version": "3.0.2", + "package_url": "https://github.com/dfinity/response-verification", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ic-certification/3.0.2/download", + "sha256": "9eae40f26fcac9c141cad54d9aa5f423efffde78ac371057c53d275ebbcad443" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic_certification", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_certification", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "serde" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_bytes 0.11.15", + "target": "serde_bytes" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "3.0.2" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "ic-certified-map 0.3.4": { "name": "ic-certified-map", "version": "0.3.4", @@ -32026,7 +31178,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32049,14 +31201,14 @@ ], "license_file": "LICENSE" }, - "ic-http-certification 2.6.0": { + "ic-http-certification 3.0.2": { "name": "ic-http-certification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-http-certification/2.6.0/download", - "sha256": "ff0b97e949845039149dc5e7ea6a7c12ee4333bb402e37bc507904643c7b3e41" + "url": "https://static.crates.io/crates/ic-http-certification/3.0.2/download", + "sha256": "479941fca8e68c2267cddf686d34ed6fb491168667ff259c08a3d65d28bd26d2" } }, "targets": [ @@ -32080,26 +31232,34 @@ ], "deps": { "common": [ + { + "id": "base64 0.22.1", + "target": "base64" + }, { "id": "candid 0.10.10", "target": "candid" }, { - "id": "http 0.2.12", + "id": "http 1.2.0", "target": "http" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, + { + "id": "serde_cbor 0.11.2", + "target": "serde_cbor" + }, { "id": "thiserror 1.0.68", "target": "thiserror" @@ -32112,7 +31272,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32120,17 +31280,14 @@ ], "license_file": "LICENSE" }, - "ic-http-gateway 0.0.0": { + "ic-http-gateway 0.1.0": { "name": "ic-http-gateway", - "version": "0.0.0", + "version": "0.1.0", "package_url": "https://github.com/dfinity/http-gateway", "repository": { - "Git": { - "remote": "https://github.com/dfinity/http-gateway", - "commitish": { - "Rev": "3be26b5a2c71bf56e05b910951c1935a1ac550c4" - }, - "strip_prefix": "packages/ic-http-gateway" + "Http": { + "url": "https://static.crates.io/crates/ic-http-gateway/0.1.0/download", + "sha256": "8e8b30a8ff19af1a7dc64b1dbe1a38f1b60c7eea566e2049f755ce3bace0e630" } }, "targets": [ @@ -32179,19 +31336,19 @@ "target": "http_body_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-response-verification 2.6.0", + "id": "ic-response-verification 3.0.2", "target": "ic_response_verification" }, { - "id": "ic-utils 0.37.0", + "id": "ic-utils 0.39.0", "target": "ic_utils" }, { @@ -32202,7 +31359,7 @@ "selects": {} }, "edition": "2021", - "version": "0.0.0" + "version": "0.1.0" }, "license": "Apache-2.0", "license_ids": [ @@ -32248,14 +31405,14 @@ ], "license_file": "LICENSE" }, - "ic-representation-independent-hash 2.6.0": { + "ic-representation-independent-hash 3.0.2": { "name": "ic-representation-independent-hash", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-representation-independent-hash/2.6.0/download", - "sha256": "08ae59483e377cd9aad94ec339ed1d2583b0d5929cab989328dac2d853b2f570" + "url": "https://static.crates.io/crates/ic-representation-independent-hash/3.0.2/download", + "sha256": "3643f12824280580d31e47d380f1be23abee29944a1430c3ed22b164ac8e68db" } }, "targets": [ @@ -32291,7 +31448,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32299,14 +31456,14 @@ ], "license_file": null }, - "ic-response-verification 2.6.0": { + "ic-response-verification 3.0.2": { "name": "ic-response-verification", - "version": "2.6.0", + "version": "3.0.2", "package_url": "https://github.com/dfinity/response-verification", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-response-verification/2.6.0/download", - "sha256": "2bef02ef84189d61a7d39889b7e9a3ae212d45c3df293513f7b2568027fd08a8" + "url": "https://static.crates.io/crates/ic-response-verification/3.0.2/download", + "sha256": "2b97514fada84797baf61a6a29f1c71695798c2628cb6013d97a5dd6ecc26df7" } }, "targets": [ @@ -32331,7 +31488,7 @@ "deps": { "common": [ { - "id": "base64 0.21.6", + "id": "base64 0.22.1", "target": "base64" }, { @@ -32347,27 +31504,27 @@ "target": "hex" }, { - "id": "http 0.2.12", + "id": "http 1.2.0", "target": "http" }, { - "id": "ic-cbor 2.6.0", + "id": "ic-cbor 3.0.2", "target": "ic_cbor" }, { - "id": "ic-certificate-verification 2.6.0", + "id": "ic-certificate-verification 3.0.2", "target": "ic_certificate_verification" }, { - "id": "ic-certification 2.6.0", + "id": "ic-certification 3.0.2", "target": "ic_certification" }, { - "id": "ic-http-certification 2.6.0", + "id": "ic-http-certification 3.0.2", "target": "ic_http_certification" }, { - "id": "ic-representation-independent-hash 2.6.0", + "id": "ic-representation-independent-hash 3.0.2", "target": "ic_representation_independent_hash" }, { @@ -32398,7 +31555,7 @@ "selects": {} }, "edition": "2021", - "version": "2.6.0" + "version": "3.0.2" }, "license": "Apache-2.0", "license_ids": [ @@ -32540,7 +31697,7 @@ "target": "ciborium" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32607,7 +31764,7 @@ "target": "leb128" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32629,7 +31786,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_repr 0.1.14", + "id": "serde_repr 0.1.19", "target": "serde_repr" } ], @@ -32643,14 +31800,102 @@ ], "license_file": null }, - "ic-utils 0.37.0": { + "ic-transport-types 0.39.2": { + "name": "ic-transport-types", + "version": "0.39.2", + "package_url": "https://github.com/dfinity/agent-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ic-transport-types/0.39.2/download", + "sha256": "21e2418868dd5857d2a5bac3f1cb6de1aecf2316d380997ef842aec3d8a79d4e" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ic_transport_types", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ic_transport_types", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "candid 0.10.10", + "target": "candid" + }, + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "ic-certification 3.0.2", + "target": "ic_certification" + }, + { + "id": "leb128 0.2.5", + "target": "leb128" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_bytes 0.11.15", + "target": "serde_bytes" + }, + { + "id": "serde_cbor 0.11.2", + "target": "serde_cbor" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + }, + { + "id": "thiserror 2.0.3", + "target": "thiserror" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "serde_repr 0.1.19", + "target": "serde_repr" + } + ], + "selects": {} + }, + "version": "0.39.2" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": null + }, + "ic-utils 0.39.0": { "name": "ic-utils", - "version": "0.37.0", + "version": "0.39.0", "package_url": "https://github.com/dfinity/agent-rs", "repository": { "Http": { - "url": "https://static.crates.io/crates/ic-utils/0.37.0/download", - "sha256": "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" + "url": "https://static.crates.io/crates/ic-utils/0.39.0/download", + "sha256": "bb1da4a68c45146018b8496c157ad94126b9c202ab4400c6c0a9030c1ef0f0ba" } }, "targets": [ @@ -32689,7 +31934,7 @@ "target": "futures_util" }, { - "id": "ic-agent 0.37.1", + "id": "ic-agent 0.39.2", "target": "ic_agent" }, { @@ -32701,7 +31946,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -32745,7 +31990,7 @@ ], "selects": {} }, - "version": "0.37.0" + "version": "0.39.0" }, "license": "Apache-2.0", "license_ids": [ @@ -32975,7 +32220,7 @@ "target": "rustc_demangle" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -33038,7 +32283,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -33313,7 +32558,7 @@ "target": "data_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -33379,7 +32624,7 @@ "target": "candid" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -34651,7 +33896,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -34903,7 +34148,7 @@ "target": "hashbrown" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35481,7 +34726,7 @@ "target": "rustls_pki_types" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -35551,7 +34796,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35701,7 +34946,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35756,7 +35001,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -35910,7 +35155,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36410,7 +35655,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36470,7 +35715,7 @@ "target": "pest" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -36615,7 +35860,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36679,7 +35924,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -36856,7 +36101,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -37146,7 +36391,7 @@ "target": "secrecy" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -37241,7 +36486,7 @@ "target": "k8s_openapi" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -40117,8 +39362,6 @@ ], "crate_features": { "common": [ - "max_level_off", - "release_max_level_off", "std" ], "selects": {} @@ -41106,7 +40349,7 @@ "target": "memchr" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -41742,7 +40985,7 @@ "target": "rustls_pemfile" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -43271,7 +42514,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -43360,7 +42603,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -44143,7 +43386,7 @@ "target": "num_traits" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -44248,7 +43491,7 @@ "target": "rand" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -45967,7 +45210,7 @@ "target": "opentelemetry_proto" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -46191,7 +45434,7 @@ "target": "opentelemetry" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -46758,14 +46001,14 @@ ], "license_file": "LICENSE" }, - "opentelemetry_sdk 0.27.0": { + "opentelemetry_sdk 0.27.1": { "name": "opentelemetry_sdk", - "version": "0.27.0", + "version": "0.27.1", "package_url": "https://github.com/open-telemetry/opentelemetry-rust", "repository": { "Http": { - "url": "https://static.crates.io/crates/opentelemetry_sdk/0.27.0/download", - "sha256": "27b742c1cae4693792cc564e58d75a2a0ba29421a34a85b50da92efa89ecb2bc" + "url": "https://static.crates.io/crates/opentelemetry_sdk/0.27.1/download", + "sha256": "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" } }, "targets": [ @@ -46824,10 +46067,6 @@ "id": "glob 0.3.1", "target": "glob" }, - { - "id": "once_cell 1.19.0", - "target": "once_cell" - }, { "id": "opentelemetry 0.27.0", "target": "opentelemetry" @@ -46873,7 +46112,7 @@ ], "selects": {} }, - "version": "0.27.0" + "version": "0.27.1" }, "license": "Apache-2.0", "license_ids": [ @@ -47309,7 +46548,7 @@ "target": "byte_slice_cast" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -49823,7 +49062,7 @@ "target": "schemars" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -50159,7 +49398,7 @@ "target": "embedded_io" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -51139,7 +50378,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -56430,7 +55669,7 @@ "target": "http" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -57580,7 +56819,7 @@ "target": "mime_guess" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -60768,7 +60007,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -62254,7 +61493,7 @@ "target": "ring" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -62910,104 +62149,7 @@ "ring", "std" ], - "selects": { - "aarch64-apple-darwin": [ - "default" - ], - "aarch64-apple-ios": [ - "default" - ], - "aarch64-apple-ios-sim": [ - "default" - ], - "aarch64-fuchsia": [ - "default" - ], - "aarch64-linux-android": [ - "default" - ], - "aarch64-pc-windows-msvc": [ - "default" - ], - "aarch64-unknown-linux-gnu": [ - "default" - ], - "aarch64-unknown-nixos-gnu": [ - "default" - ], - "aarch64-unknown-nto-qnx710": [ - "default" - ], - "arm-unknown-linux-gnueabi": [ - "default" - ], - "armv7-linux-androideabi": [ - "default" - ], - "armv7-unknown-linux-gnueabi": [ - "default" - ], - "i686-apple-darwin": [ - "default" - ], - "i686-linux-android": [ - "default" - ], - "i686-pc-windows-msvc": [ - "default" - ], - "i686-unknown-freebsd": [ - "default" - ], - "i686-unknown-linux-gnu": [ - "default" - ], - "powerpc-unknown-linux-gnu": [ - "default" - ], - "riscv32imc-unknown-none-elf": [ - "default" - ], - "riscv64gc-unknown-none-elf": [ - "default" - ], - "s390x-unknown-linux-gnu": [ - "default" - ], - "thumbv7em-none-eabi": [ - "default" - ], - "thumbv8m.main-none-eabi": [ - "default" - ], - "x86_64-apple-darwin": [ - "default" - ], - "x86_64-apple-ios": [ - "default" - ], - "x86_64-fuchsia": [ - "default" - ], - "x86_64-linux-android": [ - "default" - ], - "x86_64-pc-windows-msvc": [ - "default" - ], - "x86_64-unknown-freebsd": [ - "default" - ], - "x86_64-unknown-linux-gnu": [ - "default" - ], - "x86_64-unknown-nixos-gnu": [ - "default" - ], - "x86_64-unknown-none": [ - "default" - ] - } + "selects": {} }, "deps": { "common": [ @@ -63506,7 +62648,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -64037,7 +63179,7 @@ "target": "secp256k1_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -64108,7 +63250,7 @@ "target": "secp256k1_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -64480,7 +63622,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -64824,7 +63966,7 @@ "target": "build_script_build" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -64848,14 +63990,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde 1.0.214": { + "serde 1.0.217": { "name": "serde", - "version": "1.0.214", + "version": "1.0.217", "package_url": "https://github.com/serde-rs/serde", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde/1.0.214/download", - "sha256": "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" + "url": "https://static.crates.io/crates/serde/1.0.217/download", + "sha256": "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" } }, "targets": [ @@ -64903,7 +64045,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "build_script_build" } ], @@ -64913,13 +64055,13 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], "selects": {} }, - "version": "1.0.214" + "version": "1.0.217" }, "build_script_attrs": { "compile_data_glob": [ @@ -64976,7 +64118,7 @@ "target": "hex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65027,7 +64169,7 @@ "target": "ordered_float" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65078,7 +64220,7 @@ "target": "js_sys" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65136,7 +64278,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65195,7 +64337,7 @@ "target": "half" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65211,14 +64353,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde_derive 1.0.214": { + "serde_derive 1.0.217": { "name": "serde_derive", - "version": "1.0.214", + "version": "1.0.217", "package_url": "https://github.com/serde-rs/serde", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde_derive/1.0.214/download", - "sha256": "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" + "url": "https://static.crates.io/crates/serde_derive/1.0.217/download", + "sha256": "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" } }, "targets": [ @@ -65264,7 +64406,7 @@ "selects": {} }, "edition": "2015", - "version": "1.0.214" + "version": "1.0.217" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -65396,7 +64538,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65460,7 +64602,7 @@ "target": "itoa" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65512,7 +64654,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65568,7 +64710,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65584,14 +64726,14 @@ ], "license_file": "LICENSE-APACHE" }, - "serde_repr 0.1.14": { + "serde_repr 0.1.19": { "name": "serde_repr", - "version": "0.1.14", + "version": "0.1.19", "package_url": "https://github.com/dtolnay/serde-repr", "repository": { "Http": { - "url": "https://static.crates.io/crates/serde_repr/0.1.14/download", - "sha256": "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" + "url": "https://static.crates.io/crates/serde_repr/0.1.19/download", + "sha256": "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" } }, "targets": [ @@ -65630,8 +64772,8 @@ ], "selects": {} }, - "edition": "2018", - "version": "0.1.14" + "edition": "2021", + "version": "0.1.19" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -65676,7 +64818,7 @@ "target": "proc_macro2" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65735,7 +64877,7 @@ "target": "quote" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -65798,7 +64940,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65854,7 +64996,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -65925,7 +65067,7 @@ "target": "base64" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -66042,7 +65184,7 @@ "deps": { "common": [ { - "id": "darling 0.20.3", + "id": "darling 0.20.10", "target": "darling" }, { @@ -66110,7 +65252,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -66174,7 +65316,7 @@ "target": "ryu" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -67742,7 +66884,7 @@ "target": "erased_serde" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -68081,7 +67223,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -68855,6 +67997,66 @@ ], "license_file": "LICENSE-APACHE" }, + "stop-token 0.7.0": { + "name": "stop-token", + "version": "0.7.0", + "package_url": "https://github.com/async-rs/stop-token", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/stop-token/0.7.0/download", + "sha256": "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "stop_token", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "stop_token", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "async-channel 1.9.0", + "target": "async_channel" + }, + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "futures-core 0.3.31", + "target": "futures_core" + }, + { + "id": "pin-project-lite 0.2.13", + "target": "pin_project_lite" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.7.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": null + }, "str_stack 0.1.0": { "name": "str_stack", "version": "0.1.0", @@ -68954,7 +68156,7 @@ "target": "precomputed_hash" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -70875,7 +70077,7 @@ "target": "rand" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -72923,7 +72125,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -74081,7 +73283,7 @@ "target": "pin_project" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -74501,7 +73703,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -76146,7 +75348,7 @@ "target": "opentelemetry" }, { - "id": "opentelemetry_sdk 0.27.0", + "id": "opentelemetry_sdk 0.27.1", "target": "opentelemetry_sdk" }, { @@ -76224,7 +75426,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -76275,7 +75477,7 @@ "deps": { "common": [ { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -76430,7 +75632,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -77992,7 +77194,7 @@ "target": "percent_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -78293,7 +77495,7 @@ "target": "getrandom" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -78529,7 +77731,7 @@ "target": "regex" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -79061,7 +78263,7 @@ "target": "scoped_tls" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -80012,7 +79214,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80089,7 +79291,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80167,7 +79369,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" } ], @@ -80410,7 +79612,7 @@ "target": "rayon" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -80679,7 +79881,7 @@ "target": "paste" }, { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" }, { @@ -81099,7 +80301,7 @@ "target": "postcard" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -81129,7 +80331,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -84830,7 +84032,7 @@ "target": "semver" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -84852,7 +84054,7 @@ "proc_macro_deps": { "common": [ { - "id": "serde_derive 1.0.214", + "id": "serde_derive 1.0.217", "target": "serde_derive" } ], @@ -85070,7 +84272,7 @@ "target": "data_encoding" }, { - "id": "serde 1.0.214", + "id": "serde 1.0.217", "target": "serde" }, { @@ -87590,27 +86792,27 @@ "hyper-rustls 0.27.3", "hyper-socks2 0.9.1", "hyper-util 0.1.10", - "ic-agent 0.37.1", + "ic-agent 0.39.2", "ic-bn-lib 0.1.0", "ic-btc-interface 0.2.2", "ic-canister-log 0.2.0", - "ic-canister-sig-creation 1.0.1", - "ic-cbor 2.6.0", + "ic-canister-sig-creation 1.1.0", + "ic-cbor 3.0.2", "ic-cdk 0.16.0", "ic-cdk-macros 0.9.0", "ic-cdk-timers 0.11.0", - "ic-certificate-verification 2.6.0", - "ic-certification 2.6.0", + "ic-certificate-verification 3.0.2", + "ic-certification 3.0.2", "ic-certified-map 0.3.4", - "ic-http-certification 2.6.0", - "ic-http-gateway 0.0.0", + "ic-http-certification 3.0.2", + "ic-http-gateway 0.1.0", "ic-metrics-encoder 1.1.1", - "ic-response-verification 2.6.0", + "ic-response-verification 3.0.2", "ic-sha3 1.0.0", "ic-stable-structures 0.6.5", "ic-test-state-machine-client 3.0.1", - "ic-transport-types 0.37.1", - "ic-utils 0.37.0", + "ic-transport-types 0.39.2", + "ic-utils 0.39.0", "ic-verify-bls-signature 0.6.0", "ic-wasm 0.8.4", "ic-xrc-types 1.2.0", @@ -87670,7 +86872,7 @@ "opentelemetry 0.27.0", "opentelemetry-otlp 0.27.0", "opentelemetry-prometheus 0.13.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "p256 0.13.2", "pairing 0.23.0", "parking_lot 0.12.1", @@ -87734,7 +86936,7 @@ "scraper 0.17.1", "secp256k1 0.22.2", "semver 1.0.22", - "serde 1.0.214", + "serde 1.0.217", "serde-bytes-repr 0.1.5", "serde_bytes 0.11.15", "serde_cbor 0.11.2", diff --git a/Cargo.Bazel.toml.lock b/Cargo.Bazel.toml.lock index 51590937d8d..000a15ed28e 100644 --- a/Cargo.Bazel.toml.lock +++ b/Cargo.Bazel.toml.lock @@ -571,6 +571,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-channel" version = "2.3.1" @@ -724,6 +735,15 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "async-watch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a078faf4e27c0c6cc0efb20e5da59dcccc04968ebf2801d8e0b2195124cdcdb2" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "async-web-client" version = "0.6.2" @@ -1343,7 +1363,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel", + "async-channel 2.3.1", "async-task", "futures-io", "futures-lite", @@ -1611,13 +1631,10 @@ checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" [[package]] name = "cached" -version = "0.47.0" +version = "0.49.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" +checksum = "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" dependencies = [ - "ahash 0.8.11", - "cached_proc_macro", - "cached_proc_macro_types", "hashbrown 0.14.5", "instant", "once_cell", @@ -1626,10 +1643,11 @@ dependencies = [ [[package]] name = "cached" -version = "0.49.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f251fd1e72720ca07bf5d8e310f54a193fd053479a1f6342c6663ee4fa01cf96" +checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" dependencies = [ + "ahash 0.8.11", "hashbrown 0.14.5", "instant", "once_cell", @@ -1638,34 +1656,36 @@ dependencies = [ [[package]] name = "cached" -version = "0.52.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" +checksum = "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" dependencies = [ "ahash 0.8.11", + "cached_proc_macro", + "cached_proc_macro_types", "hashbrown 0.14.5", - "instant", "once_cell", "thiserror 1.0.68", + "web-time", ] [[package]] name = "cached_proc_macro" -version = "0.18.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" dependencies = [ - "darling 0.14.4", + "darling 0.20.10", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.87", ] [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "camino" @@ -2709,22 +2729,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -2743,29 +2753,15 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim 0.11.1", "syn 2.0.87", ] @@ -2782,22 +2778,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.10", "quote", "syn 2.0.87", ] @@ -3083,7 +3068,7 @@ dependencies = [ "ic-cdk-macros 0.9.0", "ic-cdk-timers", "ic-certificate-verification", - "ic-certification", + "ic-certification 3.0.2", "ic-certified-map", "ic-http-certification", "ic-http-gateway", @@ -3092,7 +3077,7 @@ dependencies = [ "ic-sha3", "ic-stable-structures", "ic-test-state-machine-client", - "ic-transport-types", + "ic-transport-types 0.39.2", "ic-utils", "ic-verify-bls-signature 0.6.0", "ic-wasm", @@ -3153,7 +3138,7 @@ dependencies = [ "opentelemetry 0.27.0", "opentelemetry-otlp", "opentelemetry-prometheus 0.13.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "p256", "pairing", "parking_lot 0.12.1", @@ -3781,6 +3766,12 @@ dependencies = [ "serde", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "event-listener" version = "4.0.3" @@ -4675,17 +4666,6 @@ dependencies = [ "http 1.2.0", ] -[[package]] -name = "http-body-to-bytes" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" -dependencies = [ - "bytes", - "http-body 1.0.1", - "http-body-util", -] - [[package]] name = "http-body-util" version = "0.1.2" @@ -4909,26 +4889,28 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.37.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" +checksum = "1ba408987ca48fc3eee6a613e760d076a9046cccbbb5ba29efbada339ab28ed9" dependencies = [ + "arc-swap", + "async-channel 1.9.0", "async-lock", + "async-trait", + "async-watch", "backoff", "cached 0.52.0", "candid", + "der", + "ecdsa", "ed25519-consensus", + "elliptic-curve", "futures-util", "hex", "http 1.2.0", "http-body 1.0.1", - "http-body-to-bytes", - "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", - "hyper-util", - "ic-certification", - "ic-transport-types", + "ic-certification 3.0.2", + "ic-transport-types 0.39.2", "ic-verify-bls-signature 0.5.0", "k256", "leb128", @@ -4939,7 +4921,6 @@ dependencies = [ "rangemap", "reqwest 0.12.9", "ring 0.17.7", - "rustls-webpki 0.102.8", "sec1", "serde", "serde_bytes", @@ -4947,10 +4928,11 @@ dependencies = [ "serde_repr", "sha2 0.10.8", "simple_asn1", - "thiserror 1.0.68", + "stop-token", + "thiserror 2.0.3", "time", "tokio", - "tower 0.4.13", + "tower-service", "url", ] @@ -5041,31 +5023,30 @@ dependencies = [ [[package]] name = "ic-canister-sig-creation" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1fc58d747480967a25810d8a90d460e7e9ea4c669ab0286541a148736513f9" +version = "1.1.0" +source = "git+https://github.com/dfinity/ic-canister-sig-creation?rev=7f9e931954637526295269155881207f6c832d6d#7f9e931954637526295269155881207f6c832d6d" dependencies = [ "candid", "hex", - "ic-cdk 0.14.1", - "ic-certification", + "ic-cdk 0.17.0", + "ic-certification 3.0.2", "ic-representation-independent-hash", "lazy_static", "serde", "serde_bytes", "serde_cbor", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 2.0.3", ] [[package]] name = "ic-cbor" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b0e48b4166c891e79d624f3a184b4a7c145d307576872d9a46dedb8c73ea8f" +checksum = "5500d6e85bc2ca8ea8aaed16cb84811882589244831a2fd8eefe02e90b3006c6" dependencies = [ "candid", - "ic-certification", + "ic-certification 3.0.2", "leb128", "nom", "thiserror 1.0.68", @@ -5084,19 +5065,6 @@ dependencies = [ "serde_bytes", ] -[[package]] -name = "ic-cdk" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cff1a3c3db565e3384c9c9d6d676b0a3f89a0886f4f787294d9c946d844369f" -dependencies = [ - "candid", - "ic-cdk-macros 0.14.0", - "ic0 0.23.0", - "serde", - "serde_bytes", -] - [[package]] name = "ic-cdk" version = "0.16.0" @@ -5151,20 +5119,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "ic-cdk-macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01dc6bc425ec048d6ac4137c7c0f2cfbd6f8b0be8efc568feae2b265f566117c" -dependencies = [ - "candid", - "proc-macro2", - "quote", - "serde", - "serde_tokenstream 0.2.1", - "syn 2.0.87", -] - [[package]] name = "ic-cdk-macros" version = "0.16.0" @@ -5209,14 +5163,14 @@ dependencies = [ [[package]] name = "ic-certificate-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586e09b06a93d930f6a33f5f909bb11d2e4a06be3635dd5da1eb0e6554b7dae4" +checksum = "2daec653eb7895b5549cdf58d871985711c03cf5e389f7800a970f4f42dc0897" dependencies = [ - "cached 0.47.0", + "cached 0.54.0", "candid", "ic-cbor", - "ic-certification", + "ic-certification 3.0.2", "lazy_static", "leb128", "miracl_core_bls12381", @@ -5238,6 +5192,18 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ic-certification" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eae40f26fcac9c141cad54d9aa5f423efffde78ac371057c53d275ebbcad443" +dependencies = [ + "hex", + "serde", + "serde_bytes", + "sha2 0.10.8", +] + [[package]] name = "ic-certified-map" version = "0.3.4" @@ -5251,23 +5217,26 @@ dependencies = [ [[package]] name = "ic-http-certification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0b97e949845039149dc5e7ea6a7c12ee4333bb402e37bc507904643c7b3e41" +checksum = "479941fca8e68c2267cddf686d34ed6fb491168667ff259c08a3d65d28bd26d2" dependencies = [ + "base64 0.22.1", "candid", - "http 0.2.12", - "ic-certification", + "http 1.2.0", + "ic-certification 3.0.2", "ic-representation-independent-hash", "serde", + "serde_cbor", "thiserror 1.0.68", "urlencoding", ] [[package]] name = "ic-http-gateway" -version = "0.0.0" -source = "git+https://github.com/dfinity/http-gateway?tag=0.1.0-b0#3be26b5a2c71bf56e05b910951c1935a1ac550c4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8b30a8ff19af1a7dc64b1dbe1a38f1b60c7eea566e2049f755ce3bace0e630" dependencies = [ "bytes", "candid", @@ -5290,9 +5259,9 @@ checksum = "8b5c7628eac357aecda461130f8074468be5aa4d258a002032d82d817f79f1f8" [[package]] name = "ic-representation-independent-hash" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ae59483e377cd9aad94ec339ed1d2583b0d5929cab989328dac2d853b2f570" +checksum = "3643f12824280580d31e47d380f1be23abee29944a1430c3ed22b164ac8e68db" dependencies = [ "leb128", "sha2 0.10.8", @@ -5300,18 +5269,18 @@ dependencies = [ [[package]] name = "ic-response-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef02ef84189d61a7d39889b7e9a3ae212d45c3df293513f7b2568027fd08a8" +checksum = "2b97514fada84797baf61a6a29f1c71695798c2628cb6013d97a5dd6ecc26df7" dependencies = [ - "base64 0.21.6", + "base64 0.22.1", "candid", "flate2", "hex", - "http 0.2.12", + "http 1.2.0", "ic-cbor", "ic-certificate-verification", - "ic-certification", + "ic-certification 3.0.2", "ic-http-certification", "ic-representation-independent-hash", "leb128", @@ -5360,7 +5329,7 @@ checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" dependencies = [ "candid", "hex", - "ic-certification", + "ic-certification 2.6.0", "leb128", "serde", "serde_bytes", @@ -5369,11 +5338,29 @@ dependencies = [ "thiserror 1.0.68", ] +[[package]] +name = "ic-transport-types" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e2418868dd5857d2a5bac3f1cb6de1aecf2316d380997ef842aec3d8a79d4e" +dependencies = [ + "candid", + "hex", + "ic-certification 3.0.2", + "leb128", + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "sha2 0.10.8", + "thiserror 2.0.3", +] + [[package]] name = "ic-utils" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" +checksum = "bb1da4a68c45146018b8496c157ad94126b9c202ab4400c6c0a9030c1ef0f0ba" dependencies = [ "async-trait", "candid", @@ -7470,7 +7457,7 @@ dependencies = [ "http 1.2.0", "opentelemetry 0.27.0", "opentelemetry-proto", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "prost 0.13.3", "thiserror 1.0.68", "tokio", @@ -7511,7 +7498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" dependencies = [ "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "prost 0.13.3", "tonic", ] @@ -7618,16 +7605,15 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b742c1cae4693792cc564e58d75a2a0ba29421a34a85b50da92efa89ecb2bc" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" dependencies = [ "async-trait", "futures-channel", "futures-executor", "futures-util", "glob", - "once_cell", "opentelemetry 0.27.0", "percent-encoding", "rand 0.8.5", @@ -8130,8 +8116,8 @@ dependencies = [ "base64 0.13.1", "candid", "hex", - "ic-certification", - "ic-transport-types", + "ic-certification 2.6.0", + "ic-transport-types 0.37.1", "reqwest 0.12.9", "schemars", "serde", @@ -10018,9 +10004,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -10078,9 +10064,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -10145,9 +10131,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.14" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", @@ -10233,7 +10219,7 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.87", @@ -10671,6 +10657,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if 1.0.0", + "futures-core", + "pin-project-lite", +] + [[package]] name = "str_stack" version = "0.1.0" @@ -11763,7 +11761,7 @@ dependencies = [ "js-sys", "once_cell", "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "smallvec", "tracing", "tracing-core", diff --git a/Cargo.lock b/Cargo.lock index 6f0f534c2cf..a5559f584c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "abnf" @@ -96,7 +96,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -136,8 +136,8 @@ dependencies = [ "actix-utils", "futures-core", "futures-util", - "mio 1.0.2", - "socket2 0.5.7", + "mio 1.0.3", + "socket2 0.5.8", "tokio", "tracing", ] @@ -200,7 +200,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.7", + "socket2 0.5.8", "time", "url", ] @@ -214,7 +214,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -300,12 +300,12 @@ dependencies = [ "bytes", "cfg-if 1.0.0", "http 1.2.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "schemars", "serde", "serde_json", "serde_qs", - "thiserror 1.0.68", + "thiserror 1.0.69", "tower-layer", "tower-service", "tracing", @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -375,7 +375,7 @@ dependencies = [ "prometheus", "rand 0.8.5", "rsa", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -403,14 +403,14 @@ dependencies = [ "lazy_static", "prometheus", "serde", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -423,49 +423,49 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" dependencies = [ "derive_arbitrary", ] @@ -525,7 +525,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -555,7 +555,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 1.0.68", + "thiserror 1.0.69", "time", ] @@ -567,7 +567,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -579,7 +579,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -614,6 +614,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-channel" version = "2.3.1" @@ -628,9 +639,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb8f1d480b0ea3783ab015936d2a55c87e219676f0c0b7dec61494043f21857" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "brotli 7.0.0", "flate2", @@ -657,9 +668,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ "async-lock", "cfg-if 1.0.0", @@ -680,7 +691,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] @@ -713,7 +724,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da2537846e16b96d2972ee52a3b355663872a1a687ce6d57a3b6f6b6a181c89" dependencies = [ - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", ] @@ -736,7 +747,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -753,7 +764,16 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", +] + +[[package]] +name = "async-watch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a078faf4e27c0c6cc0efb20e5da59dcccc04968ebf2801d8e0b2195124cdcdb2" +dependencies = [ + "event-listener 2.5.3", ] [[package]] @@ -770,8 +790,8 @@ dependencies = [ "lazy_static", "log", "rustls-pki-types", - "thiserror 1.0.68", - "webpki-roots 0.26.6", + "thiserror 1.0.69", + "webpki-roots 0.26.7", ] [[package]] @@ -799,7 +819,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -830,7 +850,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "itoa", "matchit", @@ -843,9 +863,9 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -866,7 +886,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -874,25 +894,26 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c3220b188aea709cf1b6c5f9b01c3bd936bb08bd2b5184a12b35ac8131b1f9" +checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" dependencies = [ "axum", "axum-core", "bytes", + "fastrand", "futures-util", "headers 0.4.0", "http 1.2.0", "http-body 1.0.1", "http-body-util", "mime", + "multer 3.1.0", "pin-project-lite", "serde", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -907,7 +928,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "pin-project-lite", "rustls 0.21.12", @@ -1098,7 +1119,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1148,7 +1169,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -1157,6 +1187,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitcoin" version = "0.28.2" @@ -1185,9 +1221,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.3" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0032b0e8ead7074cda7fc4f034409607e3f03a6f71d66ade8a307f79b4d99e73" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" dependencies = [ "base58ck", "bech32 0.11.0", @@ -1208,9 +1244,9 @@ checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" [[package]] name = "bitcoin-io" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" [[package]] name = "bitcoin-private" @@ -1341,7 +1377,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel", + "async-channel 2.3.1", "async-task", "futures-io", "futures-lite", @@ -1350,9 +1386,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ "borsh-derive", "cfg_aliases", @@ -1360,16 +1396,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", - "syn_derive", + "syn 2.0.90", ] [[package]] @@ -1416,12 +1451,12 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "serde", ] @@ -1536,9 +1571,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -1563,9 +1598,9 @@ checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "bytestring" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" dependencies = [ "bytes", ] @@ -1589,54 +1624,54 @@ checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" [[package]] name = "cached" -version = "0.47.0" +version = "0.49.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" +checksum = "8e8e463fceca5674287f32d252fb1d94083758b8709c160efae66d263e5f4eba" dependencies = [ - "ahash 0.8.11", - "cached_proc_macro", - "cached_proc_macro_types", "hashbrown 0.14.5", "instant", "once_cell", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] name = "cached" -version = "0.49.3" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8e463fceca5674287f32d252fb1d94083758b8709c160efae66d263e5f4eba" +checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" dependencies = [ + "ahash 0.8.11", "hashbrown 0.14.5", "instant", "once_cell", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] name = "cached" -version = "0.52.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" +checksum = "9718806c4a2fe9e8a56fd736f97b340dd10ed1be8ed733ed50449f351dc33cae" dependencies = [ "ahash 0.8.11", + "cached_proc_macro", + "cached_proc_macro_types", "hashbrown 0.14.5", - "instant", "once_cell", - "thiserror 1.0.68", + "thiserror 1.0.69", + "web-time", ] [[package]] name = "cached_proc_macro" -version = "0.18.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" dependencies = [ - "darling 0.14.4", + "darling 0.20.10", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -1672,12 +1707,12 @@ version = "0.1.0" dependencies = [ "anyhow", "bytes", - "clap 4.5.20", + "clap 4.5.23", "futures-util", "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "once_cell", "pin-project-lite", "regex", @@ -1689,9 +1724,9 @@ dependencies = [ [[package]] name = "canbench-rs" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85a8f1ee95044a770b3d5166a12f55814283cb3aed71b81439dc59960ab76c1" +checksum = "497d900e11ab1891dd9743dd45dbeaada540ce323aa1adc7fc0ce1da2c6e86ff" dependencies = [ "canbench-rs-macros", "candid", @@ -1701,9 +1736,9 @@ dependencies = [ [[package]] name = "canbench-rs-macros" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37aa9dbb190b03569ab14aadf669884a331712d54462c5a6c5b86c9867fe4e65" +checksum = "5a5509bcfe6eeb86f057d46fbf20a2ba6b6bf9a1099b053a8f491cd7a909dfa6" dependencies = [ "proc-macro2", "quote", @@ -1712,9 +1747,9 @@ dependencies = [ [[package]] name = "candid" -version = "0.10.10" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" +checksum = "d04aa85a9ba2542bded33d1eff0ffb17cb98b1be8117e0a25e1ad8c62bedc881" dependencies = [ "anyhow", "binread", @@ -1730,7 +1765,7 @@ dependencies = [ "serde", "serde_bytes", "stacker", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -1742,7 +1777,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1761,7 +1796,7 @@ dependencies = [ "logos 0.13.0", "num-bigint 0.4.6", "pretty 0.12.3", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -1822,9 +1857,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -1850,9 +1885,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.31" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" dependencies = [ "jobserver", "libc", @@ -1902,15 +1937,15 @@ dependencies = [ "candid", "certificate_orchestrator_interface", "chacha20poly1305", - "clap 4.5.20", + "clap 4.5.23", "cloudflare 0.12.0 (git+https://github.com/dfinity/cloudflare-rs.git?rev=a6538a036926bd756986c9c0a5de356daef48881)", "flate2", "futures", "http 1.2.0", - "ic-agent 0.37.1", + "ic-agent", "ic-http-certification", "ic-response-verification", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "idna 1.0.3", "instant-acme", "leb128", @@ -1925,9 +1960,9 @@ dependencies = [ "serde_cbor", "serde_json", "sha2 0.10.8", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", "tracing-subscriber", "trust-dns-resolver", @@ -1957,7 +1992,7 @@ dependencies = [ "serde", "serde_cbor", "sha2 0.10.8", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -1969,7 +2004,7 @@ dependencies = [ "ic-stable-structures", "serde", "serde_bytes", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -2031,9 +2066,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2112,9 +2147,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive 4.5.18", @@ -2122,13 +2157,13 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.2", + "clap_lex 0.7.4", "strsim 0.11.1", ] @@ -2154,7 +2189,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2168,9 +2203,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clocksource" @@ -2215,7 +2250,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "serde_with 2.3.3", - "thiserror 1.0.68", + "thiserror 1.0.69", "url", "uuid", ] @@ -2233,7 +2268,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "serde_with 2.3.3", - "thiserror 1.0.68", + "thiserror 1.0.69", "url", "uuid", ] @@ -2251,23 +2286,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2282,9 +2317,9 @@ dependencies = [ [[package]] name = "comparable" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb513ee8037bf08c5270ecefa48da249f4c58e57a71ccfce0a5b0877d2a20eb2" +checksum = "8606f9aa5b5a2df738584b139c79413d0c1545ed0ffd16e76e0944d1de7388c0" dependencies = [ "comparable_derive", "comparable_helper", @@ -2294,9 +2329,9 @@ dependencies = [ [[package]] name = "comparable_derive" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54b9c40054eb8999c5d1d36fdc90e4e5f7ff0d1d9621706f360b3cbc8beb828" +checksum = "41f36ea7383b9a2a9ae0a4e225d8a9c1c3aeadde78c59cdc35bad5c02b4dad01" dependencies = [ "convert_case 0.4.0", "proc-macro2", @@ -2306,9 +2341,9 @@ dependencies = [ [[package]] name = "comparable_helper" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5437e327e861081c91270becff184859f706e3e50f5301a9d4dc8eb50752c3" +checksum = "71c9b60259084f32c14d32476f3a299b4997e3c186e1473bd972ff8a8c83d1b4" dependencies = [ "convert_case 0.6.0", "proc-macro2", @@ -2330,7 +2365,7 @@ name = "config" version = "1.0.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config_types", "ic-types", "macaddr", @@ -2357,7 +2392,7 @@ dependencies = [ "serde_json", "serde_with 1.14.0", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "url", ] @@ -2387,7 +2422,7 @@ version = "0.9.0" dependencies = [ "anyhow", "canister-test", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-interfaces-registry", "ic-nns-common", @@ -2419,7 +2454,7 @@ dependencies = [ "candid", "canister-test", "canister_http", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-client", "ic-management-canister-types", @@ -2432,7 +2467,7 @@ dependencies = [ "ic-types", "ic_consensus_system_test_utils", "ic_consensus_threshold_sig_system_test_utils", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_json", "slog", @@ -2447,7 +2482,7 @@ dependencies = [ "canister-test", "chrono", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-config", "ic-limits", @@ -2480,7 +2515,7 @@ dependencies = [ "anyhow", "candid", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-canister-client", "ic-management-canister-types", "ic-nervous-system-common-test-keys", @@ -2502,28 +2537,28 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c0994e656bba7b922d8dd1245db90672ffb701e684e45be58f20719d69abc5a" dependencies = [ - "encode_unicode", + "encode_unicode 0.3.6", "lazy_static", "libc", "regex", "terminal_size", "termios", - "unicode-width", + "unicode-width 0.1.14", "winapi 0.3.9", "winapi-util", ] [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ - "encode_unicode", - "lazy_static", + "encode_unicode 1.0.0", "libc", - "unicode-width", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -2538,9 +2573,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2591,6 +2626,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -2634,9 +2679,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -2678,7 +2723,7 @@ dependencies = [ "hashbrown 0.14.5", "log", "regalloc2", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "smallvec", "target-lexicon", @@ -2766,7 +2811,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.20", + "clap 4.5.23", "criterion-plot", "futures", "is-terminal", @@ -2818,18 +2863,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -2846,18 +2891,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -2933,14 +2978,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -2993,7 +3038,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3053,7 +3098,7 @@ dependencies = [ "icrc-ledger-types", "lazy_static", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "serde_cbor", @@ -3094,16 +3139,6 @@ dependencies = [ "darling_macro 0.13.4", ] -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - [[package]] name = "darling" version = "0.20.10" @@ -3128,20 +3163,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - [[package]] name = "darling_core" version = "0.20.10" @@ -3153,7 +3174,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3167,17 +3188,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.10" @@ -3186,7 +3196,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3279,7 +3289,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3300,18 +3310,18 @@ checksum = "2cdc8d50f426189eef89dac62fabfa0abb27d5cc008f25bf4156a0203325becc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3324,7 +3334,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3344,7 +3354,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3352,11 +3362,11 @@ name = "deterministic_ips" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config_types", "ic-crypto-sha2", "macaddr", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -3364,7 +3374,7 @@ name = "dflate" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "libc", "tar", ] @@ -3438,7 +3448,7 @@ name = "dfn_protobuf" version = "0.9.0" dependencies = [ "on_wire", - "prost 0.13.3", + "prost 0.13.4", ] [[package]] @@ -3479,7 +3489,7 @@ name = "diroid" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "walkdir", ] @@ -3512,7 +3522,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3617,7 +3627,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.9.9", - "thiserror 1.0.68", + "thiserror 1.0.69", "zeroize", ] @@ -3721,11 +3731,17 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if 1.0.0", ] @@ -3751,7 +3767,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3764,7 +3780,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3780,18 +3796,18 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", ] [[package]] name = "env_logger" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" dependencies = [ "env_filter", "log", @@ -3814,7 +3830,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3845,12 +3861,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3865,9 +3881,9 @@ dependencies = [ [[package]] name = "escargot" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000f23e9d459aef148b7267e02b03b94a0aaacf4ec64c65612f67e02f525fb6" +checksum = "05a3ac187a16b5382fef8c69fd1bad123c67b7cf3932240a2d43dcdd32cded88" dependencies = [ "log", "once_cell", @@ -3888,7 +3904,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror 1.0.68", + "thiserror 1.0.69", "uint", ] @@ -3945,7 +3961,7 @@ dependencies = [ "serde_json", "strum", "tempfile", - "thiserror 1.0.68", + "thiserror 1.0.69", "tiny-keccak", "unicode-xid", ] @@ -3959,6 +3975,12 @@ dependencies = [ "serde", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "event-listener" version = "5.3.1" @@ -3972,11 +3994,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ - "event-listener", + "event-listener 5.3.1", "pin-project-lite", ] @@ -3991,7 +4013,7 @@ dependencies = [ "ic-cdk 0.16.0", "mockall", "serde", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -4007,7 +4029,7 @@ dependencies = [ "num-bigint 0.4.6", "serde", "strum", - "thiserror 1.0.68", + "thiserror 1.0.69", "url", ] @@ -4059,7 +4081,7 @@ dependencies = [ "bitcoincore-rpc", "candid", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-cdk 0.16.0", "ic-config", @@ -4074,7 +4096,7 @@ dependencies = [ "ic-types", "ic-types-test-utils", "ic-universal-canister", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "lazy_static", "rand 0.8.5", "rand_chacha 0.3.1", @@ -4115,9 +4137,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fe-derive" @@ -4218,9 +4240,9 @@ checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -4228,9 +4250,9 @@ dependencies = [ [[package]] name = "float-cmp" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ "num-traits", ] @@ -4243,9 +4265,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "form_urlencoded" @@ -4263,7 +4285,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" dependencies = [ "nonempty", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -4274,9 +4296,9 @@ checksum = "eb540cf7bc4fe6df9d8f7f0c974cfd0dce8ed4e9e8884e73433b503ee78b4e7d" [[package]] name = "fqdn" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eeee501d87b436020fcd3065cc981b5e4d22f2066735268b36b9d513d23e553" +checksum = "8f66e93156d144bd3a9a970033d04c6fbfb4b641275d8eaa3ff83f5b9c232496" [[package]] name = "fragile" @@ -4362,9 +4384,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ "fastrand", "futures-core", @@ -4381,7 +4403,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -4391,7 +4413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", ] @@ -4485,7 +4507,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -4519,7 +4541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" dependencies = [ "fallible-iterator 0.3.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "stable_deref_trait", ] @@ -4565,7 +4587,7 @@ name = "guestos_tool" version = "1.0.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config", "indoc", "itertools 0.12.1", @@ -4586,7 +4608,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -4595,9 +4617,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -4605,7 +4627,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.2.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -4650,9 +4672,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "foldhash", ] @@ -4804,9 +4826,9 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hickory-proto" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5" dependencies = [ "async-trait", "bytes", @@ -4818,14 +4840,14 @@ dependencies = [ "futures-util", "h2 0.3.26", "http 0.2.12", - "idna 0.4.0", + "idna 1.0.3", "ipnet", "once_cell", "rand 0.8.5", "ring 0.16.20", "rustls 0.21.12", "rustls-pemfile 1.0.4", - "thiserror 1.0.68", + "thiserror 1.0.69", "tinyvec", "tokio", "tokio-rustls 0.24.1", @@ -4836,9 +4858,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" dependencies = [ "cfg-if 1.0.0", "futures-util", @@ -4851,7 +4873,7 @@ dependencies = [ "resolv-conf", "rustls 0.21.12", "smallvec", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-rustls 0.24.1", "tracing", @@ -4878,11 +4900,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4901,7 +4923,7 @@ name = "hostos_tool" version = "1.0.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config", "config_types", "deterministic_ips", @@ -4966,17 +4988,6 @@ dependencies = [ "http 1.2.0", ] -[[package]] -name = "http-body-to-bytes" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" -dependencies = [ - "bytes", - "http-body 1.0.1", - "http-body-util", -] - [[package]] name = "http-body-util" version = "0.1.2" @@ -5012,15 +5023,15 @@ name = "httpbin-rs" version = "0.9.0" dependencies = [ "axum", - "clap 4.5.20", - "hyper 1.5.1", + "clap 4.5.23", + "hyper 1.5.2", "hyper-util", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "serde_json", "tokio", - "tokio-rustls 0.26.0", - "tower 0.5.1", + "tokio-rustls 0.26.1", + "tower 0.5.2", ] [[package]] @@ -5056,9 +5067,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.31" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", @@ -5071,7 +5082,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -5080,14 +5091,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "http 1.2.0", "http-body 1.0.1", "httparse", @@ -5109,13 +5120,13 @@ dependencies = [ "futures-util", "headers 0.4.0", "http 1.2.0", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "pin-project-lite", "rustls-native-certs 0.7.3", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tower-service", ] @@ -5127,7 +5138,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", @@ -5135,22 +5146,22 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http 1.2.0", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "log", - "rustls 0.23.19", - "rustls-native-certs 0.8.0", + "rustls 0.23.20", + "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tower-service", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", ] [[package]] @@ -5161,20 +5172,20 @@ checksum = "51c227614c208f7e7c2e040526912604a1a957fe467c9c2f5b06c5d032337dab" dependencies = [ "async-socks5", "http 1.2.0", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tower-service", ] [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "pin-project-lite", "tokio", @@ -5192,9 +5203,9 @@ dependencies = [ "futures-util", "http 1.2.0", "http-body 1.0.1", - "hyper 1.5.1", + "hyper 1.5.2", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -5235,7 +5246,7 @@ dependencies = [ "slog", "tokio", "tonic", - "tower 0.5.1", + "tower 0.5.2", ] [[package]] @@ -5256,8 +5267,8 @@ dependencies = [ name = "ic-adapter-metrics-service" version = "0.9.0" dependencies = [ - "prost 0.13.3", - "prost-build 0.13.3", + "prost 0.13.4", + "prost-build 0.13.4", "tonic", "tonic-build", ] @@ -5272,7 +5283,7 @@ dependencies = [ "base64 0.13.1", "candid", "chrono", - "clap 4.5.20", + "clap 4.5.23", "cycles-minting-canister", "futures", "hex", @@ -5316,12 +5327,12 @@ dependencies = [ "ic-sns-swap", "ic-sns-wasm", "ic-types", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.12.1", "maplit", "pocket-ic", "pretty_assertions", - "prost 0.13.3", + "prost 0.13.4", "registry-canister", "serde", "serde_json", @@ -5342,59 +5353,15 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.37.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" -dependencies = [ - "async-lock", - "backoff", - "cached 0.52.0", - "candid", - "ed25519-consensus", - "futures-util", - "hex", - "http 1.2.0", - "http-body 1.0.1", - "http-body-to-bytes", - "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", - "hyper-util", - "ic-certification 2.6.0", - "ic-transport-types 0.37.1", - "ic-verify-bls-signature 0.5.0", - "k256", - "leb128", - "p256", - "pem 3.0.4", - "pkcs8", - "rand 0.8.5", - "rangemap", - "reqwest 0.12.9", - "ring 0.17.8", - "rustls-webpki 0.102.8", - "sec1", - "serde", - "serde_bytes", - "serde_cbor", - "serde_repr", - "sha2 0.10.8", - "simple_asn1", - "thiserror 1.0.68", - "time", - "tokio", - "tower 0.4.13", - "url", -] - -[[package]] -name = "ic-agent" -version = "0.39.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158138fcb769fe6288e63d5db221c904e472cfb7d376aba13a38c060f2984e63" +checksum = "1ba408987ca48fc3eee6a613e760d076a9046cccbbb5ba29efbada339ab28ed9" dependencies = [ + "arc-swap", + "async-channel 1.9.0", "async-lock", "async-trait", + "async-watch", "backoff", "cached 0.52.0", "candid", @@ -5406,8 +5373,8 @@ dependencies = [ "hex", "http 1.2.0", "http-body 1.0.1", - "ic-certification 2.6.0", - "ic-transport-types 0.39.1", + "ic-certification 3.0.2", + "ic-transport-types", "ic-verify-bls-signature 0.5.0", "k256", "leb128", @@ -5417,6 +5384,7 @@ dependencies = [ "rand 0.8.5", "rangemap", "reqwest 0.12.9", + "ring 0.17.8", "sec1", "serde", "serde_bytes", @@ -5424,7 +5392,8 @@ dependencies = [ "serde_repr", "sha2 0.10.8", "simple_asn1", - "thiserror 1.0.68", + "stop-token", + "thiserror 2.0.8", "time", "tokio", "tower-service", @@ -5457,12 +5426,12 @@ dependencies = [ "mockall", "phantom_newtype", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "slog", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", ] @@ -5489,7 +5458,7 @@ version = "0.9.0" dependencies = [ "bincode", "byteorder", - "clap 4.5.20", + "clap 4.5.23", "criterion", "ic-config", "ic-crypto-test-utils-canister-threshold-sigs", @@ -5512,7 +5481,7 @@ dependencies = [ "lmdb-rkv-sys", "nix 0.24.3", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rocksdb", "serde", @@ -5532,7 +5501,7 @@ version = "0.9.0" dependencies = [ "anyhow", "chrono", - "clap 4.5.20", + "clap 4.5.23", "ic-config", "ic-crypto-utils-threshold-sig-der", "ic-logger", @@ -5572,7 +5541,7 @@ dependencies = [ "phantom_newtype", "proptest", "proptest-derive", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_cbor", "strum", @@ -5585,7 +5554,7 @@ name = "ic-base-types-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -5626,11 +5595,11 @@ dependencies = [ "base64 0.22.1", "bytes", "chacha20poly1305", - "clap 4.5.20", + "clap 4.5.23", "clap_derive 4.5.18", "cloudflare 0.12.0 (git+https://github.com/cloudflare/cloudflare-rs.git?rev=f14720e42184ee176a97676e85ef2d2d85bc3aae)", "derive-new", - "fqdn 0.4.1", + "fqdn 0.4.4", "futures", "futures-util", "hickory-proto", @@ -5639,18 +5608,18 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "humantime", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "instant-acme", "moka", "parse-size", "prometheus", - "prost 0.13.3", - "prost-types 0.13.3", + "prost 0.13.4", + "prost-types 0.13.4", "rand 0.8.5", "rcgen", "reqwest 0.12.9", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-acme", "rustls-pemfile 2.2.0", "rustls-platform-verifier", @@ -5661,12 +5630,12 @@ dependencies = [ "strum", "strum_macros", "systemstat", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tokio-io-timeout", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tower-service", "tracing", "url", @@ -5690,7 +5659,7 @@ dependencies = [ "axum-extra", "bytes", "candid", - "clap 4.5.20", + "clap 4.5.23", "criterion", "dashmap 6.1.0", "ethnum", @@ -5700,7 +5669,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "humantime", - "ic-agent 0.39.1", + "ic-agent", "ic-base-types", "ic-bn-lib", "ic-canister-client", @@ -5743,7 +5712,7 @@ dependencies = [ "rcgen", "regex", "reqwest 0.12.9", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "serde", "serde_bytes", @@ -5755,12 +5724,12 @@ dependencies = [ "slog", "strum", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tikv-jemalloc-ctl", "tikv-jemallocator", "tokio", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tower-http 0.6.2", "tower_governor", "tracing", @@ -5779,7 +5748,7 @@ dependencies = [ "candid", "certificate_orchestrator_interface", "chacha20poly1305", - "ic-agent 0.37.1", + "ic-agent", "ic-interfaces-registry", "ic-protobuf", "ic-registry-keys", @@ -5804,7 +5773,7 @@ version = "0.9.0" dependencies = [ "anyhow", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-boundary-nodes-system-test-utils", "ic-crypto-tree-hash", "ic-system-test-driver", @@ -5823,7 +5792,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-boundary-nodes-system-test-utils", "ic-protobuf", "ic-registry-keys", @@ -5831,7 +5800,7 @@ dependencies = [ "ic-registry-routing-table", "ic-registry-subnet-type", "ic-system-test-driver", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "reqwest 0.12.9", "slog", @@ -5844,7 +5813,7 @@ version = "0.9.0" dependencies = [ "anyhow", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-interfaces-registry", "ic-protobuf", @@ -5854,7 +5823,7 @@ dependencies = [ "ic-registry-subnet-type", "ic-system-test-driver", "ic-types", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "slog", "url", ] @@ -5866,7 +5835,7 @@ dependencies = [ "bitcoin 0.28.2", "bitcoincore-rpc", "bitcoind", - "clap 4.5.20", + "clap 4.5.23", "criterion", "futures", "hashlink", @@ -5888,18 +5857,18 @@ dependencies = [ "ic-test-utilities-logger", "parking_lot 0.12.3", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "serde_json", "slog", "slog-async", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tokio-socks", "tonic", - "tower 0.5.1", + "tower 0.5.2", ] [[package]] @@ -5921,7 +5890,7 @@ dependencies = [ "slog", "tokio", "tonic", - "tower 0.5.1", + "tower 0.5.2", "tracing", ] @@ -5943,7 +5912,7 @@ version = "0.9.0" dependencies = [ "askama", "base64 0.13.1", - "bitcoin 0.32.3", + "bitcoin 0.32.5", "candid", "candid_parser", "ciborium", @@ -5999,9 +5968,9 @@ dependencies = [ "mockall", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "slog", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -6031,7 +6000,7 @@ dependencies = [ name = "ic-btc-service" version = "0.9.0" dependencies = [ - "prost 0.13.3", + "prost 0.13.4", "tonic", "tonic-build", ] @@ -6052,8 +6021,8 @@ dependencies = [ "futures-util", "hex", "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "ic-canister-client-sender", "ic-canonical-state", @@ -6072,15 +6041,15 @@ dependencies = [ "ic-types", "ic-validator", "itertools 0.12.1", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", - "rustls 0.23.19", + "rustls 0.23.20", "serde", "serde_cbor", "tokio", "tokio-test", - "tower 0.5.1", + "tower 0.5.2", "tree-deserializer", "url", ] @@ -6189,20 +6158,19 @@ dependencies = [ [[package]] name = "ic-canister-sig-creation" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db33deb06e0edb366d8d86ef67d7bc1e1759bc7046b0323a33b85b21b8d8d87" +source = "git+https://github.com/dfinity/ic-canister-sig-creation?rev=7f9e931954637526295269155881207f6c832d6d#7f9e931954637526295269155881207f6c832d6d" dependencies = [ "candid", "hex", - "ic-cdk 0.14.1", - "ic-certification 2.6.0", + "ic-cdk 0.17.1", + "ic-certification 3.0.2", "ic-representation-independent-hash", "lazy_static", "serde", "serde_bytes", "serde_cbor", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 2.0.8", ] [[package]] @@ -6269,7 +6237,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "scoped_threadpool", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -6284,15 +6252,15 @@ dependencies = [ [[package]] name = "ic-cbor" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b0e48b4166c891e79d624f3a184b4a7c145d307576872d9a46dedb8c73ea8f" +checksum = "5500d6e85bc2ca8ea8aaed16cb84811882589244831a2fd8eefe02e90b3006c6" dependencies = [ "candid", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "leb128", "nom", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -6323,12 +6291,12 @@ dependencies = [ [[package]] name = "ic-cdk" -version = "0.14.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cff1a3c3db565e3384c9c9d6d676b0a3f89a0886f4f787294d9c946d844369f" +checksum = "dd8ecacd682fa05a985253592963306cb9799622d7b1cce4b1edb89c6ec85be1" dependencies = [ "candid", - "ic-cdk-macros 0.14.0", + "ic-cdk-macros 0.16.0", "ic0 0.23.0", "serde", "serde_bytes", @@ -6336,12 +6304,12 @@ dependencies = [ [[package]] name = "ic-cdk" -version = "0.16.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8ecacd682fa05a985253592963306cb9799622d7b1cce4b1edb89c6ec85be1" +checksum = "122efbcb0af5280d408a75a57b7dc6e9d92893bf6ed9cc98fe4dcff51f18b67c" dependencies = [ "candid", - "ic-cdk-macros 0.16.0", + "ic-cdk-macros 0.17.1", "ic0 0.23.0", "serde", "serde_bytes", @@ -6391,30 +6359,30 @@ dependencies = [ [[package]] name = "ic-cdk-macros" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01dc6bc425ec048d6ac4137c7c0f2cfbd6f8b0be8efc568feae2b265f566117c" +checksum = "0d4d857135deef20cc7ea8f3869a30cd9cfeb1392b3a81043790b2cd82adc3e0" dependencies = [ "candid", "proc-macro2", "quote", "serde", "serde_tokenstream 0.2.2", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "ic-cdk-macros" -version = "0.16.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4d857135deef20cc7ea8f3869a30cd9cfeb1392b3a81043790b2cd82adc3e0" +checksum = "c792bf0d1621c893ccf2bcdeac4ee70121103a03030a1827031a6b3c60488944" dependencies = [ "candid", "proc-macro2", "quote", "serde", "serde_tokenstream 0.2.2", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6433,21 +6401,21 @@ dependencies = [ [[package]] name = "ic-certificate-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586e09b06a93d930f6a33f5f909bb11d2e4a06be3635dd5da1eb0e6554b7dae4" +checksum = "2daec653eb7895b5549cdf58d871985711c03cf5e389f7800a970f4f42dc0897" dependencies = [ - "cached 0.47.0", + "cached 0.54.0", "candid", "ic-cbor", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "lazy_static", "leb128", "miracl_core_bls12381", "nom", "parking_lot 0.12.3", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -6474,9 +6442,9 @@ dependencies = [ [[package]] name = "ic-certification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64ee3d8b6e81b51f245716d3e0badb63c283c00f3c9fb5d5219afc30b5bf821" +checksum = "9eae40f26fcac9c141cad54d9aa5f423efffde78ac371057c53d275ebbcad443" dependencies = [ "hex", "serde", @@ -6524,7 +6492,7 @@ name = "ic-ckbtc-agent" version = "0.9.0" dependencies = [ "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-canisters-http-types", "ic-ckbtc-minter", "ic-icrc1", @@ -6572,7 +6540,7 @@ dependencies = [ "ciborium", "flate2", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-bitcoin-canister-mock", "ic-btc-checker", @@ -6630,7 +6598,7 @@ dependencies = [ "futures", "hex", "hex-literal", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-log 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ic-canisters-http-types", @@ -6669,7 +6637,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "thousands", "time", "tokio", @@ -6781,7 +6749,7 @@ dependencies = [ "phantom_newtype", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", @@ -6819,12 +6787,12 @@ dependencies = [ "mockall", "phantom_newtype", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "slog", "tokio", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tracing", "turmoil", ] @@ -6889,7 +6857,7 @@ dependencies = [ "assert_matches", "async-trait", "bincode", - "clap 4.5.20", + "clap 4.5.23", "criterion", "hex", "ic-adapter-metrics-server", @@ -6964,11 +6932,11 @@ dependencies = [ "parking_lot 0.12.3", "proptest", "proptest-derive", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rsa", - "rustls 0.23.19", + "rustls 0.23.20", "serde", "sha2 0.10.8", "simple_asn1", @@ -7012,7 +6980,7 @@ dependencies = [ "pem 1.1.1", "rand 0.8.5", "rand_chacha 0.3.1", - "thiserror 2.0.3", + "thiserror 2.0.8", "wycheproof", "zeroize", ] @@ -7303,7 +7271,7 @@ dependencies = [ "parking_lot 0.12.3", "proptest", "proptest-derive", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", @@ -7318,7 +7286,7 @@ dependencies = [ "stubborn-io", "tarpc", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "time", "tokio", "tokio-serde", @@ -7354,7 +7322,7 @@ name = "ic-crypto-internal-csp-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -7560,7 +7528,7 @@ dependencies = [ "serde_cbor", "strum", "strum_macros", - "thiserror 2.0.3", + "thiserror 2.0.8", "zeroize", ] @@ -7729,7 +7697,7 @@ dependencies = [ "ic-types-test-utils", "rand 0.8.5", "rand_chacha 0.3.1", - "rustls 0.23.19", + "rustls 0.23.20", "tempfile", "tokio", ] @@ -7908,7 +7876,7 @@ version = "0.9.0" dependencies = [ "ic-types", "mockall", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -7929,11 +7897,11 @@ dependencies = [ "ic-types", "pkcs8", "rand 0.8.5", - "rustls 0.23.19", + "rustls 0.23.20", "signature", "time", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "x509-cert", ] @@ -7965,9 +7933,9 @@ dependencies = [ "ic-types", "json5", "maplit", - "rustls 0.23.19", + "rustls 0.23.20", "serde", - "thiserror 2.0.3", + "thiserror 2.0.8", "x509-parser", ] @@ -7978,7 +7946,7 @@ dependencies = [ "ic-base-types", "ic-crypto-tls-interfaces", "mockall", - "rustls 0.23.19", + "rustls 0.23.20", ] [[package]] @@ -7994,12 +7962,12 @@ dependencies = [ "ic-protobuf", "maplit", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "serde_bytes", "serde_cbor", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -8011,7 +7979,7 @@ dependencies = [ "ic-crypto-tree-hash", "proptest", "rand 0.8.5", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -8078,7 +8046,7 @@ name = "ic-crypto-utils-tls" version = "0.9.0" dependencies = [ "ic-base-types", - "thiserror 2.0.3", + "thiserror 2.0.8", "x509-parser", ] @@ -8092,7 +8060,7 @@ dependencies = [ "ic-registry-keys", "ic-registry-nns-data-provider", "ic-types", - "prost 0.13.3", + "prost 0.13.4", "reqwest 0.12.9", "tokio", ] @@ -8163,7 +8131,7 @@ dependencies = [ name = "ic-drun" version = "0.9.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "futures", "hex", "ic-canister-sandbox-backend-lib", @@ -8195,7 +8163,7 @@ dependencies = [ "slog", "slog-term", "tokio", - "tower 0.5.1", + "tower 0.5.2", "wasmparser 0.217.0", ] @@ -8208,7 +8176,7 @@ dependencies = [ "bincode", "candid", "canister-test", - "clap 4.5.20", + "clap 4.5.23", "criterion", "embedders_bench", "ic-base-types", @@ -8364,7 +8332,7 @@ dependencies = [ "test-strategy 0.3.1", "threadpool", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tracing", "wasmparser 0.217.0", "wat", @@ -8386,7 +8354,7 @@ dependencies = [ "anyhow", "assert_cmd", "assert_matches", - "clap 4.5.20", + "clap 4.5.23", "ic-crypto-test-utils-reproducible-rng", "ic-sys", "maplit", @@ -8397,16 +8365,18 @@ dependencies = [ [[package]] name = "ic-http-certification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0b97e949845039149dc5e7ea6a7c12ee4333bb402e37bc507904643c7b3e41" +checksum = "479941fca8e68c2267cddf686d34ed6fb491168667ff259c08a3d65d28bd26d2" dependencies = [ + "base64 0.22.1", "candid", - "http 0.2.12", - "ic-certification 2.6.0", + "http 1.2.0", + "ic-certification 3.0.2", "ic-representation-independent-hash", "serde", - "thiserror 1.0.68", + "serde_cbor", + "thiserror 1.0.69", "urlencoding", ] @@ -8420,7 +8390,7 @@ dependencies = [ "bytes", "futures", "futures-util", - "hyper 1.5.1", + "hyper 1.5.2", "rand 0.8.5", "slog", "tokio", @@ -8439,10 +8409,10 @@ dependencies = [ "prometheus", "reqwest 0.12.9", "slog", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tokio-io-timeout", - "tower 0.5.1", + "tower 0.5.2", ] [[package]] @@ -8462,7 +8432,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "ic-canister-client", "ic-canister-client-sender", @@ -8508,11 +8478,11 @@ dependencies = [ "pretty_assertions", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "reqwest 0.12.9", "rstest", - "rustls 0.23.19", + "rustls 0.23.20", "serde", "serde_bytes", "serde_cbor", @@ -8520,9 +8490,9 @@ dependencies = [ "tempfile", "tokio", "tokio-io-timeout", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tower-http 0.6.2", "tower-test", "tracing-flame", @@ -8536,7 +8506,7 @@ dependencies = [ "axum", "bytes", "crossbeam-channel", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "ic-config", "ic-crypto-tls-interfaces", @@ -8558,21 +8528,22 @@ dependencies = [ "ic-types", "maplit", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "reqwest 0.12.9", "serde", "serde_json", "slog", "tokio", - "tokio-rustls 0.26.0", - "tower 0.5.1", + "tokio-rustls 0.26.1", + "tower 0.5.2", "url", ] [[package]] name = "ic-http-gateway" -version = "0.0.0" -source = "git+https://github.com/dfinity/http-gateway?tag=0.1.0-b0#3be26b5a2c71bf56e05b910951c1935a1ac550c4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8b30a8ff19af1a7dc64b1dbe1a38f1b60c7eea566e2049f755ce3bace0e630" dependencies = [ "bytes", "candid", @@ -8580,11 +8551,11 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "ic-agent 0.37.1", + "ic-agent", "ic-http-certification", "ic-response-verification", - "ic-utils 0.37.0", - "thiserror 1.0.68", + "ic-utils 0.39.0", + "thiserror 1.0.69", ] [[package]] @@ -8614,12 +8585,12 @@ dependencies = [ "async-stream", "byte-unit", "bytes", - "clap 4.5.20", + "clap 4.5.23", "futures", "http 1.2.0", "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-socks2", "hyper-util", "ic-adapter-metrics-server", @@ -8632,17 +8603,17 @@ dependencies = [ "prometheus", "rand 0.8.5", "rstest", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "serde", "serde_json", "slog", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tonic", - "tower 0.5.1", + "tower 0.5.2", "uuid", "warp", ] @@ -8672,7 +8643,7 @@ dependencies = [ "slog", "tokio", "tonic", - "tower 0.5.1", + "tower 0.5.2", "tower-test", "tracing", ] @@ -8716,7 +8687,7 @@ dependencies = [ name = "ic-https-outcalls-service" version = "0.9.0" dependencies = [ - "prost 0.13.3", + "prost 0.13.4", "tonic", "tonic-build", ] @@ -8802,10 +8773,10 @@ dependencies = [ "axum", "candid", "ciborium", - "clap 4.5.20", + "clap 4.5.23", "futures", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-icrc-rosetta-client", "ic-icrc-rosetta-runner", @@ -8822,7 +8793,7 @@ dependencies = [ "ic-rosetta-test-utils", "ic-sys", "ic-test-utilities-load-wasm", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "icrc-ledger-agent", "icrc-ledger-types", "indicatif", @@ -8859,9 +8830,9 @@ version = "0.1.0" dependencies = [ "anyhow", "candid", - "clap 4.5.20", + "clap 4.5.23", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-crypto-ed25519", "ic-crypto-secp256k1", "ic-icrc-rosetta", @@ -8923,7 +8894,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_bytes", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -8958,7 +8929,7 @@ dependencies = [ "candid", "candid_parser", "ciborium", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-log 0.2.0", "ic-canister-profiler", @@ -9003,14 +8974,14 @@ dependencies = [ "cddl", "ciborium", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-log 0.2.0", "ic-canisters-http-types", "ic-cdk 0.16.0", "ic-cdk-macros 0.9.0", "ic-cdk-timers", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "ic-crypto-tree-hash", "ic-icrc1", "ic-icrc1-test-utils", @@ -9039,7 +9010,7 @@ name = "ic-icrc1-test-utils" version = "0.9.0" dependencies = [ "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-crypto-ed25519", "ic-crypto-secp256k1", "ic-crypto-test-utils-reproducible-rng", @@ -9159,12 +9130,12 @@ dependencies = [ "ic-wasm-types", "phantom_newtype", "proptest", - "prost 0.13.3", + "prost 0.13.4", "serde", "strum", "strum_macros", - "thiserror 2.0.3", - "tower 0.5.1", + "thiserror 2.0.8", + "tower 0.5.2", ] [[package]] @@ -9172,7 +9143,7 @@ name = "ic-interfaces-adapter-client" version = "0.9.0" dependencies = [ "strum_macros", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -9206,7 +9177,7 @@ name = "ic-interfaces-registry" version = "0.9.0" dependencies = [ "ic-types", - "prost 0.13.3", + "prost 0.13.4", "serde", ] @@ -9227,7 +9198,7 @@ dependencies = [ "ic-crypto-tree-hash", "ic-types", "phantom_newtype", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -9251,7 +9222,7 @@ dependencies = [ "chrono", "ciborium", "dfn_protobuf", - "ic-agent 0.37.1", + "ic-agent", "ic-certification 0.9.0", "ic-crypto-sha2", "ic-ledger-canister-blocks-synchronizer-test-utils", @@ -9262,6 +9233,7 @@ dependencies = [ "icp-ledger", "on_wire", "proptest", + "reqwest 0.12.9", "rusqlite", "serde", "tokio", @@ -9397,7 +9369,7 @@ dependencies = [ "cddl", "futures", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canisters-http-types", "ic-config", @@ -9500,7 +9472,7 @@ dependencies = [ "assert_matches", "candid", "candid_parser", - "clap 4.5.20", + "clap 4.5.23", "futures", "hex", "maplit", @@ -9545,7 +9517,7 @@ dependencies = [ "ic-quic-transport", "ic-types", "tokio", - "tower 0.5.1", + "tower 0.5.2", ] [[package]] @@ -9655,7 +9627,7 @@ name = "ic-metrics-tool" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", ] [[package]] @@ -9664,7 +9636,7 @@ version = "0.0.1" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-nervous-system-clients", "ic-nns-common", @@ -9677,7 +9649,7 @@ dependencies = [ "pocket-ic", "serde", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -9760,7 +9732,7 @@ dependencies = [ "num-traits", "priority-queue", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rust_decimal", "serde", "serde_bytes", @@ -9942,7 +9914,7 @@ dependencies = [ "maplit", "num-traits", "pocket-ic", - "prost 0.13.3", + "prost 0.13.4", "registry-canister", "rust_decimal", "rust_decimal_macros", @@ -9993,7 +9965,7 @@ dependencies = [ "ic-base-types", "ic-nervous-system-proto-protobuf-generator", "ic-test-utilities-compare-dirs", - "prost 0.13.3", + "prost 0.13.4", "rust_decimal", "serde", "tempfile", @@ -10004,7 +9976,7 @@ name = "ic-nervous-system-proto-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10067,7 +10039,7 @@ name = "ic-networking-subnet-update-workload" version = "0.9.0" dependencies = [ "anyhow", - "ic-agent 0.37.1", + "ic-agent", "ic-interfaces-registry", "ic-protobuf", "ic-registry-canister-api", @@ -10106,7 +10078,7 @@ version = "0.9.0" dependencies = [ "candid", "colored", - "ic-agent 0.37.1", + "ic-agent", "ic-neurons-fund", "ic-sns-governance", "ic-sns-swap", @@ -10138,7 +10110,7 @@ dependencies = [ "lazy_static", "num-traits", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_bytes", "sha2 0.10.8", @@ -10150,7 +10122,7 @@ name = "ic-nns-common-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10233,7 +10205,7 @@ dependencies = [ "pretty_assertions", "prometheus-parse", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "registry-canister", @@ -10272,7 +10244,7 @@ dependencies = [ "ic-utils 0.9.0", "icp-ledger", "itertools 0.12.1", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_bytes", "strum", @@ -10300,7 +10272,7 @@ name = "ic-nns-governance-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10332,7 +10304,7 @@ dependencies = [ "ic-test-utilities-compare-dirs", "icp-ledger", "lazy_static", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "sha3", @@ -10348,7 +10320,7 @@ name = "ic-nns-gtc-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10402,7 +10374,7 @@ dependencies = [ "maplit", "on_wire", "pretty_assertions", - "prost 0.13.3", + "prost 0.13.4", "registry-canister", "serde", "serde_bytes", @@ -10428,7 +10400,7 @@ name = "ic-nns-handler-root-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10437,7 +10409,7 @@ version = "0.9.0" dependencies = [ "candid", "canister-test", - "clap 4.5.20", + "clap 4.5.23", "ic-base-types", "ic-canister-client", "ic-interfaces-registry", @@ -10451,7 +10423,7 @@ dependencies = [ "ic-sys", "ic-test-identity", "icp-ledger", - "prost 0.13.3", + "prost 0.13.4", "tempfile", "tokio", "url", @@ -10461,7 +10433,7 @@ dependencies = [ name = "ic-nns-inspector" version = "0.1.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "csv", "hex", "ic-base-types", @@ -10471,7 +10443,7 @@ dependencies = [ "ic-nns-gtc", "icp-ledger", "ledger-canister", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_cbor", "stable_reader", @@ -10502,7 +10474,7 @@ dependencies = [ "ic-cdk-macros 0.9.0", "ic-cdk-timers", "ic-certificate-verification", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "ic-config", "ic-crypto", "ic-crypto-sha2", @@ -10553,7 +10525,7 @@ dependencies = [ "pocket-ic", "pretty_assertions", "prometheus-parse", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "registry-canister", "rustc-hash 1.1.0", @@ -10629,7 +10601,7 @@ dependencies = [ "num-traits", "on_wire", "prometheus-parse", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "registry-canister", "serde", @@ -10696,7 +10668,7 @@ dependencies = [ "quinn", "quinn-udp", "rcgen", - "rustls 0.23.19", + "rustls 0.23.20", "serde", "slog", "tempfile", @@ -10733,7 +10705,7 @@ dependencies = [ "pprof", "prost 0.12.6", "regex", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -10744,7 +10716,7 @@ dependencies = [ "anyhow", "assert_matches", "base64 0.13.1", - "clap 4.5.20", + "clap 4.5.23", "fs_extra", "ic-config", "ic-crypto-node-key-generation", @@ -10773,14 +10745,14 @@ dependencies = [ "json5", "maplit", "pretty_assertions", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "reqwest 0.12.9", "serde", "serde_json", "slog", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "url", "x509-cert", ] @@ -10796,7 +10768,7 @@ dependencies = [ "ic-protobuf-generator", "ic-test-utilities-compare-dirs", "maplit", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_json", "slog", @@ -10808,7 +10780,7 @@ name = "ic-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -10857,18 +10829,18 @@ dependencies = [ "ic-types-test-utils", "phantom_newtype", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "quinn", "rstest", - "rustls 0.23.19", + "rustls 0.23.20", "slog", - "socket2 0.5.7", + "socket2 0.5.8", "static_assertions", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tokio-metrics", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tracing", "turmoil", ] @@ -10892,7 +10864,7 @@ name = "ic-recovery" version = "0.9.0" dependencies = [ "base64 0.13.1", - "clap 4.5.20", + "clap 4.5.23", "futures", "hex", "ic-artifact-pool", @@ -10921,7 +10893,7 @@ dependencies = [ "ic-test-utilities-tmpdir", "ic-test-utilities-types", "ic-types", - "prost 0.13.3", + "prost 0.13.4", "reqwest 0.12.9", "serde", "serde_cbor", @@ -10942,7 +10914,7 @@ version = "0.9.0" dependencies = [ "anyhow", "base64 0.13.1", - "clap 4.5.20", + "clap 4.5.23", "ic-base-types", "ic-crypto-sha2", "ic-crypto-utils-threshold-sig-der", @@ -10956,11 +10928,11 @@ dependencies = [ "ic-registry-provisional-whitelist", "ic-registry-subnet-type", "ic-types", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_json", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "url", ] @@ -10972,7 +10944,7 @@ dependencies = [ "candid", "ic-base-types", "serde", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -11047,7 +11019,7 @@ dependencies = [ "ic-registry-subnet-features", "ic-types", "serde_cbor", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -11056,7 +11028,7 @@ version = "0.9.0" dependencies = [ "ic-registry-common-proto-generator", "ic-test-utilities-compare-dirs", - "prost 0.13.3", + "prost 0.13.4", "tempfile", ] @@ -11065,7 +11037,7 @@ name = "ic-registry-common-proto-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -11096,7 +11068,7 @@ dependencies = [ "ic-registry-transport", "ic-types", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "url", ] @@ -11110,7 +11082,7 @@ dependencies = [ "ic-registry-local-store-artifacts", "ic-sys", "ic-types", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "tempfile", ] @@ -11133,7 +11105,7 @@ dependencies = [ "ic-registry-transport", "ic-types", "leb128", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "tree-deserializer", @@ -11169,7 +11141,7 @@ dependencies = [ "ic-registry-transport", "ic-sys", "ic-types", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -11184,7 +11156,7 @@ dependencies = [ name = "ic-registry-replicator" version = "0.9.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "ic-config", "ic-crypto-utils-threshold-sig-der", "ic-http-endpoints-metrics", @@ -11200,7 +11172,7 @@ dependencies = [ "ic-registry-routing-table", "ic-types", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "slog", "tempfile", "tokio", @@ -11251,7 +11223,7 @@ dependencies = [ "ic-registry-keys", "ic-registry-transport-protobuf-generator", "ic-test-utilities-compare-dirs", - "prost 0.13.3", + "prost 0.13.4", "serde", "tempfile", ] @@ -11261,7 +11233,7 @@ name = "ic-registry-transport-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -11269,7 +11241,7 @@ name = "ic-replay" version = "0.9.0" dependencies = [ "candid", - "clap 4.5.20", + "clap 4.5.23", "hex", "ic-artifact-pool", "ic-canister-client", @@ -11304,7 +11276,7 @@ dependencies = [ "ic-test-utilities-types", "ic-types", "icp-ledger", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "serde_json", @@ -11312,7 +11284,7 @@ dependencies = [ "slog-async", "tempfile", "tokio", - "tower 0.5.1", + "tower 0.5.2", "url", ] @@ -11322,7 +11294,7 @@ version = "0.9.0" dependencies = [ "assert_cmd", "canister-test", - "clap 4.5.20", + "clap 4.5.23", "criterion", "hex", "ic-artifact-pool", @@ -11457,14 +11429,14 @@ dependencies = [ "ic-types", "ic-utils 0.9.0", "maplit", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "slog", "slog-scope", "tempfile", "tokio", "tonic", - "tower 0.5.1", + "tower 0.5.2", "tracing-subscriber", "wat", ] @@ -11475,7 +11447,7 @@ version = "0.9.0" dependencies = [ "arbitrary", "assert_matches", - "bit-vec", + "bit-vec 0.6.3", "criterion", "criterion-time", "cvt", @@ -11516,7 +11488,7 @@ dependencies = [ "phantom_newtype", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", @@ -11534,9 +11506,9 @@ dependencies = [ [[package]] name = "ic-representation-independent-hash" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ae59483e377cd9aad94ec339ed1d2583b0d5929cab989328dac2d853b2f570" +checksum = "3643f12824280580d31e47d380f1be23abee29944a1430c3ed22b164ac8e68db" dependencies = [ "leb128", "sha2 0.10.8", @@ -11544,25 +11516,25 @@ dependencies = [ [[package]] name = "ic-response-verification" -version = "2.6.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef02ef84189d61a7d39889b7e9a3ae212d45c3df293513f7b2568027fd08a8" +checksum = "2b97514fada84797baf61a6a29f1c71695798c2628cb6013d97a5dd6ecc26df7" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "candid", "flate2", "hex", - "http 0.2.12", + "http 1.2.0", "ic-cbor", "ic-certificate-verification", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "ic-http-certification", "ic-representation-independent-hash", "leb128", "log", "nom", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 1.0.69", "urlencoding", ] @@ -11576,12 +11548,12 @@ dependencies = [ "async-trait", "base64 0.13.1", "candid", - "clap 4.5.20", + "clap 4.5.23", "dfn_candid", "dfn_protobuf", "futures", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-crypto-ed25519", "ic-crypto-sha2", @@ -11619,7 +11591,7 @@ dependencies = [ "pocket-ic", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "registry-canister", @@ -11702,7 +11674,7 @@ dependencies = [ "assert_matches", "hex", "ic-canister-sig-creation", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "ic-crypto-internal-types", "ic-crypto-test-utils-canister-sigs", "ic-crypto-test-utils-reproducible-rng", @@ -11723,7 +11695,7 @@ dependencies = [ "candid", "colored", "csv", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-nervous-system-agent", "ic-nervous-system-common-test-keys", @@ -11737,7 +11709,7 @@ dependencies = [ "serde", "serde_json", "textplots", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -11748,10 +11720,10 @@ dependencies = [ "anyhow", "base64 0.13.1", "candid", - "clap 4.5.20", + "clap 4.5.23", "futures", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-crypto-sha2", "ic-nervous-system-agent", @@ -11774,7 +11746,7 @@ dependencies = [ "serde_json", "serde_yaml", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", ] @@ -11790,7 +11762,7 @@ dependencies = [ "canbench-rs", "candid", "candid_parser", - "clap 4.5.20", + "clap 4.5.23", "comparable", "futures", "hex", @@ -11843,8 +11815,8 @@ dependencies = [ "num-traits", "pretty_assertions", "proptest", - "prost 0.13.3", - "prost-build 0.13.3", + "prost 0.13.4", + "prost-build 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rust_decimal", @@ -11864,7 +11836,7 @@ version = "0.9.0" dependencies = [ "bytes", "candid", - "clap 4.5.20", + "clap 4.5.23", "comparable", "ic-base-types", "ic-nervous-system-proto", @@ -11874,7 +11846,7 @@ dependencies = [ "ic-utils 0.9.0", "icp-ledger", "itertools 0.12.1", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_bytes", "strum", @@ -11908,7 +11880,7 @@ name = "ic-sns-governance-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -11961,7 +11933,7 @@ dependencies = [ "lazy_static", "maplit", "num-traits", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_yaml", "tempfile", @@ -11972,7 +11944,7 @@ name = "ic-sns-init-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -12028,7 +12000,7 @@ dependencies = [ "pretty-bytes", "pretty_assertions", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rust_decimal", "rust_decimal_macros", @@ -12068,7 +12040,7 @@ dependencies = [ "ic-test-utilities-compare-dirs", "icrc-ledger-types", "maplit", - "prost 0.13.3", + "prost 0.13.4", "serde", "tempfile", "tokio", @@ -12079,7 +12051,7 @@ name = "ic-sns-root-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -12123,7 +12095,7 @@ dependencies = [ "maplit", "pretty_assertions", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rust_decimal", "rust_decimal_macros", "serde", @@ -12142,7 +12114,7 @@ dependencies = [ "ic-base-types", "ic-nervous-system-proto", "ic-utils 0.9.0", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_bytes", ] @@ -12152,7 +12124,7 @@ name = "ic-sns-swap-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -12197,7 +12169,7 @@ dependencies = [ "maplit", "num-traits", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "tokio", ] @@ -12248,7 +12220,7 @@ dependencies = [ "icrc-ledger-types", "maplit", "pretty_assertions", - "prost 0.13.3", + "prost 0.13.4", "registry-canister", "serde", "serde_bytes", @@ -12262,14 +12234,14 @@ name = "ic-sns-wasm-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] name = "ic-stable-structures" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f3044466a69802de74e710dc0300b706a05696a0531c942ca856751a13b0db" +checksum = "b492c5a16455ae78623eaa12ead96dda6c69a83c535b1b00789f19b381c8a24c" dependencies = [ "ic_principal", ] @@ -12279,7 +12251,7 @@ name = "ic-starter" version = "0.9.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "ic-config", "ic-logger", "ic-management-canister-types", @@ -12320,7 +12292,7 @@ dependencies = [ "libc", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "scoped_threadpool", "slog", ] @@ -12331,7 +12303,7 @@ version = "0.9.0" dependencies = [ "candid", "ciborium", - "clap 4.5.20", + "clap 4.5.23", "hex", "ic-artifact-pool", "ic-base-types", @@ -12397,7 +12369,7 @@ dependencies = [ "tempfile", "tokio", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "wat", ] @@ -12406,7 +12378,7 @@ name = "ic-state-manager" version = "0.9.0" dependencies = [ "assert_matches", - "bit-vec", + "bit-vec 0.6.3", "criterion", "criterion-time", "crossbeam-channel", @@ -12452,7 +12424,7 @@ dependencies = [ "parking_lot 0.12.3", "prometheus", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "scoped_threadpool", @@ -12488,10 +12460,10 @@ dependencies = [ "ic-types-test-utils", "mockall", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "slog", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tokio-metrics", "tokio-util", @@ -12503,7 +12475,7 @@ dependencies = [ name = "ic-state-tool" version = "0.9.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "hex", "ic-config", "ic-logger", @@ -12517,7 +12489,7 @@ dependencies = [ "ic-sys", "ic-types", "ic-utils 0.9.0", - "prost 0.13.3", + "prost 0.13.4", "slog", "slog-term", "tempfile", @@ -12527,9 +12499,9 @@ dependencies = [ name = "ic-subnet-splitting" version = "0.9.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-crypto-utils-threshold-sig", "ic-crypto-utils-threshold-sig-der", @@ -12563,10 +12535,10 @@ dependencies = [ "libc", "nix 0.24.3", "phantom_newtype", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "wsl", ] @@ -12623,7 +12595,7 @@ dependencies = [ "candid", "canister-test", "chrono", - "clap 4.5.20", + "clap 4.5.23", "config_types", "crossbeam-channel", "cycles-minting-canister", @@ -12636,8 +12608,8 @@ dependencies = [ "http 1.2.0", "humantime", "humantime-serde", - "hyper 1.5.1", - "ic-agent 0.37.1", + "hyper 1.5.2", + "ic-agent", "ic-artifact-pool", "ic-base-types", "ic-btc-interface", @@ -12701,7 +12673,7 @@ dependencies = [ "ic-types", "ic-types-test-utils", "ic-universal-canister", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "ic-wasm-types", "icp-ledger", "icrc-ledger-types", @@ -12722,7 +12694,7 @@ dependencies = [ "pem 1.1.1", "phantom_newtype", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", @@ -12747,7 +12719,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "time", "tokio", "tokio-util", @@ -12848,10 +12820,10 @@ dependencies = [ "serde", "serde_cbor", "slog", - "socket2 0.5.7", + "socket2 0.5.8", "tempfile", "tokio", - "tower 0.5.1", + "tower 0.5.2", "wasmprinter 0.217.0", "wat", ] @@ -12873,7 +12845,7 @@ dependencies = [ "ic-types", "mockall", "phantom_newtype", - "prost 0.13.3", + "prost 0.13.4", "serde", ] @@ -13002,7 +12974,7 @@ version = "0.9.0" dependencies = [ "assert_matches", "ic-protobuf", - "prost 0.13.3", + "prost 0.13.4", "serde", "serde_cbor", "serde_json", @@ -13069,7 +13041,7 @@ dependencies = [ "candid", "canister-test", "dfn_candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-btc-checker", "ic-btc-interface", @@ -13154,9 +13126,9 @@ name = "ic-tracing-jaeger-exporter" version = "0.9.0" dependencies = [ "anyhow", - "opentelemetry 0.27.0", + "opentelemetry 0.27.1", "opentelemetry-otlp", - "opentelemetry_sdk 0.27.0", + "opentelemetry_sdk 0.27.1", "tokio", "tracing-opentelemetry 0.28.0", "tracing-subscriber", @@ -13176,37 +13148,20 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.37.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" -dependencies = [ - "candid", - "hex", - "ic-certification 2.6.0", - "leb128", - "serde", - "serde_bytes", - "serde_repr", - "sha2 0.10.8", - "thiserror 1.0.68", -] - -[[package]] -name = "ic-transport-types" -version = "0.39.1" +version = "0.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8789a5c176bb1b925fa58ca97c651a3995d504e76101e93d2a17f558bdcf66" +checksum = "21e2418868dd5857d2a5bac3f1cb6de1aecf2316d380997ef842aec3d8a79d4e" dependencies = [ "candid", "hex", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "leb128", "serde", "serde_bytes", "serde_cbor", "serde_repr", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 2.0.8", ] [[package]] @@ -13242,7 +13197,7 @@ dependencies = [ "pretty_assertions", "proptest", "proptest-derive", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "rusty-fork", @@ -13253,7 +13208,7 @@ dependencies = [ "serde_with 1.14.0", "strum", "strum_macros", - "thiserror 2.0.3", + "thiserror 2.0.8", "thousands", ] @@ -13294,14 +13249,14 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" +checksum = "bb1da4a68c45146018b8496c157ad94126b9c202ab4400c6c0a9030c1ef0f0ba" dependencies = [ "async-trait", "candid", "futures-util", - "ic-agent 0.37.1", + "ic-agent", "once_cell", "semver", "serde", @@ -13309,7 +13264,7 @@ dependencies = [ "sha2 0.10.8", "strum", "strum_macros", - "thiserror 1.0.68", + "thiserror 1.0.69", "time", "tokio", ] @@ -13372,7 +13327,7 @@ dependencies = [ "ic-types", "mockall", "rand 0.8.5", - "thiserror 2.0.3", + "thiserror 2.0.8", ] [[package]] @@ -13504,12 +13459,12 @@ checksum = "19fabaeecfe37f24b433c62489242fc54503d98d4cc8d0f9ef7544dfdfc0ddcb" dependencies = [ "anyhow", "candid", - "clap 4.5.20", + "clap 4.5.23", "libflate", "rustc-demangle", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", "walrus", ] @@ -13544,7 +13499,7 @@ dependencies = [ "byte-unit", "candid", "chrono", - "clap 4.5.20", + "clap 4.5.23", "console 0.11.3", "futures", "hex", @@ -13576,14 +13531,14 @@ dependencies = [ name = "ic-xnet-hyper" version = "0.9.0" dependencies = [ - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "ic-crypto-tls-interfaces", "ic-xnet-uri", "tokio", - "tokio-rustls 0.26.0", - "tower 0.5.1", + "tokio-rustls 0.26.1", + "tower 0.5.2", ] [[package]] @@ -13594,7 +13549,7 @@ dependencies = [ "async-trait", "axum", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "ic-base-types", "ic-canonical-state", @@ -13639,7 +13594,7 @@ dependencies = [ "reqwest 0.12.9", "slog", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "url", ] @@ -13702,7 +13657,7 @@ dependencies = [ "anyhow", "candid", "certificate_orchestrator_interface", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-boundary-nodes-integration-test-common", "ic-boundary-nodes-performance-test-common", @@ -13746,7 +13701,7 @@ version = "0.9.0" dependencies = [ "anyhow", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-system-test-driver", "ic-types", @@ -13765,7 +13720,7 @@ dependencies = [ "canister-test", "chrono", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-client", "ic-config", @@ -13784,7 +13739,7 @@ dependencies = [ "ic_consensus_threshold_sig_system_test_utils", "leb128", "openssh-keys", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "registry-canister", "reqwest 0.12.9", @@ -13805,7 +13760,7 @@ dependencies = [ "candid", "canister-test", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-crypto-test-utils-reproducible-rng", "ic-management-canister-types", @@ -13843,7 +13798,7 @@ dependencies = [ "candid", "canister-test", "ed25519-dalek", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-client", "ic-config", @@ -13874,7 +13829,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-crypto-test-utils-reproducible-rng", "ic-fstrim-tool", "ic-registry-subnet-type", @@ -13902,14 +13857,14 @@ dependencies = [ "data-encoding", "serde", "sha2 0.10.8", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] name = "icp-config" version = "0.9.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "eyre", "ic-config", "ic-replicated-state", @@ -13955,7 +13910,7 @@ dependencies = [ "on_wire", "pocket-ic", "proptest", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", "serde", @@ -13972,7 +13927,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-icrc-rosetta", "ic-icrc-rosetta-client", "ic-ledger-test-utils", @@ -14010,9 +13965,9 @@ dependencies = [ "candid", "ciborium", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-cbor", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "icrc-ledger-types", "leb128", ] @@ -14070,7 +14025,7 @@ dependencies = [ "async-trait", "candid", "serde", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -14199,7 +14154,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -14229,26 +14184,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "1.0.3" @@ -14305,13 +14240,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -14333,26 +14268,26 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", "serde", ] [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ - "console 0.15.8", - "instant", + "console 0.15.10", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] @@ -14368,7 +14303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ "ahash 0.8.11", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-terminal", "itoa", "log", @@ -14386,12 +14321,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75a5d75fee4d36809e6b021e4b96b686e763d365ffdb03af2bd00786353f84fe" dependencies = [ "ahash 0.8.11", - "clap 4.5.20", + "clap 4.5.23", "crossbeam-channel", "crossbeam-utils", "dashmap 6.1.0", "env_logger", - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "log", "num-format", @@ -14406,7 +14341,7 @@ name = "inject-files" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "partition_tools", "tempfile", "tokio", @@ -14423,11 +14358,11 @@ dependencies = [ [[package]] name = "insta" -version = "1.40.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" dependencies = [ - "console 0.15.8", + "console 0.15.10", "lazy_static", "linked-hash-map", "similar", @@ -14454,14 +14389,14 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "ring 0.17.8", "rustls-pki-types", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -14479,7 +14414,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.7", + "socket2 0.5.8", "widestring", "windows-sys 0.48.0", "winreg", @@ -14527,7 +14462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ea1dc4bf0fb4904ba83ffdb98af3d9c325274e92e6e295e4151e86c96363e04" dependencies = [ "serde", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -14568,9 +14503,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jni" @@ -14582,7 +14517,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror 1.0.68", + "thiserror 1.0.69", "walkdir", ] @@ -14603,10 +14538,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -14644,7 +14580,7 @@ dependencies = [ "pest_derive", "regex", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -14730,22 +14666,22 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-http-proxy", - "hyper-rustls 0.27.3", + "hyper-rustls 0.27.5", "hyper-timeout", "hyper-util", "jsonpath-rust", "k8s-openapi", "kube-core", "pem 3.0.4", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "secrecy", "serde", "serde_json", "serde_yaml", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-util", "tower 0.4.13", @@ -14765,7 +14701,7 @@ dependencies = [ "k8s-openapi", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -14790,7 +14726,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "diff", "ena", "is-terminal", @@ -14812,7 +14748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "ena", "itertools 0.11.0", "lalrpop-util 0.20.2", @@ -14842,7 +14778,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex-automata 0.4.8", + "regex-automata 0.4.9", ] [[package]] @@ -14855,7 +14791,7 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" name = "launch-single-vm" version = "0.1.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "ic-prep", "ic-registry-subnet-type", "ic-system-test-driver", @@ -14929,7 +14865,7 @@ dependencies = [ "dfn_http_metrics", "dfn_protobuf", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-log 0.2.0", "ic-cdk 0.16.0", @@ -14964,7 +14900,7 @@ name = "ledger-canister-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -15033,9 +14969,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libflate" @@ -15063,9 +14999,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if 1.0.0", "windows-targets 0.52.6", @@ -15073,9 +15009,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libnss" @@ -15096,7 +15032,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", ] [[package]] @@ -15196,9 +15132,9 @@ version = "0.9.0" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lmdb-rkv" @@ -15251,7 +15187,7 @@ checksum = "612ed4ea9ce5acfb5d26339302528a5e1e59dfed95e9e11af3c083236ff1d15d" dependencies = [ "libc", "neli", - "thiserror 1.0.68", + "thiserror 1.0.69", "windows-sys 0.48.0", ] @@ -15313,7 +15249,7 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax 0.6.29", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -15517,7 +15453,7 @@ dependencies = [ name = "memory_tracker" version = "0.9.0" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", "criterion", "ic-logger", "ic-replicated-state", @@ -15557,13 +15493,13 @@ dependencies = [ "candid", "canister-test", "dfn_candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-cdk 0.16.0", "ic-registry-subnet-type", "ic-system-test-driver", "ic-types", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "itertools 0.12.1", "rand 0.8.5", "rand_chacha 0.3.1", @@ -15633,9 +15569,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ "adler2", ] @@ -15654,11 +15590,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi", @@ -15673,9 +15608,9 @@ checksum = "d07cbe42e2a8dd41df582fb8e00fc24d920b5561cc301fcb6d14e2e0434b500f" [[package]] name = "mockall" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" dependencies = [ "cfg-if 1.0.0", "downcast", @@ -15687,21 +15622,21 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" dependencies = [ "cfg-if 1.0.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "mockito" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b34bd91b9e5c5b06338d392463e1318d683cf82ec3d3af4014609be6e2108d" +checksum = "652cd6d169a36eaf9d1e6bce1a221130439a966d7f27858af66a33a66e9c4ee2" dependencies = [ "assert-json-diff", "bytes", @@ -15710,7 +15645,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "log", "rand 0.8.5", @@ -15732,7 +15667,7 @@ dependencies = [ "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", - "event-listener", + "event-listener 5.3.1", "futures-util", "once_cell", "parking_lot 0.12.3", @@ -15740,7 +15675,7 @@ dependencies = [ "rustc_version", "smallvec", "tagptr", - "thiserror 1.0.68", + "thiserror 1.0.69", "triomphe", "uuid", ] @@ -15769,6 +15704,23 @@ dependencies = [ "version_check", ] +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.2.0", + "httparse", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + [[package]] name = "multimap" version = "0.10.0" @@ -15845,7 +15797,7 @@ dependencies = [ "canister_http", "cloner-canister-types", "dfn_candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-cdk 0.16.0", "ic-limits", @@ -15861,7 +15813,7 @@ dependencies = [ "ic-test-utilities", "ic-test-utilities-types", "ic-types", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "proxy_canister", "rand 0.8.5", "rand_chacha 0.3.1", @@ -15883,7 +15835,7 @@ name = "nft_exporter" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "serde", "serde_json", ] @@ -15899,7 +15851,7 @@ dependencies = [ "serde_path_to_error", "strum", "strum_macros", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -15961,7 +15913,7 @@ dependencies = [ "cycles_minting", "dfn_candid", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-btc-interface", "ic-canister-client", @@ -15991,7 +15943,7 @@ dependencies = [ "nns_dapp", "num-traits", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "registry-canister", "reqwest 0.12.9", "serde_cbor", @@ -16033,7 +15985,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-nns-constants", "ic-registry-canister-api", @@ -16222,7 +16174,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -16247,8 +16199,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "crc32fast", - "hashbrown 0.15.0", - "indexmap 2.6.0", + "hashbrown 0.15.2", + "indexmap 2.7.0", "memchr", ] @@ -16318,7 +16270,7 @@ dependencies = [ "byteorder", "md-5", "sha2 0.9.9", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -16361,16 +16313,16 @@ dependencies = [ [[package]] name = "opentelemetry" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3cebff57f7dbd1255b44d8bddc2cebeb0ea677dbaa2e25a3070a91b318f660" +checksum = "ab70038c28ed37b97d8ed414b6429d343a8bbf44c9f79ec854f3a643029ba6d7" dependencies = [ "futures-core", "futures-sink", "js-sys", - "once_cell", "pin-project-lite", - "thiserror 1.0.68", + "thiserror 1.0.69", + "tracing", ] [[package]] @@ -16382,11 +16334,11 @@ dependencies = [ "async-trait", "futures-core", "http 1.2.0", - "opentelemetry 0.27.0", + "opentelemetry 0.27.1", "opentelemetry-proto", - "opentelemetry_sdk 0.27.0", - "prost 0.13.3", - "thiserror 1.0.68", + "opentelemetry_sdk 0.27.1", + "prost 0.13.4", + "thiserror 1.0.69", "tokio", "tonic", "tracing", @@ -16411,9 +16363,9 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" dependencies = [ - "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", - "prost 0.13.3", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", + "prost 0.13.4", "tonic", ] @@ -16429,7 +16381,7 @@ dependencies = [ "js-sys", "once_cell", "pin-project-lite", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -16444,7 +16396,7 @@ dependencies = [ "js-sys", "once_cell", "pin-project-lite", - "thiserror 1.0.68", + "thiserror 1.0.69", "urlencoding", ] @@ -16463,7 +16415,7 @@ dependencies = [ "opentelemetry_api 0.18.0", "percent-encoding", "rand 0.8.5", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -16483,26 +16435,25 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "regex", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] name = "opentelemetry_sdk" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b742c1cae4693792cc564e58d75a2a0ba29421a34a85b50da92efa89ecb2bc" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" dependencies = [ "async-trait", "futures-channel", "futures-executor", "futures-util", "glob", - "once_cell", - "opentelemetry 0.27.0", + "opentelemetry 0.27.1", "percent-encoding", "rand 0.8.5", "serde_json", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -16515,14 +16466,14 @@ dependencies = [ "async-trait", "backoff", "candid", - "clap 4.5.20", + "clap 4.5.23", "env-file-reader", "exec", "get_if_addrs", "hex", "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "ic-canister-client", "ic-canister-client-sender", @@ -16569,7 +16520,7 @@ dependencies = [ "mockall", "nix 0.24.3", "prometheus", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "serde", "serde_cbor", @@ -16603,9 +16554,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "4.5.0" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" dependencies = [ "num-traits", ] @@ -16741,7 +16692,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", "smallvec", "windows-targets 0.52.6", ] @@ -16846,20 +16797,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.68", + "thiserror 2.0.8", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -16867,22 +16818,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -16891,9 +16842,9 @@ dependencies = [ [[package]] name = "pest_vm" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5385573c124b12495734797b8b427832b6a4182ac313c50dd09fe360795840e2" +checksum = "a8151168a80801131f6e0e79d6c84fa337ccd2493c99e59de027354c3e6fca0b" dependencies = [ "pest", "pest_meta", @@ -16906,7 +16857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -16979,7 +16930,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -17008,29 +16959,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -17046,7 +16997,7 @@ checksum = "122ee1f5a6843bec84fcbd5c6ba3622115337a6b8965b93a61aad347648f4e8d" dependencies = [ "rand 0.8.5", "socket2 0.4.10", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -17138,9 +17089,9 @@ dependencies = [ "flate2", "hex", "ic-cdk 0.16.0", - "ic-certification 2.6.0", + "ic-certification 3.0.2", "ic-error-types", - "ic-transport-types 0.37.1", + "ic-transport-types", "k256", "lazy_static", "reqwest 0.12.9", @@ -17153,7 +17104,7 @@ dependencies = [ "slog", "strum", "strum_macros", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "tracing", "tracing-appender", @@ -17178,7 +17129,7 @@ dependencies = [ "bitcoincore-rpc", "bytes", "candid", - "clap 4.5.20", + "clap 4.5.23", "ctrlc", "flate2", "form_urlencoded", @@ -17187,9 +17138,9 @@ dependencies = [ "hex", "http 1.2.0", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", - "ic-agent 0.37.1", + "ic-agent", "ic-bn-lib", "ic-boundary", "ic-btc-adapter", @@ -17227,7 +17178,7 @@ dependencies = [ "ic-test-utilities", "ic-test-utilities-registry", "ic-types", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "ic-utils-thread", "ic-validator-ingress-message", "itertools 0.12.1", @@ -17247,7 +17198,7 @@ dependencies = [ "tokio", "tokio-util", "tonic", - "tower 0.5.1", + "tower 0.5.2", "tower-http 0.6.2", "tracing", "tracing-appender", @@ -17267,9 +17218,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.3" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if 1.0.0", "concurrent-queue", @@ -17293,15 +17244,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "postcard" -version = "1.0.10" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" dependencies = [ "cobs", "embedded-io 0.4.0", @@ -17339,7 +17290,7 @@ dependencies = [ "smallvec", "symbolic-demangle", "tempfile", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -17359,9 +17310,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "3.1.2" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" dependencies = [ "anstyle", "difflib", @@ -17373,15 +17324,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" [[package]] name = "predicates-tree" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" dependencies = [ "predicates-core", "termtree", @@ -17407,7 +17358,7 @@ checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" dependencies = [ "arrayvec 0.5.2", "typed-arena", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -17432,12 +17383,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "910d41a655dac3b764f1ade94821093d3610248694320cd072303a8eedcf221d" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -17515,9 +17466,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -17573,7 +17524,7 @@ dependencies = [ "parking_lot 0.12.3", "procfs 0.16.0", "protobuf", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -17590,12 +17541,12 @@ dependencies = [ [[package]] name = "proptest" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ - "bit-set", - "bit-vec", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.6.0", "lazy_static", "num-traits", @@ -17610,13 +17561,13 @@ dependencies = [ [[package]] name = "proptest-derive" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -17631,12 +17582,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" dependencies = [ "bytes", - "prost-derive 0.13.3", + "prost-derive 0.13.4", ] [[package]] @@ -17656,17 +17607,16 @@ dependencies = [ "prost 0.12.6", "prost-types 0.12.6", "regex", - "syn 2.0.87", + "syn 2.0.90", "tempfile", ] [[package]] name = "prost-build" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" +checksum = "d0f3e5beed80eb580c68e2c600937ac2c4eedabdfd5ef1e5b7ea4f3fba84497b" dependencies = [ - "bytes", "heck 0.5.0", "itertools 0.13.0", "log", @@ -17674,10 +17624,10 @@ dependencies = [ "once_cell", "petgraph", "prettyplease", - "prost 0.13.3", - "prost-types 0.13.3", + "prost 0.13.4", + "prost-types 0.13.4", "regex", - "syn 2.0.87", + "syn 2.0.90", "tempfile", ] @@ -17691,20 +17641,20 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "prost-derive" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" dependencies = [ "anyhow", "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -17718,11 +17668,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +checksum = "cc2f1e56baa61e93533aebc21af4d2134b70f66275e0fcdf3cbe43d77ff7e8fc" dependencies = [ - "prost 0.13.3", + "prost 0.13.4", ] [[package]] @@ -17750,9 +17700,9 @@ checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" [[package]] name = "psm" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" dependencies = [ "cc", ] @@ -17779,11 +17729,11 @@ dependencies = [ [[package]] name = "publicsuffix" -version = "2.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" dependencies = [ - "idna 0.3.0", + "idna 1.0.3", "psl-types", ] @@ -17800,9 +17750,9 @@ dependencies = [ [[package]] name = "quanta" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" dependencies = [ "crossbeam-utils", "libc", @@ -17839,48 +17789,52 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", - "rustls 0.23.19", - "socket2 0.5.7", - "thiserror 1.0.68", + "rustc-hash 2.1.0", + "rustls 0.23.20", + "socket2 0.5.8", + "thiserror 2.0.8", "tokio", "tracing", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", + "getrandom", "rand 0.8.5", "ring 0.17.8", - "rustc-hash 2.0.0", - "rustls 0.23.19", + "rustc-hash 2.1.0", + "rustls 0.23.20", + "rustls-pki-types", "slab", - "thiserror 1.0.68", + "thiserror 2.0.8", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" dependencies = [ + "cfg_aliases", "libc", "once_cell", - "socket2 0.5.7", + "socket2 0.5.8", "tracing", "windows-sys 0.59.0", ] @@ -18111,8 +18065,8 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "clap 4.5.20", - "ic-agent 0.37.1", + "clap 4.5.23", + "ic-agent", "k256", "rate-limits-api", "regex", @@ -18165,7 +18119,7 @@ dependencies = [ "serde_cbor", "serde_json", "strum", - "thiserror 2.0.3", + "thiserror 2.0.8", "uuid", ] @@ -18177,7 +18131,7 @@ checksum = "6c1bb13e2dcfa2232ac6887157aad8d9b3fe4ca57f7c8d4938ff5ea9be742300" dependencies = [ "clocksource", "parking_lot 0.12.3", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -18243,9 +18197,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -18258,7 +18212,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -18269,20 +18223,20 @@ checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" dependencies = [ "hashbrown 0.14.5", "log", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "slice-group-by", "smallvec", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -18297,9 +18251,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -18393,7 +18347,7 @@ dependencies = [ "leb128", "maplit", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "rand_distr", "registry-canister-protobuf-generator", @@ -18409,7 +18363,7 @@ name = "registry-canister-protobuf-generator" version = "0.9.0" dependencies = [ "ic-utils-rustfmt", - "prost-build 0.13.3", + "prost-build 0.13.4", ] [[package]] @@ -18456,7 +18410,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.32", "hyper-rustls 0.24.2", "ipnet", "js-sys", @@ -18495,13 +18449,13 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "hickory-resolver", "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", - "hyper-rustls 0.27.3", + "hyper 1.5.2", + "hyper-rustls 0.27.5", "hyper-util", "ipnet", "js-sys", @@ -18512,16 +18466,16 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.19", - "rustls-native-certs 0.8.0", + "rustls 0.23.20", + "rustls-native-certs 0.8.1", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tokio-socks", "tokio-util", "tower-service", @@ -18530,7 +18484,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", "windows-registry", ] @@ -18705,7 +18659,7 @@ dependencies = [ "anyhow", "candid", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-crypto-ed25519", "ic-crypto-secp256k1", "ic-types", @@ -18727,7 +18681,7 @@ dependencies = [ "assert-json-diff", "canister-test", "dfn_protobuf", - "ic-agent 0.37.1", + "ic-agent", "ic-canister-client", "ic-ledger-canister-blocks-synchronizer-test-utils", "ic-ledger-core", @@ -18760,7 +18714,7 @@ dependencies = [ "canister-test", "dfn_protobuf", "hex", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-client", "ic-canister-client-sender", @@ -18779,7 +18733,7 @@ dependencies = [ "icp-ledger", "lazy_static", "on_wire", - "prost 0.13.3", + "prost 0.13.4", "rand 0.8.5", "reqwest 0.12.9", "rosetta-core", @@ -18792,9 +18746,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest 0.10.7", @@ -18836,7 +18790,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.87", + "syn 2.0.90", "unicode-ident", ] @@ -18929,9 +18883,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc-hex" @@ -18959,15 +18913,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", - "errno 0.3.9", + "errno 0.3.10", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -18998,9 +18952,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "brotli 7.0.0", "brotli-decompressor", @@ -19034,8 +18988,8 @@ dependencies = [ "ring 0.17.8", "serde", "serde_json", - "thiserror 2.0.3", - "webpki-roots 0.26.6", + "thiserror 2.0.8", + "webpki-roots 0.26.7", "x509-parser", ] @@ -19049,20 +19003,19 @@ dependencies = [ "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] name = "rustls-native-certs" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" dependencies = [ "openssl-probe", - "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.1.0", ] [[package]] @@ -19085,9 +19038,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", +] [[package]] name = "rustls-platform-verifier" @@ -19095,16 +19051,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c7dc240fec5517e6c4eab3310438636cfe6391dfc345ba013109909a90d136" dependencies = [ - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "jni", "log", "once_cell", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-native-certs 0.7.3", "rustls-platform-verifier-android", "rustls-webpki 0.102.8", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "webpki-root-certs", "windows-sys 0.52.0", @@ -19172,9 +19128,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.4" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22760a375f81a31817aeaf6f5081e9ccb7ffd7f2da1809a6e3fc82b6656f10d5" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if 1.0.0", "derive_more 1.0.0", @@ -19184,21 +19140,21 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.4" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abc61ebe25a5c410c0e245028fc9934bf8fa4817199ef5a24a68092edfd34614" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -19210,7 +19166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", - "indexmap 2.6.0", + "indexmap 2.7.0", "schemars_derive", "serde", "serde_json", @@ -19225,7 +19181,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -19386,18 +19342,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "num-bigint 0.4.6", "security-framework-sys", ] +[[package]] +name = "security-framework" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d3f8c9bfcc3cbb6b0179eb57042d75b1582bdc65c3cb95f3fa999509c03cbc" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" dependencies = [ "core-foundation-sys", "libc", @@ -19424,18 +19393,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -19493,13 +19462,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -19510,14 +19479,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -19545,7 +19514,7 @@ dependencies = [ "futures", "percent-encoding", "serde", - "thiserror 1.0.68", + "thiserror 1.0.69", ] [[package]] @@ -19566,7 +19535,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -19589,7 +19558,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -19651,7 +19620,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -19660,7 +19629,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -19681,7 +19650,7 @@ name = "setupos-disable-checks" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "indoc", "linux_kernel_command_line", "partition_tools", @@ -19695,7 +19664,7 @@ name = "setupos-inject-configuration" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config", "partition_tools", "serde", @@ -19711,7 +19680,7 @@ name = "setupos_tool" version = "1.0.0" dependencies = [ "anyhow", - "clap 4.5.20", + "clap 4.5.23", "config", "config_types", "deterministic_ips", @@ -19839,7 +19808,7 @@ checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ "num-bigint 0.4.6", "num-traits", - "thiserror 1.0.68", + "thiserror 1.0.69", "time", ] @@ -20004,7 +19973,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20013,7 +19982,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-canister-client", "ic-canister-client-sender", @@ -20032,7 +20001,7 @@ dependencies = [ "ic-system-test-driver", "ic-types", "ic-universal-canister", - "ic-utils 0.37.0", + "ic-utils 0.39.0", "ic_consensus_system_test_utils", "icp-ledger", "icrc-ledger-agent", @@ -20072,9 +20041,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -20205,6 +20174,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if 1.0.0", + "futures-core", + "pin-project-lite", +] + [[package]] name = "str_stack" version = "0.1.0" @@ -20258,7 +20239,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive 0.2.0", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20270,7 +20251,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive 0.3.0", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20281,7 +20262,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20292,7 +20273,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20314,7 +20295,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20342,9 +20323,9 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "symbolic-common" -version = "12.12.0" +version = "12.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366f1b4c6baf6cfefc234bbd4899535fca0b06c74443039a73f6dfb2fad88d77" +checksum = "cd33e73f154e36ec223c18013f7064a2c120f1162fc086ac9933542def186b00" dependencies = [ "debugid", "memmap2", @@ -20354,9 +20335,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.12.0" +version = "12.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba05ba5b9962ea5617baf556293720a8b2d0a282aa14ee4bf10e22efc7da8c8" +checksum = "89e51191290147f071777e37fe111800bb82a9059f9c95b19d2dd41bfeddf477" dependencies = [ "rustc-demangle", "symbolic-common", @@ -20375,27 +20356,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "sync-with-released-nervous-system-wasms" version = "0.9.0" @@ -20404,7 +20373,7 @@ dependencies = [ "candid", "colored", "futures", - "ic-agent 0.37.1", + "ic-agent", "ic-base-types", "ic-nervous-system-agent", "ic-nervous-system-clients", @@ -20426,9 +20395,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -20441,7 +20410,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20451,7 +20420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -20472,20 +20441,20 @@ dependencies = [ "anyhow", "async-trait", "axum", - "clap 4.5.20", + "clap 4.5.23", "http 1.2.0", "itertools 0.12.1", "reqwest 0.12.9", - "thiserror 2.0.3", + "thiserror 2.0.8", "tokio", "url", ] [[package]] name = "systemstat" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24aec24a9312c83999a28e3ef9db7e2afd5c64bf47725b758cdc1cafd5b0bd2" +checksum = "668a4db78b439df482c238f559e4ea869017f9e62ef0a059c8bfcd841a4df544" dependencies = [ "bytesize", "lazy_static", @@ -20529,9 +20498,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", @@ -20560,7 +20529,7 @@ dependencies = [ "serde", "static_assertions", "tarpc-plugins", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tokio-serde", "tokio-util", @@ -20581,9 +20550,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -20644,9 +20613,9 @@ dependencies = [ [[package]] name = "termtree" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "test-strategy" @@ -20657,7 +20626,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta 0.2.0", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20669,7 +20638,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta 0.3.0", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20678,7 +20647,7 @@ version = "0.9.0" dependencies = [ "anyhow", "candid", - "ic-agent 0.37.1", + "ic-agent", "ic-prep", "ic-regedit", "ic-registry-local-store", @@ -20735,42 +20704,42 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.68", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "2.0.3" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a" dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl 2.0.8", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "thiserror-impl" -version = "2.0.3" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20831,9 +20800,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -20854,9 +20823,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -20945,7 +20914,7 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -20957,11 +20926,11 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] @@ -20984,7 +20953,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -21022,12 +20991,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.23.19", - "rustls-pki-types", + "rustls 0.23.20", "tokio", ] @@ -21055,15 +21023,15 @@ checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" dependencies = [ "either", "futures-util", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -21124,7 +21092,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow", ] @@ -21140,17 +21108,17 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", - "h2 0.4.6", + "h2 0.4.7", "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-timeout", "hyper-util", "percent-encoding", "pin-project", - "prost 0.13.3", - "socket2 0.5.7", + "prost 0.13.4", + "socket2 0.5.8", "tokio", "tokio-stream", "tower 0.4.13", @@ -21167,10 +21135,10 @@ checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" dependencies = [ "prettyplease", "proc-macro2", - "prost-build 0.13.3", - "prost-types 0.13.3", + "prost-build 0.13.4", + "prost-types 0.13.4", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -21195,17 +21163,17 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "hdrhistogram", - "indexmap 2.6.0", + "indexmap 2.7.0", "pin-project-lite", "slab", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.2", "tokio", "tokio-util", "tower-layer", @@ -21248,7 +21216,7 @@ dependencies = [ "pin-project-lite", "tokio", "tokio-util", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -21304,8 +21272,8 @@ dependencies = [ "governor", "http 1.2.0", "pin-project", - "thiserror 1.0.68", - "tower 0.5.1", + "thiserror 1.0.69", + "tower 0.5.2", "tracing", ] @@ -21328,7 +21296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror 1.0.68", + "thiserror 1.0.69", "time", "tracing-subscriber", ] @@ -21341,7 +21309,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -21397,8 +21365,8 @@ checksum = "97a971f6058498b5c0f1affa23e7ea202057a7301dbff68e968b2d578bcbd053" dependencies = [ "js-sys", "once_cell", - "opentelemetry 0.27.0", - "opentelemetry_sdk 0.27.0", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", "smallvec", "tracing", "tracing-core", @@ -21505,7 +21473,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", - "thiserror 1.0.68", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -21526,7 +21494,7 @@ dependencies = [ "parking_lot 0.12.3", "resolv-conf", "smallvec", - "thiserror 1.0.68", + "thiserror 1.0.69", "tokio", "tracing", "trust-dns-proto", @@ -21552,7 +21520,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror 1.0.68", + "thiserror 1.0.69", "url", "utf-8", ] @@ -21632,15 +21600,15 @@ checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" @@ -21663,6 +21631,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -21719,9 +21693,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna 1.0.3", @@ -21811,7 +21785,7 @@ dependencies = [ "chrono", "lalrpop 0.20.2", "once_cell", - "ordered-float 4.5.0", + "ordered-float 4.6.0", "regex", "serde", "serde_json", @@ -21833,7 +21807,7 @@ dependencies = [ name = "vsock_guest" version = "1.0.0" dependencies = [ - "clap 4.5.20", + "clap 4.5.23", "vsock_lib", ] @@ -21934,11 +21908,11 @@ dependencies = [ "futures-util", "headers 0.3.9", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "log", "mime", "mime_guess", - "multer", + "multer 2.1.0", "percent-encoding", "pin-project", "rustls-pemfile 2.2.0", @@ -21962,9 +21936,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if 1.0.0", "once_cell", @@ -21973,36 +21947,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if 1.0.0", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -22010,22 +21984,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-encoder" @@ -22056,11 +22030,21 @@ dependencies = [ "wasmparser 0.219.1", ] +[[package]] +name = "wasm-encoder" +version = "0.222.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956" +dependencies = [ + "leb128", + "wasmparser 0.222.0", +] + [[package]] name = "wasm-streams" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -22078,7 +22062,7 @@ dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver", "serde", ] @@ -22092,7 +22076,7 @@ dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver", "serde", ] @@ -22106,11 +22090,22 @@ dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "semver", "serde", ] +[[package]] +name = "wasmparser" +version = "0.222.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5" +dependencies = [ + "bitflags 2.6.0", + "indexmap 2.7.0", + "semver", +] + [[package]] name = "wasmprinter" version = "0.217.0" @@ -22145,7 +22140,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "libc", "libm", "log", @@ -22193,7 +22188,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasmtime-component-util", "wasmtime-wit-bindgen", "wit-parser", @@ -22224,7 +22219,7 @@ dependencies = [ "object", "smallvec", "target-lexicon", - "thiserror 1.0.68", + "thiserror 1.0.69", "wasmparser 0.219.1", "wasmtime-environ", "wasmtime-versioned-export-macros", @@ -22240,7 +22235,7 @@ dependencies = [ "cranelift-bitset", "cranelift-entity", "gimli 0.31.1", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "object", "postcard", @@ -22279,7 +22274,7 @@ checksum = "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -22290,7 +22285,7 @@ checksum = "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "wit-parser", ] @@ -22303,37 +22298,37 @@ dependencies = [ "bumpalo", "leb128", "memchr", - "unicode-width", + "unicode-width 0.1.14", "wasm-encoder 0.212.0", ] [[package]] name = "wast" -version = "219.0.1" +version = "222.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f79a9d9df79986a68689a6b40bcc8d5d40d807487b235bebc2ac69a242b54a1" +checksum = "5ce7191f4b7da0dd300cc32476abae6457154e4625d9b1bc26890828a9a26f6e" dependencies = [ "bumpalo", "leb128", "memchr", - "unicode-width", - "wasm-encoder 0.219.1", + "unicode-width 0.2.0", + "wasm-encoder 0.222.0", ] [[package]] name = "wat" -version = "1.219.1" +version = "1.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc3cf014fb336883a411cd662f987abf6a1d2a27f2f0008616a0070bbf6bd0d" +checksum = "8fde61b4b52f9a84ae31b5e8902a2cd3162ea45d8bf564c729c3288fe52f4334" dependencies = [ - "wast 219.0.1", + "wast 222.0.0", ] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -22351,9 +22346,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c6dfa3ac045bc517de14c7b1384298de1dbd229d38e08e169d9ae8c170937c" +checksum = "9cd5da49bdf1f30054cfe0b8ce2958b8fbeb67c4d82c8967a598af481bef255c" dependencies = [ "rustls-pki-types", ] @@ -22366,9 +22361,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -22672,7 +22667,7 @@ checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" dependencies = [ "anyhow", "id-arena", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "semver", "serde", @@ -22753,7 +22748,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror 1.0.68", + "thiserror 1.0.69", "time", ] @@ -22840,9 +22835,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -22852,13 +22847,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -22880,27 +22875,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -22921,7 +22916,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -22943,7 +22938,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a4352eccaa4..521019dae7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -558,26 +558,23 @@ hyper-rustls = { version = "0.27.3", default-features = false, features = [ ] } hyper-socks2 = { version = "0.9.1", default-features = false } hyper-util = { version = "0.1.10", features = ["full"] } -ic-agent = { version = "0.37.1", features = [ - "experimental_sync_call", - "hyper", - "reqwest", - "pem", -] } +ic-agent = { version = "0.39.2", features = ["pem", "ring"] } ic-bn-lib = { git = "https://github.com/dfinity/ic-bn-lib", rev = "d74a6527fbaf8a2c1a7076983cc84f5c5a727923" } ic-btc-interface = "0.2.2" -ic-cbor = "2.6.0" +ic-canister-sig-creation = { git = "https://github.com/dfinity/ic-canister-sig-creation", rev = "7f9e931954637526295269155881207f6c832d6d" } +ic-cbor = "3" ic-cdk = "0.16.0" ic-cdk-macros = "0.9.0" ic-cdk-timers = "0.7.0" -ic-certificate-verification = "2.6.0" -ic-certification = "2.6.0" -ic-http-certification = "2.6.0" -ic-response-verification = "2.6.0" +ic-certificate-verification = "3" +ic-certification = "3" +ic-http-certification = "3" +ic-http-gateway = "0.1" +ic-response-verification = "3" ic-sha3 = "1.0.0" ic-stable-structures = "0.6.5" -ic-transport-types = { version = "0.37.1" } -ic-utils = { version = "0.37.0", features = ["raw"] } +ic-transport-types = { version = "0.39.2" } +ic-utils = { version = "0.39", features = ["raw"] } ic_bls12_381 = { version = "0.10.0", default-features = false, features = [ "groups", "pairings", diff --git a/bazel/external_crates.bzl b/bazel/external_crates.bzl index d2c6b4738d5..683723af702 100644 --- a/bazel/external_crates.bzl +++ b/bazel/external_crates.bzl @@ -569,13 +569,8 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable version = "^0.18.11", ), "ic-agent": crate.spec( - version = "^0.37.1", - features = [ - "experimental_sync_call", - "hyper", - "reqwest", - "pem", - ], + version = "^0.39.2", + features = ["pem", "ring"], ), "ic-bn-lib": crate.spec( git = "https://github.com/dfinity/ic-bn-lib", @@ -588,10 +583,11 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable version = "^0.2.0", ), "ic-canister-sig-creation": crate.spec( - version = "^1.0.1", + git = "https://github.com/dfinity/ic-canister-sig-creation", + rev = "7f9e931954637526295269155881207f6c832d6d", ), "ic-cbor": crate.spec( - version = "2.6.0", + version = "3.0.2", ), "ic-cdk": crate.spec( version = "^0.16.0", @@ -606,17 +602,16 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable version = "^0.3.1", ), "ic-certification": crate.spec( - version = "2.6.0", + version = "3.0.2", ), "ic-certificate-verification": crate.spec( - version = "2.6.0", + version = "3.0.2", ), "ic-http-certification": crate.spec( - version = "2.6.0", + version = "3.0.2", ), "ic-http-gateway": crate.spec( - git = "https://github.com/dfinity/http-gateway", - tag = "0.1.0-b0", + version = "0.1.0", ), "ic-metrics-encoder": crate.spec( version = "^1.1.1", @@ -626,7 +621,7 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable default_features = False, ), "ic-response-verification": crate.spec( - version = "2.6.0", + version = "3.0.2", ), "ic-sha3": crate.spec( version = "^1.0.0", @@ -646,10 +641,10 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable version = "^3.0.0", ), "ic-transport-types": crate.spec( - version = "^0.37.1", + version = "^0.39.2", ), "ic-utils": crate.spec( - version = "^0.37.0", + version = "^0.39.0", features = ["raw"], ), "ic-verify-bls-signature": crate.spec( @@ -879,7 +874,7 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable ], ), "opentelemetry_sdk": crate.spec( - version = "^0.27.0", + version = "^0.27.1", features = [ "trace", "rt-tokio", diff --git a/packages/ic-signature-verification/Cargo.toml b/packages/ic-signature-verification/Cargo.toml index b0ef343ccee..d3a4d919490 100644 --- a/packages/ic-signature-verification/Cargo.toml +++ b/packages/ic-signature-verification/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/ic-signature-verification" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ic-canister-sig-creation = "1.0" +ic-canister-sig-creation = { workspace = true } ic-certification = { workspace = true } ic-verify-bls-signature = { version = "0.6", default-features = false, features = [ "alloc", diff --git a/rs/boundary_node/certificate_issuance/certificate_issuer/src/check.rs b/rs/boundary_node/certificate_issuance/certificate_issuer/src/check.rs index f2f3abc0869..f5321deaa71 100644 --- a/rs/boundary_node/certificate_issuance/certificate_issuer/src/check.rs +++ b/rs/boundary_node/certificate_issuance/certificate_issuer/src/check.rs @@ -171,15 +171,10 @@ impl Check for Checker { })?; // Phase 4 - Ensure canister mentions known domain. - let request = HttpRequest { - method: String::from("GET"), - url: String::from("/.well-known/ic-domains"), - headers: vec![], - body: vec![], - }; + let request = HttpRequest::get("/.well-known/ic-domains").build(); let (response,) = HttpRequestCanister::create(&self.agent, canister_id) - .http_request(&request.method, &request.url, vec![], vec![], None) + .http_request(&request.method(), &request.url(), vec![], vec![], None) .call() .await .map_err(|_| CheckError::KnownDomainsUnavailable { @@ -197,16 +192,18 @@ impl Check for Checker { }?; // Check response certification - let response_for_verification = HttpResponse { - status_code: response.status_code, - headers: response + let response_for_verification = HttpResponse::ok( + // body + response.body.clone(), + // headers + response .headers .iter() .map(|field| (field.0.to_string(), field.1.to_string())) .collect::>(), - body: response.body.clone(), - upgrade: response.upgrade, - }; + ) + .with_upgrade(response.upgrade.unwrap_or_default()) + .build(); let max_cert_time_offset_ns = 300_000_000_000; let current_time_ns = SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/rs/boundary_node/certificate_issuance/certificate_issuer/src/main.rs b/rs/boundary_node/certificate_issuance/certificate_issuer/src/main.rs index ab2dca4f12c..f21af9ca8c2 100644 --- a/rs/boundary_node/certificate_issuance/certificate_issuer/src/main.rs +++ b/rs/boundary_node/certificate_issuance/certificate_issuer/src/main.rs @@ -23,9 +23,7 @@ use axum::{ use candid::{DecoderConfig, Principal}; use chacha20poly1305::{KeyInit, XChaCha20Poly1305}; use clap::Parser; -use ic_agent::{ - agent::http_transport::reqwest_transport::ReqwestTransport, identity::Secp256k1Identity, Agent, -}; +use ic_agent::{identity::Secp256k1Identity, Agent}; use instant_acme::{Account, AccountCredentials, NewAccount}; use opentelemetry::{ metrics::{Counter, Histogram, MeterProvider as _}, @@ -198,15 +196,13 @@ async fn main() -> Result<(), Error> { static USER_AGENT: &str = "Ic-Certificate-Issuer"; let client = reqwest::Client::builder().user_agent(USER_AGENT).build()?; - let transport = - ReqwestTransport::create_with_client(cli.orchestrator_uri.to_string(), client)?; - let f = File::open(cli.identity_path).context("failed to open identity file")?; let identity = Secp256k1Identity::from_pem(f).context("failed to create basic identity")?; let agent = Agent::builder() .with_identity(identity) - .with_transport(transport) + .with_url(cli.orchestrator_uri.to_string()) + .with_http_client(client) .build()?; let root_key = cli diff --git a/rs/http_endpoints/fuzz/fuzz_targets/execute_call_service.rs b/rs/http_endpoints/fuzz/fuzz_targets/execute_call_service.rs index 1eecf8e7b2e..042a41ccbfb 100644 --- a/rs/http_endpoints/fuzz/fuzz_targets/execute_call_service.rs +++ b/rs/http_endpoints/fuzz/fuzz_targets/execute_call_service.rs @@ -4,12 +4,7 @@ use axum::body::Body; use bytes::Bytes; use http_body_util::Full; use hyper::{Method, Request, Response}; -use ic_agent::{ - agent::{http_transport::reqwest_transport::ReqwestTransport, UpdateBuilder}, - export::Principal, - identity::AnonymousIdentity, - Agent, -}; +use ic_agent::{agent::UpdateBuilder, export::Principal, identity::AnonymousIdentity, Agent}; use ic_config::http_handler::Config; use ic_error_types::{ErrorCode, UserError}; use ic_http_endpoints_public::{call_v2, IngressValidatorBuilder}; @@ -166,7 +161,8 @@ fn new_update_call( ) -> Vec { let agent = Agent::builder() .with_identity(AnonymousIdentity) - .with_transport(ReqwestTransport::create(format!("http://{}", addr)).unwrap()) + .with_url(format!("http://{}", addr)) + .with_http_client(reqwest::Client::new()) .build() .unwrap(); let update = UpdateBuilder::new(&agent, effective_canister_id, content.method_name) diff --git a/rs/monitoring/tracing/jaeger_exporter/src/lib.rs b/rs/monitoring/tracing/jaeger_exporter/src/lib.rs index 59860234076..bee49183962 100644 --- a/rs/monitoring/tracing/jaeger_exporter/src/lib.rs +++ b/rs/monitoring/tracing/jaeger_exporter/src/lib.rs @@ -23,14 +23,11 @@ pub fn jaeger_exporter( .build()?; let tracer = sdk_trace::TracerProvider::builder() - .with_config( - sdk_trace::Config::default() - .with_sampler(sdk_trace::Sampler::TraceIdRatioBased(0.01)) - .with_resource(Resource::new(vec![KeyValue::new( - "service.name", - service_name, - )])), - ) + .with_sampler(sdk_trace::Sampler::TraceIdRatioBased(0.01)) + .with_resource(Resource::new(vec![KeyValue::new( + "service.name", + service_name, + )])) .with_batch_exporter(span_exporter, sdk_runtime::Tokio) .build(); diff --git a/rs/nervous_system/agent/src/agent_impl.rs b/rs/nervous_system/agent/src/agent_impl.rs index 8cd6f14b93f..c70472a01af 100644 --- a/rs/nervous_system/agent/src/agent_impl.rs +++ b/rs/nervous_system/agent/src/agent_impl.rs @@ -32,12 +32,13 @@ impl CallCanisters for Agent { .with_arg(request_bytes) .call() .await?; - match request { + let (response, _cert) = match request { ic_agent::agent::CallResponse::Response(response) => response, ic_agent::agent::CallResponse::Poll(request_id) => { self.wait(&request_id, canister_id).await? } - } + }; + response } else { self.query(&canister_id, request.method()) .with_arg(request_bytes) diff --git a/rs/pocket_ic_server/Cargo.toml b/rs/pocket_ic_server/Cargo.toml index 33adf717663..2fe09384489 100644 --- a/rs/pocket_ic_server/Cargo.toml +++ b/rs/pocket_ic_server/Cargo.toml @@ -38,7 +38,7 @@ ic-crypto-iccsa = { path = "../crypto/iccsa" } ic-crypto-sha2 = { path = "../crypto/sha2" } ic-crypto-utils-threshold-sig-der = { path = "../crypto/utils/threshold_sig_der" } ic-error-types = { path = "../types/error_types" } -ic-http-gateway = { git = "https://github.com/dfinity/http-gateway", tag = "0.1.0-b0" } +ic-http-gateway = { workspace = true } ic-http-endpoints-public = { path = "../http_endpoints/public" } ic-https-outcalls-adapter = { path = "../https_outcalls/adapter" } ic-https-outcalls-adapter-client = { path = "../https_outcalls/client" } diff --git a/rs/pocket_ic_server/src/state_api/state.rs b/rs/pocket_ic_server/src/state_api/state.rs index 703e63ffd36..05a0962c441 100644 --- a/rs/pocket_ic_server/src/state_api/state.rs +++ b/rs/pocket_ic_server/src/state_api/state.rs @@ -612,8 +612,7 @@ async fn handler( |_| ErrorCause::RequestTooLarge, ) })? - .to_bytes() - .to_vec(); + .to_bytes(); let args = HttpGatewayRequestArgs { canister_request: CanisterRequest::from_parts(parts, body), diff --git a/rs/pocket_ic_server/tests/test.rs b/rs/pocket_ic_server/tests/test.rs index 1abd4e912e5..72f615d93df 100644 --- a/rs/pocket_ic_server/tests/test.rs +++ b/rs/pocket_ic_server/tests/test.rs @@ -1,5 +1,5 @@ use candid::{Encode, Principal}; -use ic_agent::agent::{http_transport::ReqwestTransport, CallResponse}; +use ic_agent::agent::CallResponse; use ic_cdk::api::management_canister::main::CanisterIdRecord; use ic_cdk::api::management_canister::provisional::ProvisionalCreateCanisterWithCyclesArgument; use ic_interfaces_registry::{ @@ -313,14 +313,10 @@ async fn test_gateway(server_url: Url, https: bool) { } let client = builder.build().unwrap(); - // create agent with custom transport - let transport = ReqwestTransport::create_with_client( - format!("{}://{}:{}", proto, localhost, port), - client.clone(), - ) - .unwrap(); + // create agent let agent = ic_agent::Agent::builder() - .with_transport(transport) + .with_url(format!("{}://{}:{}", proto, localhost, port)) + .with_http_client(client.clone()) .build() .unwrap(); agent.fetch_root_key().await.unwrap(); @@ -897,12 +893,9 @@ fn test_specified_id_call_v3() { .build() .unwrap(); rt.block_on(async { - let transport = ReqwestTransport::create(endpoint.clone()) - .unwrap() - .with_use_call_v3_endpoint(); - let agent = ic_agent::Agent::builder() - .with_transport(transport) + .with_url(endpoint) + .with_http_client(reqwest::Client::new()) .build() .unwrap(); agent.fetch_root_key().await.unwrap(); diff --git a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/BUILD.bazel b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/BUILD.bazel index c2642f20c1b..39f15f2ecf0 100644 --- a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/BUILD.bazel +++ b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/BUILD.bazel @@ -17,6 +17,7 @@ DEPENDENCIES = [ "@crate_index//:chrono", "@crate_index//:ciborium", "@crate_index//:ic-agent", + "@crate_index//:reqwest", "@crate_index//:rusqlite", "@crate_index//:serde", "@crate_index//:tokio", diff --git a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/Cargo.toml b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/Cargo.toml index 453821ec207..65e6441cf66 100644 --- a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/Cargo.toml +++ b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/Cargo.toml @@ -20,6 +20,7 @@ ic-ledger-hash-of = { path = "../../../../packages/ic-ledger-hash-of" } ic-types = { path = "../../../types/types" } icp-ledger = { path = "../../../ledger_suite/icp" } on_wire = { path = "../../../rust_canisters/on_wire" } +reqwest = { workspace = true } rusqlite = { version = "~0.28.0", features = ["bundled"] } serde = { workspace = true } tokio = { workspace = true } diff --git a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/src/canister_access.rs b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/src/canister_access.rs index 23eef1784ab..81fae203c4c 100644 --- a/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/src/canister_access.rs +++ b/rs/rosetta-api/icp/ledger_canister_blocks_synchronizer/src/canister_access.rs @@ -1,6 +1,5 @@ #![allow(clippy::disallowed_types)] use dfn_protobuf::{ProtoBuf, ToProto}; -use ic_agent::agent::http_transport::reqwest_transport::ReqwestTransport; use ic_agent::identity::AnonymousIdentity; use ic_agent::{Agent, AgentError, NonceGenerator}; use ic_ledger_core::block::EncodedBlock; @@ -47,7 +46,8 @@ fn make_agent(url: Url) -> Result { let is_exchanges_testnet = url.host_str() == Some("exchanges.testnet.dfinity.network"); Agent::builder() .with_identity(AnonymousIdentity) - .with_transport(ReqwestTransport::create(url)?) + .with_url(url) + .with_http_client(reqwest::Client::new()) .with_nonce_generator(TimestampBlob::default()) // The testnet has an old replica version and the query // verification wouldn't work so we disable it diff --git a/rs/rosetta-api/icp/tests/system_tests/common/utils.rs b/rs/rosetta-api/icp/tests/system_tests/common/utils.rs index 1a7f685ed57..4dfcd549f52 100644 --- a/rs/rosetta-api/icp/tests/system_tests/common/utils.rs +++ b/rs/rosetta-api/icp/tests/system_tests/common/utils.rs @@ -1,6 +1,5 @@ use crate::common::constants::MAX_ROSETTA_SYNC_ATTEMPTS; use candid::{Decode, Encode}; -use ic_agent::agent::http_transport::ReqwestTransport; use ic_agent::identity::BasicIdentity; use ic_agent::Agent; use ic_agent::Identity; @@ -37,10 +36,10 @@ pub async fn get_custom_agent(basic_identity: Arc, port: u16) -> A let replica_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); // Setup the agent - let transport = ReqwestTransport::create(replica_url.clone()).unwrap(); let agent = Agent::builder() + .with_url(replica_url.clone()) + .with_http_client(reqwest::Client::new()) .with_identity(basic_identity) - .with_arc_transport(Arc::new(transport)) .build() .unwrap(); diff --git a/rs/rosetta-api/icrc1/src/main.rs b/rs/rosetta-api/icrc1/src/main.rs index 356bba5f546..1f109e31e32 100644 --- a/rs/rosetta-api/icrc1/src/main.rs +++ b/rs/rosetta-api/icrc1/src/main.rs @@ -7,9 +7,7 @@ use axum::{ Router, }; use clap::{Parser, ValueEnum}; -use ic_agent::{ - agent::http_transport::reqwest_transport::ReqwestTransport, identity::AnonymousIdentity, Agent, -}; +use ic_agent::{identity::AnonymousIdentity, Agent}; use ic_base_types::CanisterId; use ic_icrc_rosetta::{ common::constants::{BLOCK_SYNC_WAIT_SECS, MAX_BLOCK_SYNC_WAIT_SECS}, @@ -294,10 +292,11 @@ async fn main() -> Result<()> { let ic_agent = Agent::builder() .with_identity(AnonymousIdentity) - .with_transport(ReqwestTransport::create( + .with_url( Url::parse(&network_url) .context(format!("Failed to parse URL {}", network_url.clone()))?, - )?) + ) + .with_http_client(reqwest::Client::new()) .build()?; // Only fetch root key if the network is not the mainnet diff --git a/rs/rosetta-api/icrc1/tests/common/local_replica.rs b/rs/rosetta-api/icrc1/tests/common/local_replica.rs index 3c3bd8a3d29..aa800fc4df7 100644 --- a/rs/rosetta-api/icrc1/tests/common/local_replica.rs +++ b/rs/rosetta-api/icrc1/tests/common/local_replica.rs @@ -2,7 +2,7 @@ use candid::{Encode, Principal}; use ic_agent::identity::BasicIdentity; use ic_agent::Agent; -use ic_agent::{agent::http_transport::reqwest_transport::ReqwestTransport, Identity}; +use ic_agent::Identity; use ic_base_types::PrincipalId; use ic_icrc1_ledger::FeatureFlags; use ic_icrc1_ledger::{InitArgs, InitArgsBuilder, LedgerArgument}; @@ -39,10 +39,10 @@ pub async fn get_custom_agent(basic_identity: Arc, port: u16) -> A let replica_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); // Setup the agent - let transport = ReqwestTransport::create(replica_url.clone()).unwrap(); let agent = Agent::builder() + .with_url(replica_url.clone()) .with_identity(basic_identity) - .with_arc_transport(Arc::new(transport)) + .with_http_client(reqwest::Client::new()) .build() .unwrap(); diff --git a/rs/tests/boundary_nodes/api_bn_decentralization_test.rs b/rs/tests/boundary_nodes/api_bn_decentralization_test.rs index 4d0fb59a9ef..b5c0e7f6d28 100644 --- a/rs/tests/boundary_nodes/api_bn_decentralization_test.rs +++ b/rs/tests/boundary_nodes/api_bn_decentralization_test.rs @@ -36,11 +36,8 @@ use registry_canister::mutations::{ use ic_agent::{ agent::{ - http_transport::{ - reqwest_transport::reqwest::{redirect::Policy, Client, ClientBuilder}, - route_provider::RouteProvider, - ReqwestTransport, - }, + http_transport::reqwest_transport::reqwest::{redirect::Policy, Client, ClientBuilder}, + route_provider::RouteProvider, ApiBoundaryNode, }, export::Principal, @@ -185,11 +182,9 @@ async fn test(env: TestEnv) { assert!(rules.contains("ct state new add @connection_limit")); } - let transport = - ReqwestTransport::create_with_client("https://api1.com", http_client.clone()).unwrap(); - let bn_agent = Agent::builder() - .with_transport(transport) + .with_url("https://api1.com") + .with_http_client(http_client.clone()) .with_identity(AnonymousIdentity {}) .build() .unwrap(); @@ -302,10 +297,9 @@ async fn test(env: TestEnv) { "Incrementing counters on canisters for the second time" ); - let transport = ReqwestTransport::create_with_client("https://api3.com", http_client).unwrap(); - let bn_agent = Agent::builder() - .with_transport(transport) + .with_url("https://api3.com") + .with_http_client(http_client) .with_identity(AnonymousIdentity {}) .build() .unwrap(); diff --git a/rs/tests/boundary_nodes/integration_test_common/src/lib.rs b/rs/tests/boundary_nodes/integration_test_common/src/lib.rs index 916658e785b..84fb9a56cb8 100644 --- a/rs/tests/boundary_nodes/integration_test_common/src/lib.rs +++ b/rs/tests/boundary_nodes/integration_test_common/src/lib.rs @@ -38,15 +38,8 @@ use std::{env, iter, net::SocketAddrV6, time::Duration}; use anyhow::{anyhow, bail, Context, Error}; use futures::stream::FuturesUnordered; -use ic_agent::{ - agent::http_transport::{ - hyper_transport::hyper::StatusCode, - reqwest_transport::{reqwest, ReqwestTransport}, - }, - export::Principal, - Agent, -}; -use reqwest::{redirect::Policy, ClientBuilder, Method}; +use ic_agent::{export::Principal, Agent}; +use reqwest::{redirect::Policy, ClientBuilder, Method, StatusCode}; use serde::Deserialize; use slog::{error, info, Logger}; use tokio::{runtime::Runtime, time::sleep}; @@ -180,9 +173,10 @@ pub fn api_query_test(env: TestEnv) { block_on(async move { let cid = install_counter_canister(env, logger.clone()).await?; - let transport = ReqwestTransport::create_with_client(format!("https://{host}/"), client)?; - - let agent = Agent::builder().with_transport(transport).build()?; + let agent = Agent::builder() + .with_url(format!("https://{host}/")) + .with_http_client(client) + .build()?; agent.fetch_root_key().await?; let out = agent.query(&cid, "read").call().await?; @@ -220,8 +214,10 @@ pub fn api_call_test(env: TestEnv) { .unwrap(); // check that the update call went through - let transport = ReqwestTransport::create_with_client(format!("https://{host}/"), client)?; - let agent = Agent::builder().with_transport(transport).build()?; + let agent = Agent::builder() + .with_url(format!("https://{host}/")) + .with_http_client(client) + .build()?; agent.fetch_root_key().await?; let out = agent.query(&cid, "read").call().await?; @@ -250,10 +246,10 @@ pub fn api_sync_call_test(env: TestEnv) { block_on(async move { let cid = install_counter_canister(env.clone(), logger.clone()).await?; - let transport = ReqwestTransport::create_with_client(format!("https://{host}/"), client)? - .with_use_call_v3_endpoint(); - - let agent = Agent::builder().with_transport(transport).build()?; + let agent = Agent::builder() + .with_url(format!("https://{host}/")) + .with_http_client(client) + .build()?; agent.fetch_root_key().await?; // update call @@ -285,9 +281,10 @@ pub fn api_canister_read_state_test(env: TestEnv) { block_on(async move { let cid = install_counter_canister(env.clone(), logger.clone()).await?; - let transport = ReqwestTransport::create_with_client(format!("https://{host}/"), client)?; - - let agent = Agent::builder().with_transport(transport).build()?; + let agent = Agent::builder() + .with_url(format!("https://{host}/")) + .with_http_client(client) + .build()?; agent.fetch_root_key().await?; let _ = agent.read_state_canister_info(cid, "module_hash").await?; @@ -311,9 +308,10 @@ pub fn api_subnet_read_state_test(env: TestEnv) { let (client, host) = setup_client(env.clone()).expect("failed to setup client"); block_on(async move { - let transport = ReqwestTransport::create_with_client(format!("https://{host}/"), client)?; - - let agent = Agent::builder().with_transport(transport).build()?; + let agent = Agent::builder() + .with_url(format!("https://{host}/")) + .with_http_client(client) + .build()?; agent.fetch_root_key().await?; let subnet_id: Principal = env diff --git a/rs/tests/boundary_nodes/rate_limit_canister_test.rs b/rs/tests/boundary_nodes/rate_limit_canister_test.rs index f075db10fc7..5aba85a8aea 100644 --- a/rs/tests/boundary_nodes/rate_limit_canister_test.rs +++ b/rs/tests/boundary_nodes/rate_limit_canister_test.rs @@ -10,13 +10,14 @@ Runbook: 4. Create an `ic-agent` instance associated with an API boundary node. 5. Verify that initially the agent can successfully interact with the counter canister by sending e.g. an update call. 6. Add a rate-limit rule to the rate-limit canister, which completely blocks requests to the counter canister. +// TODO: BOUN-1330 - investigate the reason of flakiness in Step 7, temporarily disable steps below. 7. Verify that the agent can no longer send requests to the counter canister after API boundary node enforces the new rule. 8. Add a rate-limit rule, which unblocks requests to the counter canister. 9. Verify that the agent can send requests to the counter canister again, ensuring that updated rate-limit rules are enforced correctly by API boundary nodes. end::catalog[] */ -use anyhow::{bail, Result}; +use anyhow::Result; use candid::{Decode, Encode, Principal}; use ic_base_types::PrincipalId; use ic_boundary_nodes_system_test_utils::{ @@ -27,13 +28,12 @@ use k256::elliptic_curve::SecretKey; use rand::{rngs::OsRng, SeedableRng}; use rand_chacha::ChaChaRng; use slog::info; -use std::{env, net::SocketAddr, time::Duration}; -use tokio::{runtime::Runtime, time::timeout}; +use std::{env, net::SocketAddr}; +use tokio::runtime::Runtime; use ic_agent::{ - agent::http_transport::{reqwest_transport::reqwest::Client, ReqwestTransport}, - identity::Secp256k1Identity, - Agent, Identity, + agent::http_transport::reqwest_transport::reqwest::Client, identity::Secp256k1Identity, Agent, + Identity, }; use ic_registry_subnet_type::SubnetType; use ic_system_test_driver::{ @@ -47,7 +47,7 @@ use ic_system_test_driver::{ IcNodeContainer, }, }, - retry_with_msg_async, systest, + systest, util::runtime_from_url, }; use rate_limits_api::{ @@ -154,11 +154,9 @@ async fn test_async(env: TestEnv) { .resolve(&api_bn_domain, api_bn_ipv6) .build() .expect("Could not create HTTP client."); - let transport = - ReqwestTransport::create_with_client(format!("https://{api_bn_domain}"), client) - .unwrap(); let agent = Agent::builder() - .with_transport(transport) + .with_url(format!("https://{api_bn_domain}")) + .with_http_client(client) .with_identity(full_access_identity) .build() .unwrap(); @@ -193,71 +191,73 @@ async fn test_async(env: TestEnv) { ) .await; - info!( - &logger, - "Step 7. Verify that the api_bn_agent can no longer send requests to the counter canister" - ); - - retry_with_msg_async!( - "check_counter_canister_becomes_unreachable".to_string(), - &logger, - Duration::from_secs(180), - Duration::from_secs(5), - || async { - match timeout( - Duration::from_secs(2), - api_bn_agent.update(&counter_canister_id, "write").call(), - ) - .await - { - Ok(_) => bail!("counter canister is still reachable, retrying"), - Err(_) => Ok(()), - } - } - ) - .await - .expect("failed to check that canister becomes unreachable"); - - info!( - &logger, - "Step 8. Add a rate-limit rule, which unblocks requests to the counter canister" - ); - - set_rate_limit_rule( - &api_bn_agent, - rate_limit_id, - RateLimitRule { - canister_id: Some(counter_canister_id), - limit: Action::Limit(300, Duration::from_secs(60)), - ..Default::default() - }, - ) - .await; - - info!( - &logger, - "Step 9. Verify that agent can send requests to the counter canister again" - ); - - retry_with_msg_async!( - "check_counter_canister_becomes_reachable".to_string(), - &logger, - Duration::from_secs(180), - Duration::from_secs(5), - || async { - match timeout( - Duration::from_secs(2), - api_bn_agent.update(&counter_canister_id, "write").call(), - ) - .await - { - Ok(_) => Ok(()), - Err(_) => bail!("counter canister is still unreachable, retrying"), - } - } - ) - .await - .expect("failed to check that canister becomes reachable"); + // TODO: BOUN-1330 - investigate the reason of flakiness in Step 7, temporarily disable steps below. + + // info!( + // &logger, + // "Step 7. Verify that the api_bn_agent can no longer send requests to the counter canister" + // ); + + // retry_with_msg_async!( + // "check_counter_canister_becomes_unreachable".to_string(), + // &logger, + // Duration::from_secs(180), + // Duration::from_secs(5), + // || async { + // match timeout( + // Duration::from_secs(2), + // api_bn_agent.update(&counter_canister_id, "write").call(), + // ) + // .await + // { + // Ok(_) => bail!("counter canister is still reachable, retrying"), + // Err(_) => Ok(()), + // } + // } + // ) + // .await + // .expect("failed to check that canister becomes unreachable"); + + // info!( + // &logger, + // "Step 8. Add a rate-limit rule, which unblocks requests to the counter canister" + // ); + + // set_rate_limit_rule( + // &api_bn_agent, + // rate_limit_id, + // RateLimitRule { + // canister_id: Some(counter_canister_id), + // limit: Action::Limit(300, Duration::from_secs(60)), + // ..Default::default() + // }, + // ) + // .await; + + // info!( + // &logger, + // "Step 9. Verify that agent can send requests to the counter canister again" + // ); + + // retry_with_msg_async!( + // "check_counter_canister_becomes_reachable".to_string(), + // &logger, + // Duration::from_secs(180), + // Duration::from_secs(5), + // || async { + // match timeout( + // Duration::from_secs(2), + // api_bn_agent.update(&counter_canister_id, "write").call(), + // ) + // .await + // { + // Ok(_) => Ok(()), + // Err(_) => bail!("counter canister is still unreachable, retrying"), + // } + // } + // ) + // .await + // .expect("failed to check that canister becomes reachable"); } async fn set_rate_limit_rule( diff --git a/rs/tests/driver/src/util.rs b/rs/tests/driver/src/util.rs index 363f86d1687..2229a5f4216 100644 --- a/rs/tests/driver/src/util.rs +++ b/rs/tests/driver/src/util.rs @@ -19,8 +19,8 @@ use futures::{ }; use ic_agent::{ agent::{ - http_transport::reqwest_transport::{reqwest, ReqwestTransport}, - CallResponse, EnvelopeContent, RejectCode, RejectResponse, + http_transport::reqwest_transport::reqwest, CallResponse, EnvelopeContent, RejectCode, + RejectResponse, }, export::Principal, identity::BasicIdentity, @@ -813,9 +813,7 @@ pub async fn agent_with_identity_mapping( (Some(addr_mapping), Ok(Some(domain))) => builder.resolve(domain, (addr_mapping, 0).into()), _ => builder, }; - let client = builder - .build() - .map_err(|err| AgentError::TransportError(Box::new(err)))?; + let client = builder.build().map_err(AgentError::TransportError)?; agent_with_client_identity(url, client, identity).await } @@ -824,11 +822,9 @@ pub async fn agent_with_client_identity( client: reqwest::Client, identity: impl Identity + 'static, ) -> Result { - let transport = ReqwestTransport::create_with_client(url, client)? - .with_use_call_v3_endpoint() - .with_max_tcp_errors_retries(MAX_TCP_ERROR_RETRIES); let a = Agent::builder() - .with_transport(transport) + .with_url(url) + .with_http_client(client) .with_identity(identity) .with_max_concurrent_requests(MAX_CONCURRENT_REQUESTS) // Ingresses are created with the system time but are checked against the consensus time. @@ -843,7 +839,7 @@ pub async fn agent_with_client_identity( // too further in the future, i.e. greater than x+MAX_INGRESS_TTL in this case. To tolerate // the delays in the progress of consensus, we reduce 30sn from MAX_INGRESS_TTL and set the // expiry_time of ingresses accordingly. - .with_ingress_expiry(Some(MAX_INGRESS_TTL - std::time::Duration::from_secs(30))) + .with_ingress_expiry(MAX_INGRESS_TTL - std::time::Duration::from_secs(30)) .build() .unwrap(); a.fetch_root_key().await?; diff --git a/rs/tests/execution/general_execution_tests/nns_shielding.rs b/rs/tests/execution/general_execution_tests/nns_shielding.rs index 1c1c69422be..4ebab5b8a4a 100644 --- a/rs/tests/execution/general_execution_tests/nns_shielding.rs +++ b/rs/tests/execution/general_execution_tests/nns_shielding.rs @@ -81,7 +81,7 @@ pub fn mint_cycles_supported_only_on_cycles_minting_canister(env: TestEnv) { "Error from Canister {}: Canister violated contract: ic0.mint_cycles cannot be executed on non Cycles Minting Canister: {} != {}.\nThis is likely an error with the compiler/CDK toolchain being used to build the canister. Please report the error to IC devs on the forum: https://forum.dfinity.org and include which language/CDK was used to create the canister.", nns_canister_id, nns_canister_id, CYCLES_MINTING_CANISTER_ID), - error_code: None}) + error_code: Some("IC0504".to_string())}) ); let after_balance = get_balance(&nns_canister_id, &nns_agent).await; @@ -178,7 +178,7 @@ pub fn mint_cycles128_supported_only_on_cycles_minting_canister(env: TestEnv) { "Error from Canister {}: Canister violated contract: ic0.mint_cycles cannot be executed on non Cycles Minting Canister: {} != {}.\nThis is likely an error with the compiler/CDK toolchain being used to build the canister. Please report the error to IC devs on the forum: https://forum.dfinity.org and include which language/CDK was used to create the canister.", canister_id, canister_id, CYCLES_MINTING_CANISTER_ID), - error_code: None}) + error_code: Some("IC0504".to_string())}) ); assert!( after_balance == before_balance, @@ -200,7 +200,7 @@ pub fn mint_cycles128_not_supported_on_application_subnet(env: TestEnv) { "Error from Canister {}: Canister violated contract: ic0.mint_cycles cannot be executed on non Cycles Minting Canister: {} != {}.\nThis is likely an error with the compiler/CDK toolchain being used to build the canister. Please report the error to IC devs on the forum: https://forum.dfinity.org and include which language/CDK was used to create the canister.", canister_id, canister_id, CYCLES_MINTING_CANISTER_ID), - error_code: None}) + error_code: Some("IC0504".to_string())}) ); assert!( after_balance <= before_balance, diff --git a/rs/tests/execution/general_execution_tests/wasm_chunk_store.rs b/rs/tests/execution/general_execution_tests/wasm_chunk_store.rs index ccee4717e65..a4ee00f238a 100644 --- a/rs/tests/execution/general_execution_tests/wasm_chunk_store.rs +++ b/rs/tests/execution/general_execution_tests/wasm_chunk_store.rs @@ -310,7 +310,7 @@ pub fn install_large_wasm_with_other_store_fails_cross_subnet(env: TestEnv) { let expected_err = AgentError::CertifiedReject(RejectResponse { reject_code: RejectCode::CanisterReject, reject_message: format!("InstallChunkedCode Error: Store canister {} was not found on subnet {} of target canister {}", store_canister_id, app_subnet_id, target_canister_id), - error_code: None, + error_code: Some("IC0406".to_string()), }); assert_eq!(err, expected_err); } From 67cd0a790fdbbb34c2889ab2696ab0de5aea105e Mon Sep 17 00:00:00 2001 From: Leo Eichhorn <99166915+eichhorl@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:27:05 +0100 Subject: [PATCH 08/98] chore: CON-1434 Increment metric in case of `NiDkgTag` mismatches (#3329) With https://github.com/dfinity/ic/pull/3039 we will start to serialize maps of the form `(nidkg_tag, nidkg_transcript)` as a vector of `nidkg_transcript`s. This is fine since the NiDkg tag is also part of the NiDkg transcript. More generally, the change makes the assumption `nidkg_tag == nidkg_transcript.tag` explicit. As an extra pre-caution, this PR adds a log and metric to increase our confidence that this assumption already holds today (and thus that the change in https://github.com/dfinity/ic/pull/3039 is safe to roll out). --- rs/consensus/src/consensus/validator.rs | 1 + rs/consensus/src/dkg/payload_validator.rs | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/rs/consensus/src/consensus/validator.rs b/rs/consensus/src/consensus/validator.rs index c15cb3980e2..9f67d875272 100644 --- a/rs/consensus/src/consensus/validator.rs +++ b/rs/consensus/src/consensus/validator.rs @@ -1313,6 +1313,7 @@ impl Validator { self.state_manager.as_ref(), &proposal.context, &self.metrics.dkg_validator, + &self.log, ) .map_err(|err| { err.map( diff --git a/rs/consensus/src/dkg/payload_validator.rs b/rs/consensus/src/dkg/payload_validator.rs index b6e489b0f10..2d3e30c6ec1 100644 --- a/rs/consensus/src/dkg/payload_validator.rs +++ b/rs/consensus/src/dkg/payload_validator.rs @@ -8,6 +8,7 @@ use ic_interfaces::{ }; use ic_interfaces_registry::RegistryClient; use ic_interfaces_state_manager::StateManager; +use ic_logger::{warn, ReplicaLogger}; use ic_registry_client_helpers::subnet::SubnetRegistry; use ic_replicated_state::ReplicatedState; use ic_types::{ @@ -123,6 +124,7 @@ pub(crate) fn validate_payload( state_manager: &dyn StateManager, validation_context: &ValidationContext, metrics: &IntCounterVec, + log: &ReplicaLogger, ) -> ValidationResult { let current_height = parent.height.increment(); let registry_version = pool_reader @@ -164,6 +166,28 @@ pub(crate) fn validate_payload( ) .into()); } + for (tag, transcript) in summary_payload.dkg.current_transcripts() { + if *tag != transcript.dkg_id.dkg_tag { + metrics.with_label_values(&["tag_mismatch"]).inc(); + warn!( + log, + "Current transcript key {:?} doesn't match transcript tag {:?}!", + tag, + transcript.dkg_id.dkg_tag + ); + } + } + for (tag, transcript) in summary_payload.dkg.next_transcripts() { + if *tag != transcript.dkg_id.dkg_tag { + metrics.with_label_values(&["tag_mismatch"]).inc(); + warn!( + log, + "Next transcript key {:?} doesn't match transcript tag {:?}!", + tag, + transcript.dkg_id.dkg_tag + ); + } + } Ok(()) } BlockPayload::Data(data_payload) => { @@ -275,6 +299,7 @@ fn validate_dealings_payload( mod tests { use super::*; use ic_consensus_mocks::{dependencies_with_subnet_params, Dependencies}; + use ic_logger::no_op_logger; use ic_metrics::MetricsRegistry; use ic_test_utilities_consensus::fake::FakeContentSigner; use ic_test_utilities_registry::SubnetRecordBuilder; @@ -343,6 +368,7 @@ mod tests { state_manager.as_ref(), &context, &mock_metrics(), + &no_op_logger(), ) .is_ok()); @@ -364,6 +390,7 @@ mod tests { state_manager.as_ref(), &context, &mock_metrics(), + &no_op_logger(), ) .is_ok()); }) @@ -559,6 +586,7 @@ mod tests { state_manager.as_ref(), &context, &mock_metrics(), + &no_op_logger(), ); result From cc086f3a126510614f372c57fa1d1a9c38142bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Tue, 7 Jan 2025 15:20:53 +0100 Subject: [PATCH 09/98] docs(ICRC_Ledger): FI-1619: Add rustdoc to icrc-ledger-types (#3345) Add rustdoc to the `icrc-ledger-types`. --- .../src/icrc/generic_metadata_value.rs | 8 +++++++- .../src/icrc/generic_value.rs | 2 ++ packages/icrc-ledger-types/src/icrc/mod.rs | 2 ++ .../icrc-ledger-types/src/icrc1/account.rs | 5 ++++- packages/icrc-ledger-types/src/icrc1/mod.rs | 3 +++ .../icrc-ledger-types/src/icrc1/transfer.rs | 7 +++++++ .../icrc-ledger-types/src/icrc2/allowance.rs | 6 ++++++ .../icrc-ledger-types/src/icrc2/approve.rs | 6 ++++++ packages/icrc-ledger-types/src/icrc2/mod.rs | 2 ++ .../src/icrc2/transfer_from.rs | 6 ++++++ packages/icrc-ledger-types/src/icrc21/mod.rs | 3 +++ .../icrc-ledger-types/src/icrc3/archive.rs | 18 ++++++++++++++++++ packages/icrc-ledger-types/src/icrc3/blocks.rs | 17 ++++++++++++++++- packages/icrc-ledger-types/src/icrc3/mod.rs | 3 +++ packages/icrc-ledger-types/src/icrc3/schema.rs | 1 + .../src/icrc3/transactions.rs | 4 ++++ packages/icrc-ledger-types/src/lib.rs | 2 ++ 17 files changed, 92 insertions(+), 3 deletions(-) diff --git a/packages/icrc-ledger-types/src/icrc/generic_metadata_value.rs b/packages/icrc-ledger-types/src/icrc/generic_metadata_value.rs index a46c9c33bc8..bb5f4d169cd 100644 --- a/packages/icrc-ledger-types/src/icrc/generic_metadata_value.rs +++ b/packages/icrc-ledger-types/src/icrc/generic_metadata_value.rs @@ -2,7 +2,12 @@ use candid::{CandidType, Deserialize, Int, Nat}; use serde::Serialize; use serde_bytes::ByteBuf; -/// Variant type for the `metadata` endpoint values. +/// Variant type for the `icrc1_metadata` endpoint values. The corresponding metadata keys are +/// arbitrary Unicode strings and must follow the pattern `:`, where `` +/// is a string not containing colons. The namespace `icrc1` is reserved for keys defined in the +/// ICRC-1 standard. For more information, see the +/// [documentation of Metadata in the ICRC-1 standard](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-1#metadata). +/// Note that the `MetadataValue` type is a subset of the [`icrc_ledger_types::icrc::generic_value::ICRC3Value`] type. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub enum MetadataValue { Nat(Nat), @@ -12,6 +17,7 @@ pub enum MetadataValue { } impl MetadataValue { + /// Create a `(String, MetadataValue)` tuple for use in metadata maps. pub fn entry(key: impl ToString, val: impl Into) -> (String, Self) { (key.to_string(), val.into()) } diff --git a/packages/icrc-ledger-types/src/icrc/generic_value.rs b/packages/icrc-ledger-types/src/icrc/generic_value.rs index c7994cd193f..47b931e0037 100644 --- a/packages/icrc-ledger-types/src/icrc/generic_value.rs +++ b/packages/icrc-ledger-types/src/icrc/generic_value.rs @@ -15,6 +15,7 @@ pub type Map = BTreeMap; pub type ICRC3Map = BTreeMap; pub type Hash = [u8; 32]; +/// A value defined in [the ICRC-3 standard](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#value). #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum ICRC3Value { Blob(ByteBuf), @@ -33,6 +34,7 @@ impl std::fmt::Display for ICRC3Value { } impl ICRC3Value { + /// Compute [the hash of an ICRC-3 value](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#value). pub fn hash(self) -> Hash { // TODO(FI-1263): copy the value hash function to avoid cloning self Value::from(self).hash() diff --git a/packages/icrc-ledger-types/src/icrc/mod.rs b/packages/icrc-ledger-types/src/icrc/mod.rs index 299fac452e6..3ed31f22887 100644 --- a/packages/icrc-ledger-types/src/icrc/mod.rs +++ b/packages/icrc-ledger-types/src/icrc/mod.rs @@ -1,3 +1,5 @@ +//! Types for ICRC standards. + pub mod generic_metadata_value; pub mod generic_value; pub mod generic_value_predicate; diff --git a/packages/icrc-ledger-types/src/icrc1/account.rs b/packages/icrc-ledger-types/src/icrc1/account.rs index 96254ffbd17..3d9e06e836f 100644 --- a/packages/icrc-ledger-types/src/icrc1/account.rs +++ b/packages/icrc-ledger-types/src/icrc1/account.rs @@ -15,7 +15,8 @@ pub type Subaccount = [u8; 32]; pub const DEFAULT_SUBACCOUNT: &Subaccount = &[0; 32]; -// Account representation of ledgers supporting the ICRC1 standard +/// [Account](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#value) +/// representation of ledgers supporting the ICRC-1 standard. #[derive(Serialize, CandidType, Deserialize, Clone, Debug, Copy, Encode, Decode)] pub struct Account { #[cbor(n(0), with = "icrc_cbor::principal")] @@ -25,6 +26,8 @@ pub struct Account { } impl Account { + /// The effective subaccount of an account - the subaccount if it is set, otherwise the default + /// subaccount of all zeroes. #[inline] pub fn effective_subaccount(&self) -> &Subaccount { self.subaccount.as_ref().unwrap_or(DEFAULT_SUBACCOUNT) diff --git a/packages/icrc-ledger-types/src/icrc1/mod.rs b/packages/icrc-ledger-types/src/icrc1/mod.rs index 365317be2b5..9e2517c5dd8 100644 --- a/packages/icrc-ledger-types/src/icrc1/mod.rs +++ b/packages/icrc-ledger-types/src/icrc1/mod.rs @@ -1,2 +1,5 @@ +//! The [ICRC-1](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md) +//! token standard. + pub mod account; pub mod transfer; diff --git a/packages/icrc-ledger-types/src/icrc1/transfer.rs b/packages/icrc-ledger-types/src/icrc1/transfer.rs index ba1e3b62a2e..961d98f8199 100644 --- a/packages/icrc-ledger-types/src/icrc1/transfer.rs +++ b/packages/icrc-ledger-types/src/icrc1/transfer.rs @@ -7,6 +7,7 @@ use std::fmt; pub type NumTokens = Nat; pub type BlockIndex = Nat; +/// The arguments for the [ICRC-1 `transfer`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md#icrc1_transfer-) endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct TransferArg { #[serde(default)] @@ -21,6 +22,9 @@ pub struct TransferArg { pub amount: NumTokens, } +/// The [`Memo`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md#icrc1_transfer-) +/// is an arbitrary blob that has no meaning to the ledger. The ledger SHOULD allow memos of at +/// least 32 bytes in length. #[derive( Serialize, Deserialize, CandidType, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Default, )] @@ -51,6 +55,9 @@ impl From for ByteBuf { } } +/// Errors defined for the +/// [ICRC-1 `transfer`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md#icrc1_transfer-) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub enum TransferError { BadFee { expected_fee: NumTokens }, diff --git a/packages/icrc-ledger-types/src/icrc2/allowance.rs b/packages/icrc-ledger-types/src/icrc2/allowance.rs index aebda165fbb..72f9f6a36d8 100644 --- a/packages/icrc-ledger-types/src/icrc2/allowance.rs +++ b/packages/icrc-ledger-types/src/icrc2/allowance.rs @@ -3,12 +3,18 @@ use serde::Serialize; use super::super::icrc1::account::Account; +/// The arguments for the +/// [ICRC-2 `allowance`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_allowance) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct AllowanceArgs { pub account: Account, pub spender: Account, } +/// The `Allowance` response type for the +/// [ICRC-2 `allowance`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_allowance) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct Allowance { pub allowance: Nat, diff --git a/packages/icrc-ledger-types/src/icrc2/approve.rs b/packages/icrc-ledger-types/src/icrc2/approve.rs index b85f625fbdf..b1d68f9bd56 100644 --- a/packages/icrc-ledger-types/src/icrc2/approve.rs +++ b/packages/icrc-ledger-types/src/icrc2/approve.rs @@ -5,6 +5,9 @@ use std::fmt; use super::super::icrc1::account::{Account, Subaccount}; use super::super::icrc1::transfer::Memo; +/// The arguments for the +/// [ICRC-2 `approve`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_approve) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct ApproveArgs { #[serde(default)] @@ -23,6 +26,9 @@ pub struct ApproveArgs { pub created_at_time: Option, } +/// The error return type for the +/// [ICRC-2 `approve`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_approve) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub enum ApproveError { BadFee { expected_fee: Nat }, diff --git a/packages/icrc-ledger-types/src/icrc2/mod.rs b/packages/icrc-ledger-types/src/icrc2/mod.rs index 29e6531d0d6..6d59e037dbd 100644 --- a/packages/icrc-ledger-types/src/icrc2/mod.rs +++ b/packages/icrc-ledger-types/src/icrc2/mod.rs @@ -1,3 +1,5 @@ +//! The [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md) +//! Approve and Transfer From standard. pub mod allowance; pub mod approve; pub mod transfer_from; diff --git a/packages/icrc-ledger-types/src/icrc2/transfer_from.rs b/packages/icrc-ledger-types/src/icrc2/transfer_from.rs index 33d599fbbd0..f4136e1d216 100644 --- a/packages/icrc-ledger-types/src/icrc2/transfer_from.rs +++ b/packages/icrc-ledger-types/src/icrc2/transfer_from.rs @@ -5,6 +5,9 @@ use std::fmt; use super::super::icrc1::account::{Account, Subaccount}; use super::super::icrc1::transfer::Memo; +/// The arguments for the +/// [ICRC-2 `transfer_from`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_transfer_from) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct TransferFromArgs { #[serde(default)] @@ -20,6 +23,9 @@ pub struct TransferFromArgs { pub created_at_time: Option, } +/// The error return type for the +/// [ICRC-2 `transfer_from`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md#icrc2_transfer_from) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub enum TransferFromError { BadFee { expected_fee: Nat }, diff --git a/packages/icrc-ledger-types/src/icrc21/mod.rs b/packages/icrc-ledger-types/src/icrc21/mod.rs index 7017638351d..3b4af7afacc 100644 --- a/packages/icrc-ledger-types/src/icrc21/mod.rs +++ b/packages/icrc-ledger-types/src/icrc21/mod.rs @@ -1,3 +1,6 @@ +//! The [ICRC-21](https://github.com/dfinity/wg-identity-authentication/blob/main/topics/ICRC-21/icrc_21_consent_msg.md) +//! Canister Call Consent Messages standard. + pub mod errors; pub mod lib; pub mod requests; diff --git a/packages/icrc-ledger-types/src/icrc3/archive.rs b/packages/icrc-ledger-types/src/icrc3/archive.rs index ddc69ba4d57..91ad27c9799 100644 --- a/packages/icrc-ledger-types/src/icrc3/archive.rs +++ b/packages/icrc-ledger-types/src/icrc3/archive.rs @@ -8,6 +8,10 @@ use candid::{CandidType, Deserialize, Nat, Principal}; use serde::Serialize; use std::marker::PhantomData; +/// Deprecated. The information in the `ArchivedRange` struct is returned as part of the return value +/// of [`crate::icrc3::blocks::GetBlocksResult`] from the +/// [`icrc3_get_blocks`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct ArchivedRange { pub start: Nat, @@ -15,6 +19,10 @@ pub struct ArchivedRange { pub callback: Callback, } +/// Details on the callback function using which archived blocks can be retrieved. Returned as part +/// of [`crate::icrc3::blocks::GetBlocksResult`] from the +/// [`icrc3_get_blocks`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint. #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(try_from = "candid::types::reference::Func")] pub struct QueryArchiveFn { @@ -108,6 +116,7 @@ impl CandidType for QueryArchiveFn; pub type QueryTxArchiveFn = QueryArchiveFn; +/// The argument for the +/// [`icrc3_get_archives`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct GetArchivesArgs { // The last archive seen by the client. @@ -126,6 +138,9 @@ pub struct GetArchivesArgs { pub from: Option, } +/// The information returned as part of the return value for the +/// [`icrc3_get_archives`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct ICRC3ArchiveInfo { // The id of the archive @@ -138,4 +153,7 @@ pub struct ICRC3ArchiveInfo { pub end: Nat, } +/// The return value for the +/// [`icrc3_get_archives`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint. pub type GetArchivesResult = Vec; diff --git a/packages/icrc-ledger-types/src/icrc3/blocks.rs b/packages/icrc-ledger-types/src/icrc3/blocks.rs index 3d44dc263bf..fb4873e54d3 100644 --- a/packages/icrc-ledger-types/src/icrc3/blocks.rs +++ b/packages/icrc-ledger-types/src/icrc3/blocks.rs @@ -8,7 +8,7 @@ use serde_bytes::ByteBuf; use super::archive::QueryArchiveFn; -/// Deprecated, use `ICRC3GenericBlock` instead +/// Deprecated, use [`ICRC3GenericBlock`] instead pub type GenericBlock = Value; pub type ICRC3GenericBlock = ICRC3Value; @@ -22,18 +22,23 @@ pub struct GetBlocksResponse { pub archived_blocks: Vec>, } +/// A block with an ID. Returned as part of [`GetBlocksResult`]. #[derive(Debug, CandidType, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct BlockWithId { pub id: Nat, pub block: ICRC3GenericBlock, } +/// Information about where to find archived blocks. Returned as part of [`GetBlocksResult`]. #[derive(Debug, CandidType, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct ArchivedBlocks { pub args: Vec, pub callback: QueryArchiveFn, GetBlocksResult>, } +/// The result type for the +/// [ICRC-3 `icrc3_get_blocks`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#icrc3_get_blocks) +/// endpoint. #[derive(Debug, CandidType, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct GetBlocksResult { pub log_length: Nat, @@ -41,12 +46,16 @@ pub struct GetBlocksResult { pub archived_blocks: Vec, } +/// The arguments for the +/// [ICRC-3 `icrc3_get_blocks`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#icrc3_get_blocks) +/// endpoint. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct GetBlocksRequest { pub start: BlockIndex, pub length: Nat, } +/// The return type for the deprecated `get_blocks` endpoint of the archive canister. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct BlockRange { pub blocks: Vec, @@ -81,12 +90,18 @@ pub struct DataCertificate { pub hash_tree: serde_bytes::ByteBuf, } +/// The data certificate returned from the +/// [ICRC-3 `icrc3_get_tip_certificate`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#icrc3_get_tip_certificate) +/// endpoint. #[derive(Debug, CandidType, Serialize, Deserialize)] pub struct ICRC3DataCertificate { pub certificate: serde_bytes::ByteBuf, pub hash_tree: serde_bytes::ByteBuf, } +/// The return type of the +/// [ICRC-3 `icrc3_supported_block_types`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md#icrc3_supported_block_types) +/// endpoint. #[derive(Debug, CandidType, Serialize, Deserialize)] pub struct SupportedBlockType { pub block_type: String, diff --git a/packages/icrc-ledger-types/src/icrc3/mod.rs b/packages/icrc-ledger-types/src/icrc3/mod.rs index db50aef6ccf..fd1572dd8ed 100644 --- a/packages/icrc-ledger-types/src/icrc3/mod.rs +++ b/packages/icrc-ledger-types/src/icrc3/mod.rs @@ -1,3 +1,6 @@ +//! The [ICRC-3](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +//! Block Log standard. + pub mod archive; pub mod blocks; pub mod schema; diff --git a/packages/icrc-ledger-types/src/icrc3/schema.rs b/packages/icrc-ledger-types/src/icrc3/schema.rs index 95b1fa75b03..3ebd7453728 100644 --- a/packages/icrc-ledger-types/src/icrc3/schema.rs +++ b/packages/icrc-ledger-types/src/icrc3/schema.rs @@ -8,6 +8,7 @@ use crate::icrc::{ }, }; +/// Validate if a block is compatible with the ICRC-3 schema. // TODO(FI-1241): make it compatible with the final ICRC-3 schema pub fn validate(block: &Value) -> Result<(), ValuePredicateFailures> { use ItemRequirement::*; diff --git a/packages/icrc-ledger-types/src/icrc3/transactions.rs b/packages/icrc-ledger-types/src/icrc3/transactions.rs index ff6fd3575d7..e6f9f06141b 100644 --- a/packages/icrc-ledger-types/src/icrc3/transactions.rs +++ b/packages/icrc-ledger-types/src/icrc3/transactions.rs @@ -113,6 +113,9 @@ impl Transaction { } } +/// Deprecated. Use [`GetBlocksResponse`] returned from the +/// [`icrc3_get_blocks`](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-3/README.md) +/// endpoint instead. #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct GetTransactionsResponse { pub log_length: Nat, @@ -121,6 +124,7 @@ pub struct GetTransactionsResponse { pub archived_transactions: Vec>, } +/// Deprecated. Use Vec<[`ICRC3GenericBlock`]> instead #[derive(CandidType, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct TransactionRange { pub transactions: Vec, diff --git a/packages/icrc-ledger-types/src/lib.rs b/packages/icrc-ledger-types/src/lib.rs index f532acb4880..454b5d6b2cb 100644 --- a/packages/icrc-ledger-types/src/lib.rs +++ b/packages/icrc-ledger-types/src/lib.rs @@ -1,3 +1,5 @@ +//! A library of types to communicate with a ledger canister that implements ICRC standards. + pub mod icrc; pub mod icrc1; pub mod icrc2; From efd5dd71518842ca7b8e7ffdecc8f291a08e9771 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:48:13 +0100 Subject: [PATCH 10/98] feat(cycles-minting-canister): When memo does not match, fall back to icrc1_memo. (#3336) # References This implements the first of two features mentioned in [this forum thread][thread]. [thread]: https://forum.dfinity.org/t/extend-cycles-minting-canister-functionality/37749 --- Cargo.lock | 1 + rs/nns/cmc/BUILD.bazel | 17 +-- rs/nns/cmc/Cargo.toml | 1 + rs/nns/cmc/src/main.rs | 240 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 241 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5559f584c1..86e8a5afab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3101,6 +3101,7 @@ dependencies = [ "prost 0.13.4", "rand 0.8.5", "serde", + "serde_bytes", "serde_cbor", "sha2 0.10.8", "yansi 0.5.1", diff --git a/rs/nns/cmc/BUILD.bazel b/rs/nns/cmc/BUILD.bazel index 56ac2907ce2..270763dd66e 100644 --- a/rs/nns/cmc/BUILD.bazel +++ b/rs/nns/cmc/BUILD.bazel @@ -50,6 +50,14 @@ BUILD_DEPENDENCIES = [ "@crate_index//:build-info-build", ] +DEV_DEPENDENCIES = [ + # Keep sorted. + "//rs/types/types_test_utils", + "@crate_index//:candid_parser", + "@crate_index//:futures", + "@crate_index//:serde_bytes", +] + ALIASES = {} cargo_build_script( @@ -86,7 +94,7 @@ rust_canister( rust_test( name = "cmc_test", crate = ":cmc", - deps = DEPENDENCIES + ["@crate_index//:futures"], + deps = DEPENDENCIES + DEV_DEPENDENCIES, ) rust_test( @@ -96,10 +104,5 @@ rust_test( env = { "CARGO_MANIFEST_DIR": "rs/nns/cmc", }, - deps = [ - # Keep sorted. - "//rs/types/types_test_utils", - "@crate_index//:candid_parser", - "@crate_index//:futures", - ], + deps = DEPENDENCIES + DEV_DEPENDENCIES, ) diff --git a/rs/nns/cmc/Cargo.toml b/rs/nns/cmc/Cargo.toml index c2597568c0d..a6d775f9d4e 100644 --- a/rs/nns/cmc/Cargo.toml +++ b/rs/nns/cmc/Cargo.toml @@ -47,6 +47,7 @@ yansi = "0.5.0" candid_parser = { workspace = true } futures = { workspace = true } ic-types-test-utils = { path = "../../types/types_test_utils" } +serde_bytes = { workspace = true } [[bin]] name = "cycles-minting-canister" diff --git a/rs/nns/cmc/src/main.rs b/rs/nns/cmc/src/main.rs index 51fe6e728e8..4d11dfce023 100644 --- a/rs/nns/cmc/src/main.rs +++ b/rs/nns/cmc/src/main.rs @@ -33,7 +33,7 @@ use ic_nns_constants::{ use ic_types::{CanisterId, Cycles, PrincipalId, SubnetId}; use icp_ledger::{ AccountIdentifier, Block, BlockIndex, BlockRes, CyclesResponse, Memo, Operation, SendArgs, - Subaccount, Tokens, TransactionNotification, DEFAULT_TRANSFER_FEE, + Subaccount, Tokens, Transaction, TransactionNotification, DEFAULT_TRANSFER_FEE, }; use icrc_ledger_types::icrc1::account::Account; use lazy_static::lazy_static; @@ -1569,6 +1569,62 @@ fn memo_to_intent_str(memo: Memo) -> String { } } +/// Returns Ok if transaction matches expected_memo. +/// +/// First, looks at the memo field. If that does not match, falls back to the +/// icrc1_field. If that is of length 8, converts assuming little endian, and if +/// that matches, returns Ok. +fn transaction_has_expected_memo( + transaction: &Transaction, + expected_memo: Memo, +) -> Result<(), NotifyError> { + fn stringify_memo(memo: Memo) -> String { + format!("{} ({})", memo_to_intent_str(memo), memo.0) + } + + if transaction.memo == expected_memo { + return Ok(()); + } + + // Fall back to icrc1_memo. + + // Read the field. + let Some(icrc1_memo) = &transaction.icrc1_memo else { + return Err(NotifyError::InvalidTransaction(format!( + "The transaction's memo ({}) does not have the required value ({}).", + stringify_memo(transaction.memo), + stringify_memo(expected_memo), + ))); + }; + + // Convert it to Memo. + type U64Array = [u8; std::mem::size_of::()]; + let observed_icrc1_memo = U64Array::try_from(icrc1_memo.as_ref()).map_err(|_err| { + NotifyError::InvalidTransaction(format!( + "The transaction's memo ({}) does not have the required value ({}).", + stringify_memo(transaction.memo), + stringify_memo(expected_memo), + )) + })?; + let observed_icrc1_memo = Memo(u64::from_le_bytes(observed_icrc1_memo)); + + // Compare to the required value. + if observed_icrc1_memo == expected_memo { + return Ok(()); + } + + Err(NotifyError::InvalidTransaction(format!( + "Neither the memo ({}) nor the icrc1_memo ({}) of the transaction \ + has the required value ({}).", + stringify_memo(transaction.memo), + stringify_memo(observed_icrc1_memo), + stringify_memo(expected_memo), + ))) +} + +/// Returns amount, and source of the transfer in (ICP) ledger. +/// +/// Returns Ok if the arguments are matched. (Otherwise, returns Err). async fn fetch_transaction( block_index: BlockIndex, expected_destination_account: AccountIdentifier, @@ -1588,22 +1644,15 @@ async fn fetch_transaction( )) } }; + if to != expected_destination_account { return Err(NotifyError::InvalidTransaction(format!( "Destination account in the block ({}) different than in the notification ({})", to, expected_destination_account ))); } - let memo = block.transaction().memo; - if memo != expected_memo { - return Err(NotifyError::InvalidTransaction(format!( - "Intent in the block ({} == {}) different than in the notification ({} == {})", - memo.0, - memo_to_intent_str(memo), - expected_memo.0, - memo_to_intent_str(expected_memo), - ))); - } + + transaction_has_expected_memo(block.transaction().as_ref(), expected_memo)?; Ok((amount, from)) } @@ -2443,6 +2492,7 @@ mod tests { use super::*; use ic_types_test_utils::ids::{subnet_test_id, user_test_id}; use rand::Rng; + use serde_bytes::ByteBuf; use std::str::FromStr; pub(crate) fn init_test_state() { @@ -3158,4 +3208,172 @@ mod tests { ) .expect("The CMC canister interface is not compatible with the cmc.did file"); } + + #[test] + fn test_transaction_has_expected_memo_happy() { + // Not relevant to this test. + let operation = Operation::Mint { + to: AccountIdentifier::new(PrincipalId::new_user_test_id(668_857_347), None), + amount: Tokens::from_e8s(123_456), + }; + + // Case A: Legacy memo is used. + let transaction_with_legacy_memo = Transaction { + memo: Memo(42), + icrc1_memo: None, + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + + assert_eq!( + transaction_has_expected_memo(&transaction_with_legacy_memo, Memo(42),), + Ok(()), + ); + + // Case B: When the user uses icrc1's memo to indicate the purpose of + // the transfer, and as a result the legacy memo field is implicitly set + // to 0. + let transaction_with_icrc1_memo = Transaction { + memo: Memo(0), + icrc1_memo: Some(ByteBuf::from(43_u64.to_le_bytes().to_vec())), + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + + assert_eq!( + transaction_has_expected_memo(&transaction_with_icrc1_memo, Memo(43),), + Ok(()), + ); + } + + #[test] + fn test_transaction_has_expected_memo_sad() { + // Not relevant to this test. + let operation = Operation::Mint { + to: AccountIdentifier::new(PrincipalId::new_user_test_id(668_857_347), None), + amount: Tokens::from_e8s(123_456), + }; + + // Case A: Legacy memo is used. + { + let transaction = Transaction { + memo: Memo(77), + icrc1_memo: None, + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + let result = transaction_has_expected_memo(&transaction, Memo(42)); + + let original_err = match result { + Err(NotifyError::InvalidTransaction(err)) => err, + wrong => panic!("{:?}", wrong), + }; + + let lower_err = original_err.to_lowercase(); + for key_word in ["memo", "77", "42"] { + assert!( + lower_err.contains(key_word), + "{} not in {:?}", + key_word, + original_err + ); + } + } + + // Case B: When the user uses icrc1's memo to indicate the purpose of + // the transfer, and as a result the legacy memo field is implicitly set + // to 0. + { + let transaction = Transaction { + memo: Memo(0), + icrc1_memo: Some(ByteBuf::from(78_u64.to_le_bytes().to_vec())), + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + + let result = transaction_has_expected_memo(&transaction, Memo(42)); + + let original_err = match result { + Err(NotifyError::InvalidTransaction(err)) => err, + wrong => panic!("{:?}", wrong), + }; + + let lower_err = original_err.to_lowercase(); + for key_word in ["memo", "78", "42"] { + assert!( + lower_err.contains(key_word), + "{} not in {:?}", + key_word, + original_err + ); + } + } + + // Case C: icrc1's memo is used, but is not of length 8, and we + // therefore do not consider it to contain a (little endian) u64. + { + let transaction = Transaction { + memo: Memo(0), + icrc1_memo: Some(ByteBuf::from(vec![1, 2, 3])), + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + + let result = transaction_has_expected_memo(&transaction, Memo(42)); + + let original_err = match result { + Err(NotifyError::InvalidTransaction(err)) => err, + wrong => panic!("{:?}", wrong), + }; + + let lower_err = original_err.to_lowercase(); + for key_word in ["memo", "0", "42"] { + assert!( + lower_err.contains(key_word), + "{} not in {:?}", + key_word, + original_err + ); + } + } + + // Case D: legacy memo is 0, and ircr1_memo is None. + { + let transaction = Transaction { + memo: Memo(0), + icrc1_memo: None, + + // Irrelevant to this test. + operation: operation.clone(), + created_at_time: None, + }; + + let result = transaction_has_expected_memo(&transaction, Memo(42)); + + let original_err = match result { + Err(NotifyError::InvalidTransaction(err)) => err, + wrong => panic!("{:?}", wrong), + }; + + let lower_err = original_err.to_lowercase(); + for key_word in ["memo", "0", "42"] { + assert!( + lower_err.contains(key_word), + "{} not in {:?}", + key_word, + original_err + ); + } + } + } } From 43e661e6eaa4fc491d476a26416d39b244f7ae4e Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:38:46 +0100 Subject: [PATCH 11/98] feat(governance): Automatically remind governance team to update unreleased_changelog.md. (#3342) This happens via a new GitHub Action. What it does is ``` if review is not requested from nns-team { return; } if already reminded { return; } Add a review that reminds the author that they need to update unreleased_changelog.md. ``` Because the reminder is done as a code review, the author is FORCED to acknowledge the reminder. --- .../ci-pr-only-nns-team-reminder.yml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/ci-pr-only-nns-team-reminder.yml diff --git a/.github/workflows/ci-pr-only-nns-team-reminder.yml b/.github/workflows/ci-pr-only-nns-team-reminder.yml new file mode 100644 index 00000000000..9f8577375f5 --- /dev/null +++ b/.github/workflows/ci-pr-only-nns-team-reminder.yml @@ -0,0 +1,68 @@ +name: Governance Unreleased Changelog Reminder + +on: + pull_request: + types: + - review_requested + +jobs: + mainJob: + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + id: mainStep + # If the PR requires nns-team to approve, GitHub will force nns-team to + # be in requested_teams. Therefore, the following condition is always + # met when nns-team must approve. (Further filtering takes place in the + # script itself.) + if: contains(github.event.pull_request.requested_teams.*.name, 'nns-team') + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + retries: 3 + script: | + const pullRequestNumber = context.payload.number; + + // Skip reminder if we already reminded (to avoid spam). + const reviews = await github.rest.pulls.listReviews({ + owner: "dfinity", + repo: "ic", + pull_number: pullRequestNumber, + }); + const alreadyRemindedAboutUnreleasedChangelog = reviews + .data + .some(review => review + .body + .startsWith("If this pull request affects the behavior of any canister owned by") + ); + console.log("alreadyRemindedAboutUnreleasedChangelog = " + alreadyRemindedAboutUnreleasedChangelog); + if (alreadyRemindedAboutUnreleasedChangelog) { + return; + } + + // Post a review to remind the author to update unreleased_changelog.md. + // TODO: Figure out how to post in such a way that there is a "Resolve" button nearby. + console.log("Adding reminder to update unreleased_changelog.md..."); + const reminderText = ` + If this pull request affects the behavior of any canister owned by + the Governance team, remember to update the corresponding + unreleased_changes.md file(s). + + To acknowldge this reminder (and unblock the PR), dismiss this + code review by going to the bottom of the pull request page, and + supply one of the following reasons: + + 1. Done. + + 2. No canister behavior changes. + ` + .replace(/^ +/gm, '') + .trim(); + await github.rest.pulls.createReview({ + owner: "dfinity", + repo: "ic", + pull_number: pullRequestNumber, + body: reminderText, + // This is what forces the author to explicitly acknowledge. + event: "REQUEST_CHANGES", + }); + console.log("Reminder was added successfully."); From b7498facfa25a90a912257ddc1a8542d5cdb43d3 Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" <189003650+pr-automation-bot-public[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:51:04 +0100 Subject: [PATCH 12/98] chore: Update Mainnet IC revisions subnets file (#3350) Update mainnet revisions file to include the latest version released on the mainnet. This PR is created automatically using [`mainnet_revisions.py`](https://github.com/dfinity/ic/blob/master/ci/src/mainnet_revisions/mainnet_revisions.py) Co-authored-by: CI Automation --- mainnet-subnet-revisions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainnet-subnet-revisions.json b/mainnet-subnet-revisions.json index 4e9a088e7f6..c29b115e706 100644 --- a/mainnet-subnet-revisions.json +++ b/mainnet-subnet-revisions.json @@ -1,6 +1,6 @@ { "subnets": { "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe": "d69648b2f5a3d90fb515824314ac2f868cbf499a", - "io67a-2jmkw-zup3h-snbwi-g6a5n-rm5dn-b6png-lvdpl-nqnto-yih6l-gqe": "76a634c31dfb840da25fbe286855eb0be1818ca8" + "io67a-2jmkw-zup3h-snbwi-g6a5n-rm5dn-b6png-lvdpl-nqnto-yih6l-gqe": "43670245ed6919790e7858813c7e838c6fbcedf5" } } \ No newline at end of file From 5d203a217a56906f494894a71c5a2c35c42d026b Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 7 Jan 2025 13:38:58 -0500 Subject: [PATCH 13/98] test: change error_code in tecdsa_signature_fails_without_cycles_test (#3352) A temporary fix for a test failure introduced by #3282 --- .../tecdsa/tecdsa_signature_fails_without_cycles_test.rs | 2 +- .../consensus/tecdsa/tecdsa_signature_life_cycle_test.rs | 6 +++--- rs/tests/consensus/tecdsa/tecdsa_signature_timeout_test.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rs/tests/consensus/tecdsa/tecdsa_signature_fails_without_cycles_test.rs b/rs/tests/consensus/tecdsa/tecdsa_signature_fails_without_cycles_test.rs index 9869d7d3626..2e335230498 100644 --- a/rs/tests/consensus/tecdsa/tecdsa_signature_fails_without_cycles_test.rs +++ b/rs/tests/consensus/tecdsa/tecdsa_signature_fails_without_cycles_test.rs @@ -79,7 +79,7 @@ fn test(env: TestEnv) { scale_cycles(ECDSA_SIGNATURE_FEE) - Cycles::from(1u64), scale_cycles(ECDSA_SIGNATURE_FEE), ), - error_code: None + error_code: Some("IC0406".to_string()) }) ) } diff --git a/rs/tests/consensus/tecdsa/tecdsa_signature_life_cycle_test.rs b/rs/tests/consensus/tecdsa/tecdsa_signature_life_cycle_test.rs index 96f29ca668c..830a459e0a0 100644 --- a/rs/tests/consensus/tecdsa/tecdsa_signature_life_cycle_test.rs +++ b/rs/tests/consensus/tecdsa/tecdsa_signature_life_cycle_test.rs @@ -100,7 +100,7 @@ fn test(env: TestEnv) { ChainKeyError(\"Requested unknown threshold key: {}, existing keys: {}\")", key_id3, initial_key_ids_as_string, ), - error_code: None, + error_code: Some("IC0406".to_string()), }) ); assert_eq!( @@ -121,7 +121,7 @@ fn test(env: TestEnv) { existing enabled keys: {}\")", key_id3, initial_key_ids_as_string, ), - error_code: None, + error_code: Some("IC0406".to_string()), }) ); @@ -228,7 +228,7 @@ fn test(env: TestEnv) { existing enabled keys: []\")", method_name, key_id ), - error_code: None + error_code: Some("IC0406".to_string()) }) ); break; diff --git a/rs/tests/consensus/tecdsa/tecdsa_signature_timeout_test.rs b/rs/tests/consensus/tecdsa/tecdsa_signature_timeout_test.rs index 81285874790..eb2de9fed5e 100644 --- a/rs/tests/consensus/tecdsa/tecdsa_signature_timeout_test.rs +++ b/rs/tests/consensus/tecdsa/tecdsa_signature_timeout_test.rs @@ -67,7 +67,7 @@ fn test(env: TestEnv) { AgentError::CertifiedReject(RejectResponse { reject_code: RejectCode::CanisterReject, reject_message: "Signature request expired".to_string(), - error_code: None + error_code: Some("IC0406".to_string()) }) ) } From 4b88e7b09b5f877a9b751552fec4d4a98e4e602c Mon Sep 17 00:00:00 2001 From: David Derler <55094821+derlerd-dfinity@users.noreply.github.com> Date: Wed, 8 Jan 2025 07:24:52 +0100 Subject: [PATCH 14/98] chore: Update codeowners NET -> CON (#3349) This PR updates the CODEOWNERS file to reflect the merge of the Networking team into the Consensus team. --- .github/CODEOWNERS | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 88e5221b28d..8ae0fbacec3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -27,9 +27,9 @@ /WORKSPACE.bazel @dfinity/idx # [Rust Lang] -rust-toolchain.toml @dfinity/networking -rustfmt.toml @dfinity/networking -deny.toml @dfinity/networking +rust-toolchain.toml @dfinity/consensus +rustfmt.toml @dfinity/consensus +deny.toml @dfinity/consensus clippy.toml @dfinity/ic-interface-owners # [Golang] @@ -91,22 +91,22 @@ go_deps.bzl @dfinity/idx /rs/artifact_pool/ @dfinity/consensus /rs/backup/ @dfinity/consensus /rs/bitcoin/ @dfinity/ic-interface-owners -/rs/bitcoin/adapter/ @dfinity/networking +/rs/bitcoin/adapter/ @dfinity/consensus /rs/bitcoin/ckbtc/ @dfinity/cross-chain-team /rs/bitcoin/mock/ @dfinity/cross-chain-team -/rs/bitcoin/client/ @dfinity/networking +/rs/bitcoin/client/ @dfinity/consensus /rs/bitcoin/consensus/ @dfinity/execution @dfinity/consensus /rs/bitcoin/checker/ @dfinity/cross-chain-team -/rs/bitcoin/service/ @dfinity/networking +/rs/bitcoin/service/ @dfinity/consensus /rs/bitcoin/replica_types/ @dfinity/execution -/rs/bitcoin/validation @dfinity/networking @dfinity/execution +/rs/bitcoin/validation @dfinity/consensus @dfinity/execution /rs/boundary_node/ @dfinity/boundary-node -/rs/canister_client/ @dfinity/networking +/rs/canister_client/ @dfinity/consensus /rs/canister_sandbox/ @dfinity/execution /rs/canonical_state/ @dfinity/ic-message-routing-owners /rs/canonical_state/tree_hash/ @dfinity/ic-message-routing-owners @dfinity/crypto-team /rs/certification/ @dfinity/ic-message-routing-owners @dfinity/crypto-team -/rs/config/ @dfinity/networking +/rs/config/ @dfinity/consensus /rs/config/src/embedders.rs @dfinity/execution /rs/config/src/execution_environment.rs @dfinity/execution /rs/config/src/state_manager.rs @dfinity/ic-message-routing-owners @@ -125,18 +125,18 @@ go_deps.bzl @dfinity/idx /rs/ethereum/ @dfinity/cross-chain-team /rs/execution_environment/ @dfinity/execution /rs/fuzzers/ @dfinity/product-security -/rs/http_endpoints/ @dfinity/networking +/rs/http_endpoints/ @dfinity/consensus /rs/http_endpoints/fuzz/ @dfinity/product-security -/rs/http_endpoints/xnet/ @dfinity/networking @dfinity/ic-message-routing-owners +/rs/http_endpoints/xnet/ @dfinity/consensus @dfinity/ic-message-routing-owners /rs/http_utils/ @dfinity/consensus -/rs/https_outcalls/ @dfinity/networking +/rs/https_outcalls/ @dfinity/consensus /rs/https_outcalls/consensus/ @dfinity/consensus /rs/ic_os/ @dfinity/node /rs/ic_os/fstrim_tool/ @dfinity/node @dfinity/crypto-team /rs/ic_os/nss_icos/ @dfinity/dre /rs/ingress_manager/ @dfinity/consensus /rs/interfaces/ @dfinity/ic-interface-owners -/rs/interfaces/adapter_client/ @dfinity/networking +/rs/interfaces/adapter_client/ @dfinity/consensus /rs/interfaces/certified_stream_store/ @dfinity/ic-message-routing-owners /rs/interfaces/registry/ @dfinity/nns-team /rs/interfaces/src/canister_http.rs @dfinity/consensus @@ -147,22 +147,22 @@ go_deps.bzl @dfinity/idx /rs/interfaces/src/dkg.rs @dfinity/consensus /rs/interfaces/src/execution_environment.rs @dfinity/execution /rs/interfaces/src/messaging.rs @dfinity/ic-message-routing-owners -/rs/interfaces/src/p2p.rs @dfinity/networking -/rs/interfaces/src/p2p/ @dfinity/networking +/rs/interfaces/src/p2p.rs @dfinity/consensus +/rs/interfaces/src/p2p/ @dfinity/consensus /rs/interfaces/state_manager/ @dfinity/ic-message-routing-owners /rs/ledger_suite/ @dfinity/finint /rs/limits/ @dfinity/ic-interface-owners /rs/memory_tracker/ @dfinity/execution /rs/messaging/ @dfinity/ic-message-routing-owners -/rs/monitoring/ @dfinity/networking -/rs/monitoring/backtrace/ @dfinity/networking @dfinity/ic-message-routing-owners -/rs/monitoring/metrics @dfinity/networking @dfinity/ic-message-routing-owners -/rs/monitoring/pprof/ @dfinity/networking @dfinity/ic-message-routing-owners +/rs/monitoring/ @dfinity/consensus +/rs/monitoring/backtrace/ @dfinity/consensus @dfinity/ic-message-routing-owners +/rs/monitoring/metrics @dfinity/consensus @dfinity/ic-message-routing-owners +/rs/monitoring/pprof/ @dfinity/consensus @dfinity/ic-message-routing-owners /rs/nervous_system/ @dfinity/nns-team /rs/nns/ @dfinity/nns-team /rs/orchestrator/ @dfinity/consensus /rs/orchestrator/src/hostos_upgrade.rs @dfinity/consensus @dfinity/node -/rs/p2p/ @dfinity/networking +/rs/p2p/ @dfinity/consensus /rs/phantom_newtype/ @dfinity/ic-interface-owners /rs/pocket_ic_server/ @dfinity/pocket-ic /rs/prep/ @dfinity/utopia @@ -170,13 +170,13 @@ go_deps.bzl @dfinity/idx /rs/protobuf/def/bitcoin/ @dfinity/execution /rs/protobuf/def/crypto/ @dfinity/crypto-team /rs/protobuf/def/messaging/ @dfinity/ic-message-routing-owners -/rs/protobuf/def/p2p/ @dfinity/networking +/rs/protobuf/def/p2p/ @dfinity/consensus /rs/protobuf/def/registry/ @dfinity/nns-team /rs/protobuf/def/state/ @dfinity/execution @dfinity/ic-message-routing-owners /rs/protobuf/gen/bitcoin/ @dfinity/execution /rs/protobuf/gen/crypto/ @dfinity/crypto-team /rs/protobuf/gen/messaging/ @dfinity/ic-message-routing-owners -/rs/protobuf/gen/p2p/ @dfinity/networking +/rs/protobuf/gen/p2p/ @dfinity/consensus /rs/protobuf/gen/registry/ @dfinity/nns-team /rs/protobuf/gen/state/ @dfinity/execution @dfinity/ic-message-routing-owners /rs/query_stats/ @dfinity/execution @dfinity/consensus @@ -184,7 +184,7 @@ go_deps.bzl @dfinity/idx /rs/registry/ @dfinity/nns-team /rs/registry/helpers/src/crypto.rs @dfinity/crypto-team /rs/registry/helpers/src/crypto/ @dfinity/crypto-team -/rs/registry/helpers/src/firewall.rs @dfinity/networking +/rs/registry/helpers/src/firewall.rs @dfinity/consensus /rs/registry/helpers/src/node.rs @dfinity/node /rs/registry/helpers/src/provisional_whitelist.rs @dfinity/execution /rs/registry/helpers/src/routing_table.rs @dfinity/execution @dfinity/ic-message-routing-owners @@ -192,7 +192,7 @@ go_deps.bzl @dfinity/idx /rs/registry/helpers/src/unassigned_nodes.rs @dfinity/consensus /rs/registry/helpers/tests/root_of_trust.rs @dfinity/crypto-team /rs/replay/ @dfinity/consensus -/rs/replica/ @dfinity/networking +/rs/replica/ @dfinity/consensus /rs/replica_tests/ @dfinity/execution /rs/replicated_state/ @dfinity/execution @dfinity/ic-message-routing-owners /rs/replicated_state/src/canister_state/queues.rs @dfinity/ic-message-routing-owners @@ -204,7 +204,7 @@ go_deps.bzl @dfinity/idx /rs/rust_canisters/backtrace_canister @dfinity/execution /rs/rust_canisters/memory_test/ @dfinity/execution /rs/rust_canisters/call_tree_test/ @dfinity/execution -/rs/rust_canisters/proxy_canister/ @dfinity/networking +/rs/rust_canisters/proxy_canister/ @dfinity/consensus /rs/rust_canisters/response_payload_test/ @dfinity/execution /rs/rust_canisters/stable_structures/ @dfinity/execution /rs/rust_canisters/stable_memory_integrity @dfinity/execution @@ -215,7 +215,7 @@ go_deps.bzl @dfinity/idx /rs/rust_canisters/downstream_calls_test/ @dfinity/ic-message-routing-owners /rs/rust_canisters/random_traffic_test/ @dfinity/ic-message-routing-owners /rs/sns/ @dfinity/nns-team -/rs/starter/ @dfinity/networking +/rs/starter/ @dfinity/consensus /rs/state_layout/ @dfinity/ic-message-routing-owners /rs/state_machine_tests/ @dfinity/ic-message-routing-owners @dfinity/pocket-ic /rs/state_manager/ @dfinity/ic-message-routing-owners @@ -228,7 +228,7 @@ go_deps.bzl @dfinity/idx /rs/test_utilities/embedders/ @dfinity/execution /rs/test_utilities/execution_environment/ @dfinity/execution /rs/test_utilities/in_memory_logger/ @dfinity/crypto-team -/rs/test_utilities/metrics @dfinity/networking @dfinity/ic-message-routing-owners +/rs/test_utilities/metrics @dfinity/consensus @dfinity/ic-message-routing-owners /rs/test_utilities/src/crypto.rs @dfinity/crypto-team /rs/test_utilities/src/crypto/ @dfinity/crypto-team /rs/test_utilities/src/cycles_account_manager.rs @dfinity/execution @@ -238,7 +238,7 @@ go_deps.bzl @dfinity/idx /rs/tests/idx/ @dfinity/idx /rs/tests/testnets/ @dfinity/idx /rs/tests/research @dfinity/research -/rs/tests/driver/src/driver/simulate_network.rs @dfinity/networking @dfinity/idx +/rs/tests/driver/src/driver/simulate_network.rs @dfinity/consensus @dfinity/idx /rs/tests/boundary_nodes/ @dfinity/boundary-node /rs/tests/ckbtc/ @dfinity/cross-chain-team /rs/tests/consensus/ @dfinity/consensus @@ -248,7 +248,7 @@ go_deps.bzl @dfinity/idx /rs/tests/execution/ @dfinity/execution /rs/tests/financial_integrations/ @dfinity/finint /rs/tests/message_routing/ @dfinity/ic-message-routing-owners -/rs/tests/networking/ @dfinity/networking +/rs/tests/networking/ @dfinity/consensus /rs/tests/nns/ @dfinity/nns-team /rs/tests/node/ @dfinity/node /rs/tests/query_stats/ @dfinity/execution @dfinity/consensus @@ -264,7 +264,7 @@ go_deps.bzl @dfinity/idx /rs/types/ @dfinity/ic-interface-owners /rs/types/exhaustive_derive/ @dfinity/consensus /rs/types/management_canister_types/ @dfinity/execution -/rs/types/types/src/artifact.rs @dfinity/consensus @dfinity/networking +/rs/types/types/src/artifact.rs @dfinity/consensus /rs/types/types/src/batch.rs @dfinity/consensus /rs/types/types/src/batch/ @dfinity/consensus /rs/types/types/src/canister_http.rs @dfinity/execution @dfinity/consensus From bfa465036eb19fdc41020ca3109bff8502e959b6 Mon Sep 17 00:00:00 2001 From: gregorydemay <112856886+gregorydemay@users.noreply.github.com> Date: Wed, 8 Jan 2025 08:21:37 +0100 Subject: [PATCH 15/98] chore(cketh): Proposal to fix developer dashboard (#3281) --- .../mainnet/minter_upgrade_2024_12_20.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 rs/ethereum/cketh/mainnet/minter_upgrade_2024_12_20.md diff --git a/rs/ethereum/cketh/mainnet/minter_upgrade_2024_12_20.md b/rs/ethereum/cketh/mainnet/minter_upgrade_2024_12_20.md new file mode 100644 index 00000000000..4ffa3a564d8 --- /dev/null +++ b/rs/ethereum/cketh/mainnet/minter_upgrade_2024_12_20.md @@ -0,0 +1,50 @@ +# Proposal to upgrade the ckETH minter canister + +Repository: `https://github.com/dfinity/ic.git` + +Git hash: `8843e7e6c89aa13efc7caca275d8dd053c11c815` + +New compressed Wasm hash: `9125677d7577cd3ceb0ba990615f6a17c9041baf166640fbbc537bb3dfd4f08c` + +Upgrade args hash: `0fee102bd16b053022b69f2c65fd5e2f41d150ce9c214ac8731cfaf496ebda4e` + +Target canister: `sv3dd-oaaaa-aaaar-qacoa-cai` + +Previous ckETH minter proposal: https://dashboard.internetcomputer.org/proposal/134344 + +--- + +## Motivation + +Upgrade the ckETH minter to add pagination to the developer [dashboard](https://sv3dd-oaaaa-aaaar-qacoa-cai.raw.icp0.io/dashboard). +The current dashboard is too big and can no longer be rendered (`Error from Canister sv3dd-oaaaa-aaaar-qacoa-cai: [...] application payload size (3185081) cannot be larger than 3145728`). + +## Upgrade args + +``` +git fetch +git checkout 8843e7e6c89aa13efc7caca275d8dd053c11c815 +cd rs/ethereum/cketh/minter +didc encode '()' | xxd -r -p | sha256sum +``` + +## Release Notes + +``` +git log --format='%C(auto) %h %s' 5ce01d0a871d5162d0b2ff0b585d71ef2e644ac9..8843e7e6c89aa13efc7caca275d8dd053c11c815 -- rs/ethereum/cketh/minter +eb61ab2449 refactor(ckbtc/cketh): unify blocklist (#2947) +5368baee2f chore(cketh): add pagination to minter dashboard (#3046) +74f377289b docs(cketh/ckerc20): update docs (#2992) +2456414f7a fix: Use workspace rust edition instead of specifying it in the Cargo.toml file (#3049) + ``` + +## Wasm Verification + +Verify that the hash of the gzipped WASM matches the proposed hash. + +``` +git fetch +git checkout 8843e7e6c89aa13efc7caca275d8dd053c11c815 +"./ci/container/build-ic.sh" "--canisters" +sha256sum ./artifacts/canisters/ic-cketh-minter.wasm.gz +``` From a9d2098e87b9ef15bc60ebf7ecc9039fcefe9626 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Wed, 8 Jan 2025 10:51:11 +0200 Subject: [PATCH 16/98] fix: Include reservation cycles in error reported during taking a canister snapshot (#3331) When taking a canister snapshot, the balance of the canister is checked to confirm that it has enough cycles to cover its freezing threshold as well as any reservation of cycles needed in case the subnet's capacity is above the storage reservation threshold. However, in the error reported in case the canister does not have sufficient balance, only the freezing threshold was included, thus resulting in cases where an incorrect required amount would be reported to the user. This PR fixes the issue and adds some tests to ensure that there are no regressions in the future. --- .../src/canister_manager.rs | 2 +- .../tests/storage_reservation.rs | 43 ++++++++++++++++--- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/rs/execution_environment/src/canister_manager.rs b/rs/execution_environment/src/canister_manager.rs index 5e1ad8738bd..0ed11e35306 100644 --- a/rs/execution_environment/src/canister_manager.rs +++ b/rs/execution_environment/src/canister_manager.rs @@ -1914,7 +1914,7 @@ impl CanisterManager { Err(CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes: new_snapshot_increase, available: canister.system_state.balance(), - threshold, + threshold: threshold + reservation_cycles, }), NumInstructions::new(0), ); diff --git a/rs/execution_environment/tests/storage_reservation.rs b/rs/execution_environment/tests/storage_reservation.rs index b0ed3ed14b8..8c9e4598235 100644 --- a/rs/execution_environment/tests/storage_reservation.rs +++ b/rs/execution_environment/tests/storage_reservation.rs @@ -1,5 +1,6 @@ use ic_config::execution_environment::Config as ExecutionConfig; use ic_config::subnet_config::SubnetConfig; +use ic_management_canister_types::TakeCanisterSnapshotArgs; use ic_management_canister_types::{self as ic00, CanisterInstallMode, EmptyBlob, Payload}; use ic_registry_subnet_type::SubnetType; use ic_state_machine_tests::{StateMachine, StateMachineBuilder, StateMachineConfig}; @@ -17,7 +18,11 @@ const SUBNET_MEMORY_CAPACITY: u64 = 20 * GIB; const PAGE_SIZE: usize = 64 * KIB as usize; -fn setup(subnet_memory_threshold: u64, subnet_memory_capacity: u64) -> (StateMachine, CanisterId) { +fn setup( + subnet_memory_threshold: u64, + subnet_memory_capacity: u64, + initial_cycles: Option, +) -> (StateMachine, CanisterId) { let subnet_type = SubnetType::Application; let execution_config = ExecutionConfig { subnet_memory_threshold: NumBytes::new(subnet_memory_threshold), @@ -30,7 +35,11 @@ fn setup(subnet_memory_threshold: u64, subnet_memory_capacity: u64) -> (StateMac .with_subnet_type(subnet_type) .with_checkpoints_enabled(false) .build(); - let canister_id = env.create_canister_with_cycles(None, Cycles::from(100 * T), None); + let canister_id = env.create_canister_with_cycles( + None, + Cycles::from(initial_cycles.unwrap_or(100 * T)), + None, + ); env.install_wasm_in_mode( canister_id, @@ -55,7 +64,7 @@ fn test_storage_reservation_not_triggered() { // Baseline test: ensures that calling an update method alone does not trigger storage reservation. // This test is used as a reference for other tests that involve additional operations // causing storage reservation. - let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY); + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); assert_eq!(reserved_balance(&env, canister_id), 0); let initial_balance = env.cycle_balance(canister_id); @@ -68,7 +77,7 @@ fn test_storage_reservation_not_triggered() { #[test] fn test_storage_reservation_triggered_in_update_by_stable_grow() { // Verifies that growing stable memory within the update method triggers storage reservation. - let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY); + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); assert_eq!(reserved_balance(&env, canister_id), 0); let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(100).build()); @@ -79,7 +88,7 @@ fn test_storage_reservation_triggered_in_update_by_stable_grow() { #[test] fn test_storage_reservation_triggered_in_update_by_growing_wasm_memory() { // Verifies that growing Wasm memory within the update method triggers storage reservation. - let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY); + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); assert_eq!(reserved_balance(&env, canister_id), 0); let _ = env.execute_ingress( @@ -94,7 +103,7 @@ fn test_storage_reservation_triggered_in_update_by_growing_wasm_memory() { #[test] fn test_storage_reservation_triggered_in_response() { // Verifies that growing stable memory during the response callback triggers storage reservation. - let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY); + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); assert_eq!(reserved_balance(&env, canister_id), 0); let _ = env.execute_ingress( @@ -118,7 +127,7 @@ fn test_storage_reservation_triggered_in_response() { #[test] fn test_storage_reservation_triggered_in_cleanup() { // Verifies that growing stable memory during the cleanup callback triggers storage reservation. - let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY); + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); assert_eq!(reserved_balance(&env, canister_id), 0); let _ = env.execute_ingress( @@ -139,3 +148,23 @@ fn test_storage_reservation_triggered_in_cleanup() { assert_gt!(reserved_balance(&env, canister_id), 0); // Storage reservation is triggered. } + +#[test] +fn test_storage_reservation_triggered_in_canister_snapshot_with_enough_cycles_available() { + let (env, canister_id) = setup(SUBNET_MEMORY_THRESHOLD, SUBNET_MEMORY_CAPACITY, None); + assert_eq!(reserved_balance(&env, canister_id), 0); + + // Grow memory in update call, should trigger storage reservation. + let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(100).build()); + let reserved_balance_before_snapshot = reserved_balance(&env, canister_id); + assert_gt!(reserved_balance_before_snapshot, 0); // Storage reservation is triggered. + + // Take a snapshot to trigger more storage reservation. + env.take_canister_snapshot(TakeCanisterSnapshotArgs::new(canister_id, None)) + .unwrap(); + let reserved_balance_after_snapshot = reserved_balance(&env, canister_id); + assert_gt!( + reserved_balance_after_snapshot, + reserved_balance_before_snapshot + ); +} From ba248f7679cecf6d7014204a44f6bfe29c2343d9 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Wed, 8 Jan 2025 11:41:35 +0200 Subject: [PATCH 17/98] refactor: Rename field in InsufficientCyclesInMemoryGrow error (#3333) The field `threshold` in `InsufficientCyclesInMemoryGrow` error is not quite accurate. Some times it's not only the freezing threshold that might need to be taken into account (assuming the naming comes from that) but also other sources of consuming cycles, like for example the storage reservation cycles. Rename the field to `required` which also matches with the naming of other similar errors that deal with out of cycles cases. --- rs/execution_environment/src/canister_manager.rs | 12 ++++++------ .../src/execution/install_code.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rs/execution_environment/src/canister_manager.rs b/rs/execution_environment/src/canister_manager.rs index 0ed11e35306..14877845010 100644 --- a/rs/execution_environment/src/canister_manager.rs +++ b/rs/execution_environment/src/canister_manager.rs @@ -1708,7 +1708,7 @@ impl CanisterManager { } => CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes: chunk_bytes, available, - threshold: requested, + required: requested, }, ReservationError::ReservedLimitExceed { requested, limit } => { CanisterManagerError::ReservedCyclesLimitExceededInMemoryGrow { @@ -1914,7 +1914,7 @@ impl CanisterManager { Err(CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes: new_snapshot_increase, available: canister.system_state.balance(), - threshold: threshold + reservation_cycles, + required: threshold + reservation_cycles, }), NumInstructions::new(0), ); @@ -1948,7 +1948,7 @@ impl CanisterManager { } => CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes: new_snapshot_increase, available, - threshold: requested, + required: requested, }, ReservationError::ReservedLimitExceed { requested, limit } => { CanisterManagerError::ReservedCyclesLimitExceededInMemoryGrow { @@ -2403,7 +2403,7 @@ pub(crate) enum CanisterManagerError { InsufficientCyclesInMemoryGrow { bytes: NumBytes, available: Cycles, - threshold: Cycles, + required: Cycles, }, ReservedCyclesLimitExceededInMemoryAllocation { memory_allocation: MemoryAllocation, @@ -2831,7 +2831,7 @@ impl From for UserError { ) } - InsufficientCyclesInMemoryGrow { bytes, available, threshold} => + InsufficientCyclesInMemoryGrow { bytes, available, required} => { Self::new( ErrorCode::InsufficientCyclesInMemoryGrow, @@ -2839,7 +2839,7 @@ impl From for UserError { "Canister cannot grow memory by {} bytes due to insufficient cycles. \ At least {} additional cycles are required.{additional_help}", bytes, - threshold - available) + required - available) ) } ReservedCyclesLimitExceededInMemoryAllocation { memory_allocation, requested, limit} => diff --git a/rs/execution_environment/src/execution/install_code.rs b/rs/execution_environment/src/execution/install_code.rs index 2b7b6a2443a..d4dbc3ad19f 100644 --- a/rs/execution_environment/src/execution/install_code.rs +++ b/rs/execution_environment/src/execution/install_code.rs @@ -332,7 +332,7 @@ impl InstallCodeHelper { } => CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes, available, - threshold: requested, + required: requested, }, ReservationError::ReservedLimitExceed { requested, limit } => { CanisterManagerError::ReservedCyclesLimitExceededInMemoryGrow { @@ -366,7 +366,7 @@ impl InstallCodeHelper { let err = CanisterManagerError::InsufficientCyclesInMemoryGrow { bytes, available: self.canister.system_state.balance(), - threshold, + required: threshold, }; return finish_err( clean_canister, From 4f3b77e0a4524000cfc5d15965292651db374529 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:37:11 +0100 Subject: [PATCH 18/98] docs(governance): Added unreleased_changelog.md and CHANGELOG.md to governance. (#3332) If this works, we will do the same thing to other canisters that we (the Governance team) own. Automation will be implemented in other PRs. # References ## Follow Up Pull Requests [Remind the team to update unreleased_changelog.md][remind] (if it exists). [remind]: https://github.com/dfinity/ic/pull/3342 [Automate proposal generation][propose]. [propose]: https://github.com/dfinity/ic/pull/3353 --- rs/nns/governance/CHANGELOG.md | 18 ++++++++ rs/nns/governance/unreleased_changelog.md | 53 +++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 rs/nns/governance/CHANGELOG.md create mode 100644 rs/nns/governance/unreleased_changelog.md diff --git a/rs/nns/governance/CHANGELOG.md b/rs/nns/governance/CHANGELOG.md new file mode 100644 index 00000000000..f749025ba6b --- /dev/null +++ b/rs/nns/governance/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in the adjacent +unreleased_changelog.md file. In general though, the entries you see here were +moved from there. + + +# TEMPLATE: Proposal $ID + +http://dashboard.internetcomputer.org/proposal/$ID + +## Added + +* Flying feature was added to widgets. This feature was discussed and/or + proposed at $FORUM_THREAD_URL and $MOTION_PROPOSAL_URL. diff --git a/rs/nns/governance/unreleased_changelog.md b/rs/nns/governance/unreleased_changelog.md new file mode 100644 index 00000000000..53464956db0 --- /dev/null +++ b/rs/nns/governance/unreleased_changelog.md @@ -0,0 +1,53 @@ +# How This File Is Used + +1. When there is a user-visible behavior change to this canister, add an entry + to this file (in the "Next Upgrade Proposal" section) in the same PR. + +2. When making an NNS proposal to upgrade this canister, copy entries to the + proposal's summary. + +3. After the proposal is executed, move the entries from this file to a new + section in the adjacent CHANGELOG.md file. + +If your new code is not active in release builds (because it is behind a feature +flag, or it is simply not called yet), then do NOT add an entry to this file, +because this new function has no user-visible behavior change yet. Wait until it +is active (e.g. the feature flag is flipped to "enable") before adding an entry +to this file. + +TODO: Automate step 2. by modifying the script that composes the proposal +summary. It might be helpful to look at nns-dapp's [split-changelog] script for +inspiration. + +[split-changelog]: https://github.com/dfinity/nns-dapp/blob/main/scripts/nns-dapp/split-changelog + +TODO: Perhaps, the script that drafts the proposal summary can also move content +from here to CHANGELOG.md (step 3.). OTOH, it might be better if this is done by +a second (new) script, because the proposal ID is not known until later? + + +# How to Write a Good Entry + +The intended audience here is people who vote (with their neurons) in NNS, not +necessarily engineers who develop this canister. + + +# The Origin of This Process + +This process is modeled after the process used by nns-dapp. nns-dapp in turn +links to keepachangelog.com as its source of inspiration. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security From 9377651bb2052a97c950c586bbef42ff94208b98 Mon Sep 17 00:00:00 2001 From: Arshavir Ter-Gabrielyan Date: Wed, 8 Jan 2025 11:53:09 +0100 Subject: [PATCH 19/98] chore(execution-environment): Specify image-classification canister WASM as a Bazel dependency (#3355) This PR makes image-classification.wasm.gz (currently, a checked-in binary artifact) a Bazel dependency, so multiple tests that require either specifically this canister, or just a very large WASM, can share it. This change required adjusting `//rs/execution_environment:execution_environment_misc_integration_tests/smoke`. --- rs/execution_environment/BUILD.bazel | 2 ++ rs/execution_environment/tests/smoke.rs | 12 ++++++++++-- testnet/prebuilt-canisters/BUILD.bazel | 7 +++++++ .../image-classification.wasm.gz | Bin 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 testnet/prebuilt-canisters/BUILD.bazel rename {rs/execution_environment/tests/test-data => testnet/prebuilt-canisters}/image-classification.wasm.gz (100%) diff --git a/rs/execution_environment/BUILD.bazel b/rs/execution_environment/BUILD.bazel index 44fb5751f44..500ffee7242 100644 --- a/rs/execution_environment/BUILD.bazel +++ b/rs/execution_environment/BUILD.bazel @@ -140,11 +140,13 @@ rust_ic_test_suite( "//rs/rust_canisters/backtrace_canister:backtrace-canister", "//rs/universal_canister/impl:universal_canister.module", "//rs/universal_canister/impl:universal_canister.wasm.gz", + "//testnet/prebuilt-canisters:image-classification", ], env = dict(ENV.items() + [ ("BACKTRACE_CANISTER_WASM_PATH", "$(rootpath //rs/rust_canisters/backtrace_canister:backtrace-canister)"), ("UNIVERSAL_CANISTER_WASM_PATH", "$(rootpath //rs/universal_canister/impl:universal_canister.wasm.gz)"), ("UNIVERSAL_CANISTER_SERIALIZED_MODULE_PATH", "$(rootpath //rs/universal_canister/impl:universal_canister.module)"), + ("IMAGE_CLASSIFICATION_CANISTER_WASM_PATH", "$(rootpath //testnet/prebuilt-canisters:image-classification)"), ]), proc_macro_deps = MACRO_DEPENDENCIES + MACRO_DEV_DEPENDENCIES, tags = [ diff --git a/rs/execution_environment/tests/smoke.rs b/rs/execution_environment/tests/smoke.rs index 4cce2f00074..7804e224834 100644 --- a/rs/execution_environment/tests/smoke.rs +++ b/rs/execution_environment/tests/smoke.rs @@ -14,7 +14,15 @@ const COPYING_GC: &[u8] = include_bytes!("test-data/copying-gc.wasm.gz"); const SHA256: &[u8] = include_bytes!("test-data/sha256.wasm"); // https://github.com/dfinity/examples/tree/master/rust/image-classification -const IMAGE_CLASSIFICATION: &[u8] = include_bytes!("test-data/image-classification.wasm.gz"); +fn image_classification_canister_wasm() -> Vec { + let image_classification_canister_wasm_path = + std::env::var("IMAGE_CLASSIFICATION_CANISTER_WASM_PATH") + .expect("Please ensure that this Bazel test target correctly specifies env and data."); + + let wasm_path = std::path::PathBuf::from(image_classification_canister_wasm_path); + + std::fs::read(&wasm_path).expect("Failed to read WASM file") +} #[test] fn qr() { @@ -89,7 +97,7 @@ fn image_classification() { let env = StateMachine::new(); let image_classification = env .install_canister( - IMAGE_CLASSIFICATION.to_vec(), + image_classification_canister_wasm(), encode_args(()).unwrap(), None, ) diff --git a/testnet/prebuilt-canisters/BUILD.bazel b/testnet/prebuilt-canisters/BUILD.bazel new file mode 100644 index 00000000000..75ab166ea22 --- /dev/null +++ b/testnet/prebuilt-canisters/BUILD.bazel @@ -0,0 +1,7 @@ +package(default_visibility = ["//visibility:public"]) + +# https://github.com/dfinity/examples/tree/master/rust/image-classification +filegroup( + name = "image-classification", + srcs = ["image-classification.wasm.gz"], +) diff --git a/rs/execution_environment/tests/test-data/image-classification.wasm.gz b/testnet/prebuilt-canisters/image-classification.wasm.gz similarity index 100% rename from rs/execution_environment/tests/test-data/image-classification.wasm.gz rename to testnet/prebuilt-canisters/image-classification.wasm.gz From 41b1a2ed4707f5c7957f25f278f59d9e85dbdd80 Mon Sep 17 00:00:00 2001 From: Adrian Alic <39585474+dist1ll@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:08:57 +0100 Subject: [PATCH 20/98] feat(recovery): [CON-1407] Add CLI option to use existing binaries for local recoveries (#3301) This PR adds `ic-admin` to the guest OS & adds a CLI argument to make the recovery tool use the local binaries from `/opt/ic/bin`. With this, we can kick off a non-interactive, local subnet recovery via ssh, by calling the recovery tool with the right arguments. With this change, we should be able to create a system test for local recoveries. To confirm that this works, I performed a non-interactive recovery on a testnet with the following arguments: ``` /opt/ic/bin/ic-recovery \ --nns-url http://[2602:fb2b:110:10:5025:8bff:fe14:daee]:8080 \ --test \ --skip-prompts \ --use-local-binaries \ app-subnet-recovery \ --subnet-id c3es6-ogziq-a5elm-47c4o-vkins-7kiu4-ekgun-oaeo2-ojd2m-j26wh-eae \ --pub-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFx8H9eVvkxl1n7crh/uUzqH03m8Qwlo2k5EE3MJa4Bs adrian.alic@dfinity.org" \ --download-node 2602:fb2b:110:10:506a:22ff:fe1c:ef69 \ --upload-method local \ --keep-downloaded-state false ``` The subnet recovered successfully without user input. --- ic-os/guestos/defs.bzl | 1 + rs/recovery/src/args_merger.rs | 3 +++ rs/recovery/src/cmd.rs | 6 ++++++ rs/recovery/src/lib.rs | 16 +++++++++++++--- rs/recovery/src/main.rs | 1 + rs/recovery/src/recovery_state.rs | 1 + rs/recovery/subnet_splitting/src/main.rs | 7 +++++++ rs/tests/consensus/subnet_recovery/common.rs | 1 + .../sr_nns_failover_nodes_test.rs | 1 + .../subnet_recovery/sr_nns_same_nodes_test.rs | 1 + rs/tests/consensus/subnet_splitting_test.rs | 1 + 11 files changed, 36 insertions(+), 3 deletions(-) diff --git a/ic-os/guestos/defs.bzl b/ic-os/guestos/defs.bzl index 1d4f3c570c2..745165a3132 100644 --- a/ic-os/guestos/defs.bzl +++ b/ic-os/guestos/defs.bzl @@ -40,6 +40,7 @@ def image_deps(mode, malicious = False): "//publish/binaries:ic-boundary-tls": "/opt/ic/bin/ic-boundary:0755", # API boundary node binary, required by the IC protocol. The same GuestOS is used both for the replica and API boundary nodes. "//publish/binaries:ic-consensus-pool-util": "/opt/ic/bin/ic-consensus-pool-util:0755", # May be used during recoveries to export/import consensus pool artifacts. "//publish/binaries:ic-recovery": "/opt/ic/bin/ic-recovery:0755", # Required for performing subnet recoveries on the node directly. + "//publish/binaries:ic-admin": "/opt/ic/bin/ic-admin:0755", # Required for issuing recovery proposals directly from the node (primarily used for system tests). "//publish/binaries:state-tool": "/opt/ic/bin/state-tool:0755", # May be used during recoveries for calculating the state hash and inspecting the state more generally. "//publish/binaries:ic-regedit": "/opt/ic/bin/ic-regedit:0755", # May be used for inspecting and recovering the registry. # Required by the GuestOS diff --git a/rs/recovery/src/args_merger.rs b/rs/recovery/src/args_merger.rs index e648cf35876..52718495a7e 100644 --- a/rs/recovery/src/args_merger.rs +++ b/rs/recovery/src/args_merger.rs @@ -66,6 +66,7 @@ mod tests { key_file: Some(PathBuf::from("/dir1/key_file")), test_mode: true, skip_prompts: true, + use_local_binaries: false, }; let args2 = RecoveryArgs { dir: PathBuf::from("/dir2/"), @@ -74,6 +75,7 @@ mod tests { key_file: None, test_mode: false, skip_prompts: true, + use_local_binaries: false, }; let expected = RecoveryArgs { @@ -83,6 +85,7 @@ mod tests { key_file: args1.key_file.clone(), test_mode: args2.test_mode, skip_prompts: true, + use_local_binaries: false, }; assert_eq!(expected, merge(&logger, "test", &args1, &args2).unwrap()); diff --git a/rs/recovery/src/cmd.rs b/rs/recovery/src/cmd.rs index 43fabcb13fb..929d53a06f2 100644 --- a/rs/recovery/src/cmd.rs +++ b/rs/recovery/src/cmd.rs @@ -54,6 +54,12 @@ pub struct RecoveryToolArgs { #[clap(long)] pub skip_prompts: bool, + /// Flag to indicate we're running recovery directly on a node, and should use + /// the locally available binaries. If this option is not set, missing binaries + /// will be downloaded. + #[clap(long)] + pub use_local_binaries: bool, + #[clap(subcommand)] pub subcmd: Option, } diff --git a/rs/recovery/src/lib.rs b/rs/recovery/src/lib.rs index 091ba060bd0..d2db2aa29f3 100644 --- a/rs/recovery/src/lib.rs +++ b/rs/recovery/src/lib.rs @@ -107,6 +107,7 @@ pub struct RecoveryArgs { pub key_file: Option, pub test_mode: bool, pub skip_prompts: bool, + pub use_local_binaries: bool, } /// The recovery struct comprises working directories for the recovery of a @@ -145,13 +146,22 @@ impl Recovery { ) -> RecoveryResult { let ssh_confirmation = !args.test_mode; let recovery_dir = args.dir.join(RECOVERY_DIRECTORY_NAME); - let binary_dir = recovery_dir.join("binaries"); + let binary_dir = if args.use_local_binaries { + PathBuf::from_str("/opt/ic/bin/").expect("bad file path string") + } else { + recovery_dir.join("binaries") + }; let data_dir = recovery_dir.join("original_data"); let work_dir = recovery_dir.join("working_dir"); let local_store_path = work_dir.join("data").join(IC_REGISTRY_LOCAL_STORE); let nns_pem = recovery_dir.join("nns.pem"); - match Recovery::create_dirs(&[&binary_dir, &data_dir, &work_dir, &local_store_path]) { + let mut to_create: Vec<&Path> = vec![&data_dir, &work_dir, &local_store_path]; + if !args.use_local_binaries { + to_create.push(&binary_dir); + } + + match Recovery::create_dirs(&to_create) { Err(RecoveryError::IoError(s, err)) => match err.kind() { ErrorKind::PermissionDenied => Err(RecoveryError::IoError( format!( @@ -180,7 +190,7 @@ impl Recovery { wait_for_confirmation(&logger); } - if !binary_dir.join("ic-admin").exists() { + if !args.use_local_binaries && !binary_dir.join("ic-admin").exists() { if let Some(version) = args.replica_version { block_on(download_binary( &logger, diff --git a/rs/recovery/src/main.rs b/rs/recovery/src/main.rs index 80dc35eb73a..f66ecda26e9 100644 --- a/rs/recovery/src/main.rs +++ b/rs/recovery/src/main.rs @@ -34,6 +34,7 @@ fn main() { key_file: args.key_file, test_mode: args.test, skip_prompts: args.skip_prompts, + use_local_binaries: args.use_local_binaries, }; let recovery_state = cli::read_and_maybe_update_state(&logger, recovery_args, args.subcmd); diff --git a/rs/recovery/src/recovery_state.rs b/rs/recovery/src/recovery_state.rs index 24cc57df1a2..73f28a7444b 100644 --- a/rs/recovery/src/recovery_state.rs +++ b/rs/recovery/src/recovery_state.rs @@ -177,6 +177,7 @@ mod tests { key_file: Some(PathBuf::from(dir)), test_mode: true, skip_prompts: true, + use_local_binaries: false, }, subcommand_args: SubCommand::AppSubnetRecovery(AppSubnetRecoveryArgs { subnet_id: fake_subnet_id(), diff --git a/rs/recovery/subnet_splitting/src/main.rs b/rs/recovery/subnet_splitting/src/main.rs index 84777025b6e..48e291a4d0b 100644 --- a/rs/recovery/subnet_splitting/src/main.rs +++ b/rs/recovery/subnet_splitting/src/main.rs @@ -47,6 +47,12 @@ struct SplitArgs { #[clap(long)] pub skip_prompts: bool, + /// Flag to indicate we're running recovery directly on a node, and should use + /// the locally available binaries. If this option is not set, missing binaries + /// will be downloaded. + #[clap(long)] + pub use_local_binaries: bool, + #[clap(flatten)] subnet_splitting_args: SubnetSplittingArgs, } @@ -145,6 +151,7 @@ fn do_split(args: SplitArgs, logger: Logger) -> RecoveryResult<()> { key_file: args.key_file, test_mode: args.test, skip_prompts: args.skip_prompts, + use_local_binaries: args.use_local_binaries, }; let subnet_splitting_state = diff --git a/rs/tests/consensus/subnet_recovery/common.rs b/rs/tests/consensus/subnet_recovery/common.rs index 9fd85e32a38..4106012edd8 100644 --- a/rs/tests/consensus/subnet_recovery/common.rs +++ b/rs/tests/consensus/subnet_recovery/common.rs @@ -339,6 +339,7 @@ fn app_subnet_recovery_test(env: TestEnv, cfg: Config) { key_file: Some(ssh_authorized_priv_keys_dir.join(SSH_USERNAME)), test_mode: true, skip_prompts: true, + use_local_binaries: false, }; let mut unassigned_nodes = env.topology_snapshot().unassigned_nodes(); diff --git a/rs/tests/consensus/subnet_recovery/sr_nns_failover_nodes_test.rs b/rs/tests/consensus/subnet_recovery/sr_nns_failover_nodes_test.rs index 5c0e54e8c59..1ef315b9bb2 100644 --- a/rs/tests/consensus/subnet_recovery/sr_nns_failover_nodes_test.rs +++ b/rs/tests/consensus/subnet_recovery/sr_nns_failover_nodes_test.rs @@ -175,6 +175,7 @@ pub fn test(env: TestEnv) { key_file: Some(ssh_authorized_priv_keys_dir.join(SSH_USERNAME)), test_mode: true, skip_prompts: true, + use_local_binaries: false, }; let subnet_args = NNSRecoveryFailoverNodesArgs { subnet_id: topo_broken_ic.root_subnet_id(), diff --git a/rs/tests/consensus/subnet_recovery/sr_nns_same_nodes_test.rs b/rs/tests/consensus/subnet_recovery/sr_nns_same_nodes_test.rs index 80adb66dba1..c0cb0e44c94 100644 --- a/rs/tests/consensus/subnet_recovery/sr_nns_same_nodes_test.rs +++ b/rs/tests/consensus/subnet_recovery/sr_nns_same_nodes_test.rs @@ -116,6 +116,7 @@ pub fn test(env: TestEnv) { key_file: Some(ssh_authorized_priv_keys_dir.join(SSH_USERNAME)), test_mode: true, skip_prompts: true, + use_local_binaries: false, }; // unlike during a production recovery using the CLI, here we already know all of parameters diff --git a/rs/tests/consensus/subnet_splitting_test.rs b/rs/tests/consensus/subnet_splitting_test.rs index 730d46c53d5..6ed0b74a661 100644 --- a/rs/tests/consensus/subnet_splitting_test.rs +++ b/rs/tests/consensus/subnet_splitting_test.rs @@ -139,6 +139,7 @@ fn subnet_splitting_test(env: TestEnv) { ), test_mode: true, skip_prompts: true, + use_local_binaries: false, }; let subnet_splitting_args = SubnetSplittingArgs { From fa3b0ad91722bd5ba68d53caef726075bd7d05c7 Mon Sep 17 00:00:00 2001 From: Igor Novgorodov Date: Wed, 8 Jan 2025 13:17:14 +0100 Subject: [PATCH 21/98] chore(BOUN-1284): replace tokio rwlock, bump ic-gateway release (#3346) --- ic-os/boundary-guestos/context/Dockerfile | 10 +++++----- rs/boundary_node/ic_boundary/src/core.rs | 3 +-- rs/boundary_node/ic_boundary/src/metrics.rs | 7 +++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ic-os/boundary-guestos/context/Dockerfile b/ic-os/boundary-guestos/context/Dockerfile index 57a95ec8e8f..3292d751cc5 100644 --- a/ic-os/boundary-guestos/context/Dockerfile +++ b/ic-os/boundary-guestos/context/Dockerfile @@ -25,8 +25,8 @@ WORKDIR /tmp # Download and verify ic-gateway RUN \ - curl -L -O https://github.com/dfinity/ic-gateway/releases/download/v0.1.61/ic-gateway_0.1.61_amd64.deb && \ - echo "dcde4601c7e57372a9488265152ed71366cc710d31f9b1219a197ffa23680fdc ic-gateway_0.1.61_amd64.deb" | sha256sum -c + curl -L -O https://github.com/dfinity/ic-gateway/releases/download/v0.1.62/ic-gateway_0.1.62_amd64.deb && \ + echo "91aa1a2de67ac8147b3d45642ddc5bb28934b1611e7f2aa31ce01c98507c5c71 ic-gateway_0.1.62_amd64.deb" | sha256sum -c # # Second build stage: @@ -56,9 +56,9 @@ FROM image-${BUILD_TYPE} USER root:root -COPY --from=download /tmp/ic-gateway_0.1.61_amd64.deb /tmp/ic-gateway_0.1.61_amd64.deb -RUN dpkg -i --force-confold /tmp/ic-gateway_0.1.61_amd64.deb && \ - rm /tmp/ic-gateway_0.1.61_amd64.deb +COPY --from=download /tmp/ic-gateway_0.1.62_amd64.deb /tmp/ic-gateway_0.1.62_amd64.deb +RUN dpkg -i --force-confold /tmp/ic-gateway_0.1.62_amd64.deb && \ + rm /tmp/ic-gateway_0.1.62_amd64.deb RUN mkdir -p /boot/config \ /boot/efi \ diff --git a/rs/boundary_node/ic_boundary/src/core.rs b/rs/boundary_node/ic_boundary/src/core.rs index 83ebdc9cc08..c52a8fc70c6 100644 --- a/rs/boundary_node/ic_boundary/src/core.rs +++ b/rs/boundary_node/ic_boundary/src/core.rs @@ -2,7 +2,7 @@ use std::{ error::Error as StdError, net::{Ipv4Addr, Ipv6Addr, SocketAddr}, - sync::Arc, + sync::{Arc, RwLock}, time::{Duration, Instant}, }; @@ -50,7 +50,6 @@ use ic_types::{crypto::threshold_sig::ThresholdSigPublicKey, messages::MessageId use nix::unistd::{getpgid, setpgid, Pid}; use prometheus::Registry; use rand::rngs::OsRng; -use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; use tower::{limit::ConcurrencyLimitLayer, util::MapResponseLayer, ServiceBuilder}; use tower_http::{compression::CompressionLayer, request_id::MakeRequestUuid, ServiceBuilderExt}; diff --git a/rs/boundary_node/ic_boundary/src/metrics.rs b/rs/boundary_node/ic_boundary/src/metrics.rs index 38ff6ad18ff..d4d363f9788 100644 --- a/rs/boundary_node/ic_boundary/src/metrics.rs +++ b/rs/boundary_node/ic_boundary/src/metrics.rs @@ -2,7 +2,7 @@ use std::{ hash::{DefaultHasher, Hash, Hasher}, - sync::Arc, + sync::{Arc, RwLock}, time::Instant, }; @@ -25,7 +25,6 @@ use prometheus::{ IntGauge, IntGaugeVec, Registry, TextEncoder, }; use tikv_jemalloc_ctl::{epoch, stats}; -use tokio::sync::RwLock; use tower_http::request_id::RequestId; use tracing::info; @@ -220,7 +219,7 @@ impl Run for MetricsRunner { } // Take a write lock, truncate the vector and encode the metrics into it - let mut metrics_cache = self.metrics_cache.write().await; + let mut metrics_cache = self.metrics_cache.write().unwrap(); metrics_cache.buffer.clear(); self.encoder .encode(&metric_families, &mut metrics_cache.buffer)?; @@ -707,7 +706,7 @@ pub async fn metrics_handler( // Get a read lock and clone the buffer contents ( [(CONTENT_TYPE, PROMETHEUS_CONTENT_TYPE)], - cache.read().await.buffer.clone(), + cache.read().unwrap().buffer.clone(), ) } From baa83d5f2f0d4267032311214b95be0353d7c298 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Wed, 8 Jan 2025 16:59:56 +0200 Subject: [PATCH 22/98] test: Add test for taking a snapshot that triggers storage reservation (#3360) --- .../tests/storage_reservation.rs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/rs/execution_environment/tests/storage_reservation.rs b/rs/execution_environment/tests/storage_reservation.rs index 8c9e4598235..99eecc00113 100644 --- a/rs/execution_environment/tests/storage_reservation.rs +++ b/rs/execution_environment/tests/storage_reservation.rs @@ -1,5 +1,6 @@ use ic_config::execution_environment::Config as ExecutionConfig; use ic_config::subnet_config::SubnetConfig; +use ic_error_types::ErrorCode; use ic_management_canister_types::TakeCanisterSnapshotArgs; use ic_management_canister_types::{self as ic00, CanisterInstallMode, EmptyBlob, Payload}; use ic_registry_subnet_type::SubnetType; @@ -168,3 +169,44 @@ fn test_storage_reservation_triggered_in_canister_snapshot_with_enough_cycles_av reserved_balance_before_snapshot ); } + +#[test] +fn test_storage_reservation_triggered_in_canister_snapshot_without_enough_cycles_available() { + // This test verifies that a canister cannot take a snapshot if it does not have enough + // cycles to cover the storage reservation triggered by the snapshot operation. The main + // point of the test is to verify that the error message is informative and includes the + // amount of cycles required to cover the storage reservation. + // + // The error message is produced by running the test once and checking the output. Calculating + // the exact amounts is hard to do in advance. Note that any changes to cycles cost or how + // the reservation mechanism works may require updating the error message in the test. + + let (env, canister_id) = setup( + SUBNET_MEMORY_THRESHOLD, + SUBNET_MEMORY_CAPACITY, + Some(300_400_000_000), + ); + assert_eq!(reserved_balance(&env, canister_id), 0); + + // Grow memory in update call, should trigger storage reservation. + let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(3000).build()); + let reserved_balance_before_snapshot = reserved_balance(&env, canister_id); + assert_gt!(reserved_balance_before_snapshot, 0); // Storage reservation is triggered. + + // Take a snapshot to trigger more storage reservation. The canister does not have + // enough cycles in its balance, so this should fail. + let res = env.take_canister_snapshot(TakeCanisterSnapshotArgs::new(canister_id, None)); + match res { + Ok(_) => panic!("Expected an error but got Ok(_)"), + Err(err) => { + assert_eq!(err.code(), ErrorCode::InsufficientCyclesInMemoryGrow); + println!("error description {}", err.description()); + // Match on the first part of the error message. Due to a difference in instructions consumed on + // Mac vs Linux, we cannot match on the exact number of cycles but we only need to verify it's + // a non-zero amount. + assert!(err.description().contains( + "Canister cannot grow memory by 200067930 bytes due to insufficient cycles. At least 339_603_" + )); + } + } +} From dfc8987d4bdc50fba6426f7dd31496456f54e011 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:02:05 +0100 Subject: [PATCH 23/98] feat(governance-tools): Use unreleased_changelog.md when generating proposals. (#3353) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the canister does not yet have an unreleased_changelog.md file, the "Features & Fixes" section defaults to a TODO, forcing the release tsar to hand-craft that section. If this works well, we will also do this for SNS later. # References [👈 Previous PR][prev] [prev]: https://github.com/dfinity/ic/pull/3332 --- rs/nns/governance/unreleased_changelog.md | 10 +--------- testnet/tools/nns-tools/lib/proposals.sh | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/rs/nns/governance/unreleased_changelog.md b/rs/nns/governance/unreleased_changelog.md index 53464956db0..992f06a9226 100644 --- a/rs/nns/governance/unreleased_changelog.md +++ b/rs/nns/governance/unreleased_changelog.md @@ -15,15 +15,7 @@ because this new function has no user-visible behavior change yet. Wait until it is active (e.g. the feature flag is flipped to "enable") before adding an entry to this file. -TODO: Automate step 2. by modifying the script that composes the proposal -summary. It might be helpful to look at nns-dapp's [split-changelog] script for -inspiration. - -[split-changelog]: https://github.com/dfinity/nns-dapp/blob/main/scripts/nns-dapp/split-changelog - -TODO: Perhaps, the script that drafts the proposal summary can also move content -from here to CHANGELOG.md (step 3.). OTOH, it might be better if this is done by -a second (new) script, because the proposal ID is not known until later? +TODO: Automate moving content from unreleased_changelog.md to CHANGELOG.md. # How to Write a Good Entry diff --git a/testnet/tools/nns-tools/lib/proposals.sh b/testnet/tools/nns-tools/lib/proposals.sh index 251940021a4..c89a9930d87 100644 --- a/testnet/tools/nns-tools/lib/proposals.sh +++ b/testnet/tools/nns-tools/lib/proposals.sh @@ -128,6 +128,22 @@ generate_nns_upgrade_proposal_text() { ESCAPED_IC_REPO=$(printf '%s\n' "$IC_REPO" | sed -e 's/[]\/$*.^[]/\\&/g') RELATIVE_CODE_LOCATION="$(echo "$CANISTER_CODE_LOCATION" | sed "s/$ESCAPED_IC_REPO/./g")" + # If the canister has an unrelease_changelog.md file, use that to populate + # the "Features & Fixes" section of the upgrade proposal. Eventually, all of + # our canisters will have such a file, but for now, we are still test + # driving this process. + FEATURES_AND_FIXES="TODO Hand-craft this section." + PRIMARY_RELATIVE_CODE_LOCATION=$(echo "${RELATIVE_CODE_LOCATION}" | cut -d' ' -f1) + UNRELEASED_CHANGELOG_PATH="${PRIMARY_RELATIVE_CODE_LOCATION}/unreleased_changelog.md" + if [[ -e "${UNRELEASED_CHANGELOG_PATH}" ]]; then + FEATURES_AND_FIXES=$( + sed -n '/# Next Upgrade Proposal/,$p' \ + "${UNRELEASED_CHANGELOG_PATH}" \ + | tail -n +3 \ + | sed 's/^## /### /g' + ) + fi + ARGS_HASH="" if [ ! -z "$CANDID_ARGS" ]; then FILE=$(encode_candid_args_in_file "$CANDID_ARGS") @@ -144,9 +160,11 @@ __Source code__: [$NEXT_COMMIT][new-commit] [new-commit]: https://github.com/dfinity/ic/tree/$NEXT_COMMIT -## Summary -TODO add a summary of changes +## Features & Fixes + +$FEATURES_AND_FIXES + ## New Commits From 5f9f2d3d24faba8e9ce331a896a1de45a8cc668f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Wed, 8 Jan 2025 16:04:43 +0100 Subject: [PATCH 24/98] feat(icrc-ledger-types): FI-1624: Bump icrc-ledger-types version with the added rustdoc (#3365) Bump the version of `icrc-ledger-types` to `0.1.7` in order to release the added rustdoc. --- Cargo.lock | 2 +- packages/icrc-ledger-types/CHANGELOG.md | 6 ++++++ packages/icrc-ledger-types/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86e8a5afab8..93a42371a7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13995,7 +13995,7 @@ dependencies = [ [[package]] name = "icrc-ledger-types" -version = "0.1.6" +version = "0.1.7" dependencies = [ "assert_matches", "base32", diff --git a/packages/icrc-ledger-types/CHANGELOG.md b/packages/icrc-ledger-types/CHANGELOG.md index 4d367351f7c..6333bd3c777 100644 --- a/packages/icrc-ledger-types/CHANGELOG.md +++ b/packages/icrc-ledger-types/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## 0.1.7 + +### Added + +- Rustdoc. + ## 0.1.6 ### Added diff --git a/packages/icrc-ledger-types/Cargo.toml b/packages/icrc-ledger-types/Cargo.toml index cac51dc29ab..0ffee34cbb6 100644 --- a/packages/icrc-ledger-types/Cargo.toml +++ b/packages/icrc-ledger-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "icrc-ledger-types" -version = "0.1.6" +version = "0.1.7" description = "Types for interacting with DFINITY's implementation of the ICRC-1 fungible token standard." license = "Apache-2.0" readme = "README.md" From f73b98993817328504dc30a70d9c80a75cdbcb8c Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:44:44 +0100 Subject: [PATCH 25/98] fix: reject code in synchronous rejects (#3362) This PR fixes the reject code in synchronous rejects of mgmt canister calls to be derived from the given `UserError` instead of hard-coded to `CanisterError`. --- hs/spec_compliance/src/IC/Test/Spec.hs | 2 +- rs/system_api/src/sandbox_safe_system_state.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hs/spec_compliance/src/IC/Test/Spec.hs b/hs/spec_compliance/src/IC/Test/Spec.hs index 8512be18c94..8379bd5d8d2 100644 --- a/hs/spec_compliance/src/IC/Test/Spec.hs +++ b/hs/spec_compliance/src/IC/Test/Spec.hs @@ -754,7 +754,7 @@ icTests my_sub other_sub conf = ic_canister_status'' anonymousUser cid >>= isErrOrReject [3, 5] ic_canister_status'' secp256k1User cid >>= isErrOrReject [3, 5], simpleTestCase "> 10 controllers" ecid $ \cid -> do - ic_create_with_controllers' (ic00viaWithCycles cid 20_000_000_000_000) ecid (replicate 11 cid) >>= isReject [3, 5] + ic_create_with_controllers' (ic00viaWithCycles cid 20_000_000_000_000) ecid (replicate 11 cid) >>= isReject [4] ic_set_controllers' ic00 cid (replicate 11 cid) >>= isReject [4], simpleTestCase "No controller" ecid $ \cid -> do cid2 <- ic_create_with_controllers (ic00viaWithCycles cid 20_000_000_000_000) ecid [] diff --git a/rs/system_api/src/sandbox_safe_system_state.rs b/rs/system_api/src/sandbox_safe_system_state.rs index 19dd37d7015..ba4da893c7d 100644 --- a/rs/system_api/src/sandbox_safe_system_state.rs +++ b/rs/system_api/src/sandbox_safe_system_state.rs @@ -187,7 +187,7 @@ impl SystemStateChanges { err ); - let reject_context = RejectContext::new(RejectCode::CanisterError, err.to_string()); + let reject_context = RejectContext::new(err.code().into(), err.to_string()); system_state .reject_subnet_output_request(msg, reject_context, subnet_ids) .map_err(|e| Self::error(format!("Failed to push IC00 reject response: {:?}", e)))?; From 6410e399d1a0d7aa22559982b6ba888bb5c52872 Mon Sep 17 00:00:00 2001 From: Leon Tan Date: Wed, 8 Jan 2025 16:59:30 +0100 Subject: [PATCH 26/98] refactor(CON-1447): Factor out DKG submodule into its own crate (#3340) This PR moves the `dkg` code from a submodule in `consensus/src` to it's own crate in `consensus`. This should improve compile times somewhat and especially makes working with the `dkg` code easier. --- Cargo.lock | 35 ++++++++++- rs/consensus/BUILD.bazel | 2 +- rs/consensus/Cargo.toml | 2 +- rs/consensus/dkg/BUILD.bazel | 60 +++++++++++++++++++ rs/consensus/dkg/Cargo.toml | 34 +++++++++++ .../{src/dkg => dkg/src}/dkg_key_manager.rs | 0 rs/consensus/{src/dkg.rs => dkg/src/lib.rs} | 7 ++- .../{src/dkg => dkg/src}/payload_builder.rs | 2 +- .../{src/dkg => dkg/src}/payload_validator.rs | 6 +- .../{src/dkg => dkg/src}/test_utils.rs | 0 rs/consensus/{src/dkg => dkg/src}/utils.rs | 0 rs/consensus/src/consensus.rs | 15 ++--- rs/consensus/src/consensus/block_maker.rs | 2 +- rs/consensus/src/consensus/validator.rs | 3 +- rs/consensus/src/cup_utils.rs | 12 ++-- rs/consensus/src/lib.rs | 1 - rs/consensus/tests/framework/driver.rs | 2 +- rs/consensus/tests/framework/mod.rs | 9 +-- rs/consensus/tests/framework/runner.rs | 6 +- rs/consensus/tests/framework/types.rs | 4 +- rs/consensus/tests/payload.rs | 12 ++-- rs/replay/BUILD.bazel | 1 + rs/replay/Cargo.toml | 1 + rs/replay/src/backup.rs | 2 +- rs/replay/src/validator.rs | 2 +- rs/replica/Cargo.toml | 1 + rs/replica/setup_ic_network/BUILD.bazel | 1 + rs/replica/setup_ic_network/Cargo.toml | 1 + rs/replica/setup_ic_network/src/lib.rs | 8 +-- rs/test_utilities/artifact_pool/BUILD.bazel | 1 + rs/test_utilities/artifact_pool/Cargo.toml | 1 + .../artifact_pool/src/consensus_pool.rs | 4 +- 32 files changed, 184 insertions(+), 53 deletions(-) create mode 100644 rs/consensus/dkg/BUILD.bazel create mode 100644 rs/consensus/dkg/Cargo.toml rename rs/consensus/{src/dkg => dkg/src}/dkg_key_manager.rs (100%) rename rs/consensus/{src/dkg.rs => dkg/src/lib.rs} (99%) rename rs/consensus/{src/dkg => dkg/src}/payload_builder.rs (99%) rename rs/consensus/{src/dkg => dkg/src}/payload_validator.rs (99%) rename rs/consensus/{src/dkg => dkg/src}/test_utils.rs (100%) rename rs/consensus/{src/dkg => dkg/src}/utils.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 93a42371a7b..5228d801ea2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6701,6 +6701,7 @@ dependencies = [ "ic-btc-replica-types", "ic-config", "ic-consensus", + "ic-consensus-dkg", "ic-consensus-mocks", "ic-consensus-utils", "ic-crypto", @@ -6753,7 +6754,6 @@ dependencies = [ "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", - "rayon", "rstest", "serde_cbor", "slog", @@ -6766,6 +6766,35 @@ dependencies = [ "tokio", ] +[[package]] +name = "ic-consensus-dkg" +version = "0.9.0" +dependencies = [ + "ic-artifact-pool", + "ic-consensus-mocks", + "ic-consensus-utils", + "ic-crypto-test-utils-ni-dkg", + "ic-interfaces", + "ic-interfaces-registry", + "ic-interfaces-state-manager", + "ic-logger", + "ic-metrics", + "ic-protobuf", + "ic-registry-client-helpers", + "ic-replicated-state", + "ic-test-artifact-pool", + "ic-test-utilities", + "ic-test-utilities-consensus", + "ic-test-utilities-logger", + "ic-test-utilities-registry", + "ic-test-utilities-state", + "ic-test-utilities-types", + "ic-types", + "prometheus", + "rayon", + "slog", +] + [[package]] name = "ic-consensus-manager" version = "0.9.0" @@ -11249,6 +11278,7 @@ dependencies = [ "ic-canister-sandbox-backend-lib", "ic-config", "ic-consensus", + "ic-consensus-dkg", "ic-consensus-utils", "ic-crypto-for-verification-only", "ic-cycles-account-manager", @@ -11303,6 +11333,7 @@ dependencies = [ "ic-btc-consensus", "ic-config", "ic-consensus", + "ic-consensus-dkg", "ic-crypto", "ic-crypto-sha2", "ic-cycles-account-manager", @@ -11364,6 +11395,7 @@ dependencies = [ "ic-artifact-pool", "ic-config", "ic-consensus", + "ic-consensus-dkg", "ic-consensus-manager", "ic-consensus-utils", "ic-crypto-interfaces-sig-verification", @@ -12740,6 +12772,7 @@ dependencies = [ "ic-artifact-pool", "ic-config", "ic-consensus", + "ic-consensus-dkg", "ic-consensus-utils", "ic-interfaces", "ic-interfaces-registry", diff --git a/rs/consensus/BUILD.bazel b/rs/consensus/BUILD.bazel index 55d0c52f6e1..512d45e0049 100644 --- a/rs/consensus/BUILD.bazel +++ b/rs/consensus/BUILD.bazel @@ -6,6 +6,7 @@ package(default_visibility = ["//visibility:public"]) DEPENDENCIES = [ # Keep sorted. "//rs/config", + "//rs/consensus/dkg", "//rs/consensus/utils", "//rs/crypto", "//rs/crypto/prng", @@ -30,7 +31,6 @@ DEPENDENCIES = [ "@crate_index//:prometheus", "@crate_index//:rand", "@crate_index//:rand_chacha", - "@crate_index//:rayon", "@crate_index//:slog", "@crate_index//:tokio", ] diff --git a/rs/consensus/Cargo.toml b/rs/consensus/Cargo.toml index 910b2aeae5a..38bee84bf8a 100644 --- a/rs/consensus/Cargo.toml +++ b/rs/consensus/Cargo.toml @@ -8,6 +8,7 @@ documentation.workspace = true [dependencies] ic-config = { path = "../config" } +ic-consensus-dkg = { path = "./dkg" } ic-consensus-utils = { path = "./utils" } ic-crypto = { path = "../crypto" } ic-crypto-prng = { path = "../crypto/prng" } @@ -33,7 +34,6 @@ phantom_newtype = { path = "../phantom_newtype" } prometheus = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } -rayon = { workspace = true } slog = { workspace = true } strum_macros = { workspace = true } tokio = { workspace = true } diff --git a/rs/consensus/dkg/BUILD.bazel b/rs/consensus/dkg/BUILD.bazel new file mode 100644 index 00000000000..0f5a9ae42c0 --- /dev/null +++ b/rs/consensus/dkg/BUILD.bazel @@ -0,0 +1,60 @@ +load("@rules_rust//rust:defs.bzl", "rust_doc", "rust_library", "rust_test") + +package(default_visibility = ["//visibility:public"]) + +DEPENDENCIES = [ + # Keep sorted. + "//rs/consensus/utils", + "//rs/interfaces", + "//rs/interfaces/registry", + "//rs/interfaces/state_manager", + "//rs/monitoring/logger", + "//rs/monitoring/metrics", + "//rs/protobuf", + "//rs/registry/helpers", + "//rs/replicated_state", + "//rs/types/types", + "@crate_index//:prometheus", + "@crate_index//:rayon", + "@crate_index//:slog", +] + +DEV_DEPENDENCIES = [ + # Keep sorted. + "//rs/artifact_pool", + "//rs/consensus/mocks", + "//rs/crypto/test_utils/ni-dkg", + "//rs/test_utilities", + "//rs/test_utilities/artifact_pool", + "//rs/test_utilities/consensus", + "//rs/test_utilities/logger", + "//rs/test_utilities/registry", + "//rs/test_utilities/state", + "//rs/test_utilities/types", +] + +rust_library( + name = "dkg", + srcs = glob(["src/**/*.rs"]), + crate_features = select({ + "//conditions:default": [], + }), + crate_name = "ic_consensus_dkg", + proc_macro_deps = [ + # Keep sorted. + "@crate_index//:strum_macros", + ], + version = "0.9.0", + deps = DEPENDENCIES, +) + +rust_doc( + name = "consensus_dkg_doc", + crate = ":dkg", +) + +rust_test( + name = "consensus_dkg_test", + crate = ":dkg", + deps = DEPENDENCIES + DEV_DEPENDENCIES, +) diff --git a/rs/consensus/dkg/Cargo.toml b/rs/consensus/dkg/Cargo.toml new file mode 100644 index 00000000000..6d21a754f2a --- /dev/null +++ b/rs/consensus/dkg/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "ic-consensus-dkg" +version.workspace = true +authors.workspace = true +edition.workspace = true +description.workspace = true +documentation.workspace = true + +[dependencies] +ic-consensus-utils = { path = "../utils" } +ic-interfaces = { path = "../../interfaces" } +ic-interfaces-registry = { path = "../../interfaces/registry" } +ic-interfaces-state-manager = { path = "../../interfaces/state_manager" } +ic-logger = { path = "../../monitoring/logger" } +ic-metrics = { path = "../../monitoring/metrics" } +ic-protobuf = { path = "../../protobuf" } +ic-registry-client-helpers = { path = "../../registry/helpers" } +ic-replicated-state = { path = "../../replicated_state" } +ic-types = { path = "../../types/types" } +prometheus = { workspace = true } +slog = { workspace = true } +rayon = { workspace = true } + +[dev-dependencies] +ic-artifact-pool = { path = "../../artifact_pool" } +ic-consensus-mocks = { path = "../mocks" } +ic-crypto-test-utils-ni-dkg = { path = "../../crypto/test_utils/ni-dkg" } +ic-test-artifact-pool = { path = "../../test_utilities/artifact_pool" } +ic-test-utilities = { path = "../../test_utilities" } +ic-test-utilities-consensus = { path = "../../test_utilities/consensus" } +ic-test-utilities-logger = { path = "../../test_utilities/logger" } +ic-test-utilities-registry = { path = "../../test_utilities/registry" } +ic-test-utilities-state = { path = "../../test_utilities/state" } +ic-test-utilities-types = { path = "../../test_utilities/types" } diff --git a/rs/consensus/src/dkg/dkg_key_manager.rs b/rs/consensus/dkg/src/dkg_key_manager.rs similarity index 100% rename from rs/consensus/src/dkg/dkg_key_manager.rs rename to rs/consensus/dkg/src/dkg_key_manager.rs diff --git a/rs/consensus/src/dkg.rs b/rs/consensus/dkg/src/lib.rs similarity index 99% rename from rs/consensus/src/dkg.rs rename to rs/consensus/dkg/src/lib.rs index 2646c0635b0..9c7a257e9c1 100644 --- a/rs/consensus/src/dkg.rs +++ b/rs/consensus/dkg/src/lib.rs @@ -22,7 +22,6 @@ use ic_types::{ }, Height, NodeId, ReplicaVersion, }; -pub(crate) use payload_validator::{DkgPayloadValidationFailure, InvalidDkgPayloadReason}; use prometheus::Histogram; use rayon::prelude::*; use std::{ @@ -31,8 +30,10 @@ use std::{ }; pub mod dkg_key_manager; -pub(crate) mod payload_builder; -pub(crate) mod payload_validator; +pub mod payload_builder; +pub mod payload_validator; + +pub use crate::payload_validator::{DkgPayloadValidationFailure, InvalidDkgPayloadReason}; #[cfg(test)] mod test_utils; diff --git a/rs/consensus/src/dkg/payload_builder.rs b/rs/consensus/dkg/src/payload_builder.rs similarity index 99% rename from rs/consensus/src/dkg/payload_builder.rs rename to rs/consensus/dkg/src/payload_builder.rs index 7a6e929f62b..7a8b55b32c7 100644 --- a/rs/consensus/src/dkg/payload_builder.rs +++ b/rs/consensus/dkg/src/payload_builder.rs @@ -401,7 +401,7 @@ fn compute_remote_dkg_data( Ok((configs, new_transcripts_vec, attempts)) } -pub(crate) fn get_dkg_summary_from_cup_contents( +pub fn get_dkg_summary_from_cup_contents( cup_contents: CatchUpPackageContents, subnet_id: SubnetId, registry: &dyn RegistryClient, diff --git a/rs/consensus/src/dkg/payload_validator.rs b/rs/consensus/dkg/src/payload_validator.rs similarity index 99% rename from rs/consensus/src/dkg/payload_validator.rs rename to rs/consensus/dkg/src/payload_validator.rs index 2d3e30c6ec1..f5b8febc868 100644 --- a/rs/consensus/src/dkg/payload_validator.rs +++ b/rs/consensus/dkg/src/payload_validator.rs @@ -31,7 +31,7 @@ use prometheus::IntCounterVec; // enum. See https://github.com/rust-lang/rust/issues/88900 #[allow(dead_code)] #[derive(PartialEq, Debug)] -pub(crate) enum InvalidDkgPayloadReason { +pub enum InvalidDkgPayloadReason { CryptoError(CryptoError), DkgVerifyDealingError(DkgVerifyDealingError), MismatchedDkgSummary(dkg::Summary, dkg::Summary), @@ -54,7 +54,7 @@ pub(crate) enum InvalidDkgPayloadReason { /// payload is invalid. #[allow(dead_code)] #[derive(PartialEq, Debug)] -pub(crate) enum DkgPayloadValidationFailure { +pub enum DkgPayloadValidationFailure { PayloadCreationFailed(PayloadCreationError), /// Crypto related errors. CryptoError(CryptoError), @@ -113,7 +113,7 @@ impl From for PayloadValidationError { /// Validates the DKG payload. The parent block is expected to be a valid block. #[allow(clippy::too_many_arguments)] -pub(crate) fn validate_payload( +pub fn validate_payload( subnet_id: SubnetId, registry_client: &dyn RegistryClient, crypto: &dyn ConsensusCrypto, diff --git a/rs/consensus/src/dkg/test_utils.rs b/rs/consensus/dkg/src/test_utils.rs similarity index 100% rename from rs/consensus/src/dkg/test_utils.rs rename to rs/consensus/dkg/src/test_utils.rs diff --git a/rs/consensus/src/dkg/utils.rs b/rs/consensus/dkg/src/utils.rs similarity index 100% rename from rs/consensus/src/dkg/utils.rs rename to rs/consensus/dkg/src/utils.rs diff --git a/rs/consensus/src/consensus.rs b/rs/consensus/src/consensus.rs index 250ccff1a41..4b627cc7ad4 100644 --- a/rs/consensus/src/consensus.rs +++ b/rs/consensus/src/consensus.rs @@ -22,16 +22,13 @@ pub mod validator; #[cfg(all(test, feature = "proptest"))] mod proptests; -use crate::{ - consensus::{ - block_maker::BlockMaker, catchup_package_maker::CatchUpPackageMaker, finalizer::Finalizer, - metrics::ConsensusMetrics, notary::Notary, payload_builder::PayloadBuilderImpl, - priority::new_bouncer, purger::Purger, random_beacon_maker::RandomBeaconMaker, - random_tape_maker::RandomTapeMaker, share_aggregator::ShareAggregator, - validator::Validator, - }, - dkg::DkgKeyManager, +use crate::consensus::{ + block_maker::BlockMaker, catchup_package_maker::CatchUpPackageMaker, finalizer::Finalizer, + metrics::ConsensusMetrics, notary::Notary, payload_builder::PayloadBuilderImpl, + priority::new_bouncer, purger::Purger, random_beacon_maker::RandomBeaconMaker, + random_tape_maker::RandomTapeMaker, share_aggregator::ShareAggregator, validator::Validator, }; +use ic_consensus_dkg::DkgKeyManager; use ic_consensus_utils::{ bouncer_metrics::BouncerMetrics, crypto::ConsensusCrypto, get_notarization_delay_settings, membership::Membership, pool_reader::PoolReader, RoundRobin, diff --git a/rs/consensus/src/consensus/block_maker.rs b/rs/consensus/src/consensus/block_maker.rs index 863241bf16b..ffff9b32351 100755 --- a/rs/consensus/src/consensus/block_maker.rs +++ b/rs/consensus/src/consensus/block_maker.rs @@ -5,9 +5,9 @@ use crate::{ status::{self, Status}, ConsensusCrypto, }, - dkg::payload_builder::create_payload as create_dkg_payload, idkg::{self, metrics::IDkgPayloadMetrics}, }; +use ic_consensus_dkg::payload_builder::create_payload as create_dkg_payload; use ic_consensus_utils::{ find_lowest_ranked_non_disqualified_proposals, get_notarization_delay_settings, get_subnet_record, membership::Membership, pool_reader::PoolReader, diff --git a/rs/consensus/src/consensus/validator.rs b/rs/consensus/src/consensus/validator.rs index 9f67d875272..ae946a453ad 100644 --- a/rs/consensus/src/consensus/validator.rs +++ b/rs/consensus/src/consensus/validator.rs @@ -8,8 +8,9 @@ use crate::{ status::{self, Status}, ConsensusMessageId, }, - dkg, idkg, + idkg, }; +use ic_consensus_dkg as dkg; use ic_consensus_utils::{ active_high_threshold_nidkg_id, active_low_threshold_nidkg_id, crypto::ConsensusCrypto, diff --git a/rs/consensus/src/cup_utils.rs b/rs/consensus/src/cup_utils.rs index 484a5140248..4138eadbcaf 100644 --- a/rs/consensus/src/cup_utils.rs +++ b/rs/consensus/src/cup_utils.rs @@ -1,13 +1,11 @@ //! This module contains functions for constructing CUPs from registry -use crate::{ - dkg::payload_builder::get_dkg_summary_from_cup_contents, - idkg::{ - make_bootstrap_summary, - payload_builder::make_bootstrap_summary_with_initial_dealings, - utils::{get_idkg_chain_key_config_if_enabled, inspect_idkg_chain_key_initializations}, - }, +use crate::idkg::{ + make_bootstrap_summary, + payload_builder::make_bootstrap_summary_with_initial_dealings, + utils::{get_idkg_chain_key_config_if_enabled, inspect_idkg_chain_key_initializations}, }; +use ic_consensus_dkg::payload_builder::get_dkg_summary_from_cup_contents; use ic_interfaces_registry::RegistryClient; use ic_logger::{warn, ReplicaLogger}; use ic_protobuf::registry::subnet::v1::CatchUpPackageContents; diff --git a/rs/consensus/src/lib.rs b/rs/consensus/src/lib.rs index 92a491940a2..4f0a9ecdc66 100755 --- a/rs/consensus/src/lib.rs +++ b/rs/consensus/src/lib.rs @@ -8,7 +8,6 @@ pub mod certification; pub mod consensus; pub mod cup_utils; -pub mod dkg; pub mod idkg; pub use cup_utils::{make_registry_cup, make_registry_cup_from_cup_contents}; diff --git a/rs/consensus/tests/framework/driver.rs b/rs/consensus/tests/framework/driver.rs index 7d3f5d967fe..dbd07aff8f9 100644 --- a/rs/consensus/tests/framework/driver.rs +++ b/rs/consensus/tests/framework/driver.rs @@ -31,7 +31,7 @@ impl<'a> ConsensusDriver<'a> { dyn PoolMutationsProducer, >, consensus_bouncer: ConsensusBouncer, - dkg: ic_consensus::dkg::DkgImpl, + dkg: ic_consensus_dkg::DkgImpl, idkg: Box>, certifier: Box< dyn PoolMutationsProducer diff --git a/rs/consensus/tests/framework/mod.rs b/rs/consensus/tests/framework/mod.rs index 227f194a1a6..fc7c4fa7098 100644 --- a/rs/consensus/tests/framework/mod.rs +++ b/rs/consensus/tests/framework/mod.rs @@ -195,12 +195,9 @@ pub fn setup_subnet( registry_client.reload(); registry_client.update_to_latest_version(); - let summary = ic_consensus::dkg::make_genesis_summary( - &*registry_client, - subnet_id, - Option::from(version), - ) - .with_current_transcripts(ni_transcripts); + let summary = + ic_consensus_dkg::make_genesis_summary(&*registry_client, subnet_id, Option::from(version)) + .with_current_transcripts(ni_transcripts); let cup = make_genesis(summary); (registry_client, cup, cryptos) } diff --git a/rs/consensus/tests/framework/runner.rs b/rs/consensus/tests/framework/runner.rs index a98c2164057..e660f4b1c4f 100644 --- a/rs/consensus/tests/framework/runner.rs +++ b/rs/consensus/tests/framework/runner.rs @@ -2,11 +2,11 @@ use super::delivery::*; use super::execution::*; use super::types::*; use ic_config::artifact_pool::ArtifactPoolConfig; -use ic_consensus::dkg::DkgKeyManager; use ic_consensus::{ certification::{CertificationCrypto, CertifierImpl}, - dkg, idkg, + idkg, }; +use ic_consensus_dkg::DkgKeyManager; use ic_consensus_utils::crypto::ConsensusCrypto; use ic_consensus_utils::membership::Membership; use ic_consensus_utils::pool_reader::PoolReader; @@ -175,7 +175,7 @@ impl<'a> ConsensusRunner<'a> { &deps.metrics_registry, deps.message_routing.clone(), ); - let dkg = dkg::DkgImpl::new( + let dkg = ic_consensus_dkg::DkgImpl::new( deps.replica_config.node_id, Arc::clone(&consensus_crypto), deps.consensus_pool.read().unwrap().get_cache(), diff --git a/rs/consensus/tests/framework/types.rs b/rs/consensus/tests/framework/types.rs index f35aa80320b..90983fc40eb 100644 --- a/rs/consensus/tests/framework/types.rs +++ b/rs/consensus/tests/framework/types.rs @@ -6,7 +6,7 @@ use ic_artifact_pool::{ use ic_config::artifact_pool::ArtifactPoolConfig; use ic_consensus::{ consensus::{ConsensusBouncer, ConsensusImpl}, - dkg, idkg, + idkg, }; use ic_https_outcalls_consensus::test_utils::FakeCanisterHttpPayloadBuilder; use ic_interfaces::{ @@ -349,7 +349,7 @@ pub struct ConsensusDriver<'a> { pub(crate) consensus: Box>, pub(crate) consensus_bouncer: ConsensusBouncer, - pub(crate) dkg: dkg::DkgImpl, + pub(crate) dkg: ic_consensus_dkg::DkgImpl, pub(crate) idkg: Box>, pub(crate) certifier: diff --git a/rs/consensus/tests/payload.rs b/rs/consensus/tests/payload.rs index 7f678bd5937..cffef44f458 100644 --- a/rs/consensus/tests/payload.rs +++ b/rs/consensus/tests/payload.rs @@ -3,8 +3,8 @@ mod framework; use crate::framework::ConsensusDriver; use ic_artifact_pool::{consensus_pool, dkg_pool, idkg_pool}; -use ic_consensus::dkg::DkgKeyManager; -use ic_consensus::{certification::CertifierImpl, dkg, idkg}; +use ic_consensus::{certification::CertifierImpl, idkg}; +use ic_consensus_dkg::DkgKeyManager; use ic_consensus_utils::pool_reader::PoolReader; use ic_https_outcalls_consensus::test_utils::FakeCanisterHttpPayloadBuilder; use ic_interfaces_state_manager::Labeled; @@ -116,7 +116,11 @@ fn consensus_produces_expected_batches() { .build(), )], ); - let summary = dkg::make_genesis_summary(&*registry_client, replica_config.subnet_id, None); + let summary = ic_consensus_dkg::make_genesis_summary( + &*registry_client, + replica_config.subnet_id, + None, + ); let consensus_pool = Arc::new(RwLock::new(consensus_pool::ConsensusPoolImpl::new( node_id, subnet_id, @@ -159,7 +163,7 @@ fn consensus_produces_expected_batches() { ); let consensus_bouncer = ic_consensus::consensus::ConsensusBouncer::new(&metrics_registry, router.clone()); - let dkg = dkg::DkgImpl::new( + let dkg = ic_consensus_dkg::DkgImpl::new( replica_config.node_id, Arc::clone(&fake_crypto) as Arc<_>, Arc::clone(&consensus_cache), diff --git a/rs/replay/BUILD.bazel b/rs/replay/BUILD.bazel index 3e1ac174640..0f0c57c7d8c 100644 --- a/rs/replay/BUILD.bazel +++ b/rs/replay/BUILD.bazel @@ -7,6 +7,7 @@ DEPENDENCIES = [ "//rs/canister_sandbox:backend_lib", "//rs/config", "//rs/consensus", + "//rs/consensus/dkg", "//rs/consensus/utils", "//rs/crypto", "//rs/crypto/for_verification_only", diff --git a/rs/replay/Cargo.toml b/rs/replay/Cargo.toml index 4397dbfaac0..fbadf17d59c 100644 --- a/rs/replay/Cargo.toml +++ b/rs/replay/Cargo.toml @@ -15,6 +15,7 @@ ic-canister-client = { path = "../canister_client" } ic-canister-sandbox-backend-lib = { path = "../canister_sandbox" } ic-config = { path = "../config" } ic-consensus = { path = "../consensus" } +ic-consensus-dkg = { path = "../consensus/dkg" } ic-consensus-utils = { path = "../consensus/utils" } ic-crypto-for-verification-only = { path = "../crypto/for_verification_only" } ic-cycles-account-manager = { path = "../cycles_account_manager" } diff --git a/rs/replay/src/backup.rs b/rs/replay/src/backup.rs index 49d91080da9..b97a4996fbd 100644 --- a/rs/replay/src/backup.rs +++ b/rs/replay/src/backup.rs @@ -4,7 +4,7 @@ use crate::{ }; use ic_artifact_pool::consensus_pool::ConsensusPoolImpl; use ic_config::artifact_pool::BACKUP_GROUP_SIZE; -use ic_consensus::dkg::DkgKeyManager; +use ic_consensus_dkg::DkgKeyManager; use ic_consensus_utils::pool_reader::PoolReader; use ic_crypto_for_verification_only::CryptoComponentForVerificationOnly; use ic_interfaces::{ diff --git a/rs/replay/src/validator.rs b/rs/replay/src/validator.rs index 55189f3a6f2..d370b302b31 100644 --- a/rs/replay/src/validator.rs +++ b/rs/replay/src/validator.rs @@ -9,8 +9,8 @@ use ic_config::{artifact_pool::ArtifactPoolConfig, Config}; use ic_consensus::{ certification::CertificationCrypto, consensus::{validator::Validator, ValidatorMetrics}, - dkg::DkgKeyManager, }; +use ic_consensus_dkg::DkgKeyManager; use ic_consensus_utils::{ active_high_threshold_nidkg_id, crypto::ConsensusCrypto, membership::Membership, pool_reader::PoolReader, registry_version_at_height, diff --git a/rs/replica/Cargo.toml b/rs/replica/Cargo.toml index 727fdb68426..e1253355c52 100644 --- a/rs/replica/Cargo.toml +++ b/rs/replica/Cargo.toml @@ -15,6 +15,7 @@ ic-btc-adapter-client = { path = "../bitcoin/client" } ic-btc-consensus = { path = "../bitcoin/consensus" } ic-config = { path = "../config" } ic-consensus = { path = "../consensus" } +ic-consensus-dkg = { path = "../consensus/dkg" } ic-crypto = { path = "../crypto" } ic-crypto-sha2 = { path = "../crypto/sha2" } ic-cycles-account-manager = { path = "../cycles_account_manager" } diff --git a/rs/replica/setup_ic_network/BUILD.bazel b/rs/replica/setup_ic_network/BUILD.bazel index e65ff55b14d..bba68f83a82 100644 --- a/rs/replica/setup_ic_network/BUILD.bazel +++ b/rs/replica/setup_ic_network/BUILD.bazel @@ -6,6 +6,7 @@ DEPENDENCIES = [ # Keep sorted. "//rs/artifact_pool", "//rs/config", + "//rs/consensus/dkg", "//rs/consensus/utils", "//rs/crypto/interfaces/sig_verification", "//rs/crypto/tls_interfaces", diff --git a/rs/replica/setup_ic_network/Cargo.toml b/rs/replica/setup_ic_network/Cargo.toml index 9305f10cd2f..a9e464849a7 100644 --- a/rs/replica/setup_ic_network/Cargo.toml +++ b/rs/replica/setup_ic_network/Cargo.toml @@ -12,6 +12,7 @@ ic-artifact-manager = { path = "../../p2p/artifact_manager" } ic-artifact-pool = { path = "../../artifact_pool" } ic-config = { path = "../../config" } ic-consensus = { path = "../../consensus" } +ic-consensus-dkg = { path = "../../consensus/dkg" } ic-consensus-manager = { path = "../../p2p/consensus_manager" } ic-consensus-utils = { path = "../../consensus/utils" } ic-crypto-interfaces-sig-verification = { path = "../../crypto/interfaces/sig_verification" } diff --git a/rs/replica/setup_ic_network/src/lib.rs b/rs/replica/setup_ic_network/src/lib.rs index 46e10534717..982cddc301c 100644 --- a/rs/replica/setup_ic_network/src/lib.rs +++ b/rs/replica/setup_ic_network/src/lib.rs @@ -13,7 +13,7 @@ use ic_config::{artifact_pool::ArtifactPoolConfig, transport::TransportConfig}; use ic_consensus::{ certification::{CertificationCrypto, CertifierBouncer, CertifierImpl}, consensus::{ConsensusBouncer, ConsensusImpl}, - dkg, idkg, + idkg, }; use ic_consensus_manager::ConsensusManagerBuilder; use ic_consensus_utils::{crypto::ConsensusCrypto, pool_reader::PoolReader}; @@ -298,7 +298,7 @@ fn start_consensus( log.clone(), )); - let dkg_key_manager = Arc::new(Mutex::new(dkg::DkgKeyManager::new( + let dkg_key_manager = Arc::new(Mutex::new(ic_consensus_dkg::DkgKeyManager::new( metrics_registry.clone(), Arc::clone(&consensus_crypto), log.clone(), @@ -439,7 +439,7 @@ fn start_consensus( // Create the DKG client. let (client, jh) = create_artifact_handler( dkg_tx, - dkg::DkgImpl::new( + ic_consensus_dkg::DkgImpl::new( node_id, Arc::clone(&consensus_crypto), Arc::clone(&consensus_pool_cache), @@ -453,7 +453,7 @@ fn start_consensus( ); join_handles.push(jh); - let bouncer = Arc::new(dkg::DkgBouncer::new(metrics_registry)); + let bouncer = Arc::new(ic_consensus_dkg::DkgBouncer::new(metrics_registry)); let assembler = ic_artifact_downloader::FetchArtifact::new( log.clone(), rt_handle.clone(), diff --git a/rs/test_utilities/artifact_pool/BUILD.bazel b/rs/test_utilities/artifact_pool/BUILD.bazel index d3c1eb1026a..7ff50877d1b 100644 --- a/rs/test_utilities/artifact_pool/BUILD.bazel +++ b/rs/test_utilities/artifact_pool/BUILD.bazel @@ -7,6 +7,7 @@ DEPENDENCIES = [ "//rs/artifact_pool", "//rs/config", "//rs/consensus", + "//rs/consensus/dkg", "//rs/consensus/utils", "//rs/interfaces", "//rs/interfaces/registry", diff --git a/rs/test_utilities/artifact_pool/Cargo.toml b/rs/test_utilities/artifact_pool/Cargo.toml index 76d3675c20e..bb8bbd6f955 100644 --- a/rs/test_utilities/artifact_pool/Cargo.toml +++ b/rs/test_utilities/artifact_pool/Cargo.toml @@ -10,6 +10,7 @@ documentation.workspace = true ic-artifact-pool = { path = "../../artifact_pool" } ic-config = { path = "../../config" } ic-consensus = { path = "../../consensus" } +ic-consensus-dkg = { path = "../../consensus/dkg" } ic-consensus-utils = { path = "../../consensus/utils" } ic-interfaces = { path = "../../interfaces" } ic-interfaces-registry = { path = "../../interfaces/registry" } diff --git a/rs/test_utilities/artifact_pool/src/consensus_pool.rs b/rs/test_utilities/artifact_pool/src/consensus_pool.rs index 2fe4c1f5b5b..8e206edc9df 100644 --- a/rs/test_utilities/artifact_pool/src/consensus_pool.rs +++ b/rs/test_utilities/artifact_pool/src/consensus_pool.rs @@ -145,7 +145,7 @@ fn dkg_payload_builder_fn( dkg_pool: Arc>, ) -> Box consensus::dkg::Payload> { Box::new(move |cons_pool, parent, validation_context| { - ic_consensus::dkg::create_payload( + ic_consensus_dkg::create_payload( subnet_id, &*registry_client, &*crypto, @@ -188,7 +188,7 @@ impl TestConsensusPool { )) }), )); - let summary = ic_consensus::dkg::make_genesis_summary(&*registry_client, subnet_id, None); + let summary = ic_consensus_dkg::make_genesis_summary(&*registry_client, subnet_id, None); let pool = ConsensusPoolImpl::new( node_id, subnet_id, From ea8cf537413e662f36bba9c16f8139646b2d53a3 Mon Sep 17 00:00:00 2001 From: Marko Kosmerl Date: Wed, 8 Jan 2025 14:25:41 -0300 Subject: [PATCH 27/98] revert: "test: Add test for taking a snapshot that triggers storage reservation" (#3372) Reverts dfinity/ic#3360 Failures on master indicate a regression: * https://github.com/dfinity/ic/actions/runs/12673499329/job/35320020267 * https://github.com/dfinity/ic/actions/runs/12673401969/job/35319700314 --- .../tests/storage_reservation.rs | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/rs/execution_environment/tests/storage_reservation.rs b/rs/execution_environment/tests/storage_reservation.rs index 99eecc00113..8c9e4598235 100644 --- a/rs/execution_environment/tests/storage_reservation.rs +++ b/rs/execution_environment/tests/storage_reservation.rs @@ -1,6 +1,5 @@ use ic_config::execution_environment::Config as ExecutionConfig; use ic_config::subnet_config::SubnetConfig; -use ic_error_types::ErrorCode; use ic_management_canister_types::TakeCanisterSnapshotArgs; use ic_management_canister_types::{self as ic00, CanisterInstallMode, EmptyBlob, Payload}; use ic_registry_subnet_type::SubnetType; @@ -169,44 +168,3 @@ fn test_storage_reservation_triggered_in_canister_snapshot_with_enough_cycles_av reserved_balance_before_snapshot ); } - -#[test] -fn test_storage_reservation_triggered_in_canister_snapshot_without_enough_cycles_available() { - // This test verifies that a canister cannot take a snapshot if it does not have enough - // cycles to cover the storage reservation triggered by the snapshot operation. The main - // point of the test is to verify that the error message is informative and includes the - // amount of cycles required to cover the storage reservation. - // - // The error message is produced by running the test once and checking the output. Calculating - // the exact amounts is hard to do in advance. Note that any changes to cycles cost or how - // the reservation mechanism works may require updating the error message in the test. - - let (env, canister_id) = setup( - SUBNET_MEMORY_THRESHOLD, - SUBNET_MEMORY_CAPACITY, - Some(300_400_000_000), - ); - assert_eq!(reserved_balance(&env, canister_id), 0); - - // Grow memory in update call, should trigger storage reservation. - let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(3000).build()); - let reserved_balance_before_snapshot = reserved_balance(&env, canister_id); - assert_gt!(reserved_balance_before_snapshot, 0); // Storage reservation is triggered. - - // Take a snapshot to trigger more storage reservation. The canister does not have - // enough cycles in its balance, so this should fail. - let res = env.take_canister_snapshot(TakeCanisterSnapshotArgs::new(canister_id, None)); - match res { - Ok(_) => panic!("Expected an error but got Ok(_)"), - Err(err) => { - assert_eq!(err.code(), ErrorCode::InsufficientCyclesInMemoryGrow); - println!("error description {}", err.description()); - // Match on the first part of the error message. Due to a difference in instructions consumed on - // Mac vs Linux, we cannot match on the exact number of cycles but we only need to verify it's - // a non-zero amount. - assert!(err.description().contains( - "Canister cannot grow memory by 200067930 bytes due to insufficient cycles. At least 339_603_" - )); - } - } -} From fc935aa7688ee31060f4bc10ace37b9cce798782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20Tomi=C4=87?= Date: Wed, 8 Jan 2025 18:44:18 +0100 Subject: [PATCH 28/98] feat(NNS): allow execution of proposals that remove non-existing nodes (#3339) Prevent that race conditions such as the one in the following proposal prevent proposal execution: https://dashboard.internetcomputer.org/proposal/134665 It's impossible to completely prevent race conditions such as this one so we should handle them gracefully when possible. ### Refactor Node Removal Logic - Extracted the node retrieval logic into a new function `get_node` that returns an `Option`. - Simplified the `get_node_or_panic` function to leverage `get_node` for node retrieval. ### Improvements in Node Management - Updated the `do_remove_nodes` logic to skip nodes that aren't found in the registry, thus handling potential race conditions gracefully. Also added several tests for the above --- rs/registry/canister/src/mutations/node.rs | 31 ++- .../node_management/do_remove_nodes.rs | 186 +++++++++++++++++- .../nns/node_removal_from_registry_test.rs | 33 ++-- 3 files changed, 212 insertions(+), 38 deletions(-) diff --git a/rs/registry/canister/src/mutations/node.rs b/rs/registry/canister/src/mutations/node.rs index a8c3dc8003d..1e7421e1ae1 100644 --- a/rs/registry/canister/src/mutations/node.rs +++ b/rs/registry/canister/src/mutations/node.rs @@ -8,22 +8,21 @@ use prost::Message; impl Registry { /// Get the Node record or panic on error with a message. pub fn get_node_or_panic(&self, node_id: NodeId) -> NodeRecord { - let RegistryValue { - value: node_record_vec, - version: _, - deletion_marker: _, - } = self - .get( - &make_node_record_key(node_id).into_bytes(), - self.latest_version(), - ) - .unwrap_or_else(|| { - panic!( - "{}node record for {:} not found in the registry.", - LOG_PREFIX, node_id - ) - }); + self.get_node(node_id).unwrap_or_else(|| { + panic!( + "{}node record for {:} not found in the registry.", + LOG_PREFIX, node_id + ); + }) + } + + /// Get the Node record if it exists in the Registry. + pub fn get_node(&self, node_id: NodeId) -> Option { + let reg_value: &RegistryValue = self.get( + &make_node_record_key(node_id).into_bytes(), + self.latest_version(), + )?; - NodeRecord::decode(node_record_vec.as_slice()).unwrap() + Some(NodeRecord::decode(reg_value.value.as_slice()).unwrap()) } } diff --git a/rs/registry/canister/src/mutations/node_management/do_remove_nodes.rs b/rs/registry/canister/src/mutations/node_management/do_remove_nodes.rs index eea3217ec4e..847c1457577 100644 --- a/rs/registry/canister/src/mutations/node_management/do_remove_nodes.rs +++ b/rs/registry/canister/src/mutations/node_management/do_remove_nodes.rs @@ -33,14 +33,21 @@ impl Registry { // 3. Loop through each node let mutations = nodes_to_be_removed .into_iter().flat_map(|node_to_remove| { + // 4. Skip nodes that are not in the registry. + // This tackles the race condition where a node is removed from the registry + // by another transaction before this transaction is processed. + if self.get_node(node_to_remove).is_none() { + println!("{}do_remove_nodes: node {} not found in registry, skipping", LOG_PREFIX, node_to_remove); + return vec![]; + }; - // 4. Find the node operator id for this record + // 5. Find the node operator id for this record // and abort if the node record is not found let node_operator_id = get_node_operator_id_for_node(self, node_to_remove) .map_err(|e| format!("{}do_remove_nodes: Aborting node removal: {}", LOG_PREFIX, e)) .unwrap(); - // 5. Ensure node is not in a subnet + // 6. Ensure node is not in a subnet let is_node_in_subnet = find_subnet_for_node(self, node_to_remove, &subnet_list_record); if let Some(subnet_id) = is_node_in_subnet { panic!("{}do_remove_nodes: Cannot remove a node that is a member of a subnet. This node is a member of Subnet: {}", @@ -49,7 +56,7 @@ impl Registry { ); } - // 6. Retrieve the NO record and increment its node allowance by 1 + // 7. Retrieve the NO record and increment its node allowance by 1 let mut new_node_operator_record = get_node_operator_record(self, node_operator_id) .map_err(|err| { format!( @@ -70,7 +77,7 @@ impl Registry { }; node_operator_hmap.insert(node_operator_id.to_string(), new_node_operator_record.node_allowance); - // 7. Finally, generate the following mutations: + // 8. Finally, generate the following mutations: // * Delete the node // * Delete entries for node encryption keys // * Increment NO's allowance by 1 @@ -97,3 +104,174 @@ pub struct RemoveNodesPayload { /// The list of Node IDs that will be removed pub node_ids: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + use crate::common::test_helpers::{invariant_compliant_registry, prepare_registry_with_nodes}; + use ic_base_types::PrincipalId; + use ic_protobuf::registry::node_operator::v1::NodeOperatorRecord; + use ic_registry_keys::{make_node_operator_record_key, make_node_record_key}; + use ic_registry_transport::insert; + use prost::Message; + + #[test] + fn test_remove_nonexistent_node() { + let mut registry = invariant_compliant_registry(0); + + let nonexistent_node_id = NodeId::from(PrincipalId::new_user_test_id(999)); + let payload = RemoveNodesPayload { + node_ids: vec![nonexistent_node_id], + }; + + // Should not panic, just skip the nonexistent node + registry.do_remove_nodes(payload); + } + + #[test] + fn test_remove_single_node() { + let mut registry = invariant_compliant_registry(0); + + // Add a node to the registry + let (mutate_request, node_ids) = prepare_registry_with_nodes(1, 1); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + + let node_id = *node_ids.keys().next().unwrap(); + let node_operator_id = + PrincipalId::try_from(registry.get_node_or_panic(node_id).node_operator_id).unwrap(); + + // Allow this node operator to onboard 1 more node; the initial value is not important in this test. + // We just want to later see that node_allowance gets incremented by `do_remove_nodes`. + let initial_allowance = 1; + let node_operator_record = NodeOperatorRecord { + node_allowance: initial_allowance, + ..Default::default() + }; + + registry.maybe_apply_mutation_internal(vec![insert( + make_node_operator_record_key(node_operator_id), + node_operator_record.encode_to_vec(), + )]); + + // Remove the node + let payload = RemoveNodesPayload { + node_ids: vec![node_id], + }; + registry.do_remove_nodes(payload); + // Verify node is removed + assert!(registry + .get( + make_node_record_key(node_id).as_bytes(), + registry.latest_version() + ) + .is_none()); + + // Verify node operator allowance was incremented + let updated_operator = get_node_operator_record(®istry, node_operator_id).unwrap(); + assert_eq!(updated_operator.node_allowance, initial_allowance + 1); + } + #[test] + fn test_remove_multiple_nodes_same_operator() { + let mut registry = invariant_compliant_registry(0); + + // Add multiple nodes to the registry + let (mutate_request, node_ids) = prepare_registry_with_nodes(1, 3); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + + let node_ids: Vec = node_ids.keys().cloned().collect(); + let node_operator_id = + PrincipalId::try_from(registry.get_node_or_panic(node_ids[0]).node_operator_id) + .unwrap(); + + // Add node operator record + let initial_allowance = 0; + let node_operator_record = NodeOperatorRecord { + node_allowance: initial_allowance, + ..Default::default() + }; + + registry.maybe_apply_mutation_internal(vec![insert( + make_node_operator_record_key(node_operator_id), + node_operator_record.encode_to_vec(), + )]); + + // Remove two nodes + let payload = RemoveNodesPayload { + node_ids: node_ids[..2].to_vec(), + }; + + registry.do_remove_nodes(payload); + + // Verify the two nodes are removed + for node_id in &node_ids[..2] { + assert!(registry + .get( + make_node_record_key(*node_id).as_bytes(), + registry.latest_version() + ) + .is_none()); + } + + // Verify the third node is still present + assert!(registry.get_node(node_ids[2]).is_some()); + + // Verify node operator allowance was incremented by 2 + let updated_operator = get_node_operator_record(®istry, node_operator_id).unwrap(); + assert_eq!(updated_operator.node_allowance, initial_allowance + 2); + } + + #[test] + fn test_remove_duplicate_and_nonexistent_node_ids() { + let mut registry = invariant_compliant_registry(0); + + // Add a node to the registry + let (mutate_request, node_ids) = prepare_registry_with_nodes(1, 1); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + + let node_id = node_ids.keys().next().unwrap().to_owned(); + let node_operator_id = + PrincipalId::try_from(registry.get_node_or_panic(node_id).node_operator_id).unwrap(); + + // Add node operator record + let initial_allowance = 0; + let node_operator_record = NodeOperatorRecord { + node_allowance: initial_allowance, + ..Default::default() + }; + + registry.maybe_apply_mutation_internal(vec![insert( + make_node_operator_record_key(node_operator_id), + node_operator_record.encode_to_vec(), + )]); + + // Try to remove the same node multiple times + let payload = RemoveNodesPayload { + node_ids: vec![ + node_id, + NodeId::from(PrincipalId::new_node_test_id(111)), + node_id, + NodeId::from(PrincipalId::new_node_test_id(222)), + node_id, + ], + }; + + registry.do_remove_nodes(payload); + + // Verify node is removed + assert!(registry + .get( + make_node_record_key(node_id).as_bytes(), + registry.latest_version() + ) + .is_none()); + + // Verify other node_ids are still in the registry + for other_node_id in node_ids.keys().skip(1) { + assert!(registry.get_node(*other_node_id).is_some()); + } + + // Verify node operator allowance was incremented only once + let updated_operator = get_node_operator_record(®istry, node_operator_id).unwrap(); + assert_eq!(updated_operator.node_allowance, initial_allowance + 1); + } +} diff --git a/rs/tests/nns/node_removal_from_registry_test.rs b/rs/tests/nns/node_removal_from_registry_test.rs index 5ac3653d214..a68d7b3333c 100644 --- a/rs/tests/nns/node_removal_from_registry_test.rs +++ b/rs/tests/nns/node_removal_from_registry_test.rs @@ -116,23 +116,20 @@ pub fn test(env: TestEnv) { ) .await; vote_execute_proposal_assert_executed(&governance_canister, proposal_id).await; - // Confirm that the node was indeed removed by sending the proposal again and asserting failure. - let proposal_id = submit_external_proposal_with_test_id( - &governance_canister, - NnsFunction::RemoveNodes, - RemoveNodesPayload { - node_ids: vec![unassigned_node_id], - }, - ) - .await; - vote_execute_proposal_assert_failed( - &governance_canister, - proposal_id, - format!( - "Aborting node removal: Node Id {} not found in the registry", - unassigned_node_id - ), - ) - .await; + + // Confirm that the node was indeed removed by checking the unassigned node list in the registry. + topology + .block_for_newer_registry_version() + .await + .expect("Could not obtain updated registry."); + let topology = env.topology_snapshot(); + assert_eq!( + topology + .unassigned_nodes() + .filter(|node| node.node_id == unassigned_node_id) + .map(|node| node.node_id) + .collect::>(), + vec![] + ); }); } From 194648a9fde71e38669bee90b29c23ac38e8801c Mon Sep 17 00:00:00 2001 From: Arshavir Ter-Gabrielyan Date: Wed, 8 Jan 2025 20:25:51 +0100 Subject: [PATCH 29/98] feat(nervous-system): Enable Root to upgrade canisters using chunked Wasms (#3300) This PR enables Root to upgrade canisters using chunked Wasms. This is relevant to both the NNS and the SNSs. --------- Co-authored-by: max-dfinity <100170574+max-dfinity@users.noreply.github.com> --- Cargo.lock | 1 + .../common/test_utils/BUILD.bazel | 1 + .../common/test_utils/src/wasm_helpers.rs | 13 +- .../integration_tests/BUILD.bazel | 21 ++ .../integration_tests/Cargo.toml | 1 + .../src/pocket_ic_helpers.rs | 27 ++ ...sns_controlled_canister_with_large_wasm.rs | 281 ++++++++++++++++++ rs/nervous_system/root/src/change_canister.rs | 119 ++++++-- .../governance/src/proposals/install_code.rs | 3 + rs/nns/handlers/root/impl/canister/root.did | 7 + .../src/governance_upgrade.rs | 1 + rs/registry/admin/src/main.rs | 1 + rs/sns/integration_tests/src/root.rs | 1 + rs/sns/root/canister/root.did | 7 + rs/types/management_canister_types/src/lib.rs | 16 +- 15 files changed, 474 insertions(+), 26 deletions(-) create mode 100644 rs/nervous_system/integration_tests/tests/upgrade_sns_controlled_canister_with_large_wasm.rs diff --git a/Cargo.lock b/Cargo.lock index 5228d801ea2..df0f6ed8a2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9909,6 +9909,7 @@ dependencies = [ "ic-nervous-system-clients", "ic-nervous-system-common", "ic-nervous-system-common-test-keys", + "ic-nervous-system-common-test-utils", "ic-nervous-system-proto", "ic-nervous-system-root", "ic-nervous-system-runtime", diff --git a/rs/nervous_system/common/test_utils/BUILD.bazel b/rs/nervous_system/common/test_utils/BUILD.bazel index ab304da284e..b62ecb544dd 100644 --- a/rs/nervous_system/common/test_utils/BUILD.bazel +++ b/rs/nervous_system/common/test_utils/BUILD.bazel @@ -8,6 +8,7 @@ package_group( name = "ic_nervous_system_common_test_utils_visibility", packages = [ "//rs/nervous_system/common/...", + "//rs/nervous_system/integration_tests/...", "//rs/nns/...", "//rs/sns/...", ], diff --git a/rs/nervous_system/common/test_utils/src/wasm_helpers.rs b/rs/nervous_system/common/test_utils/src/wasm_helpers.rs index 979f379df7b..124d4b3235f 100644 --- a/rs/nervous_system/common/test_utils/src/wasm_helpers.rs +++ b/rs/nervous_system/common/test_utils/src/wasm_helpers.rs @@ -1,5 +1,6 @@ use ic_wasm; use libflate::gzip; +use std::io::Read; /// A small, valid WASM suitable for tests. pub const SMALLEST_VALID_WASM_BYTES: &[u8; 8] = &[0, 0x61, 0x73, 0x6D, 1, 0, 0, 0]; @@ -25,7 +26,7 @@ pub fn annotate_wasm_with_metadata( wasm_module.emit_wasm() } -// Gzips a wasm, returning the hash of its compressed representation. +/// Gzips a wasm, returning the hash of its compressed representation. pub fn gzip_wasm(wasm: &[u8]) -> Vec { let mut encoder = gzip::Encoder::new(Vec::new()).expect("Failed to create gzip encoder."); std::io::copy(&mut &wasm[..], &mut encoder).expect("Failed to copy WASM bytes."); @@ -34,3 +35,13 @@ pub fn gzip_wasm(wasm: &[u8]) -> Vec { .into_result() .expect("Failed to finish gzip encoding.") } + +/// Decompresses a previously gzipped wasm. +pub fn ungzip_wasm(gzipped_bytes: &[u8]) -> Vec { + let mut decoder = gzip::Decoder::new(gzipped_bytes).expect("Failed to create gzip decoder."); + let mut wasm_buf = Vec::new(); + decoder + .read_to_end(&mut wasm_buf) + .expect("Failed decoding Wasm."); + wasm_buf +} diff --git a/rs/nervous_system/integration_tests/BUILD.bazel b/rs/nervous_system/integration_tests/BUILD.bazel index bc1a77c66d3..5ed2885da3c 100644 --- a/rs/nervous_system/integration_tests/BUILD.bazel +++ b/rs/nervous_system/integration_tests/BUILD.bazel @@ -41,6 +41,7 @@ BASE_DEPENDENCIES = [ "//packages/pocket-ic", "//rs/crypto/sha2", "//rs/nervous_system/common/test_keys", + "//rs/nervous_system/common/test_utils", "//rs/nns/constants", "//rs/protobuf", "//rs/registry/canister", @@ -100,6 +101,7 @@ DEV_DATA = [ "//rs/sns/root:sns-root-canister", "//rs/sns/swap:sns-swap-canister", "//rs/universal_canister/impl:universal_canister.wasm.gz", + "//testnet/prebuilt-canisters:image-classification", "@cycles-ledger.wasm.gz//file", "@mainnet_ic-icrc1-archive//file", "@mainnet_ic-icrc1-index-ng//file", @@ -124,6 +126,7 @@ DEV_ENV = { "IC_ICRC1_ARCHIVE_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/archive:archive_canister)", "IC_ICRC1_INDEX_NG_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/index-ng:index_ng_canister)", "IC_ICRC1_LEDGER_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/ledger:ledger_canister)", + "IMAGE_CLASSIFICATION_CANISTER_WASM_PATH": "$(rootpath //testnet/prebuilt-canisters:image-classification)", "LEDGER_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm)", "LEDGER_CANISTER_NOTIFY_METHOD_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm-notify-method)", "LEDGER_ARCHIVE_NODE_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/archive:ledger-archive-node-canister-wasm)", @@ -178,6 +181,7 @@ rust_test_suite_with_extra_srcs( "tests/deploy_fresh_sns_test.rs", "tests/sns_release_qualification_legacy.rs", "tests/sns_upgrade_test_utils_legacy.rs", + "tests/upgrade_sns_controlled_canister_with_large_wasm.rs", ], ), aliases = ALIASES, @@ -279,3 +283,20 @@ rust_test( ], deps = [":nervous_system_integration_tests"] + DEPENDENCIES_WITH_TEST_FEATURES + DEV_DEPENDENCIES, ) + +rust_test( + name = "upgrade_sns_controlled_canister_with_large_wasm", + timeout = "long", + srcs = [ + "tests/upgrade_sns_controlled_canister_with_large_wasm.rs", + ], + aliases = ALIASES, + data = DEV_DATA, + env = DEV_ENV | {"RUST_TEST_NOCAPTURE": "1"}, + flaky = True, + proc_macro_deps = MACRO_DEPENDENCIES + MACRO_DEV_DEPENDENCIES, + tags = [ + "cpu:4", + ], + deps = [":nervous_system_integration_tests"] + DEPENDENCIES_WITH_TEST_FEATURES + DEV_DEPENDENCIES, +) diff --git a/rs/nervous_system/integration_tests/Cargo.toml b/rs/nervous_system/integration_tests/Cargo.toml index 35e0c69236a..15a1334d584 100644 --- a/rs/nervous_system/integration_tests/Cargo.toml +++ b/rs/nervous_system/integration_tests/Cargo.toml @@ -49,6 +49,7 @@ ic-icrc1-index-ng = { path = "../../ledger_suite/icrc1/index-ng" } ic-icrc1-tokens-u64 = { path = "../../ledger_suite/icrc1/tokens_u64" } ic-management-canister-types = { path = "../../types/management_canister_types" } ic-nervous-system-common-test-keys = { path = "../common/test_keys" } +ic-nervous-system-common-test-utils = { path = "../../nervous_system/common/test_utils" } ic-nervous-system-root = { path = "../root" } ic-nns-constants = { path = "../../nns/constants" } ic-nns-gtc = { path = "../../nns/gtc" } diff --git a/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs b/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs index c75a6354ab3..ceee91c722d 100644 --- a/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs +++ b/rs/nervous_system/integration_tests/src/pocket_ic_helpers.rs @@ -185,6 +185,33 @@ pub async fn install_canister_with_controllers( ); } +pub async fn install_canister_on_subnet( + pocket_ic: &PocketIc, + subnet_id: Principal, + arg: Vec, + wasm: Option, + controllers: Vec, +) -> CanisterId { + let controllers = controllers.into_iter().map(|c| c.0).collect::>(); + let controller_principal = controllers.first().cloned(); + let settings = Some(CanisterSettings { + controllers: Some(controllers), + ..Default::default() + }); + let canister_id = pocket_ic + .create_canister_on_subnet(None, settings, subnet_id) + .await; + pocket_ic + .add_cycles(canister_id, STARTING_CYCLES_PER_CANISTER) + .await; + if let Some(wasm) = wasm { + pocket_ic + .install_canister(canister_id, wasm.bytes(), arg, controller_principal) + .await; + } + CanisterId::unchecked_from_principal(canister_id.into()) +} + // TODO migrate this to nns::governance pub async fn add_wasm_via_nns_proposal( pocket_ic: &PocketIc, diff --git a/rs/nervous_system/integration_tests/tests/upgrade_sns_controlled_canister_with_large_wasm.rs b/rs/nervous_system/integration_tests/tests/upgrade_sns_controlled_canister_with_large_wasm.rs new file mode 100644 index 00000000000..b0617beb5e0 --- /dev/null +++ b/rs/nervous_system/integration_tests/tests/upgrade_sns_controlled_canister_with_large_wasm.rs @@ -0,0 +1,281 @@ +use std::collections::BTreeSet; + +use candid::Principal; +use canister_test::Wasm; +use ic_base_types::PrincipalId; +use ic_management_canister_types::CanisterInstallMode; +use ic_nervous_system_integration_tests::pocket_ic_helpers::{ + await_with_timeout, install_canister_on_subnet, nns, sns, +}; +use ic_nervous_system_integration_tests::{ + create_service_nervous_system_builder::CreateServiceNervousSystemBuilder, + pocket_ic_helpers::{add_wasms_to_sns_wasm, install_nns_canisters}, +}; +use ic_nervous_system_root::change_canister::ChangeCanisterRequest; +use ic_nervous_system_root::change_canister::ChunkedCanisterWasm; +use ic_nns_constants::ROOT_CANISTER_ID; +use ic_nns_test_utils::common::modify_wasm_bytes; +use ic_sns_swap::pb::v1::Lifecycle; +use pocket_ic::nonblocking::PocketIc; +use pocket_ic::PocketIcBuilder; + +const MIN_INSTALL_CHUNKED_CODE_TIME_SECONDS: u64 = 20; +const MAX_INSTALL_CHUNKED_CODE_TIME_SECONDS: u64 = 5 * 60; + +const CHUNK_SIZE: usize = 1024 * 1024; // 1 MiB + +#[tokio::test] +async fn test_store_same_as_target() { + let store_same_as_target = true; + run_test(store_same_as_target).await; +} + +#[tokio::test] +async fn test_store_different_from_target() { + let store_same_as_target = false; + run_test(store_same_as_target).await; +} + +mod interim_sns_helpers { + use super::*; + + use candid::{Decode, Encode}; + use pocket_ic::nonblocking::PocketIc; + use pocket_ic::WasmResult; + + /// Interim test function for calling Root.change_canister. + /// + /// This function is not in src/pocket_ic_helpers.rs because it's going to be replaced with + /// a proposal with the same effect. It should not be used in any other tests. + pub async fn change_canister( + pocket_ic: &PocketIc, + canister_id: PrincipalId, + sender: PrincipalId, + request: ChangeCanisterRequest, + ) { + let result = pocket_ic + .update_call( + canister_id.into(), + sender.into(), + "change_canister", + Encode!(&request).unwrap(), + ) + .await + .unwrap(); + let result = match result { + WasmResult::Reply(result) => result, + WasmResult::Reject(s) => panic!("Call to change_canister failed: {:#?}", s), + }; + Decode!(&result, ()).unwrap() + } +} + +fn very_large_wasm_bytes() -> Vec { + let image_classification_canister_wasm_path = + std::env::var("IMAGE_CLASSIFICATION_CANISTER_WASM_PATH") + .expect("Please ensure that this Bazel test target correctly specifies env and data."); + + let wasm_path = std::path::PathBuf::from(image_classification_canister_wasm_path); + + std::fs::read(&wasm_path).expect("Failed to read WASM file") +} + +fn format_full_hash(hash: &[u8]) -> String { + hash.iter() + .map(|b| format!("{:02x}", b)) + .collect::>() + .join("") +} + +/// Uploads `wasm` into the store canister, one [`CHUNK_SIZE`]-sized chunk at a time. +/// +/// Returns the vector of uploaded chunk hashes. +async fn upload_wasm_as_chunks( + pocket_ic: &PocketIc, + store_controller_id: Principal, + store_canister_id: Principal, + wasm: Wasm, + num_chunks_expected: usize, +) -> Vec> { + let sender = Some(store_controller_id); + + let mut uploaded_chunk_hashes = Vec::new(); + + for chunk in wasm.bytes().chunks(CHUNK_SIZE) { + let uploaded_chunk_hash = pocket_ic + .upload_chunk(store_canister_id, sender, chunk.to_vec()) + .await + .unwrap(); + + uploaded_chunk_hashes.push(uploaded_chunk_hash); + } + + // Smoke test + { + let stored_chunk_hashes = pocket_ic + .stored_chunks(store_canister_id, sender) + .await + .unwrap() + .into_iter() + .map(|hash| format_full_hash(&hash[..])) + .collect::>(); + + let stored_chunk_hashes = BTreeSet::from_iter(stored_chunk_hashes.iter()); + + let uploaded_chunk_hashes = uploaded_chunk_hashes + .iter() + .map(|hash| format_full_hash(&hash[..])) + .collect::>(); + let uploaded_chunk_hashes = BTreeSet::from_iter(uploaded_chunk_hashes.iter()); + + assert!(uploaded_chunk_hashes.is_subset(&stored_chunk_hashes)); + assert_eq!(uploaded_chunk_hashes.len(), num_chunks_expected); + } + + uploaded_chunk_hashes +} + +async fn run_test(store_same_as_target: bool) { + // 1. Prepare the world + let pocket_ic = PocketIcBuilder::new() + .with_nns_subnet() + .with_sns_subnet() + .with_application_subnet() + .build_async() + .await; + + // Install the NNS canisters. + { + let with_mainnet_nns_canisters = false; + install_nns_canisters(&pocket_ic, vec![], with_mainnet_nns_canisters, None, vec![]).await; + } + + // Publish SNS Wasms to SNS-W. + { + let with_mainnet_sns_canisters = false; + add_wasms_to_sns_wasm(&pocket_ic, with_mainnet_sns_canisters) + .await + .unwrap(); + }; + + // Install a dapp canister. + let original_wasm = Wasm::from_bytes(very_large_wasm_bytes()); + let original_wasm_hash = original_wasm.sha256_hash(); + + let app_subnet = pocket_ic.topology().await.get_app_subnets()[0]; + + let target_canister_id = install_canister_on_subnet( + &pocket_ic, + app_subnet, + vec![], + Some(original_wasm.clone()), + vec![ROOT_CANISTER_ID.into()], + ) + .await; + + let sns = { + let create_service_nervous_system = CreateServiceNervousSystemBuilder::default() + .with_dapp_canisters(vec![target_canister_id]) + .build(); + + let swap_parameters = create_service_nervous_system + .swap_parameters + .clone() + .unwrap(); + + let sns_instance_label = "1"; + let (sns, _) = nns::governance::propose_to_deploy_sns_and_wait( + &pocket_ic, + create_service_nervous_system, + sns_instance_label, + ) + .await; + + sns::swap::await_swap_lifecycle(&pocket_ic, sns.swap.canister_id, Lifecycle::Open) + .await + .unwrap(); + sns::swap::smoke_test_participate_and_finalize( + &pocket_ic, + sns.swap.canister_id, + swap_parameters, + ) + .await; + + sns + }; + + let store_canister_id = if store_same_as_target { + target_canister_id + } else { + install_canister_on_subnet( + &pocket_ic, + app_subnet, + vec![], + None, + vec![sns.root.canister_id], + ) + .await + }; + + let new_wasm = { + let new_wasm_bytes = modify_wasm_bytes(&original_wasm.bytes(), 42); + Wasm::from_bytes(&new_wasm_bytes[..]) + }; + let new_wasm_hash = new_wasm.sha256_hash(); + + // Smoke test + assert_ne!(new_wasm_hash, original_wasm_hash); + + // WASM with 15_843_866 bytes (`image-classification.wasm.gz`) is split into 1 MiB chunks. + let num_chunks_expected = 16; + + let chunk_hashes_list = upload_wasm_as_chunks( + &pocket_ic, + sns.root.canister_id.into(), + store_canister_id.into(), + new_wasm, + num_chunks_expected, + ) + .await; + + // 2. Run code under test. + interim_sns_helpers::change_canister( + &pocket_ic, + sns.root.canister_id, + sns.governance.canister_id, + ChangeCanisterRequest { + stop_before_installing: true, + mode: CanisterInstallMode::Upgrade, + canister_id: target_canister_id, + // This is the old field being generalized. + wasm_module: vec![], + // This is the new field we want to test. + chunked_canister_wasm: Some(ChunkedCanisterWasm { + wasm_module_hash: new_wasm_hash.clone().to_vec(), + store_canister_id, + chunk_hashes_list, + }), + arg: vec![], + compute_allocation: None, + memory_allocation: None, + }, + ) + .await; + + // 3. Inspect the resulting state. + await_with_timeout( + &pocket_ic, + MIN_INSTALL_CHUNKED_CODE_TIME_SECONDS..MAX_INSTALL_CHUNKED_CODE_TIME_SECONDS, + |pocket_ic| async { + let status = pocket_ic + .canister_status(target_canister_id.into(), Some(sns.root.canister_id.into())) + .await; + status + .expect("canister status must be available") + .module_hash + }, + &Some(new_wasm_hash.to_vec()), + ) + .await + .unwrap(); +} diff --git a/rs/nervous_system/root/src/change_canister.rs b/rs/nervous_system/root/src/change_canister.rs index 8cddc7ebb92..e96dfefc4df 100644 --- a/rs/nervous_system/root/src/change_canister.rs +++ b/rs/nervous_system/root/src/change_canister.rs @@ -4,7 +4,10 @@ use dfn_core::api::CanisterId; #[cfg(target_arch = "wasm32")] use dfn_core::println; use ic_crypto_sha2::Sha256; -use ic_management_canister_types::{CanisterInstallMode, InstallCodeArgs, IC_00}; +use ic_management_canister_types::{ + CanisterInstallMode, CanisterInstallModeV2, ChunkHash, InstallChunkedCodeArgs, InstallCodeArgs, + IC_00, +}; use ic_nervous_system_clients::{ canister_id_record::CanisterIdRecord, canister_status::{ @@ -14,6 +17,23 @@ use ic_nervous_system_clients::{ use ic_nervous_system_runtime::Runtime; use serde::Serialize; +/// The structure allows reconstructing a potentially large WASM from chunks needed to upgrade or +/// reinstall some target canister. +#[derive(Clone, Debug, Eq, PartialEq, CandidType, Deserialize, Serialize)] +pub struct ChunkedCanisterWasm { + /// Check sum of the overall WASM to be reassembled from chunks. + pub wasm_module_hash: Vec, + + /// Indicates which canister stores the WASM chunks. The store canister must be on the same + /// subnet as the target canister (Root must be one of the controllers of both of them). + /// May be the same as the target canister ID. + pub store_canister_id: CanisterId, + + /// Specifies a list of hash values for the chunks that comprise this WASM. Must contain + /// at least one chunk. + pub chunk_hashes_list: Vec>, +} + /// Argument to the similarly-named methods on the NNS and SNS root canisters. #[derive(Clone, Eq, PartialEq, CandidType, Deserialize, Serialize)] pub struct ChangeCanisterRequest { @@ -44,6 +64,10 @@ pub struct ChangeCanisterRequest { #[serde(with = "serde_bytes")] pub wasm_module: Vec, + /// If the entire WASM does not into the 2 MiB ingress limit, then `new_canister_wasm` + /// should be empty, and this field should be set instead. + pub chunked_canister_wasm: Option, + /// The new canister args #[serde(with = "serde_bytes")] pub arg: Vec, @@ -68,6 +92,7 @@ impl ChangeCanisterRequest { .field("mode", &self.mode) .field("canister_id", &self.canister_id) .field("wasm_module_sha256", &format!("{:x?}", wasm_sha)) + .field("chunked_canister_wasm", &self.chunked_canister_wasm) .field("arg_sha256", &format!("{:x?}", arg_sha)) .field("compute_allocation", &self.compute_allocation) .field("memory_allocation", &self.memory_allocation) @@ -98,6 +123,7 @@ impl ChangeCanisterRequest { mode, canister_id, wasm_module: Vec::new(), + chunked_canister_wasm: None, arg: Encode!().unwrap(), compute_allocation: None, memory_allocation: None, @@ -114,6 +140,20 @@ impl ChangeCanisterRequest { self } + pub fn with_chunked_wasm( + mut self, + wasm_module_hash: Vec, + store_canister_id: CanisterId, + chunk_hashes_list: Vec>, + ) -> Self { + self.chunked_canister_wasm = Some(ChunkedCanisterWasm { + wasm_module_hash, + store_canister_id, + chunk_hashes_list, + }); + self + } + pub fn with_arg(mut self, arg: Vec) -> Self { self.arg = arg; self @@ -218,6 +258,8 @@ where } } + let request_str = format!("{:?}", request); + // Ship code to the canister. // // Note that there's no guarantee that the canister to install/reinstall/upgrade @@ -225,7 +267,7 @@ where // because there could be a concurrent request to restart it. This could be // guaranteed with a "stopped precondition" in the management canister, or // with some locking here. - let res = install_code(request.clone()).await; + let res = install_code(request).await; // For once, we don't want to unwrap the result here. The reason is that, if the // installation failed (e.g., the wasm was rejected because it's invalid), // then we want to restart the canister. So we just keep the res to be @@ -237,15 +279,21 @@ where } // Check the result of the install_code - res.map_err(|(rejection_code, message)| format!("Attempt to call install_code with request {request:?} failed with code {rejection_code:?}: {message}")) + res.map_err(|(rejection_code, message)| { + format!( + "Attempt to call install_code with request {request_str} failed with code \ + {rejection_code:?}: {message}" + ) + }) } -/// Calls the "install_code" method of the management canister. +/// Calls a function of the management canister to install the requested code. async fn install_code(request: ChangeCanisterRequest) -> ic_cdk::api::call::CallResult<()> { let ChangeCanisterRequest { mode, canister_id, wasm_module, + chunked_canister_wasm, arg, compute_allocation, memory_allocation, @@ -256,24 +304,51 @@ async fn install_code(request: ChangeCanisterRequest) -> ic_cdk::api::call::Call let canister_id = canister_id.get(); let sender_canister_version = Some(ic_cdk::api::canister_version()); - let install_code_args = InstallCodeArgs { - mode, - canister_id, - wasm_module, - arg, - compute_allocation, - memory_allocation, - sender_canister_version, - }; - // Warning: despite dfn_core::call returning a Result, it actually traps when - // the callee traps! Use the public cdk instead, which does not have this - // issue. - ic_cdk::api::call::call( - Principal::try_from(IC_00.get().as_slice()).unwrap(), - "install_code", - (&install_code_args,), - ) - .await + if let Some(ChunkedCanisterWasm { + wasm_module_hash, + store_canister_id, + chunk_hashes_list, + }) = chunked_canister_wasm + { + let target_canister = canister_id; + let store_canister = Some(store_canister_id.get()); + let chunk_hashes_list = chunk_hashes_list + .into_iter() + .map(|hash| ChunkHash { hash }) + .collect(); + let mode = CanisterInstallModeV2::from(mode); + let argument = InstallChunkedCodeArgs { + mode, + target_canister, + store_canister, + chunk_hashes_list, + wasm_module_hash, + arg, + sender_canister_version, + }; + ic_cdk::api::call::call( + Principal::try_from(IC_00.get().as_slice()).unwrap(), + "install_chunked_code", + (&argument,), + ) + .await + } else { + let argument = InstallCodeArgs { + mode, + canister_id, + wasm_module, + arg, + compute_allocation, + memory_allocation, + sender_canister_version, + }; + ic_cdk::api::call::call( + Principal::try_from(IC_00.get().as_slice()).unwrap(), + "install_code", + (&argument,), + ) + .await + } } pub async fn start_canister(canister_id: CanisterId) -> Result<(), (i32, String)> diff --git a/rs/nns/governance/src/proposals/install_code.rs b/rs/nns/governance/src/proposals/install_code.rs index 1211db9fdba..3b53094d2b8 100644 --- a/rs/nns/governance/src/proposals/install_code.rs +++ b/rs/nns/governance/src/proposals/install_code.rs @@ -110,6 +110,7 @@ impl InstallCode { arg, compute_allocation, memory_allocation, + chunked_canister_wasm: None, }) .map_err(|e| invalid_proposal_error(&format!("Failed to encode payload: {}", e))) } @@ -307,6 +308,7 @@ mod tests { arg: vec![4, 5, 6], compute_allocation: None, memory_allocation: None, + chunked_canister_wasm: None, } ); } @@ -375,6 +377,7 @@ mod tests { arg: vec![], compute_allocation: None, memory_allocation: None, + chunked_canister_wasm: None, } ); } diff --git a/rs/nns/handlers/root/impl/canister/root.did b/rs/nns/handlers/root/impl/canister/root.did index ee6ab152c0b..3e7099b6891 100644 --- a/rs/nns/handlers/root/impl/canister/root.did +++ b/rs/nns/handlers/root/impl/canister/root.did @@ -68,9 +68,16 @@ type ChangeCanisterControllersResult = variant { Err : ChangeCanisterControllersError; }; +type ChunkedCanisterWasm = record { + wasm_module_hash : blob; + store_canister_id : principal; + chunk_hashes_list : vec blob; +}; + type ChangeCanisterRequest = record { arg : blob; wasm_module : blob; + chunked_canister_wasm : opt ChunkedCanisterWasm; stop_before_installing : bool; mode : CanisterInstallMode; canister_id : principal; diff --git a/rs/nns/integration_tests/src/governance_upgrade.rs b/rs/nns/integration_tests/src/governance_upgrade.rs index 51f27993ad0..15d49a492c0 100644 --- a/rs/nns/integration_tests/src/governance_upgrade.rs +++ b/rs/nns/integration_tests/src/governance_upgrade.rs @@ -130,6 +130,7 @@ fn test_root_restarts_canister_during_upgrade_canister_with_stop_canister_timeou arg: vec![], compute_allocation: None, memory_allocation: None, + chunked_canister_wasm: None, }; let _: () = update_with_sender( diff --git a/rs/registry/admin/src/main.rs b/rs/registry/admin/src/main.rs index 4a5ca745546..c32e582296d 100644 --- a/rs/registry/admin/src/main.rs +++ b/rs/registry/admin/src/main.rs @@ -1022,6 +1022,7 @@ impl ProposalPayload for ProposeToChangeNnsCanisterCmd { arg, compute_allocation: self.compute_allocation.map(candid::Nat::from), memory_allocation: self.memory_allocation.map(candid::Nat::from), + chunked_canister_wasm: None, } } } diff --git a/rs/sns/integration_tests/src/root.rs b/rs/sns/integration_tests/src/root.rs index 65ab0246be6..7d240bd854b 100644 --- a/rs/sns/integration_tests/src/root.rs +++ b/rs/sns/integration_tests/src/root.rs @@ -317,6 +317,7 @@ fn test_root_restarts_governance_on_stop_canister_timeout() { arg: vec![], compute_allocation: None, memory_allocation: None, + chunked_canister_wasm: None, }; let _: () = update_with_sender( diff --git a/rs/sns/root/canister/root.did b/rs/sns/root/canister/root.did index bc3856b691d..352ee49fd64 100644 --- a/rs/sns/root/canister/root.did +++ b/rs/sns/root/canister/root.did @@ -43,9 +43,16 @@ type CanisterSummary = record { canister_id : opt principal; }; +type ChunkedCanisterWasm = record { + wasm_module_hash : blob; + store_canister_id : principal; + chunk_hashes_list : vec blob; +}; + type ChangeCanisterRequest = record { arg : blob; wasm_module : blob; + chunked_canister_wasm : opt ChunkedCanisterWasm; stop_before_installing : bool; mode : CanisterInstallMode; canister_id : principal; diff --git a/rs/types/management_canister_types/src/lib.rs b/rs/types/management_canister_types/src/lib.rs index e55a3d88925..0997a188ce3 100644 --- a/rs/types/management_canister_types/src/lib.rs +++ b/rs/types/management_canister_types/src/lib.rs @@ -1473,9 +1473,19 @@ impl From for CanisterInstallMode { /// The function is lossy, hence it should be avoided when possible. fn from(item: CanisterInstallModeV2) -> Self { match item { - CanisterInstallModeV2::Install => CanisterInstallMode::Install, - CanisterInstallModeV2::Reinstall => CanisterInstallMode::Reinstall, - CanisterInstallModeV2::Upgrade(_) => CanisterInstallMode::Upgrade, + CanisterInstallModeV2::Install => Self::Install, + CanisterInstallModeV2::Reinstall => Self::Reinstall, + CanisterInstallModeV2::Upgrade(_) => Self::Upgrade, + } + } +} + +impl From for CanisterInstallModeV2 { + fn from(item: CanisterInstallMode) -> Self { + match item { + CanisterInstallMode::Install => Self::Install, + CanisterInstallMode::Reinstall => Self::Reinstall, + CanisterInstallMode::Upgrade => Self::Upgrade(None), } } } From 1ed522a298b2c0f0bbe8b9ed2fce4f167730a841 Mon Sep 17 00:00:00 2001 From: Dragoljub Djuric Date: Wed, 8 Jan 2025 21:56:03 +0100 Subject: [PATCH 30/98] fix: Check hook status after an upgrade/reinstall/uninstall/install (#3195) Problem: @mraszyk pointed out [here](https://github.com/dfinity/portal/pull/3761#issuecomment-2478612486): > The hook should not run after an upgrade/reinstall/uninstall/install if the condition is not satisfied after the upgrade (although the condition was satisfied before the upgrade and the hook did not execute yet). Solution: This PR should enforce that the status of the hook condition is updated each time we `upgrade/reinstall/uninstall/install` code. --- .../src/execution_environment.rs | 3 +- .../src/execution_environment/tests.rs | 2 +- .../tests/canister_task.rs | 186 ++++- rs/replicated_state/src/canister_state.rs | 13 + .../src/canister_state/execution_state.rs | 9 +- .../src/canister_state/system_state.rs | 646 ++--------------- .../canister_state/system_state/task_queue.rs | 672 ++++++++++++++++++ rs/system_api/src/lib.rs | 4 +- .../src/sandbox_safe_system_state.rs | 52 +- 9 files changed, 930 insertions(+), 657 deletions(-) create mode 100644 rs/replicated_state/src/canister_state/system_state/task_queue.rs diff --git a/rs/execution_environment/src/execution_environment.rs b/rs/execution_environment/src/execution_environment.rs index 2b85298c2bb..0733c850446 100644 --- a/rs/execution_environment/src/execution_environment.rs +++ b/rs/execution_environment/src/execution_environment.rs @@ -3070,7 +3070,7 @@ impl ExecutionEnvironment { let execution_duration = since.elapsed().as_secs_f64(); match dts_result { DtsInstallCodeResult::Finished { - canister, + mut canister, mut message, call_id, instructions_used, @@ -3108,6 +3108,7 @@ impl ExecutionEnvironment { Err(err.into()) } }; + canister.update_on_low_wasm_memory_hook_condition(); state.put_canister_state(canister); let refund = message.take_cycles(); // The message can be removed because a response was produced. diff --git a/rs/execution_environment/src/execution_environment/tests.rs b/rs/execution_environment/src/execution_environment/tests.rs index fa67aa3417c..cf6f4a41c3e 100644 --- a/rs/execution_environment/src/execution_environment/tests.rs +++ b/rs/execution_environment/src/execution_environment/tests.rs @@ -713,7 +713,7 @@ fn get_canister_status_from_another_canister_when_memory_low() { let controller = test.universal_canister().unwrap(); let binary = wat::parse_str("(module)").unwrap(); let canister = test.create_canister(Cycles::new(1_000_000_000_000)); - let memory_allocation = NumBytes::from(158); + let memory_allocation = NumBytes::from(300); test.install_canister_with_allocation(canister, binary, None, Some(memory_allocation.get())) .unwrap(); let canister_status_args = Encode!(&CanisterIdRecord::from(canister)).unwrap(); diff --git a/rs/execution_environment/src/execution_environment/tests/canister_task.rs b/rs/execution_environment/src/execution_environment/tests/canister_task.rs index 42aae83ac06..614a499aedf 100644 --- a/rs/execution_environment/src/execution_environment/tests/canister_task.rs +++ b/rs/execution_environment/src/execution_environment/tests/canister_task.rs @@ -2,6 +2,7 @@ use assert_matches::assert_matches; use ic_config::{execution_environment::Config as HypervisorConfig, subnet_config::SubnetConfig}; use ic_error_types::RejectCode; use ic_management_canister_types::{CanisterSettingsArgsBuilder, CanisterStatusType}; +use ic_management_canister_types::{CanisterUpgradeOptions, WasmMemoryPersistence}; use ic_registry_subnet_type::SubnetType; use ic_replicated_state::canister_state::NextExecution; use ic_replicated_state::canister_state::WASM_PAGE_SIZE_IN_BYTES; @@ -823,6 +824,7 @@ fn global_timer_produces_transient_error_on_out_of_cycles() { fn get_wat_with_update_and_hook_mem_grow( update_grow_mem_size: i32, hook_grow_mem_size: i32, + with_enchanced_ortogonal_persistence: bool, ) -> String { let mut wat = r#" (module @@ -843,7 +845,17 @@ fn get_wat_with_update_and_hook_mem_grow( wat.push_str( r#"))) ) - (memory 1 20) + (memory 1 20)"#, + ); + if with_enchanced_ortogonal_persistence { + wat.push_str( + r#" + (@custom "icp:private enhanced-orthogonal-persistence" "") + "#, + ); + } + wat.push_str( + r#" )"#, ); wat @@ -856,7 +868,8 @@ fn on_low_wasm_memory_is_executed() { let update_grow_mem_size = 7; let hook_grow_mem_size = 5; - let wat = get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size); + let wat = + get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size, false); let canister_id = test.canister_from_wat(wat.as_str()).unwrap(); @@ -905,7 +918,8 @@ fn on_low_wasm_memory_is_executed_before_message() { let update_grow_mem_size = 7; let hook_grow_mem_size = 5; - let wat = get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size); + let wat = + get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size, false); let canister_id = test.canister_from_wat(wat.as_str()).unwrap(); @@ -955,6 +969,169 @@ fn on_low_wasm_memory_is_executed_before_message() { ); } +#[test] +fn on_low_wasm_memory_is_executed_after_upgrade_if_condition_holds() { + let mut test = ExecutionTestBuilder::new().with_manual_execution().build(); + + let update_grow_mem_size = 7; + let hook_grow_mem_size = 5; + + let wat: String = + get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size, true); + + let canister_id = test.canister_from_wat(wat.as_str()).unwrap(); + + test.canister_update_wasm_memory_limit_and_wasm_memory_threshold( + canister_id, + (20 * WASM_PAGE_SIZE_IN_BYTES as u64).into(), + (15 * WASM_PAGE_SIZE_IN_BYTES as u64).into(), + ) + .unwrap(); + + // Here we have: + // wasm_capacity = wasm_memory_limit = 20 Wasm Pages + // wasm_memory_threshold = 15 Wasm Pages + + // Initially wasm_memory.size = 1 + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(1) + ); + + test.ingress_raw(canister_id, "grow_mem", vec![]); + test.ingress_raw(canister_id, "grow_mem", vec![]); + + // First ingress messages gets executed. + // wasm_memory.size = 1 + 7 = 8 + // wasm_capacity - used_wasm_memory < self.wasm_memory_threshold + // Hook condition is triggered. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(8) + ); + + let result = test.upgrade_canister_v2( + canister_id, + wat::parse_str(wat).unwrap(), + CanisterUpgradeOptions { + skip_pre_upgrade: None, + wasm_memory_persistence: Some(WasmMemoryPersistence::Keep), + }, + ); + assert_eq!(result, Ok(())); + + // Upgrade is executed, and the wasm_memory size is unchanged. + // Hook condition is triggered. + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(8) + ); + + // Though we have the second ingress message awaiting to be processed, + // hook will be executed first. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(13) + ); + + // The second ingress message is executed after the hook. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(20) + ); +} + +#[test] +fn on_low_wasm_memory_is_not_executed_after_upgrade_if_condition_becomes_unsatisfied() { + let mut test = ExecutionTestBuilder::new().with_manual_execution().build(); + + let update_grow_mem_size = 3; + let hook_grow_mem_size = 5; + + let wat: String = + get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size, false); + + let canister_id = test.canister_from_wat(wat.as_str()).unwrap(); + + test.canister_update_wasm_memory_limit_and_wasm_memory_threshold( + canister_id, + (20 * WASM_PAGE_SIZE_IN_BYTES as u64).into(), + (15 * WASM_PAGE_SIZE_IN_BYTES as u64).into(), + ) + .unwrap(); + + // Here we have: + // wasm_capacity = wasm_memory_limit = 20 Wasm Pages + // wasm_memory_threshold = 15 Wasm Pages + + // Initially wasm_memory.size = 1 + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(1) + ); + + test.ingress_raw(canister_id, "grow_mem", vec![]); + test.ingress_raw(canister_id, "grow_mem", vec![]); + test.ingress_raw(canister_id, "grow_mem", vec![]); + + // First ingress messages gets executed. + // wasm_memory.size = 1 + 3 = 4 + // wasm_capacity - used_wasm_memory > self.wasm_memory_threshold + // Hook condition is not triggered. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(4) + ); + + // Second ingress messages gets executed. + // wasm_memory.size = 4 + 3 = 7 + // wasm_capacity - used_wasm_memory < self.wasm_memory_threshold + // Hook condition is triggered. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(7) + ); + println!("canister upgrade"); + + let result = test.upgrade_canister_v2( + canister_id, + wat::parse_str(wat).unwrap(), + CanisterUpgradeOptions { + skip_pre_upgrade: None, + wasm_memory_persistence: None, + }, + ); + assert_eq!(result, Ok(())); + println!("canister upgrade"); + + // Upgrade is executed, and the wasm_memory size reset to 1. + // Hook condition is not triggered. + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(1) + ); + + // Though the hook was initially scheduled, it is now removed + // from queue, and the third ingress message will be executed. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(4) + ); + + // There are no messages left to be executed. + test.execute_slice(canister_id); + assert_eq!( + test.execution_state(canister_id).wasm_memory.size, + NumWasmPages::new(4) + ); +} + #[test] fn on_low_wasm_memory_is_executed_once() { let mut test = ExecutionTestBuilder::new().build(); @@ -962,7 +1139,8 @@ fn on_low_wasm_memory_is_executed_once() { let update_grow_mem_size = 7; let hook_grow_mem_size = 2; - let wat = get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size); + let wat = + get_wat_with_update_and_hook_mem_grow(update_grow_mem_size, hook_grow_mem_size, false); let canister_id = test.canister_from_wat(wat.as_str()).unwrap(); diff --git a/rs/replicated_state/src/canister_state.rs b/rs/replicated_state/src/canister_state.rs index 216f49763d0..2c094148a25 100644 --- a/rs/replicated_state/src/canister_state.rs +++ b/rs/replicated_state/src/canister_state.rs @@ -375,6 +375,13 @@ impl CanisterState { + self.system_state.snapshots_memory_usage } + /// Returns the amount of Wasm memory currently used by the canister in bytes. + pub fn wasm_memory_usage(&self) -> NumBytes { + self.execution_state + .as_ref() + .map_or(NumBytes::from(0), |es| es.wasm_memory_usage()) + } + /// Returns the amount of execution memory (heap, stable, globals, Wasm) /// currently used by the canister in bytes. pub fn execution_memory_usage(&self) -> NumBytes { @@ -564,6 +571,12 @@ impl CanisterState { .map_or(NumBytes::from(0), |es| es.heap_delta()) + self.system_state.wasm_chunk_store.heap_delta() } + + /// Updates status of `OnLowWasmMemory` hook. + pub fn update_on_low_wasm_memory_hook_condition(&mut self) { + self.system_state + .update_on_low_wasm_memory_hook_status(self.memory_usage(), self.wasm_memory_usage()); + } } /// The result of `next_execution()` function. diff --git a/rs/replicated_state/src/canister_state/execution_state.rs b/rs/replicated_state/src/canister_state/execution_state.rs index 3cecdb1f4ae..e97d5de520e 100644 --- a/rs/replicated_state/src/canister_state/execution_state.rs +++ b/rs/replicated_state/src/canister_state/execution_state.rs @@ -561,13 +561,18 @@ impl ExecutionState { self.exports.has_method(method) } + /// Returns the Wasm memory currently used by the `ExecutionState`. + pub fn wasm_memory_usage(&self) -> NumBytes { + num_bytes_try_from(self.wasm_memory.size) + .expect("could not convert from wasm memory number of pages to bytes") + } + /// Returns the memory currently used by the `ExecutionState`. pub fn memory_usage(&self) -> NumBytes { // We use 8 bytes per global. let globals_size_bytes = 8 * self.exported_globals.len() as u64; let wasm_binary_size_bytes = self.wasm_binary.binary.len() as u64; - num_bytes_try_from(self.wasm_memory.size) - .expect("could not convert from wasm memory number of pages to bytes") + self.wasm_memory_usage() + num_bytes_try_from(self.stable_memory.size) .expect("could not convert from stable memory number of pages to bytes") + NumBytes::from(globals_size_bytes) diff --git a/rs/replicated_state/src/canister_state/system_state.rs b/rs/replicated_state/src/canister_state/system_state.rs index c00f0ddafbc..ac6753b7e52 100644 --- a/rs/replicated_state/src/canister_state/system_state.rs +++ b/rs/replicated_state/src/canister_state/system_state.rs @@ -1,6 +1,11 @@ mod call_context_manager; +mod task_queue; pub mod wasm_chunk_store; +pub use self::task_queue::{ + is_low_wasm_memory_hook_condition_satisfied, OnLowWasmMemoryHookStatus, TaskQueue, +}; + use self::wasm_chunk_store::{WasmChunkStore, WasmChunkStoreMetadata}; pub use super::queues::memory_required_to_push_request; use super::queues::{can_push, CanisterInput}; @@ -13,9 +18,8 @@ use crate::{ }; pub use call_context_manager::{CallContext, CallContextAction, CallContextManager, CallOrigin}; use ic_base_types::NumSeconds; -use ic_config::flag_status::FlagStatus; use ic_error_types::RejectCode; -use ic_interfaces::execution_environment::{ExecutionRoundType, HypervisorError}; +use ic_interfaces::execution_environment::HypervisorError; use ic_logger::{error, ReplicaLogger}; use ic_management_canister_types::{ CanisterChange, CanisterChangeDetails, CanisterChangeOrigin, CanisterStatusType, @@ -279,294 +283,6 @@ impl CanisterHistory { } } -/// `TaskQueue` represents the implementation of queue structure for canister tasks satisfying the following conditions: -/// -/// 1. If there is a `Paused` or `Aborted` task it will be returned first. -/// 2. If an `OnLowWasmMemoryHook` is ready to be executed, it will be returned next. -/// 3. All other tasks will be returned based on the order in which they are added to the queue. -#[derive(Clone, Eq, PartialEq, Debug, Default)] -pub struct TaskQueue { - /// Keeps `PausedExecution`, or `PausedInstallCode`, or `AbortedExecution`, - /// or `AbortedInstallCode` task if there is one. - paused_or_aborted_task: Option, - - /// Status of low_on_wasm_memory hook execution. - on_low_wasm_memory_hook_status: OnLowWasmMemoryHookStatus, - - /// Queue of `Heartbeat` and `GlobalTimer` tasks. - queue: VecDeque, -} - -impl TaskQueue { - pub fn from_checkpoint( - queue: VecDeque, - on_low_wasm_memory_hook_status: OnLowWasmMemoryHookStatus, - canister_id: &CanisterId, - ) -> Self { - let mut mut_queue = queue; - - // Extraction of paused_or_aborted_task from queue will be removed in the follow-up EXC-1752 when - // we introduce CanisterStateBits version of TaskQueue, so the conversion will be implicit. - let paused_or_aborted_task = match mut_queue.front() { - Some(ExecutionTask::AbortedInstallCode { .. }) - | Some(ExecutionTask::PausedExecution { .. }) - | Some(ExecutionTask::PausedInstallCode(_)) - | Some(ExecutionTask::AbortedExecution { .. }) => mut_queue.pop_front(), - Some(ExecutionTask::OnLowWasmMemory) - | Some(ExecutionTask::Heartbeat) - | Some(ExecutionTask::GlobalTimer) - | None => None, - }; - - let queue = TaskQueue { - paused_or_aborted_task, - on_low_wasm_memory_hook_status, - queue: mut_queue, - }; - - // Because paused tasks are not allowed in checkpoint rounds when - // checking dts invariants that is equivalent to disabling dts. - queue.check_dts_invariants( - FlagStatus::Disabled, - ExecutionRoundType::CheckpointRound, - canister_id, - ); - - queue - } - - pub fn front(&self) -> Option<&ExecutionTask> { - self.paused_or_aborted_task.as_ref().or_else(|| { - if self.on_low_wasm_memory_hook_status.is_ready() { - Some(&ExecutionTask::OnLowWasmMemory) - } else { - self.queue.front() - } - }) - } - - pub fn pop_front(&mut self) -> Option { - self.paused_or_aborted_task.take().or_else(|| { - if self.on_low_wasm_memory_hook_status.is_ready() { - self.on_low_wasm_memory_hook_status = OnLowWasmMemoryHookStatus::Executed; - Some(ExecutionTask::OnLowWasmMemory) - } else { - self.queue.pop_front() - } - }) - } - - pub fn remove(&mut self, task: ExecutionTask) { - match task { - ExecutionTask::OnLowWasmMemory => { - self.on_low_wasm_memory_hook_status.update(false); - } - ExecutionTask::Heartbeat - | ExecutionTask::GlobalTimer - | ExecutionTask::AbortedInstallCode { .. } - | ExecutionTask::PausedExecution { .. } - | ExecutionTask::PausedInstallCode(_) - | ExecutionTask::AbortedExecution { .. } => unreachable!( - "Unsuccessful removal of the task {:?}. Removal of task from TaskQueue is only supported for OnLowWasmMemory type.", task - ), - }; - } - - pub fn enqueue(&mut self, task: ExecutionTask) { - match task { - ExecutionTask::AbortedInstallCode { .. } - | ExecutionTask::PausedExecution { .. } - | ExecutionTask::PausedInstallCode(_) - | ExecutionTask::AbortedExecution { .. } => { - debug_assert!(self.paused_or_aborted_task.is_none()); - self.paused_or_aborted_task = Some(task); - } - ExecutionTask::OnLowWasmMemory => { - self.on_low_wasm_memory_hook_status.update(true); - } - ExecutionTask::Heartbeat | ExecutionTask::GlobalTimer => self.queue.push_front(task), - }; - } - - pub fn is_empty(&self) -> bool { - self.paused_or_aborted_task.is_none() - && !self.on_low_wasm_memory_hook_status.is_ready() - && self.queue.is_empty() - } - - pub fn len(&self) -> usize { - self.queue.len() - + self.paused_or_aborted_task.as_ref().map_or(0, |_| 1) - + if self.on_low_wasm_memory_hook_status.is_ready() { - 1 - } else { - 0 - } - } - - /// peek_hook_status will be removed in the follow-up EXC-1752. - pub fn peek_hook_status(&self) -> OnLowWasmMemoryHookStatus { - self.on_low_wasm_memory_hook_status - } - - /// get_queue will be removed in the follow-up EXC-1752. - pub fn get_queue(&self) -> VecDeque { - let mut queue = self.queue.clone(); - if let Some(task) = self.paused_or_aborted_task.as_ref() { - queue.push_front(task.clone()); - } - queue - } - - /// `check_dts_invariants` should only be called after round execution. - /// - /// It checks that the following properties are satisfied: - /// 1. Heartbeat, GlobalTimer tasks exist only during the round and must not exist after the round. - /// 2. Paused executions can exist only in ordinary rounds (not checkpoint rounds). - /// 3. If deterministic time slicing is disabled, then there are no paused tasks. - /// Aborted tasks may still exist if DTS was disabled in recent checkpoints. - pub fn check_dts_invariants( - &self, - deterministic_time_slicing: FlagStatus, - current_round_type: ExecutionRoundType, - id: &CanisterId, - ) { - if let Some(paused_or_aborted_task) = &self.paused_or_aborted_task { - match paused_or_aborted_task { - ExecutionTask::PausedExecution { .. } | ExecutionTask::PausedInstallCode(_) => { - assert_eq!( - current_round_type, - ExecutionRoundType::OrdinaryRound, - "Unexpected paused execution {:?} after a checkpoint round in canister {:?}", - paused_or_aborted_task, - id - ); - - assert_eq!( - deterministic_time_slicing, - FlagStatus::Enabled, - "Unexpected paused execution {:?} with disabled DTS in canister: {:?}", - paused_or_aborted_task, - id - ); - } - ExecutionTask::AbortedExecution { .. } - | ExecutionTask::AbortedInstallCode { .. } => {} - ExecutionTask::Heartbeat - | ExecutionTask::GlobalTimer - | ExecutionTask::OnLowWasmMemory => { - unreachable!( - "Unexpected on task type {:?} in TaskQueue::paused_or_aborted_task in canister {:?} .", paused_or_aborted_task, id - ) - } - } - } - - if let Some(task) = self.queue.front() { - match task { - ExecutionTask::Heartbeat => { - panic!( - "Unexpected heartbeat task after a round in canister {:?}", - id - ); - } - ExecutionTask::GlobalTimer => { - panic!( - "Unexpected global timer task after a round in canister {:?}", - id - ); - } - ExecutionTask::OnLowWasmMemory - | ExecutionTask::AbortedExecution { .. } - | ExecutionTask::AbortedInstallCode { .. } - | ExecutionTask::PausedExecution { .. } - | ExecutionTask::PausedInstallCode(_) => { - unreachable!( - "Unexpected task type {:?} in TaskQueue::queue, after a round in canister {:?}", task, id - ); - } - } - } - } - - /// Removes aborted install code task. - pub fn remove_aborted_install_code_task(&mut self) { - if let Some(ExecutionTask::AbortedInstallCode { .. }) = &self.paused_or_aborted_task { - self.paused_or_aborted_task = None; - } - } - - /// Removes `Heartbeat` and `GlobalTimer` tasks. - pub fn remove_heartbeat_and_global_timer(&mut self) { - for task in self.queue.iter() { - debug_assert!( - *task == ExecutionTask::Heartbeat || *task == ExecutionTask::GlobalTimer, - "Unexpected task type {:?} in TaskQueue::queue.", - task - ); - } - - self.queue.clear(); - } - - /// Returns `PausedExecution` or `PausedInstallCode` task. - pub fn get_paused_task(&self) -> Option<&ExecutionTask> { - if let Some(task) = &self.paused_or_aborted_task { - match task { - ExecutionTask::PausedExecution { .. } | ExecutionTask::PausedInstallCode(_) => { - Some(task) - } - ExecutionTask::AbortedExecution { .. } - | ExecutionTask::AbortedInstallCode { .. } => None, - ExecutionTask::Heartbeat - | ExecutionTask::GlobalTimer - | ExecutionTask::OnLowWasmMemory => unreachable!( - "Unexpected on task type in the in TaskQueue::paused_or_aborted_task." - ), - } - } else { - None - } - } - - /// Replace `PausedExecution` or `PausedInstallCode` with corresponding - /// `AbortedExecution` or `AbortedInstallCode` respectively. - pub fn replace_paused_with_aborted_task(&mut self, aborted_task: ExecutionTask) { - match &aborted_task { - ExecutionTask::AbortedExecution { .. } => assert!( - matches!( - self.paused_or_aborted_task, - Some(ExecutionTask::PausedExecution { .. }) - ), - "Received aborted task {:?} is not compatible with paused task {:?}.", - aborted_task, - self.paused_or_aborted_task - ), - ExecutionTask::AbortedInstallCode { .. } => assert!( - matches!( - self.paused_or_aborted_task, - Some(ExecutionTask::PausedInstallCode(_)) - ), - "Received aborted task {:?} is not compatible with paused task {:?}.", - aborted_task, - self.paused_or_aborted_task - ), - ExecutionTask::Heartbeat - | ExecutionTask::GlobalTimer - | ExecutionTask::OnLowWasmMemory - | ExecutionTask::PausedExecution { .. } - | ExecutionTask::PausedInstallCode(_) => { - unreachable!( - "Unexpected task type {:?} of the aborted task.", - aborted_task - ) - } - }; - - self.paused_or_aborted_task = Some(aborted_task); - } -} - /// State that is controlled and owned by the system (IC). /// /// Contains structs needed for running and maintaining the canister on the IC. @@ -682,65 +398,6 @@ pub struct SystemState { pub snapshots_memory_usage: NumBytes, } -/// A wrapper around the different statuses of `OnLowWasmMemory` hook execution. -#[derive(Clone, Copy, Eq, PartialEq, Debug, Default, Deserialize, Serialize)] -pub enum OnLowWasmMemoryHookStatus { - #[default] - ConditionNotSatisfied, - Ready, - Executed, -} - -impl OnLowWasmMemoryHookStatus { - fn update(&mut self, is_hook_condition_satisfied: bool) { - *self = if is_hook_condition_satisfied { - match *self { - Self::ConditionNotSatisfied | Self::Ready => Self::Ready, - Self::Executed => Self::Executed, - } - } else { - Self::ConditionNotSatisfied - }; - } - - fn is_ready(&self) -> bool { - *self == Self::Ready - } -} - -impl From<&OnLowWasmMemoryHookStatus> for pb::OnLowWasmMemoryHookStatus { - fn from(item: &OnLowWasmMemoryHookStatus) -> Self { - use OnLowWasmMemoryHookStatus::*; - - match *item { - ConditionNotSatisfied => Self::ConditionNotSatisfied, - Ready => Self::Ready, - Executed => Self::Executed, - } - } -} - -impl TryFrom for OnLowWasmMemoryHookStatus { - type Error = ProxyDecodeError; - - fn try_from(value: pb::OnLowWasmMemoryHookStatus) -> Result { - match value { - pb::OnLowWasmMemoryHookStatus::Unspecified => Err(ProxyDecodeError::ValueOutOfRange { - typ: "OnLowWasmMemoryHookStatus", - err: format!( - "Unexpected value of status of on low wasm memory hook: {:?}", - value - ), - }), - pb::OnLowWasmMemoryHookStatus::ConditionNotSatisfied => { - Ok(OnLowWasmMemoryHookStatus::ConditionNotSatisfied) - } - pb::OnLowWasmMemoryHookStatus::Ready => Ok(OnLowWasmMemoryHookStatus::Ready), - pb::OnLowWasmMemoryHookStatus::Executed => Ok(OnLowWasmMemoryHookStatus::Executed), - } - } -} - /// A wrapper around the different canister statuses. #[derive(Clone, Eq, PartialEq, Debug)] pub enum CanisterStatus { @@ -2356,6 +2013,41 @@ impl SystemState { _ => None, } } + + /// Enqueues or removes `OnLowWasmMemory` task from `task_queue` + /// depending if the condition for `OnLowWasmMemoryHook` is satisfied: + /// + /// 1. In the case of `memory_allocation` + /// `wasm_memory_threshold >= min(memory_allocation - memory_usage_without_wasm_memory, wasm_memory_limit) - wasm_memory_usage` + /// 2. Without memory allocation + /// `wasm_memory_threshold >= wasm_memory_limit - wasm_memory_usage` + /// + /// Note: if `wasm_memory_limit` is not set, its default value is 4 GiB. + pub fn update_on_low_wasm_memory_hook_status( + &mut self, + memory_usage: NumBytes, + wasm_memory_usage: NumBytes, + ) { + let memory_allocation = match self.memory_allocation { + MemoryAllocation::Reserved(bytes) => Some(bytes), + MemoryAllocation::BestEffort => None, + }; + + let wasm_memory_limit = self.wasm_memory_limit; + let wasm_memory_threshold = self.wasm_memory_threshold; + + if is_low_wasm_memory_hook_condition_satisfied( + memory_usage, + wasm_memory_usage, + memory_allocation, + wasm_memory_limit, + wasm_memory_threshold, + ) { + self.task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + } else { + self.task_queue.remove(ExecutionTask::OnLowWasmMemory); + } + } } /// Implements memory limits verification for pushing a canister-to-canister @@ -2628,259 +2320,3 @@ pub mod testing { }; } } - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use crate::{ - canister_state::system_state::OnLowWasmMemoryHookStatus, - metadata_state::subnet_call_context_manager::InstallCodeCallId, ExecutionTask, - }; - - use super::{PausedExecutionId, TaskQueue}; - - use ic_test_utilities_types::messages::IngressBuilder; - use ic_types::{ - messages::{CanisterCall, CanisterMessageOrTask, CanisterTask}, - Cycles, - }; - #[test] - fn test_on_low_wasm_memory_hook_start_status_condition_not_satisfied() { - let mut status = OnLowWasmMemoryHookStatus::ConditionNotSatisfied; - status.update(false); - assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); - - let mut status = OnLowWasmMemoryHookStatus::ConditionNotSatisfied; - status.update(true); - assert_eq!(status, OnLowWasmMemoryHookStatus::Ready); - } - - #[test] - fn test_on_low_wasm_memory_hook_start_status_ready() { - let mut status = OnLowWasmMemoryHookStatus::Ready; - status.update(false); - assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); - - let mut status = OnLowWasmMemoryHookStatus::Ready; - status.update(true); - assert_eq!(status, OnLowWasmMemoryHookStatus::Ready); - } - - #[test] - fn test_on_low_wasm_memory_hook_start_status_executed() { - let mut status = OnLowWasmMemoryHookStatus::Executed; - status.update(false); - assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); - - let mut status = OnLowWasmMemoryHookStatus::Executed; - status.update(true); - assert_eq!(status, OnLowWasmMemoryHookStatus::Executed); - } - - #[test] - #[should_panic(expected = "Unexpected task type")] - fn test_replace_paused_with_aborted_task_heartbeat() { - let mut task_queue = TaskQueue::default(); - task_queue.replace_paused_with_aborted_task(ExecutionTask::Heartbeat); - } - - #[test] - #[should_panic(expected = "Unexpected task type")] - fn test_replace_paused_with_aborted_task_global_timer() { - let mut task_queue = TaskQueue::default(); - task_queue.replace_paused_with_aborted_task(ExecutionTask::GlobalTimer); - } - - #[test] - #[should_panic(expected = "Unexpected task type")] - fn test_replace_paused_with_aborted_task_on_low_wasm_memory() { - let mut task_queue = TaskQueue::default(); - task_queue.replace_paused_with_aborted_task(ExecutionTask::OnLowWasmMemory); - } - - #[test] - #[should_panic(expected = "Unexpected task type")] - fn test_replace_paused_with_aborted_task_on_paused_execution() { - let mut task_queue = TaskQueue::default(); - task_queue.replace_paused_with_aborted_task(ExecutionTask::PausedExecution { - id: PausedExecutionId(0), - input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), - }); - } - - #[test] - #[should_panic(expected = "Unexpected task type")] - fn test_replace_paused_with_aborted_task_on_paused_install_code() { - let mut task_queue = TaskQueue::default(); - task_queue.replace_paused_with_aborted_task(ExecutionTask::PausedInstallCode( - PausedExecutionId(0), - )); - } - - #[test] - #[should_panic(expected = "is not compatible with paused task")] - fn test_replace_paused_with_aborted_task_on_paused_install_code_aborted_execution() { - let mut task_queue = TaskQueue::default(); - task_queue.enqueue(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); - - task_queue.replace_paused_with_aborted_task(ExecutionTask::AbortedExecution { - input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), - prepaid_execution_cycles: Cycles::zero(), - }); - } - - #[test] - #[should_panic(expected = "is not compatible with paused task")] - fn test_replace_paused_with_aborted_task_on_paused_execution_aborted_install_code() { - let mut task_queue = TaskQueue::default(); - task_queue.enqueue(ExecutionTask::PausedExecution { - id: PausedExecutionId(0), - input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), - }); - - let ingress = Arc::new(IngressBuilder::new().method_name("test_ingress").build()); - - let aborted_install_code = ExecutionTask::AbortedInstallCode { - message: CanisterCall::Ingress(Arc::clone(&ingress)), - prepaid_execution_cycles: Cycles::new(1), - call_id: InstallCodeCallId::new(0), - }; - - task_queue.replace_paused_with_aborted_task(aborted_install_code); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_heartbeat() { - let mut task_queue = TaskQueue::default(); - task_queue.remove(ExecutionTask::Heartbeat); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_global_timer() { - let mut task_queue = TaskQueue::default(); - task_queue.remove(ExecutionTask::GlobalTimer); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_paused_install_code() { - let mut task_queue = TaskQueue::default(); - task_queue.remove(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_paused_execution() { - let mut task_queue = TaskQueue::default(); - task_queue.remove(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_aborted_install_code() { - let mut task_queue = TaskQueue::default(); - - let ingress = Arc::new(IngressBuilder::new().method_name("test_ingress").build()); - - task_queue.remove(ExecutionTask::AbortedInstallCode { - message: CanisterCall::Ingress(Arc::clone(&ingress)), - prepaid_execution_cycles: Cycles::new(1), - call_id: InstallCodeCallId::new(0), - }); - } - - #[test] - #[should_panic(expected = "Unsuccessful removal of the task")] - fn test_task_queue_remove_aborted_execution() { - let mut task_queue = TaskQueue::default(); - task_queue.remove(ExecutionTask::AbortedExecution { - input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), - prepaid_execution_cycles: Cycles::zero(), - }); - } - - #[test] - fn test_task_queue_remove_on_low_wasm_memory_hook() { - let mut task_queue = TaskQueue::default(); - assert!(task_queue.is_empty()); - - // Queue is empty, so remove should be no_op. - task_queue.remove(ExecutionTask::OnLowWasmMemory); - assert!(task_queue.is_empty()); - - // ExecutionTask::OnLowWasmMemory is added to queue. - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - assert_eq!(task_queue.len(), 1); - assert_eq!(task_queue.front(), Some(&ExecutionTask::OnLowWasmMemory)); - - // After removing queue is empty. - task_queue.remove(ExecutionTask::OnLowWasmMemory); - assert!(task_queue.is_empty()); - - // ExecutionTask::OnLowWasmMemory can be added to the queue again. - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - assert_eq!(task_queue.len(), 1); - assert_eq!(task_queue.front(), Some(&ExecutionTask::OnLowWasmMemory)); - } - - #[test] - fn test_task_queue_pop_front_on_low_wasm_memory() { - let mut task_queue = TaskQueue::default(); - - // `ExecutionTask::OnLowWasmMemory` is added to queue. - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - assert_eq!(task_queue.len(), 1); - - assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); - assert!(task_queue.is_empty()); - - // After `pop` of `OnLowWasmMemory` from queue `OnLowWasmMemoryHookStatus` - // will be `Executed` so `enqueue` of `OnLowWasmMemory` is no-op. - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - assert!(task_queue.is_empty()); - - // After removing `OnLowWasmMemory` from queue `OnLowWasmMemoryHookStatus` - // will become `ConditionNotSatisfied`. - task_queue.remove(ExecutionTask::OnLowWasmMemory); - assert!(task_queue.is_empty()); - - // So now `enqueue` of `OnLowWasmMemory` will set `OnLowWasmMemoryHookStatus` - // to `Ready`. - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - assert_eq!(task_queue.len(), 1); - - assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); - } - - #[test] - fn test_task_queue_test_enqueue() { - let mut task_queue = TaskQueue::default(); - assert!(task_queue.is_empty()); - - task_queue.enqueue(ExecutionTask::Heartbeat); - task_queue.enqueue(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); - task_queue.enqueue(ExecutionTask::GlobalTimer); - task_queue.enqueue(ExecutionTask::OnLowWasmMemory); - - assert!(!task_queue.is_empty()); - assert_eq!(task_queue.len(), 4); - - // Disregarding order of `enqueue` operations, if there is - // paused task, it should be returned the first. - assert_eq!( - task_queue.pop_front(), - Some(ExecutionTask::PausedInstallCode(PausedExecutionId(0))) - ); - - // Disregarding order of `enqueue` operations, if there is OnLowWasmMemory - // task, it should be returned right after paused or aborted task if there is one. - assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); - - // The rest of the tasks should be returned in the LIFO order. - assert_eq!(task_queue.pop_front(), Some(ExecutionTask::GlobalTimer)); - assert_eq!(task_queue.pop_front(), Some(ExecutionTask::Heartbeat)); - } -} diff --git a/rs/replicated_state/src/canister_state/system_state/task_queue.rs b/rs/replicated_state/src/canister_state/system_state/task_queue.rs new file mode 100644 index 00000000000..db5221e93a2 --- /dev/null +++ b/rs/replicated_state/src/canister_state/system_state/task_queue.rs @@ -0,0 +1,672 @@ +use crate::ExecutionTask; +use ic_config::flag_status::FlagStatus; +use ic_interfaces::execution_environment::ExecutionRoundType; +use ic_protobuf::proxy::ProxyDecodeError; +use ic_protobuf::state::canister_state_bits::v1 as pb; +use ic_types::CanisterId; +use ic_types::NumBytes; +use serde::{Deserialize, Serialize}; +use std::collections::VecDeque; + +/// A wrapper around the different statuses of `OnLowWasmMemory` hook execution. +#[derive(Clone, Copy, Eq, PartialEq, Debug, Default, Deserialize, Serialize)] +pub enum OnLowWasmMemoryHookStatus { + #[default] + ConditionNotSatisfied, + Ready, + Executed, +} + +impl OnLowWasmMemoryHookStatus { + pub(crate) fn update(&mut self, is_hook_condition_satisfied: bool) { + *self = if is_hook_condition_satisfied { + match *self { + Self::ConditionNotSatisfied | Self::Ready => Self::Ready, + Self::Executed => Self::Executed, + } + } else { + Self::ConditionNotSatisfied + }; + } + + fn is_ready(&self) -> bool { + *self == Self::Ready + } +} + +impl From<&OnLowWasmMemoryHookStatus> for pb::OnLowWasmMemoryHookStatus { + fn from(item: &OnLowWasmMemoryHookStatus) -> Self { + use OnLowWasmMemoryHookStatus::*; + + match *item { + ConditionNotSatisfied => Self::ConditionNotSatisfied, + Ready => Self::Ready, + Executed => Self::Executed, + } + } +} + +impl TryFrom for OnLowWasmMemoryHookStatus { + type Error = ProxyDecodeError; + + fn try_from(value: pb::OnLowWasmMemoryHookStatus) -> Result { + match value { + pb::OnLowWasmMemoryHookStatus::Unspecified => Err(ProxyDecodeError::ValueOutOfRange { + typ: "OnLowWasmMemoryHookStatus", + err: format!( + "Unexpected value of status of on low wasm memory hook: {:?}", + value + ), + }), + pb::OnLowWasmMemoryHookStatus::ConditionNotSatisfied => { + Ok(OnLowWasmMemoryHookStatus::ConditionNotSatisfied) + } + pb::OnLowWasmMemoryHookStatus::Ready => Ok(OnLowWasmMemoryHookStatus::Ready), + pb::OnLowWasmMemoryHookStatus::Executed => Ok(OnLowWasmMemoryHookStatus::Executed), + } + } +} + +/// `TaskQueue` represents the implementation of queue structure for canister tasks satisfying the following conditions: +/// +/// 1. If there is a `Paused` or `Aborted` task it will be returned first. +/// 2. If an `OnLowWasmMemoryHook` is ready to be executed, it will be returned next. +/// 3. All other tasks will be returned based on the order in which they are added to the queue. +#[derive(Clone, Eq, PartialEq, Debug, Default)] +pub struct TaskQueue { + /// Keeps `PausedExecution`, or `PausedInstallCode`, or `AbortedExecution`, + /// or `AbortedInstallCode` task if there is one. + paused_or_aborted_task: Option, + + /// Status of low_on_wasm_memory hook execution. + on_low_wasm_memory_hook_status: OnLowWasmMemoryHookStatus, + + /// Queue of `Heartbeat` and `GlobalTimer` tasks. + queue: VecDeque, +} + +impl TaskQueue { + pub fn from_checkpoint( + queue: VecDeque, + on_low_wasm_memory_hook_status: OnLowWasmMemoryHookStatus, + canister_id: &CanisterId, + ) -> Self { + let mut mut_queue = queue; + + // Extraction of paused_or_aborted_task from queue will be removed in the follow-up EXC-1752 when + // we introduce CanisterStateBits version of TaskQueue, so the conversion will be implicit. + let paused_or_aborted_task = match mut_queue.front() { + Some(ExecutionTask::AbortedInstallCode { .. }) + | Some(ExecutionTask::PausedExecution { .. }) + | Some(ExecutionTask::PausedInstallCode(_)) + | Some(ExecutionTask::AbortedExecution { .. }) => mut_queue.pop_front(), + Some(ExecutionTask::OnLowWasmMemory) + | Some(ExecutionTask::Heartbeat) + | Some(ExecutionTask::GlobalTimer) + | None => None, + }; + + let queue = TaskQueue { + paused_or_aborted_task, + on_low_wasm_memory_hook_status, + queue: mut_queue, + }; + + // Because paused tasks are not allowed in checkpoint rounds when + // checking dts invariants that is equivalent to disabling dts. + queue.check_dts_invariants( + FlagStatus::Disabled, + ExecutionRoundType::CheckpointRound, + canister_id, + ); + + queue + } + + pub fn front(&self) -> Option<&ExecutionTask> { + self.paused_or_aborted_task.as_ref().or_else(|| { + if self.on_low_wasm_memory_hook_status.is_ready() { + Some(&ExecutionTask::OnLowWasmMemory) + } else { + self.queue.front() + } + }) + } + + pub fn pop_front(&mut self) -> Option { + self.paused_or_aborted_task.take().or_else(|| { + if self.on_low_wasm_memory_hook_status.is_ready() { + self.on_low_wasm_memory_hook_status = OnLowWasmMemoryHookStatus::Executed; + Some(ExecutionTask::OnLowWasmMemory) + } else { + self.queue.pop_front() + } + }) + } + + pub fn remove(&mut self, task: ExecutionTask) { + match task { + ExecutionTask::OnLowWasmMemory => { + self.on_low_wasm_memory_hook_status.update(false); + } + ExecutionTask::Heartbeat + | ExecutionTask::GlobalTimer + | ExecutionTask::AbortedInstallCode { .. } + | ExecutionTask::PausedExecution { .. } + | ExecutionTask::PausedInstallCode(_) + | ExecutionTask::AbortedExecution { .. } => unreachable!( + "Unsuccessful removal of the task {:?}. Removal of task from TaskQueue is only supported for OnLowWasmMemory type.", task + ), + }; + } + + pub fn enqueue(&mut self, task: ExecutionTask) { + match task { + ExecutionTask::AbortedInstallCode { .. } + | ExecutionTask::PausedExecution { .. } + | ExecutionTask::PausedInstallCode(_) + | ExecutionTask::AbortedExecution { .. } => { + debug_assert!(self.paused_or_aborted_task.is_none()); + self.paused_or_aborted_task = Some(task); + } + ExecutionTask::OnLowWasmMemory => { + self.on_low_wasm_memory_hook_status.update(true); + } + ExecutionTask::Heartbeat | ExecutionTask::GlobalTimer => self.queue.push_front(task), + }; + } + + pub fn is_empty(&self) -> bool { + self.paused_or_aborted_task.is_none() + && !self.on_low_wasm_memory_hook_status.is_ready() + && self.queue.is_empty() + } + + pub fn len(&self) -> usize { + self.queue.len() + + self.paused_or_aborted_task.as_ref().map_or(0, |_| 1) + + if self.on_low_wasm_memory_hook_status.is_ready() { + 1 + } else { + 0 + } + } + + /// peek_hook_status will be removed in the follow-up EXC-1752. + pub fn peek_hook_status(&self) -> OnLowWasmMemoryHookStatus { + self.on_low_wasm_memory_hook_status + } + + /// get_queue will be removed in the follow-up EXC-1752. + pub fn get_queue(&self) -> VecDeque { + let mut queue = self.queue.clone(); + if let Some(task) = self.paused_or_aborted_task.as_ref() { + queue.push_front(task.clone()); + } + queue + } + + /// `check_dts_invariants` should only be called after round execution. + /// + /// It checks that the following properties are satisfied: + /// 1. Heartbeat, GlobalTimer tasks exist only during the round and must not exist after the round. + /// 2. Paused executions can exist only in ordinary rounds (not checkpoint rounds). + /// 3. If deterministic time slicing is disabled, then there are no paused tasks. + /// Aborted tasks may still exist if DTS was disabled in recent checkpoints. + pub fn check_dts_invariants( + &self, + deterministic_time_slicing: FlagStatus, + current_round_type: ExecutionRoundType, + id: &CanisterId, + ) { + if let Some(paused_or_aborted_task) = &self.paused_or_aborted_task { + match paused_or_aborted_task { + ExecutionTask::PausedExecution { .. } | ExecutionTask::PausedInstallCode(_) => { + assert_eq!( + current_round_type, + ExecutionRoundType::OrdinaryRound, + "Unexpected paused execution {:?} after a checkpoint round in canister {:?}", + paused_or_aborted_task, + id + ); + + assert_eq!( + deterministic_time_slicing, + FlagStatus::Enabled, + "Unexpected paused execution {:?} with disabled DTS in canister: {:?}", + paused_or_aborted_task, + id + ); + } + ExecutionTask::AbortedExecution { .. } + | ExecutionTask::AbortedInstallCode { .. } => {} + ExecutionTask::Heartbeat + | ExecutionTask::GlobalTimer + | ExecutionTask::OnLowWasmMemory => { + unreachable!( + "Unexpected on task type {:?} in TaskQueue::paused_or_aborted_task in canister {:?} .", paused_or_aborted_task, id + ) + } + } + } + + if let Some(task) = self.queue.front() { + match task { + ExecutionTask::Heartbeat => { + panic!( + "Unexpected heartbeat task after a round in canister {:?}", + id + ); + } + ExecutionTask::GlobalTimer => { + panic!( + "Unexpected global timer task after a round in canister {:?}", + id + ); + } + ExecutionTask::OnLowWasmMemory + | ExecutionTask::AbortedExecution { .. } + | ExecutionTask::AbortedInstallCode { .. } + | ExecutionTask::PausedExecution { .. } + | ExecutionTask::PausedInstallCode(_) => { + unreachable!( + "Unexpected task type {:?} in TaskQueue::queue, after a round in canister {:?}", task, id + ); + } + } + } + } + + /// Removes aborted install code task. + pub fn remove_aborted_install_code_task(&mut self) { + if let Some(ExecutionTask::AbortedInstallCode { .. }) = &self.paused_or_aborted_task { + self.paused_or_aborted_task = None; + } + } + + /// Removes `Heartbeat` and `GlobalTimer` tasks. + pub fn remove_heartbeat_and_global_timer(&mut self) { + for task in self.queue.iter() { + debug_assert!( + *task == ExecutionTask::Heartbeat || *task == ExecutionTask::GlobalTimer, + "Unexpected task type {:?} in TaskQueue::queue.", + task + ); + } + + self.queue.clear(); + } + + /// Returns `PausedExecution` or `PausedInstallCode` task. + pub fn get_paused_task(&self) -> Option<&ExecutionTask> { + if let Some(task) = &self.paused_or_aborted_task { + match task { + ExecutionTask::PausedExecution { .. } | ExecutionTask::PausedInstallCode(_) => { + Some(task) + } + ExecutionTask::AbortedExecution { .. } + | ExecutionTask::AbortedInstallCode { .. } => None, + ExecutionTask::Heartbeat + | ExecutionTask::GlobalTimer + | ExecutionTask::OnLowWasmMemory => unreachable!( + "Unexpected on task type in the in TaskQueue::paused_or_aborted_task." + ), + } + } else { + None + } + } + + /// Replace `PausedExecution` or `PausedInstallCode` with corresponding + /// `AbortedExecution` or `AbortedInstallCode` respectively. + pub fn replace_paused_with_aborted_task(&mut self, aborted_task: ExecutionTask) { + match &aborted_task { + ExecutionTask::AbortedExecution { .. } => assert!( + matches!( + self.paused_or_aborted_task, + Some(ExecutionTask::PausedExecution { .. }) + ), + "Received aborted task {:?} is not compatible with paused task {:?}.", + aborted_task, + self.paused_or_aborted_task + ), + ExecutionTask::AbortedInstallCode { .. } => assert!( + matches!( + self.paused_or_aborted_task, + Some(ExecutionTask::PausedInstallCode(_)) + ), + "Received aborted task {:?} is not compatible with paused task {:?}.", + aborted_task, + self.paused_or_aborted_task + ), + ExecutionTask::Heartbeat + | ExecutionTask::GlobalTimer + | ExecutionTask::OnLowWasmMemory + | ExecutionTask::PausedExecution { .. } + | ExecutionTask::PausedInstallCode(_) => { + unreachable!( + "Unexpected task type {:?} of the aborted task.", + aborted_task + ) + } + }; + + self.paused_or_aborted_task = Some(aborted_task); + } +} + +/// Condition for `OnLowWasmMemoryHook` is satisfied if the following holds: +/// +/// 1. In the case of `memory_allocation` +/// `wasm_memory_threshold >= min(memory_allocation - memory_usage_without_wasm_memory, wasm_memory_limit) - wasm_memory_usage` +/// 2. Without memory allocation +/// `wasm_memory_threshold >= wasm_memory_limit - wasm_memory_usage` +/// +/// Note: if `wasm_memory_limit` is not set, its default value is 4 GiB. +pub fn is_low_wasm_memory_hook_condition_satisfied( + memory_usage: NumBytes, + wasm_memory_usage: NumBytes, + memory_allocation: Option, + wasm_memory_limit: Option, + wasm_memory_threshold: NumBytes, +) -> bool { + // If wasm memory limit is not set, the default is 4 GiB. Wasm memory + // limit is ignored for query methods, response callback handlers, + // global timers, heartbeats, and canister pre_upgrade. + let wasm_memory_limit = + wasm_memory_limit.unwrap_or_else(|| NumBytes::new(4 * 1024 * 1024 * 1024)); + + debug_assert!( + wasm_memory_usage <= memory_usage, + "Wasm memory usage {} is greater that memory usage {}.", + wasm_memory_usage, + memory_usage + ); + + let memory_usage_without_wasm_memory = + NumBytes::new(memory_usage.get().saturating_sub(wasm_memory_usage.get())); + + // If the canister has memory allocation, then it maximum allowed Wasm memory can be calculated + // as min(memory_allocation - memory_usage_without_wasm_memory, wasm_memory_limit). + let wasm_capacity = memory_allocation.map_or_else( + || wasm_memory_limit, + |memory_allocation| { + debug_assert!( + memory_usage_without_wasm_memory <= memory_allocation, + "Used non-Wasm memory: {:?} is larger than memory allocation: {:?}.", + memory_usage_without_wasm_memory, + memory_allocation + ); + std::cmp::min( + memory_allocation - memory_usage_without_wasm_memory, + wasm_memory_limit, + ) + }, + ); + + // Conceptually we can think that the remaining Wasm memory is + // equal to `wasm_capacity - wasm_memory_usage` and that should + // be compared with `wasm_memory_threshold` when checking for + // the condition for the hook. However, since `wasm_memory_limit` + // is ignored in some executions as stated above it is possible + // that `wasm_memory_usage` is greater than `wasm_capacity` to + // avoid overflowing subtraction we adopted inequality. + wasm_capacity < wasm_memory_usage + wasm_memory_threshold +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use crate::{ + canister_state::system_state::OnLowWasmMemoryHookStatus, + metadata_state::subnet_call_context_manager::InstallCodeCallId, ExecutionTask, + }; + + use super::TaskQueue; + use crate::canister_state::system_state::PausedExecutionId; + use ic_test_utilities_types::messages::IngressBuilder; + use ic_types::{ + messages::{CanisterCall, CanisterMessageOrTask, CanisterTask}, + Cycles, + }; + + #[test] + fn test_on_low_wasm_memory_hook_start_status_condition_not_satisfied() { + let mut status = OnLowWasmMemoryHookStatus::ConditionNotSatisfied; + status.update(false); + assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); + + let mut status = OnLowWasmMemoryHookStatus::ConditionNotSatisfied; + status.update(true); + assert_eq!(status, OnLowWasmMemoryHookStatus::Ready); + } + + #[test] + fn test_on_low_wasm_memory_hook_start_status_ready() { + let mut status = OnLowWasmMemoryHookStatus::Ready; + status.update(false); + assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); + + let mut status = OnLowWasmMemoryHookStatus::Ready; + status.update(true); + assert_eq!(status, OnLowWasmMemoryHookStatus::Ready); + } + + #[test] + fn test_on_low_wasm_memory_hook_start_status_executed() { + let mut status = OnLowWasmMemoryHookStatus::Executed; + status.update(false); + assert_eq!(status, OnLowWasmMemoryHookStatus::ConditionNotSatisfied); + + let mut status = OnLowWasmMemoryHookStatus::Executed; + status.update(true); + assert_eq!(status, OnLowWasmMemoryHookStatus::Executed); + } + + #[test] + #[should_panic(expected = "Unexpected task type")] + fn test_replace_paused_with_aborted_task_heartbeat() { + let mut task_queue = TaskQueue::default(); + task_queue.replace_paused_with_aborted_task(ExecutionTask::Heartbeat); + } + + #[test] + #[should_panic(expected = "Unexpected task type")] + fn test_replace_paused_with_aborted_task_global_timer() { + let mut task_queue = TaskQueue::default(); + task_queue.replace_paused_with_aborted_task(ExecutionTask::GlobalTimer); + } + + #[test] + #[should_panic(expected = "Unexpected task type")] + fn test_replace_paused_with_aborted_task_on_low_wasm_memory() { + let mut task_queue = TaskQueue::default(); + task_queue.replace_paused_with_aborted_task(ExecutionTask::OnLowWasmMemory); + } + + #[test] + #[should_panic(expected = "Unexpected task type")] + fn test_replace_paused_with_aborted_task_on_paused_execution() { + let mut task_queue = TaskQueue::default(); + task_queue.replace_paused_with_aborted_task(ExecutionTask::PausedExecution { + id: PausedExecutionId(0), + input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), + }); + } + + #[test] + #[should_panic(expected = "Unexpected task type")] + fn test_replace_paused_with_aborted_task_on_paused_install_code() { + let mut task_queue = TaskQueue::default(); + task_queue.replace_paused_with_aborted_task(ExecutionTask::PausedInstallCode( + PausedExecutionId(0), + )); + } + + #[test] + #[should_panic(expected = "is not compatible with paused task")] + fn test_replace_paused_with_aborted_task_on_paused_install_code_aborted_execution() { + let mut task_queue = TaskQueue::default(); + task_queue.enqueue(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); + + task_queue.replace_paused_with_aborted_task(ExecutionTask::AbortedExecution { + input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), + prepaid_execution_cycles: Cycles::zero(), + }); + } + + #[test] + #[should_panic(expected = "is not compatible with paused task")] + fn test_replace_paused_with_aborted_task_on_paused_execution_aborted_install_code() { + let mut task_queue = TaskQueue::default(); + task_queue.enqueue(ExecutionTask::PausedExecution { + id: PausedExecutionId(0), + input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), + }); + + let ingress = Arc::new(IngressBuilder::new().method_name("test_ingress").build()); + + let aborted_install_code = ExecutionTask::AbortedInstallCode { + message: CanisterCall::Ingress(Arc::clone(&ingress)), + prepaid_execution_cycles: Cycles::new(1), + call_id: InstallCodeCallId::new(0), + }; + + task_queue.replace_paused_with_aborted_task(aborted_install_code); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_heartbeat() { + let mut task_queue = TaskQueue::default(); + task_queue.remove(ExecutionTask::Heartbeat); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_global_timer() { + let mut task_queue = TaskQueue::default(); + task_queue.remove(ExecutionTask::GlobalTimer); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_paused_install_code() { + let mut task_queue = TaskQueue::default(); + task_queue.remove(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_paused_execution() { + let mut task_queue = TaskQueue::default(); + task_queue.remove(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_aborted_install_code() { + let mut task_queue = TaskQueue::default(); + + let ingress = Arc::new(IngressBuilder::new().method_name("test_ingress").build()); + + task_queue.remove(ExecutionTask::AbortedInstallCode { + message: CanisterCall::Ingress(Arc::clone(&ingress)), + prepaid_execution_cycles: Cycles::new(1), + call_id: InstallCodeCallId::new(0), + }); + } + + #[test] + #[should_panic(expected = "Unsuccessful removal of the task")] + fn test_task_queue_remove_aborted_execution() { + let mut task_queue = TaskQueue::default(); + task_queue.remove(ExecutionTask::AbortedExecution { + input: CanisterMessageOrTask::Task(CanisterTask::Heartbeat), + prepaid_execution_cycles: Cycles::zero(), + }); + } + + #[test] + fn test_task_queue_remove_on_low_wasm_memory_hook() { + let mut task_queue = TaskQueue::default(); + assert!(task_queue.is_empty()); + + // Queue is empty, so remove should be no_op. + task_queue.remove(ExecutionTask::OnLowWasmMemory); + assert!(task_queue.is_empty()); + + // ExecutionTask::OnLowWasmMemory is added to queue. + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + assert_eq!(task_queue.len(), 1); + assert_eq!(task_queue.front(), Some(&ExecutionTask::OnLowWasmMemory)); + + // After removing queue is empty. + task_queue.remove(ExecutionTask::OnLowWasmMemory); + assert!(task_queue.is_empty()); + + // ExecutionTask::OnLowWasmMemory can be added to the queue again. + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + assert_eq!(task_queue.len(), 1); + assert_eq!(task_queue.front(), Some(&ExecutionTask::OnLowWasmMemory)); + } + + #[test] + fn test_task_queue_pop_front_on_low_wasm_memory() { + let mut task_queue = TaskQueue::default(); + + // `ExecutionTask::OnLowWasmMemory` is added to queue. + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + assert_eq!(task_queue.len(), 1); + + assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); + assert!(task_queue.is_empty()); + + // After `pop` of `OnLowWasmMemory` from queue `OnLowWasmMemoryHookStatus` + // will be `Executed` so `enqueue` of `OnLowWasmMemory` is no-op. + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + assert!(task_queue.is_empty()); + + // After removing `OnLowWasmMemory` from queue `OnLowWasmMemoryHookStatus` + // will become `ConditionNotSatisfied`. + task_queue.remove(ExecutionTask::OnLowWasmMemory); + assert!(task_queue.is_empty()); + + // So now `enqueue` of `OnLowWasmMemory` will set `OnLowWasmMemoryHookStatus` + // to `Ready`. + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + assert_eq!(task_queue.len(), 1); + + assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); + } + + #[test] + fn test_task_queue_test_enqueue() { + let mut task_queue = TaskQueue::default(); + assert!(task_queue.is_empty()); + + task_queue.enqueue(ExecutionTask::Heartbeat); + task_queue.enqueue(ExecutionTask::PausedInstallCode(PausedExecutionId(0))); + task_queue.enqueue(ExecutionTask::GlobalTimer); + task_queue.enqueue(ExecutionTask::OnLowWasmMemory); + + assert!(!task_queue.is_empty()); + assert_eq!(task_queue.len(), 4); + + // Disregarding order of `enqueue` operations, if there is + // paused task, it should be returned the first. + assert_eq!( + task_queue.pop_front(), + Some(ExecutionTask::PausedInstallCode(PausedExecutionId(0))) + ); + + // Disregarding order of `enqueue` operations, if there is OnLowWasmMemory + // task, it should be returned right after paused or aborted task if there is one. + assert_eq!(task_queue.pop_front(), Some(ExecutionTask::OnLowWasmMemory)); + + // The rest of the tasks should be returned in the LIFO order. + assert_eq!(task_queue.pop_front(), Some(ExecutionTask::GlobalTimer)); + assert_eq!(task_queue.pop_front(), Some(ExecutionTask::Heartbeat)); + } +} diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 4ba99460078..4a0c6575bc3 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -873,7 +873,7 @@ impl MemoryUsage { self.add_execution_memory(execution_bytes, execution_memory_type)?; - sandbox_safe_system_state.check_on_low_wasm_memory_hook_condition( + sandbox_safe_system_state.update_status_of_low_wasm_memory_hook_condition( None, self.wasm_memory_limit, self.current_usage, @@ -900,7 +900,7 @@ impl MemoryUsage { self.current_usage = NumBytes::from(new_usage); self.add_execution_memory(execution_bytes, execution_memory_type)?; - sandbox_safe_system_state.check_on_low_wasm_memory_hook_condition( + sandbox_safe_system_state.update_status_of_low_wasm_memory_hook_condition( Some(reserved_bytes), self.wasm_memory_limit, self.current_usage, diff --git a/rs/system_api/src/sandbox_safe_system_state.rs b/rs/system_api/src/sandbox_safe_system_state.rs index ba4da893c7d..174d671dcaa 100644 --- a/rs/system_api/src/sandbox_safe_system_state.rs +++ b/rs/system_api/src/sandbox_safe_system_state.rs @@ -16,7 +16,9 @@ use ic_management_canister_types::{ }; use ic_nns_constants::CYCLES_MINTING_CANISTER_ID; use ic_registry_subnet_type::SubnetType; -use ic_replicated_state::canister_state::system_state::CyclesUseCase; +use ic_replicated_state::canister_state::system_state::{ + is_low_wasm_memory_hook_condition_satisfied, CyclesUseCase, +}; use ic_replicated_state::canister_state::DEFAULT_QUEUE_CAPACITY; use ic_replicated_state::{CallOrigin, ExecutionTask, NetworkTopology, SystemState}; use ic_types::{ @@ -1270,55 +1272,21 @@ impl SandboxSafeSystemState { /// `wasm_memory_threshold >= wasm_memory_limit - wasm_memory_usage` /// /// Note: if `wasm_memory_limit` is not set, its default value is 4 GiB. - pub fn check_on_low_wasm_memory_hook_condition( + pub fn update_status_of_low_wasm_memory_hook_condition( &mut self, memory_allocation: Option, wasm_memory_limit: Option, memory_usage: NumBytes, wasm_memory_usage: NumBytes, ) { - // If wasm memory limit is not set, the default is 4 GiB. Wasm memory - // limit is ignored for query methods, response callback handlers, - // global timers, heartbeats, and canister pre_upgrade. - let wasm_memory_limit = - wasm_memory_limit.unwrap_or_else(|| NumBytes::new(4 * 1024 * 1024 * 1024)); - - debug_assert!( - wasm_memory_usage <= memory_usage, - "Wasm memory usage {} is greater that memory usage {}.", + let is_condition_satisfied = is_low_wasm_memory_hook_condition_satisfied( + memory_usage, wasm_memory_usage, - memory_usage - ); - - let memory_usage_without_wasm_memory = - NumBytes::new(memory_usage.get().saturating_sub(wasm_memory_usage.get())); - - // If the canister has memory allocation, then it maximum allowed Wasm memory can be calculated - // as min(memory_allocation - memory_usage_without_wasm_memory, wasm_memory_limit). - let wasm_capacity = memory_allocation.map_or_else( - || wasm_memory_limit, - |memory_allocation| { - debug_assert!( - memory_usage_without_wasm_memory <= memory_allocation, - "Used stable memory: {:?} is larger than memory allocation: {:?}.", - memory_usage_without_wasm_memory, - memory_allocation - ); - std::cmp::min( - memory_allocation - memory_usage_without_wasm_memory, - wasm_memory_limit, - ) - }, + memory_allocation, + wasm_memory_limit, + self.wasm_memory_threshold, ); - // Conceptually we can think that the remaining Wasm memory is - // equal to `wasm_capacity - wasm_memory_usage` and that should - // be compared with `wasm_memory_threshold` when checking for - // the condition for the hook. However, since `wasm_memory_limit` - // is ignored in some executions as stated above it is possible - // that `wasm_memory_usage` is greater than `wasm_capacity` to - // avoid overflowing subtraction we adopted inequality. - let is_condition_satisfied = wasm_capacity < wasm_memory_usage + self.wasm_memory_threshold; self.system_state_changes .on_low_wasm_memory_hook_condition_check_result = Some(is_condition_satisfied); } @@ -1602,7 +1570,7 @@ mod tests { let memory_usage = wasm_memory_usage + memory_usage_without_wasm_memory; - state.check_on_low_wasm_memory_hook_condition( + state.update_status_of_low_wasm_memory_hook_condition( memory_allocation.map(|m| m.into()), wasm_memory_limit.map(|m| m.into()), memory_usage.into(), From 36e2b45d4712908b8ddca1c05b50b8fc1d6562d1 Mon Sep 17 00:00:00 2001 From: Andrew Battat <113942931+andrewbattat@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:32:20 -0600 Subject: [PATCH 31/98] feat(node): Configuration revamp (SetupOS integration) (#3270) NODE-1360 The IC-OS tool has been created, but not yet used by the IC-OS: https://github.com/dfinity/ic/pull/1539 This PR integrates the config tool into SetupOS. The config tool is utilized for config sanitization, organization, and access. Note that the *old* config is still being passed to HostOS, so this PR should have no impact on HostOS or GuestOS --- .../components/misc/config/setupos/config.sh | 13 ++ .../setupos-scripts/check-config.sh | 37 ++++++ .../setupos-scripts/check-hardware.sh | 31 +---- .../setupos-scripts/check-network.sh | 47 +++---- .../components/setupos-scripts/config.service | 6 +- ic-os/components/setupos-scripts/config.sh | 121 ------------------ .../setupos-scripts/setup-hostos-config.sh | 64 ++++++--- ic-os/components/setupos-scripts/setupos.sh | 1 + ic-os/components/setupos.bzl | 4 +- ic-os/guestos/docs/Boot.adoc | 6 +- ic-os/guestos/docs/DiskLayout.adoc | 2 - ic-os/guestos/docs/README.adoc | 1 - ic-os/setupos/defs.bzl | 1 + rs/ic_os/config/BUILD.bazel | 4 + rs/ic_os/config/src/config_ini.rs | 5 +- rs/ic_os/config/src/lib.rs | 1 + rs/ic_os/config/src/main.rs | 39 +++--- rs/ic_os/network/src/lib.rs | 34 ++++- rs/ic_os/network/src/systemd.rs | 53 +++++++- rs/ic_os/os_tools/setupos_tool/src/main.rs | 93 ++++++-------- 20 files changed, 276 insertions(+), 287 deletions(-) create mode 100644 ic-os/components/misc/config/setupos/config.sh create mode 100644 ic-os/components/setupos-scripts/check-config.sh delete mode 100755 ic-os/components/setupos-scripts/config.sh diff --git a/ic-os/components/misc/config/setupos/config.sh b/ic-os/components/misc/config/setupos/config.sh new file mode 100644 index 00000000000..a16d9fcceba --- /dev/null +++ b/ic-os/components/misc/config/setupos/config.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Shared config utilities. + +# Retrieves a value from the config.json file using a JSON path. +# Arguments: +# $1 - JSON path to the desired value (e.g., '.icos_settings.nns_urls') +# Note: If the key is not found, this function will return null. +function get_config_value() { + local CONFIG_FILE="/var/ic/config/config.json" + local key=$1 + jq -r "${key}" "${CONFIG_FILE}" +} diff --git a/ic-os/components/setupos-scripts/check-config.sh b/ic-os/components/setupos-scripts/check-config.sh new file mode 100644 index 00000000000..06a61de1ce5 --- /dev/null +++ b/ic-os/components/setupos-scripts/check-config.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# check-config.sh verifies the existence of the configuration JSON file created by config.service, +# halting the installation if not found. + +set -o nounset +set -o pipefail + +SHELL="/bin/bash" +PATH="/sbin:/bin:/usr/sbin:/usr/bin" + +source /opt/ic/bin/functions.sh + +check_config_file() { + echo "* Checking Config..." + local CONFIG_FILE="/var/ic/config/config.json" + + if [ -f "${CONFIG_FILE}" ]; then + local config_contents=$(cat "${CONFIG_FILE}") + echo -e "Configuration file '${CONFIG_FILE}' exists.\n" + echo -e "File contents:\n${config_contents}" + else + local service_logs=$(journalctl -u config.service --no-pager) + local log_message="Error creating SetupOS configuration. Configuration file '${CONFIG_FILE}' does not exist.\n\nConfig.service logs:\n${service_logs}" + + log_and_halt_installation_on_error 1 "${log_message}" + fi +} + +# Establish run order +main() { + log_start "$(basename $0)" + check_config_file + log_end "$(basename $0)" +} + +main diff --git a/ic-os/components/setupos-scripts/check-hardware.sh b/ic-os/components/setupos-scripts/check-hardware.sh index 8bfd16a30e6..67261c63216 100644 --- a/ic-os/components/setupos-scripts/check-hardware.sh +++ b/ic-os/components/setupos-scripts/check-hardware.sh @@ -32,8 +32,6 @@ GEN2_MINIMUM_AGGREGATE_DISK_SIZE=32000000000000 GEN1_MINIMUM_DISK_SIZE=3200000000000 GEN1_MINIMUM_AGGREGATE_DISK_SIZE=32000000000000 -CONFIG_DIR="/var/ic/config" - function check_generation() { echo "* Checking Generation..." @@ -249,6 +247,7 @@ function verify_disks() { function verify_deployment_path() { echo "* Verifying deployment path..." + if [[ ${GENERATION} == 2 ]] && [[ ! -f "${CONFIG_DIR}/node_operator_private_key.pem" ]]; then echo -e "\n\n\n\n\n\n" echo -e "\033[1;31mWARNING: Gen2 hardware detected but no Node Operator Private Key found.\033[0m" @@ -261,33 +260,6 @@ function verify_deployment_path() { fi } -# TODO(NODE-1477): delete in configuration revamp integration -CONFIG="${CONFIG:=/var/ic/config/config.ini}" - -function read_variables() { - # Read limited set of keys. Be extra-careful quoting values as it could - # otherwise lead to executing arbitrary shell code! - while IFS="=" read -r key value; do - case "$key" in - "node_reward_type") node_reward_type="${value}" ;; - esac - done <"${CONFIG}" -} - -function validate_node_reward() { - read_variables - if [[ -z "$node_reward_type" ]]; then - echo "Node reward type is not set. Skipping validation." - return 0 - fi - - if [[ ! "$node_reward_type" =~ ^type[0-9]+(\.[0-9])?$ ]]; then - log_and_halt_installation_on_error 1 "Configuration error: node_reward_type is invalid: ${node_reward_type}" - fi - - echo "Valid node reward type: ${node_reward_type}" -} - # Establish run order main() { log_start "$(basename $0)" @@ -297,7 +269,6 @@ main() { verify_memory verify_disks verify_deployment_path - validate_node_reward else echo "* Hardware checks skipped by request via kernel command line" GENERATION=2 diff --git a/ic-os/components/setupos-scripts/check-network.sh b/ic-os/components/setupos-scripts/check-network.sh index 094cb5e6db4..0f06429318b 100755 --- a/ic-os/components/setupos-scripts/check-network.sh +++ b/ic-os/components/setupos-scripts/check-network.sh @@ -6,24 +6,16 @@ set -o pipefail SHELL="/bin/bash" PATH="/sbin:/bin:/usr/sbin:/usr/bin" +source /opt/ic/bin/config.sh source /opt/ic/bin/functions.sh -CONFIG="${CONFIG:=/var/ic/config/config.ini}" -DEPLOYMENT="${DEPLOYMENT:=/data/deployment.json}" - -function read_variables() { - # Read limited set of keys. Be extra-careful quoting values as it could - # otherwise lead to executing arbitrary shell code! - while IFS="=" read -r key value; do - case "$key" in - "ipv6_prefix") ipv6_prefix="${value}" ;; - "ipv6_gateway") ipv6_gateway="${value}" ;; - "ipv4_address") ipv4_address="${value}" ;; - "ipv4_prefix_length") ipv4_prefix_length="${value}" ;; - "ipv4_gateway") ipv4_gateway="${value}" ;; - "domain") domain="${value}" ;; - esac - done <"${CONFIG}" +function read_config_variables() { + ipv6_prefix=$(get_config_value '.network_settings.ipv6_config.Deterministic.prefix') + ipv6_gateway=$(get_config_value '.network_settings.ipv6_config.Deterministic.gateway') + ipv4_address=$(get_config_value '.network_settings.ipv4_config.address') + ipv4_prefix_length=$(get_config_value '.network_settings.ipv4_config.prefix_length') + ipv4_gateway=$(get_config_value '.network_settings.ipv4_config.gateway') + domain_name=$(get_config_value '.network_settings.domain_name') } # WARNING: Uses 'eval' for command execution. @@ -109,11 +101,13 @@ function print_network_settings() { echo "* Printing user defined network settings..." echo " IPv6 Prefix : ${ipv6_prefix}" echo " IPv6 Gateway: ${ipv6_gateway}" - if [[ -v ipv4_address && -n ${ipv4_address} && -v ipv4_prefix_length && -n ${ipv4_prefix_length} && -v ipv4_gateway && -n ${ipv4_gateway} && -v domain && -n ${domain} ]]; then + if [[ -n ${ipv4_address} && -n ${ipv4_prefix_length} && -n ${ipv4_gateway} ]]; then echo " IPv4 Address: ${ipv4_address}" echo " IPv4 Prefix Length: ${ipv4_prefix_length}" echo " IPv4 Gateway: ${ipv4_gateway}" - echo " Domain name : ${domain}" + fi + if [[ -n ${domain_name} ]]; then + echo " Domain name : ${domain_name}" fi echo " " @@ -134,10 +128,10 @@ function validate_domain_name() { local domain_part local -a domain_parts - IFS='.' read -ra domain_parts <<<"${domain}" + IFS='.' read -ra domain_parts <<<"${domain_name}" if [ ${#domain_parts[@]} -lt 2 ]; then - log_and_halt_installation_on_error 1 "Domain validation error: less than two domain parts in domain: ${domain}" + log_and_halt_installation_on_error 1 "Domain validation error: less than two domain parts in domain: ${domain_name}" fi for domain_part in "${domain_parts[@]}"; do @@ -184,17 +178,13 @@ function ping_ipv6_gateway() { echo " " } -function assemble_nns_nodes_list() { - NNS_URL_STRING=$(/opt/ic/bin/fetch-property.sh --key=.nns.url --config=${DEPLOYMENT}) - IFS=',' read -r -a NNS_URL_LIST <<<"$NNS_URL_STRING" -} - function query_nns_nodes() { echo "* Querying NNS nodes..." + local nns_url_list=($(get_config_value '.icos_settings.nns_urls' | jq -r '.[]')) local success=false - # At least one of the provided URLs needs to work. - for url in "${NNS_URL_LIST[@]}"; do + + for url in "${nns_url_list[@]}"; do # When running against testnets, we need to ignore self signed certs # with `--insecure`. This check is only meant to confirm from SetupOS # that NNS urls are reachable, so we do not mind that it is "weak". @@ -218,7 +208,7 @@ function query_nns_nodes() { main() { log_start "$(basename $0)" if kernel_cmdline_bool_default_true ic.setupos.check_network; then - read_variables + read_config_variables get_network_settings print_network_settings @@ -229,7 +219,6 @@ main() { fi ping_ipv6_gateway - assemble_nns_nodes_list query_nns_nodes else echo "* Network checks skipped by request via kernel command line" diff --git a/ic-os/components/setupos-scripts/config.service b/ic-os/components/setupos-scripts/config.service index 2db6cdf7dc0..f35bbae5eb3 100644 --- a/ic-os/components/setupos-scripts/config.service +++ b/ic-os/components/setupos-scripts/config.service @@ -6,9 +6,9 @@ Before=setupos.service [Service] Type=oneshot RemainAfterExit=true -ExecStart=/opt/ic/bin/output-wrapper.sh /dev/ttyS0 /opt/ic/bin/config.sh -StandardOutput=tty -StandardError=tty +ExecStart=/opt/ic/bin/config create-setupos-config +StandardOutput=journal+console +StandardError=journal+console [Install] WantedBy=multi-user.target diff --git a/ic-os/components/setupos-scripts/config.sh b/ic-os/components/setupos-scripts/config.sh deleted file mode 100755 index d4219d95637..00000000000 --- a/ic-os/components/setupos-scripts/config.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -CONFIG_DIR="/config" -CONFIG_TMP="/var/ic/config" -CONFIG_INI="${CONFIG_DIR}/config.ini" -CONFIG_INI_CLONE="${CONFIG_TMP}/config.ini" -SSH_AUTHORIZED_KEYS="${CONFIG_DIR}/ssh_authorized_keys" -SSH_AUTHORIZED_KEYS_CLONE="${CONFIG_TMP}/ssh_authorized_keys" - -source /opt/ic/bin/functions.sh - -# Define empty variables so they are not unset -ipv6_prefix="" -ipv6_gateway="" - -function print_config_file() { - if [ -e "${CONFIG_INI}" ]; then - echo "Found ${CONFIG_INI}. Contents:" - cat "${CONFIG_INI}" - else - log_and_halt_installation_on_error "1" "config.ini not found. Please copy a valid config.ini to the SetupOS installer config partition." - fi - -} - -function create_config_tmp() { - if [ ! -e "${CONFIG_TMP}" ]; then - # Create fresh config tmp directory - mkdir -p "${CONFIG_TMP}" - log_and_halt_installation_on_error "${?}" "Unable to create new '${CONFIG_TMP}' directory." - fi -} - -function clone_config() { - cp "${CONFIG_INI}" "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to copy 'config.ini' configuration file." - - if [ ! -f "${CONFIG_INI_CLONE}" ]; then - log_and_halt_installation_on_error "1" "Cloned 'config.ini' configuration file does not exist." - fi - - if [ -f "${CONFIG_DIR}/node_operator_private_key.pem" ]; then - cp ${CONFIG_DIR}/node_operator_private_key.pem ${CONFIG_TMP}/node_operator_private_key.pem - log_and_halt_installation_on_error "${?}" "Unable to copy 'node_operator_private_key.pem' configuration file." - fi - - if [ -d "${SSH_AUTHORIZED_KEYS}" ]; then - cp -r "${SSH_AUTHORIZED_KEYS}" "${CONFIG_TMP}" - log_and_halt_installation_on_error "${?}" "Unable to copy 'ssh_authorized_keys' directory." - else - log_and_halt_installation_on_error "1" "Unable to read 'ssh_authorized_keys' directory." - fi - - if [ ! -d "${SSH_AUTHORIZED_KEYS_CLONE}" ]; then - log_and_halt_installation_on_error "1" "Cloned 'ssh_authorized_keys' directory does not exist." - fi -} - -function normalize_config() { - CONFIG_VAR=$(cat "${CONFIG_INI_CLONE}" | tr '\r' '\n') - echo "${CONFIG_VAR}" >"${CONFIG_INI_CLONE}" - - sed -i 's/#.*$//g' "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to remove comments from 'config.ini'." - - sed -i 's/"//g' "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to replace double-quote characters in 'config.ini'." - - sed -i "s/'//g" "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to replace single-quote characters in 'config.ini'." - - sed -i 's/.*/\L&/' "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to convert upper- to lower-case in 'config.ini'." - - sed -i '/^$/d' "${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to remove empty lines in 'config.ini'." - - echo -e '\n' >>"${CONFIG_INI_CLONE}" - log_and_halt_installation_on_error "${?}" "Unable to inject extra new-line at the end of 'config.ini'." -} - -function read_variables() { - # Read limited set of keys. Be extra-careful quoting values as it could - # otherwise lead to executing arbitrary shell code! - while IFS="=" read -r key value; do - case "$key" in - "ipv6_prefix") ipv6_prefix="${value}" ;; - "ipv6_gateway") ipv6_gateway="${value}" ;; - esac - done <"${CONFIG_INI_CLONE}" -} - -function verify_variables() { - if [ -z "${ipv6_prefix}" ]; then - log_and_halt_installation_on_error "1" "Variable 'ipv6_prefix' is not defined in 'config.ini'." - fi - - if [ -z "${ipv6_gateway}" ]; then - log_and_halt_installation_on_error "1" "Variable 'ipv6_gateway' is not defined in 'config.ini'." - fi -} - -# Establish run order -main() { - log_start "$(basename $0)" - print_config_file - create_config_tmp - clone_config - normalize_config - read_variables - verify_variables - log_end "$(basename $0)" -} - -main diff --git a/ic-os/components/setupos-scripts/setup-hostos-config.sh b/ic-os/components/setupos-scripts/setup-hostos-config.sh index 0893a0c69aa..113e635e6cf 100755 --- a/ic-os/components/setupos-scripts/setup-hostos-config.sh +++ b/ic-os/components/setupos-scripts/setup-hostos-config.sh @@ -5,8 +5,9 @@ set -o pipefail SHELL="/bin/bash" PATH="/sbin:/bin:/usr/sbin:/usr/bin" -CONFIG_DIR="/var/ic/config" +CONFIG_DIR="/config" +source /opt/ic/bin/config.sh source /opt/ic/bin/functions.sh function mount_config_partition() { @@ -20,6 +21,7 @@ function mount_config_partition() { } function copy_config_files() { + # TODO(NODE-1518): delete config.ini copying after switch to new icos config echo "* Copying 'config.ini' to hostOS config partition..." if [ -f "${CONFIG_DIR}/config.ini" ]; then cp ${CONFIG_DIR}/config.ini /media/ @@ -28,29 +30,61 @@ function copy_config_files() { log_and_halt_installation_on_error "1" "Configuration file 'config.ini' does not exist." fi + # TODO(NODE-1518): delete deployment.json copying after switch to new icos config + echo "* Copying deployment.json to config partition..." + cp /data/deployment.json /media/ + log_and_halt_installation_on_error "${?}" "Unable to copy deployment.json to hostOS config partition." + echo "* Copying SSH authorized keys..." - if [ -d "${CONFIG_DIR}/ssh_authorized_keys" ]; then - cp -r ${CONFIG_DIR}/ssh_authorized_keys /media/ - log_and_halt_installation_on_error "${?}" "Unable to copy SSH authorized keys to hostOS config partition." + use_ssh_authorized_keys=$(get_config_value '.icos_settings.use_ssh_authorized_keys') + if [[ "${use_ssh_authorized_keys,,}" == "true" ]]; then + if [ -d "${CONFIG_DIR}/ssh_authorized_keys" ]; then + cp -a "${CONFIG_DIR}/ssh_authorized_keys" /media/ + log_and_halt_installation_on_error "${?}" "Unable to copy SSH authorized keys to hostOS config partition." + else + log_and_halt_installation_on_error "1" "use_ssh_authorized_keys set to true but not found" + fi else - log_and_halt_installation_on_error "1" "Directory 'ssh_authorized_keys' does not exist." + echo >&2 "SSH keys not in use." fi echo "* Copying node operator private key..." - if [ -f "${CONFIG_DIR}/node_operator_private_key.pem" ]; then - cp ${CONFIG_DIR}/node_operator_private_key.pem /media/ - log_and_halt_installation_on_error "${?}" "Unable to copy node operator private key to hostOS config partition." + use_node_operator_private_key=$(get_config_value '.icos_settings.use_node_operator_private_key') + if [[ "${use_node_operator_private_key,,}" == "true" ]]; then + if [ -f "${CONFIG_DIR}/node_operator_private_key.pem" ]; then + cp "${CONFIG_DIR}/node_operator_private_key.pem" /media/ + log_and_halt_installation_on_error "${?}" "Unable to copy node operator private key to hostOS config partition." + else + log_and_halt_installation_on_error "1" "use_node_operator_private_key set to true but not found" + fi else - echo "node_operator_private_key.pem does not exist, requiring HSM." + echo >&2 "Warning: node_operator_private_key.pem does not exist, requiring HSM." fi - echo "* Copying deployment.json to config partition..." - cp /data/deployment.json /media/ - log_and_halt_installation_on_error "${?}" "Unable to copy deployment.json to hostOS config partition." - echo "* Copying NNS public key to hostOS config partition..." - cp /data/nns_public_key.pem /media/ - log_and_halt_installation_on_error "${?}" "Unable to copy NNS public key to hostOS config partition." + use_nns_public_key=$(get_config_value '.icos_settings.use_nns_public_key') + if [[ "${use_nns_public_key,,}" == "true" ]]; then + if [ -f "/data/nns_public_key.pem" ]; then + cp /data/nns_public_key.pem /media/ + log_and_halt_installation_on_error "${?}" "Unable to copy NNS public key to hostOS config partition." + else + log_and_halt_installation_on_error "1" "use_nns_public_key set to true but not found." + fi + else + log_and_halt_installation_on_error "1" "use_nns_public_key must be set to true." + fi + + echo "* Converting 'config.json' to hostOS config file 'config-hostos.json'..." + /opt/ic/bin/config generate-hostos-config + log_and_halt_installation_on_error "${?}" "Unable to generate hostos configuration." + + echo "* Copying 'config-hostos.json' to hostOS config partition..." + if [ -f "/var/ic/config/config-hostos.json" ]; then + cp /var/ic/config/config-hostos.json /media/config.json + log_and_halt_installation_on_error "${?}" "Unable to copy 'config-hostos.json' to hostOS config partition." + else + log_and_halt_installation_on_error "1" "Configuration file 'config-hostos.json' does not exist." + fi } function insert_hsm_if_necessary() { diff --git a/ic-os/components/setupos-scripts/setupos.sh b/ic-os/components/setupos-scripts/setupos.sh index 70c860207bf..622dc3973fd 100755 --- a/ic-os/components/setupos-scripts/setupos.sh +++ b/ic-os/components/setupos-scripts/setupos.sh @@ -39,6 +39,7 @@ main() { log_start "$(basename $0)" start_setupos /opt/ic/bin/check-setupos-age.sh + /opt/ic/bin/check-config.sh /opt/ic/bin/check-hardware.sh /opt/ic/bin/check-network.sh if kernel_cmdline_bool_default_true ic.setupos.perform_installation; then diff --git a/ic-os/components/setupos.bzl b/ic-os/components/setupos.bzl index f5bf1323bef..b60e576cd8c 100644 --- a/ic-os/components/setupos.bzl +++ b/ic-os/components/setupos.bzl @@ -8,7 +8,7 @@ component_files = { # setupos-scripts Label("//ic-os/components/setupos-scripts:check-setupos-age.sh"): "/opt/ic/bin/check-setupos-age.sh", - Label("//ic-os/components/setupos-scripts:config.sh"): "/opt/ic/bin/config.sh", + Label("//ic-os/components/setupos-scripts:check-config.sh"): "/opt/ic/bin/check-config.sh", Label("//ic-os/components/setupos-scripts:setup-hostos-config.sh"): "/opt/ic/bin/setup-hostos-config.sh", Label("//ic-os/components/setupos-scripts:setup-disk.sh"): "/opt/ic/bin/setup-disk.sh", Label("//ic-os/components/setupos-scripts:functions.sh"): "/opt/ic/bin/functions.sh", @@ -31,9 +31,9 @@ component_files = { # misc Label("misc/logging.sh"): "/opt/ic/bin/logging.sh", + Label("misc/config/setupos/config.sh"): "/opt/ic/bin/config.sh", Label("misc/chrony/chrony.conf"): "/etc/chrony/chrony.conf", Label("misc/chrony/chrony-var.service"): "/etc/systemd/system/chrony-var.service", - Label("misc/fetch-property.sh"): "/opt/ic/bin/fetch-property.sh", Label("misc/serial-getty@/setupos/override.conf"): "/etc/systemd/system/serial-getty@.service.d/override.conf", Label("monitoring/journald.conf"): "/etc/systemd/journald.conf", diff --git a/ic-os/guestos/docs/Boot.adoc b/ic-os/guestos/docs/Boot.adoc index 6c94e394e59..bffa12bce7e 100644 --- a/ic-os/guestos/docs/Boot.adoc +++ b/ic-os/guestos/docs/Boot.adoc @@ -57,7 +57,7 @@ not held in +/etc/fstab+ but is generated by the shell script Afterwards, the first three partitions are mounted as +/boot/efi+, +/boot/grub+ and +/boot/config+, respectively. The +config+ partition is used as (small) store for data that is preserved across upgrades -and is available at early boot time already (see link:ConfigStore{outfilesuffix}[config store]). +and is available at early boot time already. == Save machine-id @@ -167,8 +167,8 @@ depends on mount of all filesystems. This is only executed once on first boot after provisioning. It looks for a "virtual USB stick" attached to the VM that contains a tar file with initial configuration -for parts of the system (see link:ConfigStore{outfilesuffix}[config store] for a description). Required -files in the +config+ partition as well as payload store are created. +for parts of the system. Required files in the +config+ partition as well as +payload store are created. == Deploy updated ssh account keys diff --git a/ic-os/guestos/docs/DiskLayout.adoc b/ic-os/guestos/docs/DiskLayout.adoc index 8a690680b9d..13dbcbd99f5 100644 --- a/ic-os/guestos/docs/DiskLayout.adoc +++ b/ic-os/guestos/docs/DiskLayout.adoc @@ -41,8 +41,6 @@ tampering). == *config* System config store Contains the config store persisted across system upgrades. -See link:ConfigStore{outfilesuffix}[config store] for a -specification of its contents. == *A_boot* / *B_boot* Boot partition for system A/B diff --git a/ic-os/guestos/docs/README.adoc b/ic-os/guestos/docs/README.adoc index 4caa2719d2c..92e95a07169 100644 --- a/ic-os/guestos/docs/README.adoc +++ b/ic-os/guestos/docs/README.adoc @@ -3,7 +3,6 @@ Refer to detailed documentation on: * link:DiskLayout{outfilesuffix}[Disk layout] -* link:ConfigStore{outfilesuffix}[GuestOS config store] * link:Boot{outfilesuffix}[Boot sequence] * link:SELinux{outfilesuffix}[SELinux security policy] * link:Interface{outfilesuffix}[GuestOS input/output interface] \ No newline at end of file diff --git a/ic-os/setupos/defs.bzl b/ic-os/setupos/defs.bzl index 325ebb995fa..6483645fd41 100644 --- a/ic-os/setupos/defs.bzl +++ b/ic-os/setupos/defs.bzl @@ -31,6 +31,7 @@ def image_deps(mode, _malicious = False): "bootfs": {}, "rootfs": { "//rs/ic_os/release:setupos_tool": "/opt/ic/bin/setupos_tool:0755", + "//rs/ic_os/release:config": "/opt/ic/bin/config:0755", }, # Set various configuration values diff --git a/rs/ic_os/config/BUILD.bazel b/rs/ic_os/config/BUILD.bazel index 57f6e9aed83..0207b75976d 100644 --- a/rs/ic_os/config/BUILD.bazel +++ b/rs/ic_os/config/BUILD.bazel @@ -35,6 +35,10 @@ rust_library( exclude = ["src/main.rs"], ), crate_name = "config", + visibility = [ + "//rs:ic-os-pkg", + "//rs:system-tests-pkg", + ], deps = DEPENDENCIES, ) diff --git a/rs/ic_os/config/src/config_ini.rs b/rs/ic_os/config/src/config_ini.rs index 12ea4b9f2b3..2c697d231fd 100644 --- a/rs/ic_os/config/src/config_ini.rs +++ b/rs/ic_os/config/src/config_ini.rs @@ -89,7 +89,10 @@ pub fn get_config_ini_settings(config_file_path: &Path) -> Result Result<()> { Some(Commands::CreateSetuposConfig { config_ini_path, deployment_json_path, - use_nns_public_key, - use_ssh_authorized_keys, - use_node_operator_private_key, setupos_config_json_path, }) => { // get config.ini settings @@ -209,25 +197,28 @@ pub fn main() -> Result<()> { let mgmt_mac = resolve_mgmt_mac(deployment_json_settings.deployment.mgmt_mac)?; - let node_reward_type = node_reward_type.expect("Node reward type is required."); - - let node_reward_type_pattern = Regex::new(r"^type[0-9]+(\.[0-9])?$")?; - if !node_reward_type_pattern.is_match(&node_reward_type) { - anyhow::bail!( - "Invalid node_reward_type '{}'. It must match the pattern ^type[0-9]+(\\.[0-9])?$", - node_reward_type - ); + if let Some(ref node_reward_type) = node_reward_type { + let node_reward_type_pattern = Regex::new(r"^type[0-9]+(\.[0-9])?$")?; + if !node_reward_type_pattern.is_match(node_reward_type) { + anyhow::bail!( + "Invalid node_reward_type '{}'. It must match the pattern ^type[0-9]+(\\.[0-9])?$", + node_reward_type + ); + } + } else { + println!("Node reward type is not set. Skipping validation."); } let icos_settings = ICOSSettings { - node_reward_type: Some(node_reward_type), + node_reward_type, mgmt_mac, deployment_environment: deployment_json_settings.deployment.name.parse()?, logging: Logging::default(), - use_nns_public_key, + use_nns_public_key: Path::new("/data/nns_public_key.pem").exists(), nns_urls: deployment_json_settings.nns.url.clone(), - use_node_operator_private_key, - use_ssh_authorized_keys, + use_node_operator_private_key: Path::new("/config/node_operator_private_key.pem") + .exists(), + use_ssh_authorized_keys: Path::new("/config/ssh_authorized_keys").exists(), icos_dev_settings: ICOSDevSettings::default(), }; diff --git a/rs/ic_os/network/src/lib.rs b/rs/ic_os/network/src/lib.rs index 6db2156fda2..dcb1f5fa5f6 100644 --- a/rs/ic_os/network/src/lib.rs +++ b/rs/ic_os/network/src/lib.rs @@ -1,10 +1,11 @@ use std::path::Path; use std::process::Command; -use anyhow::{Context, Result}; +use anyhow::{anyhow, Context, Result}; use regex::Regex; -use crate::systemd::generate_systemd_config_files; +use crate::systemd::{generate_systemd_config_files, generate_systemd_config_files_new_config}; +use config_types::{Ipv6Config, NetworkSettings}; use deterministic_ips::MacAddr6Ext; use info::NetworkInfo; use macaddr::MacAddr6; @@ -13,6 +14,35 @@ pub mod info; pub mod interfaces; pub mod systemd; +/// Write SetupOS or HostOS systemd network configuration. +/// Requires superuser permissions to run `ipmitool` and write to the systemd directory +/// TODO(NODE-1466): Consolidate generate_network_config_new_config and generate_network_config +pub fn generate_network_config_new_config( + network_settings: &NetworkSettings, + generated_mac: &MacAddr6, + output_directory: &Path, +) -> Result<()> { + eprintln!("Generating IPv6 address"); + + match &network_settings.ipv6_config { + Ipv6Config::RouterAdvertisement => { + Err(anyhow!("IC-OS router advertisement is not yet supported")) + } + Ipv6Config::Fixed(_) => Err(anyhow!("Fixed IP configuration is not yet supported")), + Ipv6Config::Deterministic(ipv6_config) => { + let ipv6_address = generated_mac.calculate_slaac(&ipv6_config.prefix)?; + eprintln!("Using IPv6 address: {ipv6_address}"); + + generate_systemd_config_files_new_config( + output_directory, + ipv6_config, + Some(generated_mac), + &ipv6_address, + ) + } + } +} + /// Write SetupOS or HostOS systemd network configuration. /// Requires superuser permissions to run `ipmitool` and write to the systemd directory pub fn generate_network_config( diff --git a/rs/ic_os/network/src/systemd.rs b/rs/ic_os/network/src/systemd.rs index f1b3a76364f..7e55c0b446b 100644 --- a/rs/ic_os/network/src/systemd.rs +++ b/rs/ic_os/network/src/systemd.rs @@ -1,3 +1,4 @@ +use std::cmp::Reverse; use std::fs::{create_dir_all, write}; use std::net::Ipv6Addr; use std::path::Path; @@ -7,6 +8,7 @@ use anyhow::{Context, Result}; use crate::info::NetworkInfo; use crate::interfaces::{get_interfaces, has_ipv6_connectivity, Interface}; +use config_types::DeterministicIpv6Config; use macaddr::MacAddr6; pub static DEFAULT_SYSTEMD_NETWORK_DIR: &str = "/run/systemd/network"; @@ -74,6 +76,54 @@ pub fn restart_systemd_networkd() { // Explicitly don't care about return code status... } +// TODO(NODE-1466): Consolidate generate_systemd_config_files_new_config and generate_and_write_systemd_files +pub fn generate_systemd_config_files_new_config( + output_directory: &Path, + ipv6_config: &DeterministicIpv6Config, + generated_mac: Option<&MacAddr6>, + ipv6_address: &Ipv6Addr, +) -> Result<()> { + let mut interfaces = get_interfaces()?; + interfaces.sort_by_key(|v| Reverse(v.speed_mbps)); + eprintln!("Interfaces sorted decending by speed: {:?}", interfaces); + + let ping_target = ipv6_config.gateway.to_string(); + + let fastest_interface = interfaces + .iter() + .find(|i| { + match has_ipv6_connectivity(i, ipv6_address, ipv6_config.prefix_length, &ping_target) { + Ok(result) => result, + Err(e) => { + eprintln!("Error testing connectivity on {}: {}", &i.name, e); + false + } + } + }) + .context("Could not find any network interfaces")?; + + eprintln!("Using fastest interface: {:?}", fastest_interface); + + // Format the IP address to include the subnet length. See `man systemd.network`. + let ipv6_address = format!( + "{}/{}", + &ipv6_address.to_string(), + ipv6_config.prefix_length + ); + generate_and_write_systemd_files( + output_directory, + fastest_interface, + generated_mac, + &ipv6_address, + &ipv6_config.gateway.to_string(), + )?; + + println!("Restarting systemd networkd"); + restart_systemd_networkd(); + + Ok(()) +} + fn generate_and_write_systemd_files( output_directory: &Path, interface: &Interface, @@ -120,8 +170,7 @@ pub fn generate_systemd_config_files( ipv6_address: &Ipv6Addr, ) -> Result<()> { let mut interfaces = get_interfaces()?; - interfaces.sort_by_key(|v| v.speed_mbps); - interfaces.reverse(); + interfaces.sort_by_key(|v| Reverse(v.speed_mbps)); eprintln!("Interfaces sorted decending by speed: {:?}", interfaces); let ping_target = network_info.ipv6_gateway.to_string(); diff --git a/rs/ic_os/os_tools/setupos_tool/src/main.rs b/rs/ic_os/os_tools/setupos_tool/src/main.rs index 06eb78cbd9a..0d7ea1aa2b3 100644 --- a/rs/ic_os/os_tools/setupos_tool/src/main.rs +++ b/rs/ic_os/os_tools/setupos_tool/src/main.rs @@ -1,16 +1,14 @@ use std::path::Path; -use anyhow::{anyhow, Context, Result}; +use anyhow::{anyhow, Result}; use clap::{Parser, Subcommand}; -use config::config_ini::config_map_from_path; -use config::deployment_json::get_deployment_settings; -use config::{DEFAULT_SETUPOS_CONFIG_INI_FILE_PATH, DEFAULT_SETUPOS_DEPLOYMENT_JSON_PATH}; +use config::{deserialize_config, DEFAULT_SETUPOS_CONFIG_OBJECT_PATH}; +use config_types::{Ipv6Config, SetupOSConfig}; use deterministic_ips::node_type::NodeType; use deterministic_ips::{calculate_deterministic_mac, IpVariant, MacAddr6Ext}; -use network::info::NetworkInfo; +use network::generate_network_config_new_config; use network::systemd::DEFAULT_SYSTEMD_NETWORK_DIR; -use network::{generate_network_config, resolve_mgmt_mac}; use utils::to_cidr; #[derive(Subcommand)] @@ -29,12 +27,8 @@ pub enum Commands { #[derive(Parser)] struct SetupOSArgs { - #[arg(short, long, default_value_t = DEFAULT_SETUPOS_CONFIG_INI_FILE_PATH.to_string(), value_name = "FILE")] - config: String, - - #[arg(short, long, default_value_t = DEFAULT_SETUPOS_DEPLOYMENT_JSON_PATH.to_string(), value_name = "FILE")] - /// deployment.json file path - deployment_file: String, + #[arg(short, long, default_value_t = DEFAULT_SETUPOS_CONFIG_OBJECT_PATH.to_string(), value_name = "FILE")] + setupos_config_object_path: String, #[command(subcommand)] command: Option, @@ -50,61 +44,56 @@ pub fn main() -> Result<()> { match opts.command { Some(Commands::GenerateNetworkConfig { output_directory }) => { - let config_map = config_map_from_path(Path::new(&opts.config)).context(format!( - "Failed to get config.ini settings for path: {}", - &opts.config - ))?; - eprintln!("Using config: {:?}", config_map); - - let network_info = NetworkInfo::from_config_map(&config_map)?; - eprintln!("Network info config: {:?}", &network_info); + let setupos_config: SetupOSConfig = + deserialize_config(&opts.setupos_config_object_path)?; - let deployment_settings = get_deployment_settings(Path::new(&opts.deployment_file)) - .context(format!( - "Failed to get deployment settings for file: {}", - &opts.deployment_file - ))?; - eprintln!("Deployment config: {:?}", deployment_settings); + eprintln!( + "Network settings config: {:?}", + &setupos_config.network_settings + ); - let mgmt_mac = resolve_mgmt_mac(deployment_settings.deployment.mgmt_mac)?; - let deployment_environment = deployment_settings.deployment.name.parse()?; let generated_mac = calculate_deterministic_mac( - &mgmt_mac, - deployment_environment, + &setupos_config.icos_settings.mgmt_mac, + setupos_config.icos_settings.deployment_environment, IpVariant::V6, NodeType::SetupOS, ); - eprintln!("Using generated mac (unformatted) {}", generated_mac); + eprintln!("Using generated mac {}", generated_mac); - generate_network_config(&network_info, &generated_mac, Path::new(&output_directory)) + generate_network_config_new_config( + &setupos_config.network_settings, + &generated_mac, + Path::new(&output_directory), + ) } Some(Commands::GenerateIpv6Address { node_type }) => { - let config_map = config_map_from_path(Path::new(&opts.config)).context(format!( - "Failed to get config.ini settings for path: {}", - &opts.config - ))?; - eprintln!("Using config: {:?}", config_map); - - let network_info = NetworkInfo::from_config_map(&config_map)?; - eprintln!("Network info config: {:?}", &network_info); + let setupos_config: SetupOSConfig = + deserialize_config(&opts.setupos_config_object_path)?; - let deployment_settings = get_deployment_settings(Path::new(&opts.deployment_file)) - .context(format!( - "Failed to get deployment settings for file: {}", - &opts.deployment_file - ))?; - eprintln!("Deployment config: {:?}", deployment_settings); + eprintln!( + "Network settings config: {:?}", + &setupos_config.network_settings + ); - let mgmt_mac = resolve_mgmt_mac(deployment_settings.deployment.mgmt_mac)?; - let deployment_environment = deployment_settings.deployment.name.parse()?; let generated_mac = calculate_deterministic_mac( - &mgmt_mac, - deployment_environment, + &setupos_config.icos_settings.mgmt_mac, + setupos_config.icos_settings.deployment_environment, IpVariant::V6, node_type, ); - let ipv6_address = generated_mac.calculate_slaac(&network_info.ipv6_prefix)?; - println!("{}", to_cidr(ipv6_address, network_info.ipv6_subnet)); + eprintln!("Using generated mac address {}", generated_mac); + + let Ipv6Config::Deterministic(ipv6_config) = + &setupos_config.network_settings.ipv6_config + else { + return Err(anyhow!( + "Ipv6Config is not of type Deterministic. Cannot generate IPv6 address." + )); + }; + + let ipv6_address = generated_mac.calculate_slaac(&ipv6_config.prefix)?; + println!("{}", to_cidr(ipv6_address, ipv6_config.prefix_length)); + Ok(()) } None => Err(anyhow!( From aa705aaa621c2e0d4f146f3a1de801edcb0fa0d5 Mon Sep 17 00:00:00 2001 From: Eero Kelly Date: Wed, 8 Jan 2025 16:55:10 -0800 Subject: [PATCH 32/98] feat: [NODE-1499] Run chown/chmod in setup-permissions in parallel (#3373) This further increases the speed of the [reboot toy](https://github.com/dfinity/ic/blob/36e2b45d4712908b8ddca1c05b50b8fc1d6562d1/rs/tests/node/BUILD.bazel#L31) from 56.578s to 33.395s. --- ic-os/components/ic/setup-permissions/erestorecon.sh | 2 +- ic-os/components/ic/setup-permissions/setup-permissions.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ic-os/components/ic/setup-permissions/erestorecon.sh b/ic-os/components/ic/setup-permissions/erestorecon.sh index 3cc9a4192e5..876c59f9af5 100755 --- a/ic-os/components/ic/setup-permissions/erestorecon.sh +++ b/ic-os/components/ic/setup-permissions/erestorecon.sh @@ -5,4 +5,4 @@ set -e # erestorecon (easy prestorecon) uses UNIX tools to parallelize restorecon, # instead of the cpp based prestorecon. -find $@ -print0 | xargs -0 -P 0 restorecon +find $@ -print0 | xargs -0 -P 0 restorecon -F diff --git a/ic-os/components/ic/setup-permissions/setup-permissions.sh b/ic-os/components/ic/setup-permissions/setup-permissions.sh index 8576d1e1e60..9b073af4954 100755 --- a/ic-os/components/ic/setup-permissions/setup-permissions.sh +++ b/ic-os/components/ic/setup-permissions/setup-permissions.sh @@ -24,8 +24,8 @@ function make_group_owned_and_sticky() { local GROUP="$3" mkdir -p "${TARGET_DIR}" - chown -R "${USER}:${GROUP}" "${TARGET_DIR}" - chmod u=rwX,g=rX,o= -R "${TARGET_DIR}" + find "${TARGET_DIR}" -print0 | xargs -0 -P 0 chown "${USER}:${GROUP}" + find "${TARGET_DIR}" -print0 | xargs -0 -P 0 chmod u=rwX,g=rX,o= find "${TARGET_DIR}" -type d | xargs chmod g+s } From dd459b9d5d37cd03bd4d25ca04089ba9a79fea11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20Tomi=C4=87?= Date: Thu, 9 Jan 2025 09:29:06 +0100 Subject: [PATCH 33/98] feat(NNS): compare node provider ID in addition to the operator when removing node directly (#3285) Specific error that this PR is trying to address, faced by one node provider who migrates from HSM to private-key operator identity: ![image](https://github.com/user-attachments/assets/c71c3e15-0266-4292-a1be-a8739731ea75) Both the node's old operator and the new one are in the same DC and under the same node provider, but the check is currently done on the operator level, which is too strict for this use case. --- rs/nns/test_utils/src/registry.rs | 31 ++- .../canister/src/common/test_helpers.rs | 17 +- .../get_node_providers_monthly_xdr_rewards.rs | 12 +- .../src/mutations/node_management/common.rs | 33 +++ .../do_remove_node_directly.rs | 221 +++++++++++++++++- rs/registry/canister/tests/remove_nodes.rs | 2 +- 6 files changed, 292 insertions(+), 24 deletions(-) diff --git a/rs/nns/test_utils/src/registry.rs b/rs/nns/test_utils/src/registry.rs index c6bf2cc68f7..5fc9befec5a 100644 --- a/rs/nns/test_utils/src/registry.rs +++ b/rs/nns/test_utils/src/registry.rs @@ -17,6 +17,7 @@ use ic_nervous_system_common_test_keys::{ }; use ic_protobuf::registry::{ crypto::v1::{PublicKey, X509PublicKeyCert}, + dc::v1::DataCenterRecord, node::v1::{ConnectionEndpoint, NodeRecord}, node_operator::v1::NodeOperatorRecord, replica_version::v1::{BlessedReplicaVersions, ReplicaVersionRecord}, @@ -30,8 +31,9 @@ use ic_registry_canister_api::AddNodePayload; use ic_registry_keys::{ make_blessed_replica_versions_key, make_catch_up_package_contents_key, make_crypto_node_key, make_crypto_threshold_signing_pubkey_key, make_crypto_tls_cert_key, - make_node_operator_record_key, make_node_record_key, make_replica_version_key, - make_routing_table_record_key, make_subnet_list_record_key, make_subnet_record_key, + make_data_center_record_key, make_node_operator_record_key, make_node_record_key, + make_replica_version_key, make_routing_table_record_key, make_subnet_list_record_key, + make_subnet_record_key, }; use ic_registry_routing_table::{CanisterIdRange, RoutingTable}; use ic_registry_subnet_type::SubnetType; @@ -43,7 +45,7 @@ use ic_registry_transport::{ }, serialize_get_value_request, Error, }; -use ic_test_utilities_types::ids::{subnet_test_id, user_test_id}; +use ic_test_utilities_types::ids::subnet_test_id; use ic_types::{ crypto::{ threshold_sig::ni_dkg::{NiDkgTag, NiDkgTargetId, NiDkgTranscript}, @@ -249,7 +251,7 @@ pub fn invariant_compliant_mutation_with_subnet_id( subnet_pid: SubnetId, chain_key_config: Option, ) -> Vec { - let node_operator_pid = user_test_id(TEST_ID); + let node_operator_pid = PrincipalId::new_user_test_id(1990); let (valid_pks, node_id) = new_node_keys_and_node_id(); @@ -270,7 +272,7 @@ pub fn invariant_compliant_mutation_with_subnet_id( port: 4321, }; NodeRecord { - node_operator_id: node_operator_pid.get().to_vec(), + node_operator_id: node_operator_pid.to_vec(), xnet: Some(xnet_connection_endpoint), http: Some(http_connection_endpoint), ..Default::default() @@ -395,11 +397,22 @@ pub fn new_node_crypto_keys_mutations( new_current_node_crypto_keys_mutations(node_id, current_npks) } +/// Make a `DataCenterRecord` with the provided `dc_id`. +pub fn make_data_center_record(dc_id: &str) -> DataCenterRecord { + DataCenterRecord { + id: dc_id.to_string(), + region: "Europe,ES,Barcelona".to_string(), + owner: "Jorge Gomez".to_string(), + ..Default::default() + } +} + /// Make a `NodeOperatorRecord` from the provided `PrincipalId`. -fn make_node_operator_record(principal_id: PrincipalId) -> NodeOperatorRecord { +fn make_node_operator_record(principal_id: PrincipalId, dc_id: &str) -> NodeOperatorRecord { NodeOperatorRecord { node_allowance: 1, node_operator_principal_id: principal_id.into(), + dc_id: dc_id.to_string(), ..Default::default() } } @@ -511,11 +524,15 @@ pub fn initial_mutations_for_a_multinode_nns_subnet() -> Vec { *TEST_USER6_PRINCIPAL, *TEST_USER7_PRINCIPAL, ] { - node_operator.push(make_node_operator_record(*principal_id)); + node_operator.push(make_node_operator_record(*principal_id, "dc1")); } let mut add_node_mutations = vec![]; let mut node_id = vec![]; + add_node_mutations.push(insert( + make_data_center_record_key("dc1").as_bytes(), + make_data_center_record("dc1").encode_to_vec(), + )); for nor in &node_operator { let (id, mut mutations) = get_new_node_id_and_mutations(nor, nns_subnet_id); node_id.push(id); diff --git a/rs/registry/canister/src/common/test_helpers.rs b/rs/registry/canister/src/common/test_helpers.rs index e3e5e6012b6..03c9c7345ed 100644 --- a/rs/registry/canister/src/common/test_helpers.rs +++ b/rs/registry/canister/src/common/test_helpers.rs @@ -91,11 +91,24 @@ pub fn get_invariant_compliant_subnet_record(node_ids: Vec) -> SubnetRec .into() } -/// Prepare a mutate request to add the desired of nodes, and returned the IDs +/// Prepare a mutate request to add the desired of number of nodes, and returned the IDs /// of the nodes to be added, together with their NI-DKG dealing encryption public keys. pub fn prepare_registry_with_nodes( start_mutation_id: u8, nodes: u64, +) -> (RegistryAtomicMutateRequest, BTreeMap) { + prepare_registry_with_nodes_and_node_operator_id( + start_mutation_id, + nodes, + PrincipalId::new_user_test_id(999), + ) +} + +/// Same as above, just with the possibility to provide a node operator principal. +pub fn prepare_registry_with_nodes_and_node_operator_id( + start_mutation_id: u8, + nodes: u64, + node_operator_id: PrincipalId, ) -> (RegistryAtomicMutateRequest, BTreeMap) { // Prepare a transaction to add the nodes to the registry let mut mutations = Vec::::default(); @@ -115,7 +128,7 @@ pub fn prepare_registry_with_nodes( ip_addr: format!("128.0.{effective_id}.1"), ..Default::default() }), - node_operator_id: PrincipalId::new_user_test_id(999).into_vec(), + node_operator_id: node_operator_id.into_vec(), // Preset this field to Some(), in order to allow seamless creation of ApiBoundaryNodeRecord if needed. domain: Some(format!("node{effective_id}.example.com")), ..Default::default() diff --git a/rs/registry/canister/src/get_node_providers_monthly_xdr_rewards.rs b/rs/registry/canister/src/get_node_providers_monthly_xdr_rewards.rs index 7c099c70621..cfdfd126b2c 100644 --- a/rs/registry/canister/src/get_node_providers_monthly_xdr_rewards.rs +++ b/rs/registry/canister/src/get_node_providers_monthly_xdr_rewards.rs @@ -107,11 +107,13 @@ mod tests { // Check invariants before applying mutations registry.maybe_apply_mutation_internal(mutations); - assert!(registry - .get_node_providers_monthly_xdr_rewards() - .unwrap() - .rewards - .is_empty()); + assert_eq!( + registry + .get_node_providers_monthly_xdr_rewards() + .unwrap() + .rewards, + std::collections::HashMap::new() + ); } fn registry_init_empty() -> Registry { diff --git a/rs/registry/canister/src/mutations/node_management/common.rs b/rs/registry/canister/src/mutations/node_management/common.rs index b4abb8e3c7c..579d752ef1e 100644 --- a/rs/registry/canister/src/mutations/node_management/common.rs +++ b/rs/registry/canister/src/mutations/node_management/common.rs @@ -80,6 +80,39 @@ pub fn get_node_operator_id_for_node( ) } +pub fn get_node_provider_id_for_operator_id( + registry: &Registry, + node_operator_id: PrincipalId, +) -> Result { + let node_operator_key = make_node_operator_record_key(node_operator_id); + registry + .get(node_operator_key.as_bytes(), registry.latest_version()) + .map_or( + Err(format!( + "Node Operator Id {:} not found in the registry.", + node_operator_key + )), + |result| { + PrincipalId::try_from( + NodeOperatorRecord::decode(result.value.as_slice()) + .map_err(|_| { + format!( + "Could not decode node_operator_record for Node Operator Id {}", + node_operator_id + ) + })? + .node_provider_principal_id, + ) + .map_err(|_| { + format!( + "Could not decode node_provider_id from the Node Operator Record for the Id {}", + node_operator_id + ) + }) + }, + ) +} + pub fn get_node_operator_record( registry: &Registry, node_operator_id: PrincipalId, diff --git a/rs/registry/canister/src/mutations/node_management/do_remove_node_directly.rs b/rs/registry/canister/src/mutations/node_management/do_remove_node_directly.rs index 4316efe65b1..1ead6617e4e 100644 --- a/rs/registry/canister/src/mutations/node_management/do_remove_node_directly.rs +++ b/rs/registry/canister/src/mutations/node_management/do_remove_node_directly.rs @@ -1,7 +1,7 @@ use crate::mutations::node_management::common::{ find_subnet_for_node, get_node_operator_id_for_node, get_node_operator_record, - get_subnet_list_record, make_remove_node_registry_mutations, - make_update_node_operator_mutation, + get_node_provider_id_for_operator_id, get_subnet_list_record, + make_remove_node_registry_mutations, make_update_node_operator_mutation, }; use crate::{common::LOG_PREFIX, registry::Registry}; use candid::{CandidType, Deserialize}; @@ -35,12 +35,56 @@ impl Registry { }) .unwrap(); - // 2. Get the caller ID and check that it matches the node's NO - assert_eq!( - node_operator_id, caller_id, - "The caller {}, does not match this Node's Operator id.", - caller_id - ); + // 2. Compare the caller_id (node operator) with the node's node operator and, if that fails, + // fall back to comparing the DC and the node provider ID for the caller and the node. + // That covers the case when the node provider added a new operator record in the same DC, and + // is trying to redeploy the nodes under the new operator. + // Hence, if the DC and the node provider of the caller and the original node operator match, + // the removal should succeed. + if caller_id != node_operator_id { + let node_operator_caller = get_node_operator_record(self, caller_id) + .map_err(|e| { + format!( + "{}do_remove_node_directly: Aborting node removal: {}", + LOG_PREFIX, e + ) + }) + .unwrap(); + let dc_caller = node_operator_caller.dc_id; + let dc_orig_node_operator = get_node_operator_record(self, node_operator_id) + .map_err(|e| { + format!( + "{}do_remove_node_directly: Aborting node removal: {}", + LOG_PREFIX, e + ) + }) + .unwrap() + .dc_id; + assert_eq!( + dc_caller, dc_orig_node_operator, + "The DC {} of the caller {}, does not match the DC of the node {}.", + dc_caller, caller_id, dc_orig_node_operator + ); + let node_provider_caller = get_node_provider_id_for_operator_id(self, caller_id) + .map_err(|e| { + format!( + "{}do_remove_node_directly: Aborting node removal: {}", + LOG_PREFIX, e + ) + }); + let node_provider_of_the_node = + get_node_provider_id_for_operator_id(self, node_operator_id).map_err(|e| { + format!( + "{}do_remove_node_directly: Aborting node removal: {}", + LOG_PREFIX, e + ) + }); + assert_eq!( + node_provider_caller, node_provider_of_the_node, + "The node provider {:?} of the caller {}, does not match the node provider {:?} of the node {}.", + node_provider_caller, caller_id, node_provider_of_the_node, payload.node_id + ); + } // 3. Ensure node is not in a subnet let subnet_list_record = get_subnet_list_record(self); @@ -115,7 +159,10 @@ mod tests { use prost::Message; use crate::{ - common::test_helpers::{invariant_compliant_registry, prepare_registry_with_nodes}, + common::test_helpers::{ + invariant_compliant_registry, prepare_registry_with_nodes, + prepare_registry_with_nodes_and_node_operator_id, + }, mutations::common::test::TEST_NODE_ID, }; @@ -184,4 +231,160 @@ mod tests { registry.do_remove_node(payload, node_operator_id); } + + #[test] + #[should_panic( + expected = "assertion `left == right` failed: The node provider Ok(5yckv-7nzbm-aaaaa-aaaap-4ai) of the caller ziab2-3ora4-aaaaa-aaaap-4ai, does not match the node provider Ok(ahdmd-q5ybm-aaaaa-aaaap-4ai) of the node" + )] + fn should_panic_different_caller() { + // This test is only added for backward compatibility. + // It should be removed once all tests are updated to include operator record. + let mut registry = invariant_compliant_registry(0); + let operator1_id = PrincipalId::new_user_test_id(2000); + let operator2_id = PrincipalId::new_user_test_id(2001); + let operator_record_1 = NodeOperatorRecord { + node_operator_principal_id: operator1_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3000).to_vec(), + dc_id: "dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + let operator_record_2 = NodeOperatorRecord { + node_operator_principal_id: operator2_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3001).to_vec(), + dc_id: "dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + registry.maybe_apply_mutation_internal(vec![ + insert( + make_node_operator_record_key(operator1_id), + operator_record_1.encode_to_vec(), + ), + insert( + make_node_operator_record_key(operator2_id), + operator_record_2.encode_to_vec(), + ), + ]); + // Add node owned by operator1 to registry + let (mutate_request, node_ids_and_dkg_pks) = + prepare_registry_with_nodes_and_node_operator_id( + 1, /* mutation id */ + 1, /* node count */ + operator1_id, + ); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + let node_id = node_ids_and_dkg_pks + .keys() + .next() + .expect("should contain at least one node ID") + .to_owned(); + + let payload = RemoveNodeDirectlyPayload { node_id }; + + registry.do_remove_node(payload, operator2_id); + } + + #[test] + fn should_succeed_remove_node_compare_dc_and_node_provider() { + let mut registry = invariant_compliant_registry(0); + // Add node operator1 and operator2 records, both under the same provider + let operator1_id = PrincipalId::new_user_test_id(2000); + let operator2_id = PrincipalId::new_user_test_id(2001); + let operator_record_1 = NodeOperatorRecord { + node_operator_principal_id: operator1_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3000).to_vec(), + dc_id: "dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + let operator_record_2 = NodeOperatorRecord { + node_operator_principal_id: operator2_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3000).to_vec(), + dc_id: "dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + registry.maybe_apply_mutation_internal(vec![ + insert( + make_node_operator_record_key(operator1_id), + operator_record_1.encode_to_vec(), + ), + insert( + make_node_operator_record_key(operator2_id), + operator_record_2.encode_to_vec(), + ), + ]); + // Add node owned by operator1 to registry + let (mutate_request, node_ids_and_dkg_pks) = + prepare_registry_with_nodes_and_node_operator_id( + 1, /* mutation id */ + 1, /* node count */ + operator1_id, + ); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + let node_id = node_ids_and_dkg_pks + .keys() + .next() + .expect("should contain at least one node ID") + .to_owned(); + + let payload = RemoveNodeDirectlyPayload { node_id }; + + // Should succeed because both operator1 and operator2 are under the same provider + registry.do_remove_node(payload, operator2_id); + } + + #[test] + #[should_panic( + expected = "assertion `left == right` failed: The DC not-dc1 of the caller ziab2-3ora4-aaaaa-aaaap-4ai, does not match the DC of the node dc1." + )] + fn should_panic_remove_node_different_dc() { + let mut registry = invariant_compliant_registry(0); + // Add node operator1 and operator2 records, both under the same provider + let operator1_id = PrincipalId::new_user_test_id(2000); + let operator2_id = PrincipalId::new_user_test_id(2001); + let operator_record_1 = NodeOperatorRecord { + node_operator_principal_id: operator1_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3000).to_vec(), + dc_id: "dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + let operator_record_2 = NodeOperatorRecord { + node_operator_principal_id: operator2_id.to_vec(), + node_provider_principal_id: PrincipalId::new_user_test_id(3000).to_vec(), + dc_id: "not-dc1".to_string(), + node_allowance: 1, + ..Default::default() + }; + registry.maybe_apply_mutation_internal(vec![ + insert( + make_node_operator_record_key(operator1_id), + operator_record_1.encode_to_vec(), + ), + insert( + make_node_operator_record_key(operator2_id), + operator_record_2.encode_to_vec(), + ), + ]); + // Add node owned by operator1 to registry + let (mutate_request, node_ids_and_dkg_pks) = + prepare_registry_with_nodes_and_node_operator_id( + 1, /* mutation id */ + 1, /* node count */ + operator1_id, + ); + registry.maybe_apply_mutation_internal(mutate_request.mutations); + let node_id = node_ids_and_dkg_pks + .keys() + .next() + .expect("should contain at least one node ID") + .to_owned(); + + let payload = RemoveNodeDirectlyPayload { node_id }; + + // Should fail because the DC of operator1 and operator2 does not match + registry.do_remove_node(payload, operator2_id); + } } diff --git a/rs/registry/canister/tests/remove_nodes.rs b/rs/registry/canister/tests/remove_nodes.rs index 2c220dbdad9..b3fe119debf 100644 --- a/rs/registry/canister/tests/remove_nodes.rs +++ b/rs/registry/canister/tests/remove_nodes.rs @@ -352,7 +352,7 @@ fn remove_nodes_removes_all_keys() { // Add the node along with keys and certs let mut mutations = make_add_node_registry_mutations(node_id, node, valid_pks); - // Add node operator records + // Add node operator record mutations.push(insert( make_node_operator_record_key(user_test_id(NO_ID).get()).as_bytes(), node_operator.encode_to_vec(), From ba5e99bf15c7b4b77861b73b0db3606440c67fa6 Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Thu, 9 Jan 2025 11:32:22 +0100 Subject: [PATCH 34/98] chore(IDX): don't cache ic-os images (#3256) This saves a couple gigabytes of cache space per build: ``` ubuntu@devenv-container:/ic$ bazel --noworkspace_rc --bazelrc=./bazel/conf/.bazelrc.build build --disk_cache=,out/disk-cache --config=systest //ic-os/setupos/envs/dev && du -sh ,out ... Target //ic-os/setupos/envs/dev:dev up-to-date: bazel-bin/ic-os/setupos/envs/dev/dev_pre_check_result.txt bazel-bin/ic-os/setupos/envs/dev/disk-img.tar.zst INFO: Elapsed time: 0.929s, Critical Path: 0.10s INFO: 1 process: 1 internal. INFO: Build completed successfully, 1 total action 24G ,out ubuntu@devenv-container:/ic$ bazel --noworkspace_rc --bazelrc=./bazel/conf/.bazelrc.build build --disk_cache=,out/disk-cache --config=systest //ic-os/setupos/envs/dev && du -sh ,out ... Target //ic-os/setupos/envs/dev:dev up-to-date: bazel-bin/ic-os/setupos/envs/dev/dev_pre_check_result.txt bazel-bin/ic-os/setupos/envs/dev/disk-img.tar.zst INFO: Elapsed time: 0.857s, Critical Path: 0.04s INFO: 1 process: 1 internal. INFO: Build completed successfully, 1 total action 6.9G ,out # NOTE: this is when everything in ic-os is marked as no-cache ``` The images are rebuilt on almost every change anyway. --- ic-os/defs.bzl | 36 +++++++++---------- ic-os/guestos/envs/local-base-dev/BUILD.bazel | 5 ++- .../guestos/envs/local-base-prod/BUILD.bazel | 5 ++- ic-os/hostos/defs.bzl | 2 +- ic-os/hostos/envs/local-base-dev/BUILD.bazel | 5 ++- ic-os/hostos/envs/local-base-prod/BUILD.bazel | 5 ++- ic-os/setupos/defs.bzl | 8 ++--- ic-os/setupos/envs/local-base-dev/BUILD.bazel | 5 ++- .../setupos/envs/local-base-prod/BUILD.bazel | 5 ++- 9 files changed, 47 insertions(+), 29 deletions(-) diff --git a/ic-os/defs.bzl b/ic-os/defs.bzl index a7484c2d786..3160f022e7b 100644 --- a/ic-os/defs.bzl +++ b/ic-os/defs.bzl @@ -123,7 +123,7 @@ def icos_build( build_args = image_deps["build_args"], file_build_arg = image_deps["file_build_arg"], target_compatible_with = ["@platforms//os:linux"], - tags = ["manual"], + tags = ["manual", "no-cache"], ) # Extract SElinux file_contexts to use later when building ext4 filesystems @@ -192,7 +192,7 @@ def icos_build( k: v for k, v in (image_deps["rootfs"].items() + [(":version.txt", "/opt/ic/share/version.txt:0644")]) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) # Inherit tags for this test, to avoid triggering builds for local base images @@ -213,16 +213,16 @@ def icos_build( k: v for k, v in (image_deps["rootfs"].items() + [(":version-test.txt", "/opt/ic/share/version.txt:0644")]) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) # When boot_args are fixed, don't bother signing if "boot_args_template" not in image_deps: - native.alias(name = "partition-root.tzst", actual = ":partition-root-unsigned.tzst", tags = ["manual"]) + native.alias(name = "partition-root.tzst", actual = ":partition-root-unsigned.tzst", tags = ["manual", "no-cache"]) native.alias(name = "extra_boot_args", actual = image_deps["extra_boot_args"], tags = ["manual"]) if upgrades: - native.alias(name = "partition-root-test.tzst", actual = ":partition-root-test-unsigned.tzst", tags = ["manual"]) + native.alias(name = "partition-root-test.tzst", actual = ":partition-root-test-unsigned.tzst", tags = ["manual", "no-cache"]) native.alias(name = "extra_boot_test_args", actual = image_deps["extra_boot_args"], tags = ["manual"]) else: native.alias(name = "extra_boot_args_template", actual = image_deps["boot_args_template"], tags = ["manual"]) @@ -235,7 +235,7 @@ def icos_build( cmd = "$(location //toolchains/sysimage:proc_wrapper) $(location //toolchains/sysimage:verity_sign.py) -i $< -o $(location :partition-root.tzst) -r $(location partition-root-hash) --dflate $(location //rs/ic_os/build_tools/dflate)", executable = False, tools = ["//toolchains/sysimage:proc_wrapper", "//toolchains/sysimage:verity_sign.py", "//rs/ic_os/build_tools/dflate"], - tags = ["manual"], + tags = ["manual", "no-cache"], ) native.genrule( @@ -257,7 +257,7 @@ def icos_build( outs = ["partition-root-test.tzst", "partition-root-test-hash"], cmd = "$(location //toolchains/sysimage:proc_wrapper) $(location //toolchains/sysimage:verity_sign.py) -i $< -o $(location :partition-root-test.tzst) -r $(location partition-root-test-hash) --dflate $(location //rs/ic_os/build_tools/dflate)", tools = ["//toolchains/sysimage:proc_wrapper", "//toolchains/sysimage:verity_sign.py", "//rs/ic_os/build_tools/dflate"], - tags = ["manual"], + tags = ["manual", "no-cache"], ) native.genrule( @@ -285,7 +285,7 @@ def icos_build( ] ) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) if upgrades: @@ -303,7 +303,7 @@ def icos_build( ] ) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) # -------------------- Assemble disk partitions --------------- @@ -326,7 +326,7 @@ def icos_build( ":partition-root.tzst", ] + custom_partitions, expanded_size = image_deps.get("expanded_size", default = None), - tags = ["manual"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], @@ -343,7 +343,7 @@ def icos_build( ":partition-root.tzst", ] + custom_partitions, expanded_size = image_deps.get("expanded_size", default = None), - tags = ["manual", "no-remote-cache"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], @@ -363,7 +363,7 @@ def icos_build( name = "update-img.tar", boot_partition = ":partition-boot.tzst", root_partition = ":partition-root.tzst", - tags = ["manual"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], @@ -381,7 +381,7 @@ def icos_build( name = "update-img-test.tar", boot_partition = ":partition-boot-test.tzst", root_partition = ":partition-root-test.tzst", - tags = ["manual"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], @@ -671,7 +671,7 @@ def boundary_node_icos_build( build_args = image_deps["build_args"], file_build_arg = image_deps["file_build_arg"], target_compatible_with = ["@platforms//os:linux"], - tags = ["manual"], + tags = ["manual", "no-cache"], ) # Helpful tool to print a hash of all input component files @@ -740,7 +740,7 @@ EOF ] ) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) ext4_image( @@ -764,7 +764,7 @@ EOF k: v for k, v in (image_deps["rootfs"].items() + [(":version.txt", "/opt/ic/share/version.txt:0644")]) }, - tags = ["manual"], + tags = ["manual", "no-cache"], ) native.genrule( @@ -774,7 +774,7 @@ EOF cmd = "$(location //toolchains/sysimage:proc_wrapper) $(location //toolchains/sysimage:verity_sign.py) -i $< -o $(location :partition-root.tzst) -r $(location partition-root-hash) --dflate $(location //rs/ic_os/build_tools/dflate)", executable = False, tools = ["//toolchains/sysimage:proc_wrapper", "//toolchains/sysimage:verity_sign.py", "//rs/ic_os/build_tools/dflate"], - tags = ["manual"], + tags = ["manual", "no-cache"], ) native.genrule( @@ -799,7 +799,7 @@ EOF ":partition-root.tzst", ], expanded_size = "50G", - tags = ["manual"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], diff --git a/ic-os/guestos/envs/local-base-dev/BUILD.bazel b/ic-os/guestos/envs/local-base-dev/BUILD.bazel index ab0d2b6e912..983caaffd07 100644 --- a/ic-os/guestos/envs/local-base-dev/BUILD.bazel +++ b/ic-os/guestos/envs/local-base-dev/BUILD.bazel @@ -10,7 +10,10 @@ icos_build( build_local_base_image = True, ic_version = "//bazel:rc_only_version.txt", image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upload_prefix = None, # Do not upload locally built base images visibility = ["//rs:ic-os-pkg"], ) diff --git a/ic-os/guestos/envs/local-base-prod/BUILD.bazel b/ic-os/guestos/envs/local-base-prod/BUILD.bazel index 021e01ce1ed..eaf48fd86cb 100644 --- a/ic-os/guestos/envs/local-base-prod/BUILD.bazel +++ b/ic-os/guestos/envs/local-base-prod/BUILD.bazel @@ -9,7 +9,10 @@ icos_build( name = "local-base-prod", build_local_base_image = True, image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upload_prefix = None, # Do not upload locally built base images visibility = ["//rs:ic-os-pkg"], ) diff --git a/ic-os/hostos/defs.bzl b/ic-os/hostos/defs.bzl index 114e6cb361a..f60ab207c02 100644 --- a/ic-os/hostos/defs.bzl +++ b/ic-os/hostos/defs.bzl @@ -97,7 +97,7 @@ def _custom_partitions(): vg_name = "hostlvm", vg_uuid = "4c7GVZ-Df82-QEcJ-xXtV-JgRL-IjLE-hK0FgA", pv_uuid = "eu0VQE-HlTi-EyRc-GceP-xZtn-3j6t-iqEwyv", - tags = ["manual"], + tags = ["manual", "no-cache"], target_compatible_with = [ "@platforms//os:linux", ], diff --git a/ic-os/hostos/envs/local-base-dev/BUILD.bazel b/ic-os/hostos/envs/local-base-dev/BUILD.bazel index 9d5e2c98427..b179b8ce556 100644 --- a/ic-os/hostos/envs/local-base-dev/BUILD.bazel +++ b/ic-os/hostos/envs/local-base-dev/BUILD.bazel @@ -10,7 +10,10 @@ icos_build( build_local_base_image = True, ic_version = "//bazel:rc_only_version.txt", image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upload_prefix = None, # Do not upload locally built base images visibility = ["//rs:ic-os-pkg"], vuln_scan = False, diff --git a/ic-os/hostos/envs/local-base-prod/BUILD.bazel b/ic-os/hostos/envs/local-base-prod/BUILD.bazel index 34c7e5523a3..afb5e210401 100644 --- a/ic-os/hostos/envs/local-base-prod/BUILD.bazel +++ b/ic-os/hostos/envs/local-base-prod/BUILD.bazel @@ -9,7 +9,10 @@ icos_build( name = "local-base-prod", build_local_base_image = True, image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upload_prefix = None, # Do not upload locally built base images visibility = ["//rs:ic-os-pkg"], vuln_scan = False, diff --git a/ic-os/setupos/defs.bzl b/ic-os/setupos/defs.bzl index 6483645fd41..d0c6ce774c2 100644 --- a/ic-os/setupos/defs.bzl +++ b/ic-os/setupos/defs.bzl @@ -102,7 +102,7 @@ def _custom_partitions(mode): src = guest_image, out = "guest-os.img.tar.zst", allow_symlink = True, - tags = ["manual"], + tags = ["manual", "no-cache"], ) copy_file( @@ -110,7 +110,7 @@ def _custom_partitions(mode): src = host_image, out = "host-os.img.tar.zst", allow_symlink = True, - tags = ["manual"], + tags = ["manual", "no-cache"], ) config_dict = { @@ -159,7 +159,7 @@ def _custom_partitions(mode): ], mode = "0644", package_dir = "data", - tags = ["manual"], + tags = ["manual", "no-cache"], ) ext4_image( @@ -170,7 +170,7 @@ def _custom_partitions(mode): target_compatible_with = [ "@platforms//os:linux", ], - tags = ["manual"], + tags = ["manual", "no-cache"], ) return [ diff --git a/ic-os/setupos/envs/local-base-dev/BUILD.bazel b/ic-os/setupos/envs/local-base-dev/BUILD.bazel index 12ca12c676f..66712587e07 100644 --- a/ic-os/setupos/envs/local-base-dev/BUILD.bazel +++ b/ic-os/setupos/envs/local-base-dev/BUILD.bazel @@ -11,7 +11,10 @@ icos_build( build_local_base_image = True, ic_version = "//bazel:rc_only_version.txt", image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upgrades = False, upload_prefix = None, # Do not upload locally built base images visibility = ["//rs:ic-os-pkg"], diff --git a/ic-os/setupos/envs/local-base-prod/BUILD.bazel b/ic-os/setupos/envs/local-base-prod/BUILD.bazel index 3b564fe8583..948df7e85c3 100644 --- a/ic-os/setupos/envs/local-base-prod/BUILD.bazel +++ b/ic-os/setupos/envs/local-base-prod/BUILD.bazel @@ -10,7 +10,10 @@ icos_build( name = "local-base-prod", build_local_base_image = True, image_deps_func = image_deps, - tags = ["manual"], + tags = [ + "manual", + "no-cache", + ], upgrades = False, upload_prefix = None, # Do not upload locally built base images vuln_scan = False, From 8054acfaca5bda9233bd51f6ccec7f1ad34b6d0a Mon Sep 17 00:00:00 2001 From: Maksym Arutyunyan <103510076+maksymar@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:39:06 +0100 Subject: [PATCH 35/98] chore: upgrade wasmtime to v.28 (#3330) Wasmtime release notes: https://github.com/bytecodealliance/wasmtime/releases/tag/v28.0.0 - Changed `LinearMemory` trait API, [code](https://github.com/bytecodealliance/wasmtime/pull/9577) - Changed static/dynamic memory config, removed `static_memory_maximum_size` [code](https://github.com/bytecodealliance/wasmtime/pull/9545) --------- Co-authored-by: Andriy Berestovskyy Co-authored-by: IDX GitHub Automation --- Cargo.Bazel.Fuzzing.json.lock | 927 +++-- Cargo.Bazel.Fuzzing.toml.lock | 224 +- Cargo.Bazel.json.lock | 909 +++-- Cargo.Bazel.toml.lock | 220 +- Cargo.lock | 189 +- bazel/external_crates.bzl | 4 +- rs/embedders/Cargo.toml | 4 +- rs/embedders/src/wasm_utils/validation.rs | 2 +- .../src/wasmtime_embedder/host_memory.rs | 13 +- rs/execution_environment/benches/README.md | 46 + .../baseline/EMBEDDERS_COMPILATION.min | 30 +- .../benches/baseline/EMBEDDERS_HEAP.min | 192 +- .../baseline/EMBEDDERS_STABLE_MEMORY.min | 28 +- .../baseline/SYSTEM_API_INSPECT_MESSAGE.min | 16 +- .../benches/baseline/SYSTEM_API_QUERY.min | 12 +- .../benches/baseline/SYSTEM_API_UPDATE.min | 206 +- .../benches/baseline/WASM_INSTRUCTIONS.min | 3408 ++++++++--------- .../benches/run-all-benchmarks.sh | 11 +- .../benches/run-benchmark.sh | 9 +- .../benches/summarize-results.sh | 4 +- 20 files changed, 3739 insertions(+), 2715 deletions(-) create mode 100644 rs/execution_environment/benches/README.md diff --git a/Cargo.Bazel.Fuzzing.json.lock b/Cargo.Bazel.Fuzzing.json.lock index 0d2fc0a35cd..bcbb23035a8 100644 --- a/Cargo.Bazel.Fuzzing.json.lock +++ b/Cargo.Bazel.Fuzzing.json.lock @@ -1,5 +1,5 @@ { - "checksum": "e904ebd5eba74e59f5c8c82f9170ceb30c11cb23b89e7edc0f00a0b3bade57c1", + "checksum": "8fd8fccec5a57eefbac6e6bc61cde6077b347dc896dd713bf649cb70bb4778b1", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -1821,14 +1821,14 @@ ], "license_file": null }, - "allocator-api2 0.2.16": { + "allocator-api2 0.2.21": { "name": "allocator-api2", - "version": "0.2.16", + "version": "0.2.21", "package_url": "https://github.com/zakarumych/allocator-api2", "repository": { "Http": { - "url": "https://static.crates.io/crates/allocator-api2/0.2.16/download", - "sha256": "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + "url": "https://static.crates.io/crates/allocator-api2/0.2.21/download", + "sha256": "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" } }, "targets": [ @@ -1857,14 +1857,14 @@ "selects": {} }, "edition": "2018", - "version": "0.2.16" + "version": "0.2.21" }, "license": "MIT OR Apache-2.0", "license_ids": [ "Apache-2.0", "MIT" ], - "license_file": "license" + "license_file": "LICENSE-APACHE" }, "android-tzdata 0.1.1": { "name": "android-tzdata", @@ -8979,14 +8979,14 @@ ], "license_file": null }, - "bumpalo 3.14.0": { + "bumpalo 3.16.0": { "name": "bumpalo", - "version": "3.14.0", + "version": "3.16.0", "package_url": "https://github.com/fitzgen/bumpalo", "repository": { "Http": { - "url": "https://static.crates.io/crates/bumpalo/3.14.0/download", - "sha256": "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + "url": "https://static.crates.io/crates/bumpalo/3.16.0/download", + "sha256": "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" } }, "targets": [ @@ -9010,12 +9010,22 @@ ], "crate_features": { "common": [ + "allocator-api2", "default" ], "selects": {} }, + "deps": { + "common": [ + { + "id": "allocator-api2 0.2.21", + "target": "allocator_api2" + } + ], + "selects": {} + }, "edition": "2021", - "version": "3.14.0" + "version": "3.16.0" }, "license": "MIT OR Apache-2.0", "license_ids": [ @@ -14332,14 +14342,14 @@ ], "license_file": "LICENSE-APACHE" }, - "cranelift-bforest 0.114.0": { + "cranelift-bforest 0.115.0": { "name": "cranelift-bforest", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-bforest/0.114.0/download", - "sha256": "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" + "url": "https://static.crates.io/crates/cranelift-bforest/0.115.0/download", + "sha256": "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c" } }, "targets": [ @@ -14364,14 +14374,14 @@ "deps": { "common": [ { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14379,14 +14389,14 @@ ], "license_file": "LICENSE" }, - "cranelift-bitset 0.114.0": { + "cranelift-bitset 0.115.0": { "name": "cranelift-bitset", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-bitset/0.114.0/download", - "sha256": "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" + "url": "https://static.crates.io/crates/cranelift-bitset/0.115.0/download", + "sha256": "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a" } }, "targets": [ @@ -14433,7 +14443,7 @@ ], "selects": {} }, - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14441,14 +14451,14 @@ ], "license_file": null }, - "cranelift-codegen 0.114.0": { + "cranelift-codegen 0.115.0": { "name": "cranelift-codegen", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen/0.114.0/download", - "sha256": "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" + "url": "https://static.crates.io/crates/cranelift-codegen/0.115.0/download", + "sha256": "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35" } }, "targets": [ @@ -14495,31 +14505,31 @@ "deps": { "common": [ { - "id": "bumpalo 3.14.0", + "id": "bumpalo 3.16.0", "target": "bumpalo" }, { - "id": "cranelift-bforest 0.114.0", + "id": "cranelift-bforest 0.115.0", "target": "cranelift_bforest" }, { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "build_script_build" }, { - "id": "cranelift-codegen-shared 0.114.0", + "id": "cranelift-codegen-shared 0.115.0", "target": "cranelift_codegen_shared" }, { - "id": "cranelift-control 0.114.0", + "id": "cranelift-control 0.115.0", "target": "cranelift_control" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { @@ -14535,7 +14545,7 @@ "target": "log" }, { - "id": "regalloc2 0.10.2", + "id": "regalloc2 0.11.1", "target": "regalloc2" }, { @@ -14554,7 +14564,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -14566,11 +14576,11 @@ "deps": { "common": [ { - "id": "cranelift-codegen-meta 0.114.0", + "id": "cranelift-codegen-meta 0.115.0", "target": "cranelift_codegen_meta" }, { - "id": "cranelift-isle 0.114.0", + "id": "cranelift-isle 0.115.0", "target": "cranelift_isle" } ], @@ -14583,14 +14593,14 @@ ], "license_file": "LICENSE" }, - "cranelift-codegen-meta 0.114.0": { + "cranelift-codegen-meta 0.115.0": { "name": "cranelift-codegen-meta", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen-meta/0.114.0/download", - "sha256": "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7", + "url": "https://static.crates.io/crates/cranelift-codegen-meta/0.115.0/download", + "sha256": "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a", "patch_args": [ "-p4" ], @@ -14621,14 +14631,14 @@ "deps": { "common": [ { - "id": "cranelift-codegen-shared 0.114.0", + "id": "cranelift-codegen-shared 0.115.0", "target": "cranelift_codegen_shared" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14636,14 +14646,14 @@ ], "license_file": "LICENSE" }, - "cranelift-codegen-shared 0.114.0": { + "cranelift-codegen-shared 0.115.0": { "name": "cranelift-codegen-shared", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen-shared/0.114.0/download", - "sha256": "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" + "url": "https://static.crates.io/crates/cranelift-codegen-shared/0.115.0/download", + "sha256": "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181" } }, "targets": [ @@ -14666,7 +14676,7 @@ "**" ], "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14674,14 +14684,14 @@ ], "license_file": "LICENSE" }, - "cranelift-control 0.114.0": { + "cranelift-control 0.115.0": { "name": "cranelift-control", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-control/0.114.0/download", - "sha256": "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" + "url": "https://static.crates.io/crates/cranelift-control/0.115.0/download", + "sha256": "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd" } }, "targets": [ @@ -14720,7 +14730,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14728,14 +14738,14 @@ ], "license_file": "LICENSE" }, - "cranelift-entity 0.114.0": { + "cranelift-entity 0.115.0": { "name": "cranelift-entity", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-entity/0.114.0/download", - "sha256": "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" + "url": "https://static.crates.io/crates/cranelift-entity/0.115.0/download", + "sha256": "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84" } }, "targets": [ @@ -14768,7 +14778,7 @@ "deps": { "common": [ { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { @@ -14788,7 +14798,7 @@ ], "selects": {} }, - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14796,14 +14806,14 @@ ], "license_file": "LICENSE" }, - "cranelift-frontend 0.114.0": { + "cranelift-frontend 0.115.0": { "name": "cranelift-frontend", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-frontend/0.114.0/download", - "sha256": "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" + "url": "https://static.crates.io/crates/cranelift-frontend/0.115.0/download", + "sha256": "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7" } }, "targets": [ @@ -14835,7 +14845,7 @@ "deps": { "common": [ { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { @@ -14854,7 +14864,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14862,14 +14872,14 @@ ], "license_file": "LICENSE" }, - "cranelift-isle 0.114.0": { + "cranelift-isle 0.115.0": { "name": "cranelift-isle", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime/tree/main/cranelift/isle", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-isle/0.114.0/download", - "sha256": "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8", + "url": "https://static.crates.io/crates/cranelift-isle/0.115.0/download", + "sha256": "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0", "patch_args": [ "-p4" ], @@ -14918,14 +14928,14 @@ "deps": { "common": [ { - "id": "cranelift-isle 0.114.0", + "id": "cranelift-isle 0.115.0", "target": "build_script_build" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -14941,14 +14951,14 @@ ], "license_file": null }, - "cranelift-native 0.114.0": { + "cranelift-native 0.115.0": { "name": "cranelift-native", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-native/0.114.0/download", - "sha256": "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" + "url": "https://static.crates.io/crates/cranelift-native/0.115.0/download", + "sha256": "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7" } }, "targets": [ @@ -14980,7 +14990,7 @@ "deps": { "common": [ { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { @@ -14998,7 +15008,7 @@ } }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -19563,11 +19573,11 @@ "target": "wasmprinter" }, { - "id": "wasmtime 27.0.0", + "id": "wasmtime 28.0.0", "target": "wasmtime" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" }, { @@ -24248,6 +24258,44 @@ ], "license_file": "LICENSE-APACHE" }, + "foldhash 0.1.4": { + "name": "foldhash", + "version": "0.1.4", + "package_url": "https://github.com/orlp/foldhash", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/foldhash/0.1.4/download", + "sha256": "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "foldhash", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "foldhash", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.1.4" + }, + "license": "Zlib", + "license_ids": [ + "Zlib" + ], + "license_file": "LICENSE" + }, "form_urlencoded 1.2.1": { "name": "form_urlencoded", "version": "1.2.1", @@ -26517,7 +26565,7 @@ "target": "ahash" }, { - "id": "allocator-api2 0.2.16", + "id": "allocator-api2 0.2.21", "target": "allocator_api2" }, { @@ -26537,6 +26585,60 @@ ], "license_file": "LICENSE-APACHE" }, + "hashbrown 0.15.2": { + "name": "hashbrown", + "version": "0.15.2", + "package_url": "https://github.com/rust-lang/hashbrown", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/hashbrown/0.15.2/download", + "sha256": "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + } + }, + "targets": [ + { + "Library": { + "crate_name": "hashbrown", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "hashbrown", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default-hasher" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "foldhash 0.1.4", + "target": "foldhash" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.15.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "hashlink 0.8.4": { "name": "hashlink", "version": "0.8.4", @@ -44438,14 +44540,14 @@ ], "license_file": "LICENSE-APACHE" }, - "object 0.36.1": { + "object 0.36.7": { "name": "object", - "version": "0.36.1", + "version": "0.36.7", "package_url": "https://github.com/gimli-rs/object", "repository": { "Http": { - "url": "https://static.crates.io/crates/object/0.36.1/download", - "sha256": "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" + "url": "https://static.crates.io/crates/object/0.36.7/download", + "sha256": "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" } }, "targets": [ @@ -44460,6 +44562,18 @@ ] } } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } } ], "library_target_name": "object", @@ -44489,7 +44603,7 @@ "target": "crc32fast" }, { - "id": "hashbrown 0.14.5", + "id": "hashbrown 0.15.2", "target": "hashbrown" }, { @@ -44499,12 +44613,24 @@ { "id": "memchr 2.6.4", "target": "memchr" + }, + { + "id": "object 0.36.7", + "target": "build_script_build" } ], "selects": {} }, "edition": "2018", - "version": "0.36.1" + "version": "0.36.7" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] }, "license": "Apache-2.0 OR MIT", "license_ids": [ @@ -52551,14 +52677,14 @@ ], "license_file": "LICENSE" }, - "pulley-interpreter 27.0.0": { + "pulley-interpreter 28.0.0": { "name": "pulley-interpreter", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime/tree/main/pulley", "repository": { "Http": { - "url": "https://static.crates.io/crates/pulley-interpreter/27.0.0/download", - "sha256": "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" + "url": "https://static.crates.io/crates/pulley-interpreter/28.0.0/download", + "sha256": "403a1a95f4c18a45c86c7bff13df00347afd0abcbf2e54af273c837339ffcf77" } }, "targets": [ @@ -52583,7 +52709,7 @@ "deps": { "common": [ { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { @@ -52598,7 +52724,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -55137,14 +55263,14 @@ ], "license_file": "LICENSE" }, - "regalloc2 0.10.2": { + "regalloc2 0.11.1": { "name": "regalloc2", - "version": "0.10.2", + "version": "0.11.1", "package_url": "https://github.com/bytecodealliance/regalloc2", "repository": { "Http": { - "url": "https://static.crates.io/crates/regalloc2/0.10.2/download", - "sha256": "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" + "url": "https://static.crates.io/crates/regalloc2/0.11.1/download", + "sha256": "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3" } }, "targets": [ @@ -55177,7 +55303,15 @@ "deps": { "common": [ { - "id": "hashbrown 0.14.5", + "id": "allocator-api2 0.2.21", + "target": "allocator_api2" + }, + { + "id": "bumpalo 3.16.0", + "target": "bumpalo" + }, + { + "id": "hashbrown 0.15.2", "target": "hashbrown" }, { @@ -55188,10 +55322,6 @@ "id": "rustc-hash 2.0.0", "target": "rustc_hash" }, - { - "id": "slice-group-by 0.3.1", - "target": "slice_group_by" - }, { "id": "smallvec 1.13.2", "target": "smallvec" @@ -55200,7 +55330,7 @@ "selects": {} }, "edition": "2018", - "version": "0.10.2" + "version": "0.11.1" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -66701,44 +66831,6 @@ ], "license_file": "LICENSE" }, - "slice-group-by 0.3.1": { - "name": "slice-group-by", - "version": "0.3.1", - "package_url": "https://github.com/Kerollmops/slice-group-by", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/slice-group-by/0.3.1/download", - "sha256": "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - } - }, - "targets": [ - { - "Library": { - "crate_name": "slice_group_by", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "slice_group_by", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.3.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, "slog 2.7.0": { "name": "slog", "version": "2.7.0", @@ -78641,7 +78733,7 @@ "deps": { "common": [ { - "id": "bumpalo 3.14.0", + "id": "bumpalo 3.16.0", "target": "bumpalo" }, { @@ -79056,14 +79148,14 @@ ], "license_file": null }, - "wasm-encoder 0.219.1": { + "wasm-encoder 0.221.2": { "name": "wasm-encoder", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasm-encoder/0.219.1/download", - "sha256": "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" + "url": "https://static.crates.io/crates/wasm-encoder/0.221.2/download", + "sha256": "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" } }, "targets": [ @@ -79102,7 +79194,7 @@ "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79461,14 +79553,14 @@ ], "license_file": null }, - "wasmparser 0.219.1": { + "wasmparser 0.221.2": { "name": "wasmparser", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmparser/0.219.1/download", - "sha256": "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" + "url": "https://static.crates.io/crates/wasmparser/0.221.2/download", + "sha256": "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" } }, "targets": [ @@ -79483,6 +79575,18 @@ ] } } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } } ], "library_target_name": "wasmparser", @@ -79495,6 +79599,7 @@ "component-model", "features", "serde", + "simd", "std", "validate" ], @@ -79502,22 +79607,10 @@ }, "deps": { "common": [ - { - "id": "ahash 0.8.11", - "target": "ahash" - }, { "id": "bitflags 2.6.0", "target": "bitflags" }, - { - "id": "hashbrown 0.14.5", - "target": "hashbrown" - }, - { - "id": "indexmap 2.2.6", - "target": "indexmap" - }, { "id": "semver 1.0.22", "target": "semver" @@ -79525,12 +79618,24 @@ { "id": "serde 1.0.217", "target": "serde" + }, + { + "id": "wasmparser 0.221.2", + "target": "build_script_build" } ], "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79595,14 +79700,14 @@ ], "license_file": null }, - "wasmprinter 0.219.1": { + "wasmprinter 0.221.2": { "name": "wasmprinter", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmprinter", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmprinter/0.219.1/download", - "sha256": "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" + "url": "https://static.crates.io/crates/wasmprinter/0.221.2/download", + "sha256": "a80742ff1b9e6d8c231ac7c7247782c6fc5bce503af760bca071811e5fc9ee56" } }, "targets": [ @@ -79642,14 +79747,14 @@ "target": "termcolor" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" } ], "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79658,14 +79763,14 @@ ], "license_file": null }, - "wasmtime 27.0.0": { + "wasmtime 28.0.0": { "name": "wasmtime", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime/27.0.0/download", - "sha256": "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" + "url": "https://static.crates.io/crates/wasmtime/28.0.0/download", + "sha256": "f639ecae347b9a2227e453a7b7671e84370a0b61f47a15e0390fe9b7725e47b3" } }, "targets": [ @@ -79707,6 +79812,7 @@ "once_cell", "parallel-compilation", "runtime", + "signals-based-traps", "std" ], "selects": {} @@ -79722,7 +79828,7 @@ "target": "bitflags" }, { - "id": "bumpalo 3.14.0", + "id": "bumpalo 3.16.0", "target": "bumpalo" }, { @@ -79750,7 +79856,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -79782,31 +79888,31 @@ "target": "target_lexicon" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmtime 27.0.0", + "id": "wasmtime 28.0.0", "target": "build_script_build" }, { - "id": "wasmtime-asm-macros 27.0.0", + "id": "wasmtime-asm-macros 28.0.0", "target": "wasmtime_asm_macros" }, { - "id": "wasmtime-cranelift 27.0.0", + "id": "wasmtime-cranelift 28.0.0", "target": "wasmtime_cranelift" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" }, { - "id": "wasmtime-jit-icache-coherence 27.0.0", + "id": "wasmtime-jit-icache-coherence 28.0.0", "target": "wasmtime_jit_icache_coherence" }, { - "id": "wasmtime-slab 27.0.0", + "id": "wasmtime-slab 28.0.0", "target": "wasmtime_slab" } ], @@ -80039,7 +80145,7 @@ "target": "serde_derive" }, { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], @@ -80066,7 +80172,7 @@ ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -80087,7 +80193,7 @@ "proc_macro_deps": { "common": [ { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], @@ -80100,14 +80206,14 @@ ], "license_file": "LICENSE" }, - "wasmtime-asm-macros 27.0.0": { + "wasmtime-asm-macros 28.0.0": { "name": "wasmtime-asm-macros", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-asm-macros/27.0.0/download", - "sha256": "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" + "url": "https://static.crates.io/crates/wasmtime-asm-macros/28.0.0/download", + "sha256": "882a18800471cfc063c8b3ccf75723784acc3fd534009ac09421f2fac2fcdcec" } }, "targets": [ @@ -80139,7 +80245,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80147,14 +80253,14 @@ ], "license_file": null }, - "wasmtime-component-macro 27.0.0": { + "wasmtime-component-macro 28.0.0": { "name": "wasmtime-component-macro", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-component-macro/27.0.0/download", - "sha256": "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" + "url": "https://static.crates.io/crates/wasmtime-component-macro/28.0.0/download", + "sha256": "eb5c0a77c9e1927c3d471f53cc13767c3d3438e5d5ffd394e3eb31c86445fd60" } }, "targets": [ @@ -80207,26 +80313,26 @@ "target": "syn" }, { - "id": "wasmtime-component-macro 27.0.0", + "id": "wasmtime-component-macro 28.0.0", "target": "build_script_build" }, { - "id": "wasmtime-component-util 27.0.0", + "id": "wasmtime-component-util 28.0.0", "target": "wasmtime_component_util" }, { - "id": "wasmtime-wit-bindgen 27.0.0", + "id": "wasmtime-wit-bindgen 28.0.0", "target": "wasmtime_wit_bindgen" }, { - "id": "wit-parser 0.219.1", + "id": "wit-parser 0.221.2", "target": "wit_parser" } ], "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -80242,14 +80348,14 @@ ], "license_file": null }, - "wasmtime-component-util 27.0.0": { + "wasmtime-component-util 28.0.0": { "name": "wasmtime-component-util", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-component-util/27.0.0/download", - "sha256": "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" + "url": "https://static.crates.io/crates/wasmtime-component-util/28.0.0/download", + "sha256": "43702ca98bf5162eca0573db691ed9ecd36d716f8c6688410fe26ec16b6f9bcb" } }, "targets": [ @@ -80272,7 +80378,7 @@ "**" ], "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80280,14 +80386,14 @@ ], "license_file": null }, - "wasmtime-cranelift 27.0.0": { + "wasmtime-cranelift 28.0.0": { "name": "wasmtime-cranelift", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-cranelift/27.0.0/download", - "sha256": "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" + "url": "https://static.crates.io/crates/wasmtime-cranelift/28.0.0/download", + "sha256": "20070aa5b75080a8932ec328419faf841df2bc6ceb16b55b0df2b952098392a2" } }, "targets": [ @@ -80327,23 +80433,23 @@ "target": "cfg_if" }, { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { - "id": "cranelift-control 0.114.0", + "id": "cranelift-control 0.115.0", "target": "cranelift_control" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { - "id": "cranelift-frontend 0.114.0", + "id": "cranelift-frontend 0.115.0", "target": "cranelift_frontend" }, { - "id": "cranelift-native 0.114.0", + "id": "cranelift-native 0.115.0", "target": "cranelift_native" }, { @@ -80359,7 +80465,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -80375,11 +80481,11 @@ "target": "thiserror" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" } ], @@ -80389,13 +80495,13 @@ "proc_macro_deps": { "common": [ { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80403,14 +80509,14 @@ ], "license_file": "LICENSE" }, - "wasmtime-environ 27.0.0": { + "wasmtime-environ 28.0.0": { "name": "wasmtime-environ", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-environ/27.0.0/download", - "sha256": "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" + "url": "https://static.crates.io/crates/wasmtime-environ/28.0.0/download", + "sha256": "2604ddb24879d4dc1dedcb7081d7a8e017259bce916fdae097a97db52cbaab80" } }, "targets": [ @@ -80448,11 +80554,11 @@ "target": "anyhow" }, { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { @@ -80468,7 +80574,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -80488,15 +80594,15 @@ "target": "target_lexicon" }, { - "id": "wasm-encoder 0.219.1", + "id": "wasm-encoder 0.221.2", "target": "wasm_encoder" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmprinter 0.219.1", + "id": "wasmprinter 0.221.2", "target": "wasmprinter" } ], @@ -80512,7 +80618,7 @@ ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80520,14 +80626,133 @@ ], "license_file": "LICENSE" }, - "wasmtime-jit-icache-coherence 27.0.0": { + "wasmtime-fiber 28.0.0": { + "name": "wasmtime-fiber", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasmtime-fiber/28.0.0/download", + "sha256": "98593412d2b167ebe2b59d4a17a184978a72f976b53b3a0ec05629451079ac1d" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasmtime_fiber", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasmtime_fiber", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "wasmtime-asm-macros 28.0.0", + "target": "wasmtime_asm_macros" + }, + { + "id": "wasmtime-fiber 28.0.0", + "target": "build_script_build" + } + ], + "selects": { + "cfg(unix)": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], + "cfg(windows)": [ + { + "id": "windows-sys 0.59.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "wasmtime-versioned-export-macros 28.0.0", + "target": "wasmtime_versioned_export_macros" + } + ], + "selects": {} + }, + "version": "28.0.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "cc 1.0.83", + "target": "cc" + } + ], + "selects": {} + }, + "proc_macro_deps": { + "common": [ + { + "id": "wasmtime-versioned-export-macros 28.0.0", + "target": "wasmtime_versioned_export_macros" + } + ], + "selects": {} + } + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, + "wasmtime-jit-icache-coherence 28.0.0": { "name": "wasmtime-jit-icache-coherence", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-jit-icache-coherence/27.0.0/download", - "sha256": "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" + "url": "https://static.crates.io/crates/wasmtime-jit-icache-coherence/28.0.0/download", + "sha256": "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d" } }, "targets": [ @@ -80576,7 +80801,7 @@ } }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80584,14 +80809,14 @@ ], "license_file": null }, - "wasmtime-slab 27.0.0": { + "wasmtime-slab 28.0.0": { "name": "wasmtime-slab", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-slab/27.0.0/download", - "sha256": "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" + "url": "https://static.crates.io/crates/wasmtime-slab/28.0.0/download", + "sha256": "8579c335220b4ece9aa490a0e8b46de78cd342b195ab21ff981d095e14b52383" } }, "targets": [ @@ -80614,7 +80839,7 @@ "**" ], "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80622,14 +80847,14 @@ ], "license_file": null }, - "wasmtime-versioned-export-macros 27.0.0": { + "wasmtime-versioned-export-macros 28.0.0": { "name": "wasmtime-versioned-export-macros", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-versioned-export-macros/27.0.0/download", - "sha256": "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" + "url": "https://static.crates.io/crates/wasmtime-versioned-export-macros/28.0.0/download", + "sha256": "d7de0a56fb0a69b185968f2d7a9ba54750920a806470dff7ad8de91ac06d277e" } }, "targets": [ @@ -80669,7 +80894,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80677,14 +80902,93 @@ ], "license_file": null }, - "wasmtime-wit-bindgen 27.0.0": { + "wasmtime-winch 28.0.0": { + "name": "wasmtime-winch", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasmtime-winch/28.0.0/download", + "sha256": "abd309943c443f5590d12f9aba9ba63c481091c955a0a14de0c2a9e0e3aaeca9" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasmtime_winch", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasmtime_winch", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cranelift-codegen 0.115.0", + "target": "cranelift_codegen" + }, + { + "id": "gimli 0.31.1", + "target": "gimli" + }, + { + "id": "object 0.36.7", + "target": "object" + }, + { + "id": "target-lexicon 0.12.16", + "target": "target_lexicon" + }, + { + "id": "wasmparser 0.221.2", + "target": "wasmparser" + }, + { + "id": "wasmtime-cranelift 28.0.0", + "target": "wasmtime_cranelift" + }, + { + "id": "wasmtime-environ 28.0.0", + "target": "wasmtime_environ" + }, + { + "id": "winch-codegen 28.0.0", + "target": "winch_codegen" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "28.0.0" + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, + "wasmtime-wit-bindgen 28.0.0": { "name": "wasmtime-wit-bindgen", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-wit-bindgen/27.0.0/download", - "sha256": "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" + "url": "https://static.crates.io/crates/wasmtime-wit-bindgen/28.0.0/download", + "sha256": "969f83022dac3435d6469edb582ceed04cfe32aa44dc3ef16e5cb55574633df8" } }, "targets": [ @@ -80721,14 +81025,14 @@ "target": "indexmap" }, { - "id": "wit-parser 0.219.1", + "id": "wit-parser 0.221.2", "target": "wit_parser" } ], "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80775,7 +81079,7 @@ "deps": { "common": [ { - "id": "bumpalo 3.14.0", + "id": "bumpalo 3.16.0", "target": "bumpalo" }, { @@ -81697,6 +82001,109 @@ ], "license_file": null }, + "winch-codegen 28.0.0": { + "name": "winch-codegen", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/winch-codegen/28.0.0/download", + "sha256": "9110decc2983ed94de904804dcd979ba59cbabc78a94fec6b1d8468ec513d0f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "winch_codegen", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "winch_codegen", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cranelift-codegen 0.115.0", + "target": "cranelift_codegen" + }, + { + "id": "gimli 0.31.1", + "target": "gimli" + }, + { + "id": "regalloc2 0.11.1", + "target": "regalloc2" + }, + { + "id": "smallvec 1.13.2", + "target": "smallvec" + }, + { + "id": "target-lexicon 0.12.16", + "target": "target_lexicon" + }, + { + "id": "wasmparser 0.221.2", + "target": "wasmparser" + }, + { + "id": "wasmtime-cranelift 28.0.0", + "target": "wasmtime_cranelift" + }, + { + "id": "wasmtime-environ 28.0.0", + "target": "wasmtime_environ" + }, + { + "id": "winch-codegen 28.0.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "28.0.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "windows-core 0.52.0": { "name": "windows-core", "version": "0.52.0", @@ -84151,14 +84558,14 @@ ], "license_file": "LICENSE" }, - "wit-parser 0.219.1": { + "wit-parser 0.221.2": { "name": "wit-parser", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-parser", "repository": { "Http": { - "url": "https://static.crates.io/crates/wit-parser/0.219.1/download", - "sha256": "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" + "url": "https://static.crates.io/crates/wit-parser/0.221.2/download", + "sha256": "fbe1538eea6ea5ddbe5defd0dc82539ad7ba751e1631e9185d24a931f0a5adc8" } }, "targets": [ @@ -84224,7 +84631,7 @@ "target": "unicode_xid" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" } ], @@ -84240,7 +84647,7 @@ ], "selects": {} }, - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -87131,8 +87538,8 @@ "wasm-smith 0.212.0", "wasmparser 0.217.0", "wasmprinter 0.217.0", - "wasmtime 27.0.0", - "wasmtime-environ 27.0.0", + "wasmtime 28.0.0", + "wasmtime-environ 28.0.0", "wast 212.0.0", "wat 1.212.0", "wee_alloc 0.4.5", diff --git a/Cargo.Bazel.Fuzzing.toml.lock b/Cargo.Bazel.Fuzzing.toml.lock index 44f13247684..05fafc63a0d 100644 --- a/Cargo.Bazel.Fuzzing.toml.lock +++ b/Cargo.Bazel.Fuzzing.toml.lock @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -1527,9 +1527,12 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "by_address" @@ -2361,18 +2364,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" +checksum = "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" +checksum = "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a" dependencies = [ "serde", "serde_derive", @@ -2380,9 +2383,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" +checksum = "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35" dependencies = [ "bumpalo", "cranelift-bforest", @@ -2404,33 +2407,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7" +checksum = "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" +checksum = "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181" [[package]] name = "cranelift-control" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" +checksum = "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" +checksum = "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84" dependencies = [ "cranelift-bitset", "serde", @@ -2439,9 +2442,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" +checksum = "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7" dependencies = [ "cranelift-codegen", "log", @@ -2451,15 +2454,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8" +checksum = "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0" [[package]] name = "cranelift-native" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" +checksum = "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7" dependencies = [ "cranelift-codegen", "libc", @@ -3999,6 +4002,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -4380,6 +4389,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", + "serde", +] + [[package]] name = "hashlink" version = "0.8.4" @@ -7312,12 +7331,12 @@ dependencies = [ [[package]] name = "object" -version = "0.36.1" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "crc32fast", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap 2.2.6", "memchr", ] @@ -8666,9 +8685,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" +checksum = "403a1a95f4c18a45c86c7bff13df00347afd0abcbf2e54af273c837339ffcf77" dependencies = [ "cranelift-bitset", "log", @@ -9077,14 +9096,15 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.10.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" +checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3" dependencies = [ - "hashbrown 0.14.5", + "allocator-api2", + "bumpalo", + "hashbrown 0.15.2", "log", "rustc-hash 2.0.0", - "slice-group-by", "smallvec", ] @@ -10447,12 +10467,6 @@ dependencies = [ "autocfg 1.1.0", ] -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - [[package]] name = "slog" version = "2.7.0" @@ -12356,12 +12370,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" +checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" dependencies = [ "leb128", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] @@ -12433,13 +12447,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" +checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" dependencies = [ - "ahash 0.8.11", "bitflags 2.6.0", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap 2.2.6", "semver", "serde", @@ -12458,20 +12471,20 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" +checksum = "a80742ff1b9e6d8c231ac7c7247782c6fc5bce503af760bca071811e5fc9ee56" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] name = "wasmtime" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" +checksum = "f639ecae347b9a2227e453a7b7671e84370a0b61f47a15e0390fe9b7725e47b3" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -12485,7 +12498,7 @@ dependencies = [ "log", "mach2", "memfd", - "object 0.36.1", + "object 0.36.7", "once_cell", "paste", "postcard", @@ -12498,31 +12511,33 @@ dependencies = [ "smallvec", "sptr", "target-lexicon", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-cranelift", "wasmtime-environ", + "wasmtime-fiber", "wasmtime-jit-icache-coherence", "wasmtime-slab", "wasmtime-versioned-export-macros", + "wasmtime-winch", "windows-sys 0.59.0", ] [[package]] name = "wasmtime-asm-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" +checksum = "882a18800471cfc063c8b3ccf75723784acc3fd534009ac09421f2fac2fcdcec" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "wasmtime-component-macro" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" +checksum = "eb5c0a77c9e1927c3d471f53cc13767c3d3438e5d5ffd394e3eb31c86445fd60" dependencies = [ "anyhow", "proc-macro2", @@ -12535,15 +12550,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" +checksum = "43702ca98bf5162eca0573db691ed9ecd36d716f8c6688410fe26ec16b6f9bcb" [[package]] name = "wasmtime-cranelift" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" +checksum = "20070aa5b75080a8932ec328419faf841df2bc6ceb16b55b0df2b952098392a2" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -12555,20 +12570,20 @@ dependencies = [ "gimli 0.31.1", "itertools 0.12.0", "log", - "object 0.36.1", + "object 0.36.7", "smallvec", "target-lexicon", "thiserror 1.0.68", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-environ", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-environ" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" +checksum = "2604ddb24879d4dc1dedcb7081d7a8e017259bce916fdae097a97db52cbaab80" dependencies = [ "anyhow", "cranelift-bitset", @@ -12576,22 +12591,37 @@ dependencies = [ "gimli 0.31.1", "indexmap 2.2.6", "log", - "object 0.36.1", + "object 0.36.7", "postcard", "serde", "serde_derive", "smallvec", "target-lexicon", - "wasm-encoder 0.219.1", - "wasmparser 0.219.1", - "wasmprinter 0.219.1", + "wasm-encoder 0.221.2", + "wasmparser 0.221.2", + "wasmprinter 0.221.2", +] + +[[package]] +name = "wasmtime-fiber" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98593412d2b167ebe2b59d4a17a184978a72f976b53b3a0ec05629451079ac1d" +dependencies = [ + "anyhow", + "cc", + "cfg-if 1.0.0", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.59.0", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" +checksum = "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -12601,26 +12631,43 @@ dependencies = [ [[package]] name = "wasmtime-slab" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" +checksum = "8579c335220b4ece9aa490a0e8b46de78cd342b195ab21ff981d095e14b52383" [[package]] name = "wasmtime-versioned-export-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" +checksum = "d7de0a56fb0a69b185968f2d7a9ba54750920a806470dff7ad8de91ac06d277e" dependencies = [ "proc-macro2", "quote", "syn 2.0.87", ] +[[package]] +name = "wasmtime-winch" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd309943c443f5590d12f9aba9ba63c481091c955a0a14de0c2a9e0e3aaeca9" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "object 0.36.7", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", + "winch-codegen", +] + [[package]] name = "wasmtime-wit-bindgen" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" +checksum = "969f83022dac3435d6469edb582ceed04cfe32aa44dc3ef16e5cb55574633df8" dependencies = [ "anyhow", "heck 0.5.0", @@ -12761,6 +12808,23 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winch-codegen" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9110decc2983ed94de904804dcd979ba59cbabc78a94fec6b1d8468ec513d0f6" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -13044,9 +13108,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" +checksum = "fbe1538eea6ea5ddbe5defd0dc82539ad7ba751e1631e9185d24a931f0a5adc8" dependencies = [ "anyhow", "id-arena", @@ -13057,7 +13121,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] diff --git a/Cargo.Bazel.json.lock b/Cargo.Bazel.json.lock index 648b81a729a..d5c0c188242 100644 --- a/Cargo.Bazel.json.lock +++ b/Cargo.Bazel.json.lock @@ -1,5 +1,5 @@ { - "checksum": "4b1ad87a35d894e5bb253c5e0257cf4fbd0b0e806bc40273165b04099062b55d", + "checksum": "194342fc37fdddbf3dceb1e96cdf4ce10a63ff4ec17867d1a241e3e034c1ad0c", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -1825,14 +1825,14 @@ ], "license_file": null }, - "allocator-api2 0.2.16": { + "allocator-api2 0.2.21": { "name": "allocator-api2", - "version": "0.2.16", + "version": "0.2.21", "package_url": "https://github.com/zakarumych/allocator-api2", "repository": { "Http": { - "url": "https://static.crates.io/crates/allocator-api2/0.2.16/download", - "sha256": "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + "url": "https://static.crates.io/crates/allocator-api2/0.2.21/download", + "sha256": "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" } }, "targets": [ @@ -1861,14 +1861,14 @@ "selects": {} }, "edition": "2018", - "version": "0.2.16" + "version": "0.2.21" }, "license": "MIT OR Apache-2.0", "license_ids": [ "Apache-2.0", "MIT" ], - "license_file": "license" + "license_file": "LICENSE-APACHE" }, "android-tzdata 0.1.1": { "name": "android-tzdata", @@ -8927,10 +8927,20 @@ ], "crate_features": { "common": [ + "allocator-api2", "default" ], "selects": {} }, + "deps": { + "common": [ + { + "id": "allocator-api2 0.2.21", + "target": "allocator_api2" + } + ], + "selects": {} + }, "edition": "2021", "version": "3.16.0" }, @@ -14160,14 +14170,14 @@ ], "license_file": "LICENSE-APACHE" }, - "cranelift-bforest 0.114.0": { + "cranelift-bforest 0.115.0": { "name": "cranelift-bforest", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-bforest/0.114.0/download", - "sha256": "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" + "url": "https://static.crates.io/crates/cranelift-bforest/0.115.0/download", + "sha256": "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c" } }, "targets": [ @@ -14192,14 +14202,14 @@ "deps": { "common": [ { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14207,14 +14217,14 @@ ], "license_file": "LICENSE" }, - "cranelift-bitset 0.114.0": { + "cranelift-bitset 0.115.0": { "name": "cranelift-bitset", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-bitset/0.114.0/download", - "sha256": "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" + "url": "https://static.crates.io/crates/cranelift-bitset/0.115.0/download", + "sha256": "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a" } }, "targets": [ @@ -14261,7 +14271,7 @@ ], "selects": {} }, - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14269,14 +14279,14 @@ ], "license_file": null }, - "cranelift-codegen 0.114.0": { + "cranelift-codegen 0.115.0": { "name": "cranelift-codegen", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen/0.114.0/download", - "sha256": "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" + "url": "https://static.crates.io/crates/cranelift-codegen/0.115.0/download", + "sha256": "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35" } }, "targets": [ @@ -14327,27 +14337,27 @@ "target": "bumpalo" }, { - "id": "cranelift-bforest 0.114.0", + "id": "cranelift-bforest 0.115.0", "target": "cranelift_bforest" }, { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "build_script_build" }, { - "id": "cranelift-codegen-shared 0.114.0", + "id": "cranelift-codegen-shared 0.115.0", "target": "cranelift_codegen_shared" }, { - "id": "cranelift-control 0.114.0", + "id": "cranelift-control 0.115.0", "target": "cranelift_control" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { @@ -14363,7 +14373,7 @@ "target": "log" }, { - "id": "regalloc2 0.10.2", + "id": "regalloc2 0.11.1", "target": "regalloc2" }, { @@ -14382,7 +14392,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -14394,11 +14404,11 @@ "deps": { "common": [ { - "id": "cranelift-codegen-meta 0.114.0", + "id": "cranelift-codegen-meta 0.115.0", "target": "cranelift_codegen_meta" }, { - "id": "cranelift-isle 0.114.0", + "id": "cranelift-isle 0.115.0", "target": "cranelift_isle" } ], @@ -14411,14 +14421,14 @@ ], "license_file": "LICENSE" }, - "cranelift-codegen-meta 0.114.0": { + "cranelift-codegen-meta 0.115.0": { "name": "cranelift-codegen-meta", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen-meta/0.114.0/download", - "sha256": "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7", + "url": "https://static.crates.io/crates/cranelift-codegen-meta/0.115.0/download", + "sha256": "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a", "patch_args": [ "-p4" ], @@ -14449,14 +14459,14 @@ "deps": { "common": [ { - "id": "cranelift-codegen-shared 0.114.0", + "id": "cranelift-codegen-shared 0.115.0", "target": "cranelift_codegen_shared" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14464,14 +14474,14 @@ ], "license_file": "LICENSE" }, - "cranelift-codegen-shared 0.114.0": { + "cranelift-codegen-shared 0.115.0": { "name": "cranelift-codegen-shared", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-codegen-shared/0.114.0/download", - "sha256": "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" + "url": "https://static.crates.io/crates/cranelift-codegen-shared/0.115.0/download", + "sha256": "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181" } }, "targets": [ @@ -14494,7 +14504,7 @@ "**" ], "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14502,14 +14512,14 @@ ], "license_file": "LICENSE" }, - "cranelift-control 0.114.0": { + "cranelift-control 0.115.0": { "name": "cranelift-control", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-control/0.114.0/download", - "sha256": "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" + "url": "https://static.crates.io/crates/cranelift-control/0.115.0/download", + "sha256": "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd" } }, "targets": [ @@ -14548,7 +14558,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14556,14 +14566,14 @@ ], "license_file": "LICENSE" }, - "cranelift-entity 0.114.0": { + "cranelift-entity 0.115.0": { "name": "cranelift-entity", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-entity/0.114.0/download", - "sha256": "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" + "url": "https://static.crates.io/crates/cranelift-entity/0.115.0/download", + "sha256": "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84" } }, "targets": [ @@ -14596,7 +14606,7 @@ "deps": { "common": [ { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { @@ -14616,7 +14626,7 @@ ], "selects": {} }, - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14624,14 +14634,14 @@ ], "license_file": "LICENSE" }, - "cranelift-frontend 0.114.0": { + "cranelift-frontend 0.115.0": { "name": "cranelift-frontend", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-frontend/0.114.0/download", - "sha256": "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" + "url": "https://static.crates.io/crates/cranelift-frontend/0.115.0/download", + "sha256": "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7" } }, "targets": [ @@ -14663,7 +14673,7 @@ "deps": { "common": [ { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { @@ -14682,7 +14692,7 @@ "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -14690,14 +14700,14 @@ ], "license_file": "LICENSE" }, - "cranelift-isle 0.114.0": { + "cranelift-isle 0.115.0": { "name": "cranelift-isle", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime/tree/main/cranelift/isle", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-isle/0.114.0/download", - "sha256": "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8", + "url": "https://static.crates.io/crates/cranelift-isle/0.115.0/download", + "sha256": "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0", "patch_args": [ "-p4" ], @@ -14746,14 +14756,14 @@ "deps": { "common": [ { - "id": "cranelift-isle 0.114.0", + "id": "cranelift-isle 0.115.0", "target": "build_script_build" } ], "selects": {} }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -14769,14 +14779,14 @@ ], "license_file": null }, - "cranelift-native 0.114.0": { + "cranelift-native 0.115.0": { "name": "cranelift-native", - "version": "0.114.0", + "version": "0.115.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/cranelift-native/0.114.0/download", - "sha256": "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" + "url": "https://static.crates.io/crates/cranelift-native/0.115.0/download", + "sha256": "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7" } }, "targets": [ @@ -14808,7 +14818,7 @@ "deps": { "common": [ { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { @@ -14826,7 +14836,7 @@ } }, "edition": "2021", - "version": "0.114.0" + "version": "0.115.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -19391,11 +19401,11 @@ "target": "wasmprinter" }, { - "id": "wasmtime 27.0.0", + "id": "wasmtime 28.0.0", "target": "wasmtime" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" }, { @@ -24099,6 +24109,44 @@ ], "license_file": "LICENSE-APACHE" }, + "foldhash 0.1.4": { + "name": "foldhash", + "version": "0.1.4", + "package_url": "https://github.com/orlp/foldhash", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/foldhash/0.1.4/download", + "sha256": "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "foldhash", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "foldhash", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.1.4" + }, + "license": "Zlib", + "license_ids": [ + "Zlib" + ], + "license_file": "LICENSE" + }, "form_urlencoded 1.2.1": { "name": "form_urlencoded", "version": "1.2.1", @@ -26368,7 +26416,7 @@ "target": "ahash" }, { - "id": "allocator-api2 0.2.16", + "id": "allocator-api2 0.2.21", "target": "allocator_api2" }, { @@ -26388,6 +26436,60 @@ ], "license_file": "LICENSE-APACHE" }, + "hashbrown 0.15.2": { + "name": "hashbrown", + "version": "0.15.2", + "package_url": "https://github.com/rust-lang/hashbrown", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/hashbrown/0.15.2/download", + "sha256": "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + } + }, + "targets": [ + { + "Library": { + "crate_name": "hashbrown", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "hashbrown", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default-hasher" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "foldhash 0.1.4", + "target": "foldhash" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.15.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, "hashlink 0.8.3": { "name": "hashlink", "version": "0.8.3", @@ -44245,14 +44347,14 @@ ], "license_file": "LICENSE-APACHE" }, - "object 0.36.1": { + "object 0.36.7": { "name": "object", - "version": "0.36.1", + "version": "0.36.7", "package_url": "https://github.com/gimli-rs/object", "repository": { "Http": { - "url": "https://static.crates.io/crates/object/0.36.1/download", - "sha256": "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" + "url": "https://static.crates.io/crates/object/0.36.7/download", + "sha256": "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" } }, "targets": [ @@ -44267,6 +44369,18 @@ ] } } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } } ], "library_target_name": "object", @@ -44296,7 +44410,7 @@ "target": "crc32fast" }, { - "id": "hashbrown 0.14.5", + "id": "hashbrown 0.15.2", "target": "hashbrown" }, { @@ -44306,12 +44420,24 @@ { "id": "memchr 2.7.4", "target": "memchr" + }, + { + "id": "object 0.36.7", + "target": "build_script_build" } ], "selects": {} }, "edition": "2018", - "version": "0.36.1" + "version": "0.36.7" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] }, "license": "Apache-2.0 OR MIT", "license_ids": [ @@ -52353,14 +52479,14 @@ ], "license_file": "LICENSE" }, - "pulley-interpreter 27.0.0": { + "pulley-interpreter 28.0.0": { "name": "pulley-interpreter", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime/tree/main/pulley", "repository": { "Http": { - "url": "https://static.crates.io/crates/pulley-interpreter/27.0.0/download", - "sha256": "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" + "url": "https://static.crates.io/crates/pulley-interpreter/28.0.0/download", + "sha256": "403a1a95f4c18a45c86c7bff13df00347afd0abcbf2e54af273c837339ffcf77" } }, "targets": [ @@ -52385,7 +52511,7 @@ "deps": { "common": [ { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { @@ -52400,7 +52526,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -54939,14 +55065,14 @@ ], "license_file": "LICENSE" }, - "regalloc2 0.10.2": { + "regalloc2 0.11.1": { "name": "regalloc2", - "version": "0.10.2", + "version": "0.11.1", "package_url": "https://github.com/bytecodealliance/regalloc2", "repository": { "Http": { - "url": "https://static.crates.io/crates/regalloc2/0.10.2/download", - "sha256": "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" + "url": "https://static.crates.io/crates/regalloc2/0.11.1/download", + "sha256": "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3" } }, "targets": [ @@ -54979,7 +55105,15 @@ "deps": { "common": [ { - "id": "hashbrown 0.14.5", + "id": "allocator-api2 0.2.21", + "target": "allocator_api2" + }, + { + "id": "bumpalo 3.16.0", + "target": "bumpalo" + }, + { + "id": "hashbrown 0.15.2", "target": "hashbrown" }, { @@ -54990,10 +55124,6 @@ "id": "rustc-hash 2.0.0", "target": "rustc_hash" }, - { - "id": "slice-group-by 0.3.1", - "target": "slice_group_by" - }, { "id": "smallvec 1.13.2", "target": "smallvec" @@ -55002,7 +55132,7 @@ "selects": {} }, "edition": "2018", - "version": "0.10.2" + "version": "0.11.1" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -66547,44 +66677,6 @@ ], "license_file": "LICENSE" }, - "slice-group-by 0.3.1": { - "name": "slice-group-by", - "version": "0.3.1", - "package_url": "https://github.com/Kerollmops/slice-group-by", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/slice-group-by/0.3.1/download", - "sha256": "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - } - }, - "targets": [ - { - "Library": { - "crate_name": "slice_group_by", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "slice_group_by", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.3.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, "slog 2.7.0": { "name": "slog", "version": "2.7.0", @@ -78902,14 +78994,14 @@ ], "license_file": null }, - "wasm-encoder 0.219.1": { + "wasm-encoder 0.221.2": { "name": "wasm-encoder", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasm-encoder/0.219.1/download", - "sha256": "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" + "url": "https://static.crates.io/crates/wasm-encoder/0.221.2/download", + "sha256": "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" } }, "targets": [ @@ -78948,7 +79040,7 @@ "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79307,14 +79399,14 @@ ], "license_file": null }, - "wasmparser 0.219.1": { + "wasmparser 0.221.2": { "name": "wasmparser", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmparser/0.219.1/download", - "sha256": "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" + "url": "https://static.crates.io/crates/wasmparser/0.221.2/download", + "sha256": "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" } }, "targets": [ @@ -79329,6 +79421,18 @@ ] } } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } } ], "library_target_name": "wasmparser", @@ -79341,6 +79445,7 @@ "component-model", "features", "serde", + "simd", "std", "validate" ], @@ -79348,22 +79453,10 @@ }, "deps": { "common": [ - { - "id": "ahash 0.8.11", - "target": "ahash" - }, { "id": "bitflags 2.6.0", "target": "bitflags" }, - { - "id": "hashbrown 0.14.5", - "target": "hashbrown" - }, - { - "id": "indexmap 2.2.6", - "target": "indexmap" - }, { "id": "semver 1.0.22", "target": "semver" @@ -79371,12 +79464,24 @@ { "id": "serde 1.0.217", "target": "serde" + }, + { + "id": "wasmparser 0.221.2", + "target": "build_script_build" } ], "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79441,14 +79546,14 @@ ], "license_file": null }, - "wasmprinter 0.219.1": { + "wasmprinter 0.221.2": { "name": "wasmprinter", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmprinter", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmprinter/0.219.1/download", - "sha256": "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" + "url": "https://static.crates.io/crates/wasmprinter/0.221.2/download", + "sha256": "a80742ff1b9e6d8c231ac7c7247782c6fc5bce503af760bca071811e5fc9ee56" } }, "targets": [ @@ -79488,14 +79593,14 @@ "target": "termcolor" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" } ], "selects": {} }, "edition": "2021", - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -79504,14 +79609,14 @@ ], "license_file": null }, - "wasmtime 27.0.0": { + "wasmtime 28.0.0": { "name": "wasmtime", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime/27.0.0/download", - "sha256": "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" + "url": "https://static.crates.io/crates/wasmtime/28.0.0/download", + "sha256": "f639ecae347b9a2227e453a7b7671e84370a0b61f47a15e0390fe9b7725e47b3" } }, "targets": [ @@ -79553,6 +79658,7 @@ "once_cell", "parallel-compilation", "runtime", + "signals-based-traps", "std" ], "selects": {} @@ -79596,7 +79702,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -79628,31 +79734,31 @@ "target": "target_lexicon" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmtime 27.0.0", + "id": "wasmtime 28.0.0", "target": "build_script_build" }, { - "id": "wasmtime-asm-macros 27.0.0", + "id": "wasmtime-asm-macros 28.0.0", "target": "wasmtime_asm_macros" }, { - "id": "wasmtime-cranelift 27.0.0", + "id": "wasmtime-cranelift 28.0.0", "target": "wasmtime_cranelift" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" }, { - "id": "wasmtime-jit-icache-coherence 27.0.0", + "id": "wasmtime-jit-icache-coherence 28.0.0", "target": "wasmtime_jit_icache_coherence" }, { - "id": "wasmtime-slab 27.0.0", + "id": "wasmtime-slab 28.0.0", "target": "wasmtime_slab" } ], @@ -79885,13 +79991,13 @@ "target": "serde_derive" }, { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -79912,7 +80018,7 @@ "proc_macro_deps": { "common": [ { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], @@ -79925,14 +80031,14 @@ ], "license_file": "LICENSE" }, - "wasmtime-asm-macros 27.0.0": { + "wasmtime-asm-macros 28.0.0": { "name": "wasmtime-asm-macros", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-asm-macros/27.0.0/download", - "sha256": "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" + "url": "https://static.crates.io/crates/wasmtime-asm-macros/28.0.0/download", + "sha256": "882a18800471cfc063c8b3ccf75723784acc3fd534009ac09421f2fac2fcdcec" } }, "targets": [ @@ -79964,7 +80070,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -79972,14 +80078,14 @@ ], "license_file": null }, - "wasmtime-component-macro 27.0.0": { + "wasmtime-component-macro 28.0.0": { "name": "wasmtime-component-macro", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-component-macro/27.0.0/download", - "sha256": "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" + "url": "https://static.crates.io/crates/wasmtime-component-macro/28.0.0/download", + "sha256": "eb5c0a77c9e1927c3d471f53cc13767c3d3438e5d5ffd394e3eb31c86445fd60" } }, "targets": [ @@ -80032,26 +80138,26 @@ "target": "syn" }, { - "id": "wasmtime-component-macro 27.0.0", + "id": "wasmtime-component-macro 28.0.0", "target": "build_script_build" }, { - "id": "wasmtime-component-util 27.0.0", + "id": "wasmtime-component-util 28.0.0", "target": "wasmtime_component_util" }, { - "id": "wasmtime-wit-bindgen 27.0.0", + "id": "wasmtime-wit-bindgen 28.0.0", "target": "wasmtime_wit_bindgen" }, { - "id": "wit-parser 0.219.1", + "id": "wit-parser 0.221.2", "target": "wit_parser" } ], "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "build_script_attrs": { "compile_data_glob": [ @@ -80067,14 +80173,14 @@ ], "license_file": null }, - "wasmtime-component-util 27.0.0": { + "wasmtime-component-util 28.0.0": { "name": "wasmtime-component-util", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-component-util/27.0.0/download", - "sha256": "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" + "url": "https://static.crates.io/crates/wasmtime-component-util/28.0.0/download", + "sha256": "43702ca98bf5162eca0573db691ed9ecd36d716f8c6688410fe26ec16b6f9bcb" } }, "targets": [ @@ -80097,7 +80203,7 @@ "**" ], "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80105,14 +80211,14 @@ ], "license_file": null }, - "wasmtime-cranelift 27.0.0": { + "wasmtime-cranelift 28.0.0": { "name": "wasmtime-cranelift", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-cranelift/27.0.0/download", - "sha256": "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" + "url": "https://static.crates.io/crates/wasmtime-cranelift/28.0.0/download", + "sha256": "20070aa5b75080a8932ec328419faf841df2bc6ceb16b55b0df2b952098392a2" } }, "targets": [ @@ -80152,23 +80258,23 @@ "target": "cfg_if" }, { - "id": "cranelift-codegen 0.114.0", + "id": "cranelift-codegen 0.115.0", "target": "cranelift_codegen" }, { - "id": "cranelift-control 0.114.0", + "id": "cranelift-control 0.115.0", "target": "cranelift_control" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { - "id": "cranelift-frontend 0.114.0", + "id": "cranelift-frontend 0.115.0", "target": "cranelift_frontend" }, { - "id": "cranelift-native 0.114.0", + "id": "cranelift-native 0.115.0", "target": "cranelift_native" }, { @@ -80184,7 +80290,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -80200,11 +80306,11 @@ "target": "thiserror" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmtime-environ 27.0.0", + "id": "wasmtime-environ 28.0.0", "target": "wasmtime_environ" } ], @@ -80214,13 +80320,13 @@ "proc_macro_deps": { "common": [ { - "id": "wasmtime-versioned-export-macros 27.0.0", + "id": "wasmtime-versioned-export-macros 28.0.0", "target": "wasmtime_versioned_export_macros" } ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80228,14 +80334,14 @@ ], "license_file": "LICENSE" }, - "wasmtime-environ 27.0.0": { + "wasmtime-environ 28.0.0": { "name": "wasmtime-environ", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-environ/27.0.0/download", - "sha256": "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" + "url": "https://static.crates.io/crates/wasmtime-environ/28.0.0/download", + "sha256": "2604ddb24879d4dc1dedcb7081d7a8e017259bce916fdae097a97db52cbaab80" } }, "targets": [ @@ -80273,11 +80379,11 @@ "target": "anyhow" }, { - "id": "cranelift-bitset 0.114.0", + "id": "cranelift-bitset 0.115.0", "target": "cranelift_bitset" }, { - "id": "cranelift-entity 0.114.0", + "id": "cranelift-entity 0.115.0", "target": "cranelift_entity" }, { @@ -80293,7 +80399,7 @@ "target": "log" }, { - "id": "object 0.36.1", + "id": "object 0.36.7", "target": "object" }, { @@ -80313,15 +80419,15 @@ "target": "target_lexicon" }, { - "id": "wasm-encoder 0.219.1", + "id": "wasm-encoder 0.221.2", "target": "wasm_encoder" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" }, { - "id": "wasmprinter 0.219.1", + "id": "wasmprinter 0.221.2", "target": "wasmprinter" } ], @@ -80337,7 +80443,126 @@ ], "selects": {} }, - "version": "27.0.0" + "version": "28.0.0" + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, + "wasmtime-fiber 28.0.0": { + "name": "wasmtime-fiber", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasmtime-fiber/28.0.0/download", + "sha256": "98593412d2b167ebe2b59d4a17a184978a72f976b53b3a0ec05629451079ac1d" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasmtime_fiber", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasmtime_fiber", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "wasmtime-asm-macros 28.0.0", + "target": "wasmtime_asm_macros" + }, + { + "id": "wasmtime-fiber 28.0.0", + "target": "build_script_build" + } + ], + "selects": { + "cfg(unix)": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], + "cfg(windows)": [ + { + "id": "windows-sys 0.59.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "wasmtime-versioned-export-macros 28.0.0", + "target": "wasmtime_versioned_export_macros" + } + ], + "selects": {} + }, + "version": "28.0.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "cc 1.0.83", + "target": "cc" + } + ], + "selects": {} + }, + "proc_macro_deps": { + "common": [ + { + "id": "wasmtime-versioned-export-macros 28.0.0", + "target": "wasmtime_versioned_export_macros" + } + ], + "selects": {} + } }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80345,14 +80570,14 @@ ], "license_file": "LICENSE" }, - "wasmtime-jit-icache-coherence 27.0.0": { + "wasmtime-jit-icache-coherence 28.0.0": { "name": "wasmtime-jit-icache-coherence", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-jit-icache-coherence/27.0.0/download", - "sha256": "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" + "url": "https://static.crates.io/crates/wasmtime-jit-icache-coherence/28.0.0/download", + "sha256": "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d" } }, "targets": [ @@ -80401,7 +80626,7 @@ } }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80409,14 +80634,14 @@ ], "license_file": null }, - "wasmtime-slab 27.0.0": { + "wasmtime-slab 28.0.0": { "name": "wasmtime-slab", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-slab/27.0.0/download", - "sha256": "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" + "url": "https://static.crates.io/crates/wasmtime-slab/28.0.0/download", + "sha256": "8579c335220b4ece9aa490a0e8b46de78cd342b195ab21ff981d095e14b52383" } }, "targets": [ @@ -80439,7 +80664,7 @@ "**" ], "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80447,14 +80672,14 @@ ], "license_file": null }, - "wasmtime-versioned-export-macros 27.0.0": { + "wasmtime-versioned-export-macros 28.0.0": { "name": "wasmtime-versioned-export-macros", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-versioned-export-macros/27.0.0/download", - "sha256": "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" + "url": "https://static.crates.io/crates/wasmtime-versioned-export-macros/28.0.0/download", + "sha256": "d7de0a56fb0a69b185968f2d7a9ba54750920a806470dff7ad8de91ac06d277e" } }, "targets": [ @@ -80494,7 +80719,7 @@ "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -80502,14 +80727,93 @@ ], "license_file": null }, - "wasmtime-wit-bindgen 27.0.0": { + "wasmtime-winch 28.0.0": { + "name": "wasmtime-winch", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasmtime-winch/28.0.0/download", + "sha256": "abd309943c443f5590d12f9aba9ba63c481091c955a0a14de0c2a9e0e3aaeca9" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasmtime_winch", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasmtime_winch", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cranelift-codegen 0.115.0", + "target": "cranelift_codegen" + }, + { + "id": "gimli 0.31.1", + "target": "gimli" + }, + { + "id": "object 0.36.7", + "target": "object" + }, + { + "id": "target-lexicon 0.12.16", + "target": "target_lexicon" + }, + { + "id": "wasmparser 0.221.2", + "target": "wasmparser" + }, + { + "id": "wasmtime-cranelift 28.0.0", + "target": "wasmtime_cranelift" + }, + { + "id": "wasmtime-environ 28.0.0", + "target": "wasmtime_environ" + }, + { + "id": "winch-codegen 28.0.0", + "target": "winch_codegen" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "28.0.0" + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, + "wasmtime-wit-bindgen 28.0.0": { "name": "wasmtime-wit-bindgen", - "version": "27.0.0", + "version": "28.0.0", "package_url": "https://github.com/bytecodealliance/wasmtime", "repository": { "Http": { - "url": "https://static.crates.io/crates/wasmtime-wit-bindgen/27.0.0/download", - "sha256": "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" + "url": "https://static.crates.io/crates/wasmtime-wit-bindgen/28.0.0/download", + "sha256": "969f83022dac3435d6469edb582ceed04cfe32aa44dc3ef16e5cb55574633df8" } }, "targets": [ @@ -80546,14 +80850,14 @@ "target": "indexmap" }, { - "id": "wit-parser 0.219.1", + "id": "wit-parser 0.221.2", "target": "wit_parser" } ], "selects": {} }, "edition": "2021", - "version": "27.0.0" + "version": "28.0.0" }, "license": "Apache-2.0 WITH LLVM-exception", "license_ids": [ @@ -81516,6 +81820,109 @@ ], "license_file": null }, + "winch-codegen 28.0.0": { + "name": "winch-codegen", + "version": "28.0.0", + "package_url": "https://github.com/bytecodealliance/wasmtime", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/winch-codegen/28.0.0/download", + "sha256": "9110decc2983ed94de904804dcd979ba59cbabc78a94fec6b1d8468ec513d0f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "winch_codegen", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "winch_codegen", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.93", + "target": "anyhow" + }, + { + "id": "cranelift-codegen 0.115.0", + "target": "cranelift_codegen" + }, + { + "id": "gimli 0.31.1", + "target": "gimli" + }, + { + "id": "regalloc2 0.11.1", + "target": "regalloc2" + }, + { + "id": "smallvec 1.13.2", + "target": "smallvec" + }, + { + "id": "target-lexicon 0.12.16", + "target": "target_lexicon" + }, + { + "id": "wasmparser 0.221.2", + "target": "wasmparser" + }, + { + "id": "wasmtime-cranelift 28.0.0", + "target": "wasmtime_cranelift" + }, + { + "id": "wasmtime-environ 28.0.0", + "target": "wasmtime_environ" + }, + { + "id": "winch-codegen 28.0.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "28.0.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "Apache-2.0 WITH LLVM-exception", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, "windows-core 0.52.0": { "name": "windows-core", "version": "0.52.0", @@ -83971,14 +84378,14 @@ ], "license_file": "LICENSE" }, - "wit-parser 0.219.1": { + "wit-parser 0.221.2": { "name": "wit-parser", - "version": "0.219.1", + "version": "0.221.2", "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-parser", "repository": { "Http": { - "url": "https://static.crates.io/crates/wit-parser/0.219.1/download", - "sha256": "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" + "url": "https://static.crates.io/crates/wit-parser/0.221.2/download", + "sha256": "fbe1538eea6ea5ddbe5defd0dc82539ad7ba751e1631e9185d24a931f0a5adc8" } }, "targets": [ @@ -84044,7 +84451,7 @@ "target": "unicode_xid" }, { - "id": "wasmparser 0.219.1", + "id": "wasmparser 0.221.2", "target": "wasmparser" } ], @@ -84060,7 +84467,7 @@ ], "selects": {} }, - "version": "0.219.1" + "version": "0.221.2" }, "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "license_ids": [ @@ -87011,8 +87418,8 @@ "wasm-smith 0.212.0", "wasmparser 0.217.0", "wasmprinter 0.217.0", - "wasmtime 27.0.0", - "wasmtime-environ 27.0.0", + "wasmtime 28.0.0", + "wasmtime-environ 28.0.0", "wast 212.0.0", "wat 1.212.0", "wee_alloc 0.4.5", diff --git a/Cargo.Bazel.toml.lock b/Cargo.Bazel.toml.lock index 000a15ed28e..c017af7c37a 100644 --- a/Cargo.Bazel.toml.lock +++ b/Cargo.Bazel.toml.lock @@ -338,9 +338,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -1531,6 +1531,9 @@ name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "by_address" @@ -2350,18 +2353,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" +checksum = "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" +checksum = "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a" dependencies = [ "serde", "serde_derive", @@ -2369,9 +2372,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" +checksum = "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35" dependencies = [ "bumpalo", "cranelift-bforest", @@ -2393,33 +2396,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7" +checksum = "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" +checksum = "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181" [[package]] name = "cranelift-control" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" +checksum = "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" +checksum = "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84" dependencies = [ "cranelift-bitset", "serde", @@ -2428,9 +2431,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" +checksum = "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7" dependencies = [ "cranelift-codegen", "log", @@ -2440,15 +2443,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8" +checksum = "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0" [[package]] name = "cranelift-native" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" +checksum = "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7" dependencies = [ "cranelift-codegen", "libc", @@ -3988,6 +3991,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -4369,6 +4378,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", + "serde", +] + [[package]] name = "hashlink" version = "0.8.3" @@ -7303,12 +7322,12 @@ dependencies = [ [[package]] name = "object" -version = "0.36.1" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "crc32fast", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap 2.2.6", "memchr", ] @@ -8656,9 +8675,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" +checksum = "403a1a95f4c18a45c86c7bff13df00347afd0abcbf2e54af273c837339ffcf77" dependencies = [ "cranelift-bitset", "log", @@ -9067,14 +9086,15 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.10.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" +checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3" dependencies = [ - "hashbrown 0.14.5", + "allocator-api2", + "bumpalo", + "hashbrown 0.15.2", "log", "rustc-hash 2.0.0", - "slice-group-by", "smallvec", ] @@ -10443,12 +10463,6 @@ dependencies = [ "autocfg 1.1.0", ] -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - [[package]] name = "slog" version = "2.7.0" @@ -12352,12 +12366,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" +checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" dependencies = [ "leb128", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] @@ -12429,13 +12443,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" +checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" dependencies = [ - "ahash 0.8.11", "bitflags 2.6.0", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap 2.2.6", "semver", "serde", @@ -12454,20 +12467,20 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" +checksum = "a80742ff1b9e6d8c231ac7c7247782c6fc5bce503af760bca071811e5fc9ee56" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] name = "wasmtime" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" +checksum = "f639ecae347b9a2227e453a7b7671e84370a0b61f47a15e0390fe9b7725e47b3" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -12481,7 +12494,7 @@ dependencies = [ "log", "mach2", "memfd", - "object 0.36.1", + "object 0.36.7", "once_cell", "paste", "postcard", @@ -12494,31 +12507,33 @@ dependencies = [ "smallvec", "sptr", "target-lexicon", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-cranelift", "wasmtime-environ", + "wasmtime-fiber", "wasmtime-jit-icache-coherence", "wasmtime-slab", "wasmtime-versioned-export-macros", + "wasmtime-winch", "windows-sys 0.59.0", ] [[package]] name = "wasmtime-asm-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" +checksum = "882a18800471cfc063c8b3ccf75723784acc3fd534009ac09421f2fac2fcdcec" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "wasmtime-component-macro" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" +checksum = "eb5c0a77c9e1927c3d471f53cc13767c3d3438e5d5ffd394e3eb31c86445fd60" dependencies = [ "anyhow", "proc-macro2", @@ -12531,15 +12546,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" +checksum = "43702ca98bf5162eca0573db691ed9ecd36d716f8c6688410fe26ec16b6f9bcb" [[package]] name = "wasmtime-cranelift" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" +checksum = "20070aa5b75080a8932ec328419faf841df2bc6ceb16b55b0df2b952098392a2" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -12551,20 +12566,20 @@ dependencies = [ "gimli 0.31.1", "itertools 0.12.0", "log", - "object 0.36.1", + "object 0.36.7", "smallvec", "target-lexicon", "thiserror 1.0.68", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-environ", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-environ" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" +checksum = "2604ddb24879d4dc1dedcb7081d7a8e017259bce916fdae097a97db52cbaab80" dependencies = [ "anyhow", "cranelift-bitset", @@ -12572,22 +12587,37 @@ dependencies = [ "gimli 0.31.1", "indexmap 2.2.6", "log", - "object 0.36.1", + "object 0.36.7", "postcard", "serde", "serde_derive", "smallvec", "target-lexicon", - "wasm-encoder 0.219.1", - "wasmparser 0.219.1", - "wasmprinter 0.219.1", + "wasm-encoder 0.221.2", + "wasmparser 0.221.2", + "wasmprinter 0.221.2", +] + +[[package]] +name = "wasmtime-fiber" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98593412d2b167ebe2b59d4a17a184978a72f976b53b3a0ec05629451079ac1d" +dependencies = [ + "anyhow", + "cc", + "cfg-if 1.0.0", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.59.0", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" +checksum = "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -12597,26 +12627,43 @@ dependencies = [ [[package]] name = "wasmtime-slab" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" +checksum = "8579c335220b4ece9aa490a0e8b46de78cd342b195ab21ff981d095e14b52383" [[package]] name = "wasmtime-versioned-export-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" +checksum = "d7de0a56fb0a69b185968f2d7a9ba54750920a806470dff7ad8de91ac06d277e" dependencies = [ "proc-macro2", "quote", "syn 2.0.87", ] +[[package]] +name = "wasmtime-winch" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd309943c443f5590d12f9aba9ba63c481091c955a0a14de0c2a9e0e3aaeca9" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "object 0.36.7", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", + "winch-codegen", +] + [[package]] name = "wasmtime-wit-bindgen" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" +checksum = "969f83022dac3435d6469edb582ceed04cfe32aa44dc3ef16e5cb55574633df8" dependencies = [ "anyhow", "heck 0.5.0", @@ -12756,6 +12803,23 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winch-codegen" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9110decc2983ed94de904804dcd979ba59cbabc78a94fec6b1d8468ec513d0f6" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -13039,9 +13103,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" +checksum = "fbe1538eea6ea5ddbe5defd0dc82539ad7ba751e1631e9185d24a931f0a5adc8" dependencies = [ "anyhow", "id-arena", @@ -13052,7 +13116,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] diff --git a/Cargo.lock b/Cargo.lock index df0f6ed8a2c..6de323b83c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1524,6 +1524,9 @@ name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "by_address" @@ -2688,18 +2691,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" +checksum = "ac89549be94911dd0e839b4a7db99e9ed29c17517e1c026f61066884c168aa3c" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" +checksum = "b9bd49369f76c77e34e641af85d0956869237832c118964d08bf5f51f210875a" dependencies = [ "serde", "serde_derive", @@ -2707,9 +2710,9 @@ dependencies = [ [[package]] name = "cranelift-codegen" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" +checksum = "fd96ce9cf8efebd7f5ab8ced5a0ce44250280bbae9f593d74a6d7effc3582a35" dependencies = [ "bumpalo", "cranelift-bforest", @@ -2731,33 +2734,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7" +checksum = "5a68e358827afe4bfb6239fcbf6fbd5ac56206ece8a99c8f5f9bbd518773281a" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" +checksum = "e184c9767afbe73d50c55ec29abcf4c32f9baf0d9d22b86d58c4d55e06dee181" [[package]] name = "cranelift-control" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" +checksum = "5cc7664f2a66f053e33f149e952bb5971d138e3af637f5097727ed6dc0ed95dd" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" +checksum = "118597e3a9cf86c3556fa579a7a23b955fa18231651a52a77a2475d305a9cf84" dependencies = [ "cranelift-bitset", "serde", @@ -2766,9 +2769,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" +checksum = "7638ea1efb069a0aa18d8ee67401b6b0d19f6bfe5de5e9ede348bfc80bb0d8c7" dependencies = [ "cranelift-codegen", "log", @@ -2778,15 +2781,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8" +checksum = "15c53e1152a0b01c4ed2b1e0535602b8e86458777dd9d18b28732b16325c7dc0" [[package]] name = "cranelift-native" -version = "0.114.0" +version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" +checksum = "7b7d8f895444fa52dd7bdd0bed11bf007a7fb43af65a6deac8fcc4094c6372f7" dependencies = [ "cranelift-codegen", "libc", @@ -4678,6 +4681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "foldhash", + "serde", ] [[package]] @@ -17774,9 +17778,9 @@ dependencies = [ [[package]] name = "pulley-interpreter" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" +checksum = "403a1a95f4c18a45c86c7bff13df00347afd0abcbf2e54af273c837339ffcf77" dependencies = [ "cranelift-bitset", "log", @@ -18252,14 +18256,15 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.10.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" +checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3" dependencies = [ - "hashbrown 0.14.5", + "allocator-api2", + "bumpalo", + "hashbrown 0.15.2", "log", "rustc-hash 2.1.0", - "slice-group-by", "smallvec", ] @@ -19882,12 +19887,6 @@ dependencies = [ "autocfg 1.4.0", ] -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - [[package]] name = "slog" version = "2.7.0" @@ -22057,12 +22056,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" +checksum = "c17a3bd88f2155da63a1f2fcb8a56377a24f0b6dfed12733bb5f544e86f690c5" dependencies = [ "leb128", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] @@ -22118,13 +22117,12 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" +checksum = "9845c470a2e10b61dd42c385839cdd6496363ed63b5c9e420b5488b77bd22083" dependencies = [ - "ahash 0.8.11", "bitflags 2.6.0", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "indexmap 2.7.0", "semver", "serde", @@ -22154,20 +22152,20 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" +checksum = "a80742ff1b9e6d8c231ac7c7247782c6fc5bce503af760bca071811e5fc9ee56" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] name = "wasmtime" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" +checksum = "f639ecae347b9a2227e453a7b7671e84370a0b61f47a15e0390fe9b7725e47b3" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -22194,31 +22192,33 @@ dependencies = [ "smallvec", "sptr", "target-lexicon", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-asm-macros", "wasmtime-component-macro", "wasmtime-cranelift", "wasmtime-environ", + "wasmtime-fiber", "wasmtime-jit-icache-coherence", "wasmtime-slab", "wasmtime-versioned-export-macros", + "wasmtime-winch", "windows-sys 0.59.0", ] [[package]] name = "wasmtime-asm-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" +checksum = "882a18800471cfc063c8b3ccf75723784acc3fd534009ac09421f2fac2fcdcec" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "wasmtime-component-macro" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" +checksum = "eb5c0a77c9e1927c3d471f53cc13767c3d3438e5d5ffd394e3eb31c86445fd60" dependencies = [ "anyhow", "proc-macro2", @@ -22231,15 +22231,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" +checksum = "43702ca98bf5162eca0573db691ed9ecd36d716f8c6688410fe26ec16b6f9bcb" [[package]] name = "wasmtime-cranelift" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" +checksum = "20070aa5b75080a8932ec328419faf841df2bc6ceb16b55b0df2b952098392a2" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -22255,16 +22255,16 @@ dependencies = [ "smallvec", "target-lexicon", "thiserror 1.0.69", - "wasmparser 0.219.1", + "wasmparser 0.221.2", "wasmtime-environ", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-environ" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" +checksum = "2604ddb24879d4dc1dedcb7081d7a8e017259bce916fdae097a97db52cbaab80" dependencies = [ "anyhow", "cranelift-bitset", @@ -22278,16 +22278,31 @@ dependencies = [ "serde_derive", "smallvec", "target-lexicon", - "wasm-encoder 0.219.1", - "wasmparser 0.219.1", - "wasmprinter 0.219.1", + "wasm-encoder 0.221.2", + "wasmparser 0.221.2", + "wasmprinter 0.221.2", +] + +[[package]] +name = "wasmtime-fiber" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98593412d2b167ebe2b59d4a17a184978a72f976b53b3a0ec05629451079ac1d" +dependencies = [ + "anyhow", + "cc", + "cfg-if 1.0.0", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.59.0", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" +checksum = "d40d7722b9e1fbeae135715710a8a2570b1e6cf72b74dd653962d89831c6c70d" dependencies = [ "anyhow", "cfg-if 1.0.0", @@ -22297,26 +22312,43 @@ dependencies = [ [[package]] name = "wasmtime-slab" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" +checksum = "8579c335220b4ece9aa490a0e8b46de78cd342b195ab21ff981d095e14b52383" [[package]] name = "wasmtime-versioned-export-macros" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" +checksum = "d7de0a56fb0a69b185968f2d7a9ba54750920a806470dff7ad8de91ac06d277e" dependencies = [ "proc-macro2", "quote", "syn 2.0.90", ] +[[package]] +name = "wasmtime-winch" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd309943c443f5590d12f9aba9ba63c481091c955a0a14de0c2a9e0e3aaeca9" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "object", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", + "winch-codegen", +] + [[package]] name = "wasmtime-wit-bindgen" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" +checksum = "969f83022dac3435d6469edb582ceed04cfe32aa44dc3ef16e5cb55574633df8" dependencies = [ "anyhow", "heck 0.5.0", @@ -22482,6 +22514,23 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winch-codegen" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9110decc2983ed94de904804dcd979ba59cbabc78a94fec6b1d8468ec513d0f6" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli 0.31.1", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser 0.221.2", + "wasmtime-cranelift", + "wasmtime-environ", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -22696,9 +22745,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wit-parser" -version = "0.219.1" +version = "0.221.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" +checksum = "fbe1538eea6ea5ddbe5defd0dc82539ad7ba751e1631e9185d24a931f0a5adc8" dependencies = [ "anyhow", "id-arena", @@ -22709,7 +22758,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.219.1", + "wasmparser 0.221.2", ] [[package]] diff --git a/bazel/external_crates.bzl b/bazel/external_crates.bzl index 683723af702..a62c47466ce 100644 --- a/bazel/external_crates.bzl +++ b/bazel/external_crates.bzl @@ -1430,7 +1430,7 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable version = "^0.217.0", ), "wasmtime": crate.spec( - version = "^27.0.0", + version = "^28.0.0", default_features = False, features = [ "cranelift", @@ -1441,7 +1441,7 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable ], ), "wasmtime-environ": crate.spec( - version = "^27.0.0", + version = "^28.0.0", ), "wast": crate.spec( version = "^212.0.0", diff --git a/rs/embedders/Cargo.toml b/rs/embedders/Cargo.toml index 32002a3b310..53a1736e80f 100644 --- a/rs/embedders/Cargo.toml +++ b/rs/embedders/Cargo.toml @@ -39,14 +39,14 @@ slog-term = { workspace = true } tempfile = { workspace = true } wasm-encoder = { workspace = true } wasmparser = { workspace = true } -wasmtime = { version = "27.0.0", default-features = false, features = [ +wasmtime = { version = "28.0.0", default-features = false, features = [ 'cranelift', 'gc', 'gc-null', 'parallel-compilation', 'runtime', ] } -wasmtime-environ = "27.0.0" +wasmtime-environ = "28.0.0" # Wasmtime depends on 0.4.2 but specifies 0.4.1 in the toml file. # Enforce 0.4.2 using a dummy dependency until the upstream issue diff --git a/rs/embedders/src/wasm_utils/validation.rs b/rs/embedders/src/wasm_utils/validation.rs index a6d661236a4..9b8cd727a71 100644 --- a/rs/embedders/src/wasm_utils/validation.rs +++ b/rs/embedders/src/wasm_utils/validation.rs @@ -1472,7 +1472,7 @@ pub fn wasmtime_validation_config(embedders_config: &EmbeddersConfig) -> wasmtim // expect to see then the changes will likely need to be coordinated // with a change in how we create the memories in the implementation // of `wasmtime::MemoryCreator`. - .static_memory_maximum_size(MAX_STABLE_MEMORY_IN_BYTES) + .memory_reservation(MAX_STABLE_MEMORY_IN_BYTES) .guard_before_linear_memory(true) .memory_guard_size(MIN_GUARD_REGION_SIZE as u64) .max_wasm_stack(MAX_WASM_STACK_SIZE); diff --git a/rs/embedders/src/wasmtime_embedder/host_memory.rs b/rs/embedders/src/wasmtime_embedder/host_memory.rs index edd89943ed1..c596cd0d9f3 100644 --- a/rs/embedders/src/wasmtime_embedder/host_memory.rs +++ b/rs/embedders/src/wasmtime_embedder/host_memory.rs @@ -187,11 +187,6 @@ impl MmapMemory { fn as_ptr(&self) -> *mut c_void { self.wasm_memory } - - fn wasm_accessible(&self) -> std::ops::Range { - let start = self.wasm_memory as usize; - start..start + self.size_in_bytes - } } impl Drop for MmapMemory { @@ -231,8 +226,8 @@ unsafe impl LinearMemory for WasmtimeMemory { convert_pages_to_bytes(self.used.load(Ordering::SeqCst)) } - fn maximum_byte_size(&self) -> Option { - Some(convert_pages_to_bytes(self.max_size_in_pages)) + fn byte_capacity(&self) -> usize { + convert_pages_to_bytes(self.max_size_in_pages) } fn grow_to(&mut self, new_size: usize) -> anyhow::Result<()> { @@ -264,8 +259,4 @@ unsafe impl LinearMemory for WasmtimeMemory { fn as_ptr(&self) -> *mut u8 { self.mem.as_ptr() as *mut _ } - - fn wasm_accessible(&self) -> std::ops::Range { - self.mem.wasm_accessible() - } } diff --git a/rs/execution_environment/benches/README.md b/rs/execution_environment/benches/README.md new file mode 100644 index 00000000000..edda7ad2551 --- /dev/null +++ b/rs/execution_environment/benches/README.md @@ -0,0 +1,46 @@ +Execution Benchmarks +==================== + +Quick Start +----------- + +1. To run all benchmarks and compare them to the committed baseline: + + ```sh + ./rs/execution_environment/benches/run-all-benchmarks.sh | tee summary.txt + ``` + + The summary will be generated in the `summary.txt` file. + +2. To update the baseline: + + ```sh + cp *.min rs/execution_environment/benches/baseline + git add rs/execution_environment/benches/baseline/* + git commit -m "Update benches baseline" + ``` + +Adding a New Benchmark +---------------------- + +1. Create a new benchmark and test it with `bazel run ...`. + +2. To integrate the new benchmark into the CI pipeline: + + ```Starlark + rust_ic_bench( + name = "my_new_bench", + with_test = True, + [...] + ) + ``` + + Note, a single benchmark iteration should run in a reasonable amount of time: + + ```sh + bazel run //rs/execution_environment:my_new_bench -- --test + ``` + +3. To include the new benchmark in the comparison: + + Edit script: `rs/execution_environment/benches/run-all-benchmarks.sh` diff --git a/rs/execution_environment/benches/baseline/EMBEDDERS_COMPILATION.min b/rs/execution_environment/benches/baseline/EMBEDDERS_COMPILATION.min index 5a152bc2cf4..c80f3ad02e2 100644 --- a/rs/execution_environment/benches/baseline/EMBEDDERS_COMPILATION.min +++ b/rs/execution_environment/benches/baseline/EMBEDDERS_COMPILATION.min @@ -1,15 +1,15 @@ -test compilation/simple ... bench: 856325 ns/iter (+/- 25738) -test compilation/empty ... bench: 630420 ns/iter (+/- 41102) -test compilation/many_adds ... bench: 227841128 ns/iter (+/- 8410338) -test compilation/many_funcs ... bench: 647063352 ns/iter (+/- 21812709) -test compilation/real_world_wasm ... bench: 763950795 ns/iter (+/- 14152869) -test deserialization/simple ... bench: 38591 ns/iter (+/- 2403) -test deserialization/empty ... bench: 36263 ns/iter (+/- 2421) -test deserialization/many_adds ... bench: 367652 ns/iter (+/- 18746) -test deserialization/many_funcs ... bench: 9611403 ns/iter (+/- 132725) -test deserialization/real_world_wasm ... bench: 9634751 ns/iter (+/- 116462) -test validation-instrumentation/simple ... bench: 44939 ns/iter (+/- 199) -test validation-instrumentation/empty ... bench: 12826 ns/iter (+/- 20) -test validation-instrumentation/many_adds ... bench: 17189632 ns/iter (+/- 118273) -test validation-instrumentation/many_funcs ... bench: 130757108 ns/iter (+/- 2148530) -test validation-instrumentation/real_world_wasm ... bench: 249637146 ns/iter (+/- 1794580) +test compilation/simple ... bench: 829698 ns/iter (+/- 28216) +test compilation/empty ... bench: 620128 ns/iter (+/- 34488) +test compilation/many_adds ... bench: 212131971 ns/iter (+/- 12029294) +test compilation/many_funcs ... bench: 637222024 ns/iter (+/- 24032914) +test compilation/real_world_wasm ... bench: 777318340 ns/iter (+/- 17189505) +test deserialization/simple ... bench: 34086 ns/iter (+/- 3837) +test deserialization/empty ... bench: 32830 ns/iter (+/- 3067) +test deserialization/many_adds ... bench: 270273 ns/iter (+/- 3299) +test deserialization/many_funcs ... bench: 9520767 ns/iter (+/- 160008) +test deserialization/real_world_wasm ... bench: 9187724 ns/iter (+/- 588787) +test validation-instrumentation/simple ... bench: 45814 ns/iter (+/- 185) +test validation-instrumentation/empty ... bench: 13064 ns/iter (+/- 39) +test validation-instrumentation/many_adds ... bench: 17172563 ns/iter (+/- 203235) +test validation-instrumentation/many_funcs ... bench: 113483470 ns/iter (+/- 4219009) +test validation-instrumentation/real_world_wasm ... bench: 266833186 ns/iter (+/- 9943536) diff --git a/rs/execution_environment/benches/baseline/EMBEDDERS_HEAP.min b/rs/execution_environment/benches/baseline/EMBEDDERS_HEAP.min index 934402089e4..827287f37f3 100644 --- a/rs/execution_environment/benches/baseline/EMBEDDERS_HEAP.min +++ b/rs/execution_environment/benches/baseline/EMBEDDERS_HEAP.min @@ -1,96 +1,96 @@ -test query/wasm32_query_read_fwd_1gb_checkpoint ... bench: 566071952 ns/iter (+/- 33875382) -test query/wasm64_query_read_fwd_1gb_checkpoint ... bench: 567994068 ns/iter (+/- 5856920) -test query/wasm32_query_read_fwd_1gb_page_delta ... bench: 1252590180 ns/iter (+/- 24901451) -test query/wasm64_query_read_fwd_1gb_page_delta ... bench: 1207673171 ns/iter (+/- 37831965) -test query/wasm32_query_read_fwd_1gb_step_4kb_checkpoint ... bench: 253509571 ns/iter (+/- 6645160) -test query/wasm64_query_read_fwd_1gb_step_4kb_checkpoint ... bench: 258481817 ns/iter (+/- 14877051) -test query/wasm32_query_read_fwd_1gb_step_4kb_page_delta ... bench: 944185882 ns/iter (+/- 22867361) -test query/wasm64_query_read_fwd_1gb_step_4kb_page_delta ... bench: 914305908 ns/iter (+/- 53858664) -test query/wasm32_query_read_fwd_1gb_step_16kb_checkpoint ... bench: 203471778 ns/iter (+/- 7296899) -test query/wasm64_query_read_fwd_1gb_step_16kb_checkpoint ... bench: 232659114 ns/iter (+/- 5670509) -test query/wasm32_query_read_fwd_1gb_step_16kb_page_delta ... bench: 1116736321 ns/iter (+/- 148627876) -test query/wasm64_query_read_fwd_1gb_step_16kb_page_delta ... bench: 1114768191 ns/iter (+/- 23562675) -test query/wasm32_query_read_bwd_1gb_checkpoint ... bench: 3131019995 ns/iter (+/- 38789361) -test query/wasm64_query_read_bwd_1gb_checkpoint ... bench: 3129389556 ns/iter (+/- 38963054) -test query/wasm32_query_read_bwd_1gb_page_delta ... bench: 3321297544 ns/iter (+/- 239936575) -test query/wasm64_query_read_bwd_1gb_page_delta ... bench: 3324707626 ns/iter (+/- 238759070) -test query/wasm32_query_read_bwd_1gb_step_4kb_checkpoint ... bench: 2686349814 ns/iter (+/- 42112335) -test query/wasm64_query_read_bwd_1gb_step_4kb_checkpoint ... bench: 2694230896 ns/iter (+/- 50022517) -test query/wasm32_query_read_bwd_1gb_step_4kb_page_delta ... bench: 3069988497 ns/iter (+/- 192784294) -test query/wasm64_query_read_bwd_1gb_step_4kb_page_delta ... bench: 3060196901 ns/iter (+/- 253749147) -test query/wasm32_query_read_bwd_1gb_step_16kb_checkpoint ... bench: 798768780 ns/iter (+/- 49086515) -test query/wasm64_query_read_bwd_1gb_step_16kb_checkpoint ... bench: 791036028 ns/iter (+/- 62329177) -test query/wasm32_query_read_bwd_1gb_step_16kb_page_delta ... bench: 1124210407 ns/iter (+/- 23385510) -test query/wasm64_query_read_bwd_1gb_step_16kb_page_delta ... bench: 1129209497 ns/iter (+/- 13207350) -test update/wasm32_update_read_fwd_1gb_checkpoint ... bench: 495862374 ns/iter (+/- 31166126) -test update/wasm64_update_read_fwd_1gb_checkpoint ... bench: 481500253 ns/iter (+/- 18828874) -test update/wasm32_update_read_fwd_1gb_page_delta ... bench: 490100467 ns/iter (+/- 40063883) -test update/wasm64_update_read_fwd_1gb_page_delta ... bench: 479271400 ns/iter (+/- 30991860) -test update/wasm32_update_read_fwd_1gb_step_4kb_checkpoint ... bench: 191637986 ns/iter (+/- 11347090) -test update/wasm64_update_read_fwd_1gb_step_4kb_checkpoint ... bench: 200091130 ns/iter (+/- 12319154) -test update/wasm32_update_read_fwd_1gb_step_4kb_page_delta ... bench: 200887945 ns/iter (+/- 26848915) -test update/wasm64_update_read_fwd_1gb_step_4kb_page_delta ... bench: 191181910 ns/iter (+/- 33654398) -test update/wasm32_update_read_fwd_1gb_step_16kb_checkpoint ... bench: 164659360 ns/iter (+/- 16016327) -test update/wasm64_update_read_fwd_1gb_step_16kb_checkpoint ... bench: 167751313 ns/iter (+/- 12507865) -test update/wasm32_update_read_fwd_1gb_step_16kb_page_delta ... bench: 178226874 ns/iter (+/- 36575558) -test update/wasm64_update_read_fwd_1gb_step_16kb_page_delta ... bench: 167488257 ns/iter (+/- 35859624) -test update/wasm32_update_read_bwd_1gb_checkpoint ... bench: 3038709389 ns/iter (+/- 25260712) -test update/wasm64_update_read_bwd_1gb_checkpoint ... bench: 3015056556 ns/iter (+/- 143469882) -test update/wasm32_update_read_bwd_1gb_page_delta ... bench: 3024613754 ns/iter (+/- 38441759) -test update/wasm64_update_read_bwd_1gb_page_delta ... bench: 3025872369 ns/iter (+/- 43764547) -test update/wasm32_update_read_bwd_1gb_step_4kb_checkpoint ... bench: 2594372512 ns/iter (+/- 19657323) -test update/wasm64_update_read_bwd_1gb_step_4kb_checkpoint ... bench: 2593704936 ns/iter (+/- 19471533) -test update/wasm32_update_read_bwd_1gb_step_4kb_page_delta ... bench: 2614733141 ns/iter (+/- 38425806) -test update/wasm64_update_read_bwd_1gb_step_4kb_page_delta ... bench: 2619811036 ns/iter (+/- 31710983) -test update/wasm32_update_read_bwd_1gb_step_16kb_checkpoint ... bench: 748142211 ns/iter (+/- 10124696) -test update/wasm64_update_read_bwd_1gb_step_16kb_checkpoint ... bench: 750025577 ns/iter (+/- 6894714) -test update/wasm32_update_read_bwd_1gb_step_16kb_page_delta ... bench: 750482913 ns/iter (+/- 30618447) -test update/wasm64_update_read_bwd_1gb_step_16kb_page_delta ... bench: 759889711 ns/iter (+/- 27908549) -test query/wasm32_query_write_fwd_1gb_checkpoint ... bench: 1048513080 ns/iter (+/- 36137991) -test query/wasm64_query_write_fwd_1gb_checkpoint ... bench: 1141283959 ns/iter (+/- 15317053) -test query/wasm32_query_write_fwd_1gb_page_delta ... bench: 1085022015 ns/iter (+/- 18085747) -test query/wasm64_query_write_fwd_1gb_page_delta ... bench: 1145632789 ns/iter (+/- 82882851) -test query/wasm32_query_write_fwd_1gb_step_4kb_checkpoint ... bench: 941341125 ns/iter (+/- 14370035) -test query/wasm64_query_write_fwd_1gb_step_4kb_checkpoint ... bench: 936786272 ns/iter (+/- 11253818) -test query/wasm32_query_write_fwd_1gb_step_4kb_page_delta ... bench: 940876176 ns/iter (+/- 38530565) -test query/wasm64_query_write_fwd_1gb_step_4kb_page_delta ... bench: 950999818 ns/iter (+/- 35785902) -test query/wasm32_query_write_fwd_1gb_step_16kb_checkpoint ... bench: 260246243 ns/iter (+/- 3669950) -test query/wasm64_query_write_fwd_1gb_step_16kb_checkpoint ... bench: 266622205 ns/iter (+/- 2844192) -test query/wasm32_query_write_fwd_1gb_step_16kb_page_delta ... bench: 1115696478 ns/iter (+/- 28613025) -test query/wasm64_query_write_fwd_1gb_step_16kb_page_delta ... bench: 1120604199 ns/iter (+/- 11499546) -test query/wasm32_query_write_bwd_1gb_checkpoint ... bench: 3218197280 ns/iter (+/- 79733164) -test query/wasm64_query_write_bwd_1gb_checkpoint ... bench: 3274708967 ns/iter (+/- 50357013) -test query/wasm32_query_write_bwd_1gb_page_delta ... bench: 3178496249 ns/iter (+/- 199919336) -test query/wasm64_query_write_bwd_1gb_page_delta ... bench: 3265618671 ns/iter (+/- 150823399) -test query/wasm32_query_write_bwd_1gb_step_4kb_checkpoint ... bench: 3069720106 ns/iter (+/- 61501775) -test query/wasm64_query_write_bwd_1gb_step_4kb_checkpoint ... bench: 3065358723 ns/iter (+/- 103497871) -test query/wasm32_query_write_bwd_1gb_step_4kb_page_delta ... bench: 3063899660 ns/iter (+/- 238416399) -test query/wasm64_query_write_bwd_1gb_step_4kb_page_delta ... bench: 3045575000 ns/iter (+/- 55980421) -test query/wasm32_query_write_bwd_1gb_step_16kb_checkpoint ... bench: 820028885 ns/iter (+/- 20588735) -test query/wasm64_query_write_bwd_1gb_step_16kb_checkpoint ... bench: 812033935 ns/iter (+/- 16839057) -test query/wasm32_query_write_bwd_1gb_step_16kb_page_delta ... bench: 1123574848 ns/iter (+/- 84315308) -test query/wasm64_query_write_bwd_1gb_step_16kb_page_delta ... bench: 1131765206 ns/iter (+/- 10528381) -test update/wasm32_update_write_fwd_1gb_checkpoint ... bench: 2321409270 ns/iter (+/- 135290641) -test update/wasm64_update_write_fwd_1gb_checkpoint ... bench: 2477323426 ns/iter (+/- 126582502) -test update/wasm32_update_write_fwd_1gb_page_delta ... bench: 2337749610 ns/iter (+/- 111267329) -test update/wasm64_update_write_fwd_1gb_page_delta ... bench: 2524662852 ns/iter (+/- 72145168) -test update/wasm32_update_write_fwd_1gb_step_4kb_checkpoint ... bench: 2254550147 ns/iter (+/- 94077216) -test update/wasm64_update_write_fwd_1gb_step_4kb_checkpoint ... bench: 2224385038 ns/iter (+/- 70133516) -test update/wasm32_update_write_fwd_1gb_step_4kb_page_delta ... bench: 2289611981 ns/iter (+/- 140815330) -test update/wasm64_update_write_fwd_1gb_step_4kb_page_delta ... bench: 2226708722 ns/iter (+/- 117532662) -test update/wasm32_update_write_fwd_1gb_step_16kb_checkpoint ... bench: 1736796638 ns/iter (+/- 118259308) -test update/wasm64_update_write_fwd_1gb_step_16kb_checkpoint ... bench: 1698157163 ns/iter (+/- 143190409) -test update/wasm32_update_write_fwd_1gb_step_16kb_page_delta ... bench: 1694718111 ns/iter (+/- 46283526) -test update/wasm64_update_write_fwd_1gb_step_16kb_page_delta ... bench: 1693770083 ns/iter (+/- 143248879) -test update/wasm32_update_write_bwd_1gb_checkpoint ... bench: 4440134645 ns/iter (+/- 133801311) -test update/wasm64_update_write_bwd_1gb_checkpoint ... bench: 4621898310 ns/iter (+/- 113352150) -test update/wasm32_update_write_bwd_1gb_page_delta ... bench: 4486284937 ns/iter (+/- 105987018) -test update/wasm64_update_write_bwd_1gb_page_delta ... bench: 4626140858 ns/iter (+/- 55951007) -test update/wasm32_update_write_bwd_1gb_step_4kb_checkpoint ... bench: 4349704897 ns/iter (+/- 165045355) -test update/wasm64_update_write_bwd_1gb_step_4kb_checkpoint ... bench: 4398434057 ns/iter (+/- 73051773) -test update/wasm32_update_write_bwd_1gb_step_4kb_page_delta ... bench: 4392069761 ns/iter (+/- 119628166) -test update/wasm64_update_write_bwd_1gb_step_4kb_page_delta ... bench: 4381513680 ns/iter (+/- 205766222) -test update/wasm32_update_write_bwd_1gb_step_16kb_checkpoint ... bench: 750546478 ns/iter (+/- 25545386) -test update/wasm64_update_write_bwd_1gb_step_16kb_checkpoint ... bench: 755837858 ns/iter (+/- 37446590) -test update/wasm32_update_write_bwd_1gb_step_16kb_page_delta ... bench: 753380369 ns/iter (+/- 35267889) -test update/wasm64_update_write_bwd_1gb_step_16kb_page_delta ... bench: 756614051 ns/iter (+/- 25325043) +test query/wasm32_query_read_fwd_1gb_checkpoint ... bench: 554136824 ns/iter (+/- 21958843) +test query/wasm64_query_read_fwd_1gb_checkpoint ... bench: 559241618 ns/iter (+/- 24701515) +test query/wasm32_query_read_fwd_1gb_page_delta ... bench: 1221173660 ns/iter (+/- 33959740) +test query/wasm64_query_read_fwd_1gb_page_delta ... bench: 1258070683 ns/iter (+/- 54937181) +test query/wasm32_query_read_fwd_1gb_step_4kb_checkpoint ... bench: 269804220 ns/iter (+/- 20685058) +test query/wasm64_query_read_fwd_1gb_step_4kb_checkpoint ... bench: 246801822 ns/iter (+/- 3609533) +test query/wasm32_query_read_fwd_1gb_step_4kb_page_delta ... bench: 969456344 ns/iter (+/- 35541480) +test query/wasm64_query_read_fwd_1gb_step_4kb_page_delta ... bench: 908099675 ns/iter (+/- 40949196) +test query/wasm32_query_read_fwd_1gb_step_16kb_checkpoint ... bench: 232739408 ns/iter (+/- 2129891) +test query/wasm64_query_read_fwd_1gb_step_16kb_checkpoint ... bench: 232300473 ns/iter (+/- 16527120) +test query/wasm32_query_read_fwd_1gb_step_16kb_page_delta ... bench: 981751330 ns/iter (+/- 184386123) +test query/wasm64_query_read_fwd_1gb_step_16kb_page_delta ... bench: 987421544 ns/iter (+/- 31779364) +test query/wasm32_query_read_bwd_1gb_checkpoint ... bench: 2500332009 ns/iter (+/- 40950883) +test query/wasm64_query_read_bwd_1gb_checkpoint ... bench: 2510513931 ns/iter (+/- 57184345) +test query/wasm32_query_read_bwd_1gb_page_delta ... bench: 2796912762 ns/iter (+/- 71888763) +test query/wasm64_query_read_bwd_1gb_page_delta ... bench: 2746131660 ns/iter (+/- 99198883) +test query/wasm32_query_read_bwd_1gb_step_4kb_checkpoint ... bench: 2106967335 ns/iter (+/- 26940348) +test query/wasm64_query_read_bwd_1gb_step_4kb_checkpoint ... bench: 2119744640 ns/iter (+/- 52846624) +test query/wasm32_query_read_bwd_1gb_step_4kb_page_delta ... bench: 2495189675 ns/iter (+/- 111698699) +test query/wasm64_query_read_bwd_1gb_step_4kb_page_delta ... bench: 2503332957 ns/iter (+/- 108651444) +test query/wasm32_query_read_bwd_1gb_step_16kb_checkpoint ... bench: 660003369 ns/iter (+/- 14878615) +test query/wasm64_query_read_bwd_1gb_step_16kb_checkpoint ... bench: 635628301 ns/iter (+/- 4117010) +test query/wasm32_query_read_bwd_1gb_step_16kb_page_delta ... bench: 987893986 ns/iter (+/- 91149949) +test query/wasm64_query_read_bwd_1gb_step_16kb_page_delta ... bench: 990169897 ns/iter (+/- 24251536) +test update/wasm32_update_read_fwd_1gb_checkpoint ... bench: 500013038 ns/iter (+/- 12924539) +test update/wasm64_update_read_fwd_1gb_checkpoint ... bench: 484542582 ns/iter (+/- 16464487) +test update/wasm32_update_read_fwd_1gb_page_delta ... bench: 500545639 ns/iter (+/- 33071908) +test update/wasm64_update_read_fwd_1gb_page_delta ... bench: 500995344 ns/iter (+/- 33990411) +test update/wasm32_update_read_fwd_1gb_step_4kb_checkpoint ... bench: 200672168 ns/iter (+/- 10294887) +test update/wasm64_update_read_fwd_1gb_step_4kb_checkpoint ... bench: 196073561 ns/iter (+/- 8881176) +test update/wasm32_update_read_fwd_1gb_step_4kb_page_delta ... bench: 207746287 ns/iter (+/- 29095732) +test update/wasm64_update_read_fwd_1gb_step_4kb_page_delta ... bench: 201221461 ns/iter (+/- 31245933) +test update/wasm32_update_read_fwd_1gb_step_16kb_checkpoint ... bench: 177404755 ns/iter (+/- 11583938) +test update/wasm64_update_read_fwd_1gb_step_16kb_checkpoint ... bench: 177431060 ns/iter (+/- 9667557) +test update/wasm32_update_read_fwd_1gb_step_16kb_page_delta ... bench: 175255257 ns/iter (+/- 31828015) +test update/wasm64_update_read_fwd_1gb_step_16kb_page_delta ... bench: 180776164 ns/iter (+/- 32320129) +test update/wasm32_update_read_bwd_1gb_checkpoint ... bench: 2459243264 ns/iter (+/- 28529731) +test update/wasm64_update_read_bwd_1gb_checkpoint ... bench: 2439395897 ns/iter (+/- 25752795) +test update/wasm32_update_read_bwd_1gb_page_delta ... bench: 2457013630 ns/iter (+/- 27263173) +test update/wasm64_update_read_bwd_1gb_page_delta ... bench: 2450329380 ns/iter (+/- 31533036) +test update/wasm32_update_read_bwd_1gb_step_4kb_checkpoint ... bench: 2067905142 ns/iter (+/- 38844892) +test update/wasm64_update_read_bwd_1gb_step_4kb_checkpoint ... bench: 2057371982 ns/iter (+/- 18071779) +test update/wasm32_update_read_bwd_1gb_step_4kb_page_delta ... bench: 2064926536 ns/iter (+/- 23619113) +test update/wasm64_update_read_bwd_1gb_step_4kb_page_delta ... bench: 2064678505 ns/iter (+/- 21331184) +test update/wasm32_update_read_bwd_1gb_step_16kb_checkpoint ... bench: 618127627 ns/iter (+/- 7055066) +test update/wasm64_update_read_bwd_1gb_step_16kb_checkpoint ... bench: 621973553 ns/iter (+/- 6900486) +test update/wasm32_update_read_bwd_1gb_step_16kb_page_delta ... bench: 622510040 ns/iter (+/- 28352753) +test update/wasm64_update_read_bwd_1gb_step_16kb_page_delta ... bench: 614914636 ns/iter (+/- 26612393) +test query/wasm32_query_write_fwd_1gb_checkpoint ... bench: 1134604879 ns/iter (+/- 71740058) +test query/wasm64_query_write_fwd_1gb_checkpoint ... bench: 1216942320 ns/iter (+/- 1982486) +test query/wasm32_query_write_fwd_1gb_page_delta ... bench: 1113930414 ns/iter (+/- 46200795) +test query/wasm64_query_write_fwd_1gb_page_delta ... bench: 1216550016 ns/iter (+/- 25020000) +test query/wasm32_query_write_fwd_1gb_step_4kb_checkpoint ... bench: 964007352 ns/iter (+/- 18792581) +test query/wasm64_query_write_fwd_1gb_step_4kb_checkpoint ... bench: 963288471 ns/iter (+/- 18864847) +test query/wasm32_query_write_fwd_1gb_step_4kb_page_delta ... bench: 937400454 ns/iter (+/- 44683828) +test query/wasm64_query_write_fwd_1gb_step_4kb_page_delta ... bench: 981185079 ns/iter (+/- 67605965) +test query/wasm32_query_write_fwd_1gb_step_16kb_checkpoint ... bench: 284085027 ns/iter (+/- 7791537) +test query/wasm64_query_write_fwd_1gb_step_16kb_checkpoint ... bench: 271074172 ns/iter (+/- 9567367) +test query/wasm32_query_write_fwd_1gb_step_16kb_page_delta ... bench: 983497096 ns/iter (+/- 150423362) +test query/wasm64_query_write_fwd_1gb_step_16kb_page_delta ... bench: 976269045 ns/iter (+/- 20564970) +test query/wasm32_query_write_bwd_1gb_checkpoint ... bench: 2612092786 ns/iter (+/- 21681814) +test query/wasm64_query_write_bwd_1gb_checkpoint ... bench: 2711815810 ns/iter (+/- 30339057) +test query/wasm32_query_write_bwd_1gb_page_delta ... bench: 2619570716 ns/iter (+/- 63556002) +test query/wasm64_query_write_bwd_1gb_page_delta ... bench: 2717435898 ns/iter (+/- 181485890) +test query/wasm32_query_write_bwd_1gb_step_4kb_checkpoint ... bench: 2495759064 ns/iter (+/- 24541526) +test query/wasm64_query_write_bwd_1gb_step_4kb_checkpoint ... bench: 2489645973 ns/iter (+/- 32339163) +test query/wasm32_query_write_bwd_1gb_step_4kb_page_delta ... bench: 2451475102 ns/iter (+/- 77674753) +test query/wasm64_query_write_bwd_1gb_step_4kb_page_delta ... bench: 2450866274 ns/iter (+/- 46002190) +test query/wasm32_query_write_bwd_1gb_step_16kb_checkpoint ... bench: 658126881 ns/iter (+/- 10633467) +test query/wasm64_query_write_bwd_1gb_step_16kb_checkpoint ... bench: 649101043 ns/iter (+/- 10091320) +test query/wasm32_query_write_bwd_1gb_step_16kb_page_delta ... bench: 983264157 ns/iter (+/- 112803125) +test query/wasm64_query_write_bwd_1gb_step_16kb_page_delta ... bench: 980028077 ns/iter (+/- 10380500) +test update/wasm32_update_write_fwd_1gb_checkpoint ... bench: 2440048902 ns/iter (+/- 79889220) +test update/wasm64_update_write_fwd_1gb_checkpoint ... bench: 2515664193 ns/iter (+/- 57549239) +test update/wasm32_update_write_fwd_1gb_page_delta ... bench: 2388757893 ns/iter (+/- 73143292) +test update/wasm64_update_write_fwd_1gb_page_delta ... bench: 2505792333 ns/iter (+/- 74655875) +test update/wasm32_update_write_fwd_1gb_step_4kb_checkpoint ... bench: 2233437905 ns/iter (+/- 85868496) +test update/wasm64_update_write_fwd_1gb_step_4kb_checkpoint ... bench: 2313153497 ns/iter (+/- 62249510) +test update/wasm32_update_write_fwd_1gb_step_4kb_page_delta ... bench: 2322824348 ns/iter (+/- 54025317) +test update/wasm64_update_write_fwd_1gb_step_4kb_page_delta ... bench: 2262136110 ns/iter (+/- 66851906) +test update/wasm32_update_write_fwd_1gb_step_16kb_checkpoint ... bench: 1566774279 ns/iter (+/- 119024880) +test update/wasm64_update_write_fwd_1gb_step_16kb_checkpoint ... bench: 1574286331 ns/iter (+/- 180410706) +test update/wasm32_update_write_fwd_1gb_step_16kb_page_delta ... bench: 1568373099 ns/iter (+/- 27035578) +test update/wasm64_update_write_fwd_1gb_step_16kb_page_delta ... bench: 1562581295 ns/iter (+/- 239620252) +test update/wasm32_update_write_bwd_1gb_checkpoint ... bench: 3911194473 ns/iter (+/- 88367782) +test update/wasm64_update_write_bwd_1gb_checkpoint ... bench: 4012190989 ns/iter (+/- 92737692) +test update/wasm32_update_write_bwd_1gb_page_delta ... bench: 3930461363 ns/iter (+/- 76275266) +test update/wasm64_update_write_bwd_1gb_page_delta ... bench: 3991291084 ns/iter (+/- 74520451) +test update/wasm32_update_write_bwd_1gb_step_4kb_checkpoint ... bench: 3811772782 ns/iter (+/- 76222355) +test update/wasm64_update_write_bwd_1gb_step_4kb_checkpoint ... bench: 3775270783 ns/iter (+/- 92528446) +test update/wasm32_update_write_bwd_1gb_step_4kb_page_delta ... bench: 3802094751 ns/iter (+/- 73287167) +test update/wasm64_update_write_bwd_1gb_step_4kb_page_delta ... bench: 3757763967 ns/iter (+/- 115111277) +test update/wasm32_update_write_bwd_1gb_step_16kb_checkpoint ... bench: 618053198 ns/iter (+/- 13435852) +test update/wasm64_update_write_bwd_1gb_step_16kb_checkpoint ... bench: 613323013 ns/iter (+/- 7368418) +test update/wasm32_update_write_bwd_1gb_step_16kb_page_delta ... bench: 622103424 ns/iter (+/- 24597311) +test update/wasm64_update_write_bwd_1gb_step_16kb_page_delta ... bench: 628049206 ns/iter (+/- 17254721) diff --git a/rs/execution_environment/benches/baseline/EMBEDDERS_STABLE_MEMORY.min b/rs/execution_environment/benches/baseline/EMBEDDERS_STABLE_MEMORY.min index 910959157dd..2f091f6c857 100644 --- a/rs/execution_environment/benches/baseline/EMBEDDERS_STABLE_MEMORY.min +++ b/rs/execution_environment/benches/baseline/EMBEDDERS_STABLE_MEMORY.min @@ -1,14 +1,14 @@ -test update/direct_u64_sparse_write ... bench: 1056031784 ns/iter (+/- 59194034) -test update/vec_u64_sparse_write ... bench: 543055284 ns/iter (+/- 15632091) -test query/direct_u64_single_read ... bench: 4901186 ns/iter (+/- 458874) -test query/direct_u64_sparse_read ... bench: 22734588 ns/iter (+/- 2557722) -test update/direct_u64_single_write ... bench: 7490523 ns/iter (+/- 2898665) -test query/direct_20mb_read ... bench: 22413500 ns/iter (+/- 1673616) -test update/direct_2mb_write ... bench: 7928882 ns/iter (+/- 1532545) -test query/btree_u64_single_read ... bench: 8581880 ns/iter (+/- 2920676) -test query/btree_u64_sparse_read ... bench: 10890444 ns/iter (+/- 1936312) -test update/btree_u64_single_write ... bench: 11687816 ns/iter (+/- 3294248) -test update/btree_u64_sparse_write ... bench: 32527143 ns/iter (+/- 2001941) -test query/vec_u64_single_read ... bench: 9080461 ns/iter (+/- 2786004) -test query/vec_u64_sparse_read ... bench: 20971039 ns/iter (+/- 1877064) -test update/vec_u64_single_write ... bench: 9332235 ns/iter (+/- 2603556) +test update/direct_u64_sparse_write ... bench: 1087281869 ns/iter (+/- 24711953) +test update/vec_u64_sparse_write ... bench: 579849351 ns/iter (+/- 21826053) +test query/direct_u64_single_read ... bench: 5690732 ns/iter (+/- 1060661) +test query/direct_u64_sparse_read ... bench: 27515216 ns/iter (+/- 1540154) +test update/direct_u64_single_write ... bench: 6871253 ns/iter (+/- 5445215) +test query/direct_20mb_read ... bench: 24108867 ns/iter (+/- 1845190) +test update/direct_2mb_write ... bench: 7860365 ns/iter (+/- 2833384) +test query/btree_u64_single_read ... bench: 12947333 ns/iter (+/- 2803198) +test query/btree_u64_sparse_read ... bench: 10665763 ns/iter (+/- 2748199) +test update/btree_u64_single_write ... bench: 11474626 ns/iter (+/- 2870892) +test update/btree_u64_sparse_write ... bench: 32163631 ns/iter (+/- 2136481) +test query/vec_u64_single_read ... bench: 8464848 ns/iter (+/- 2075379) +test query/vec_u64_sparse_read ... bench: 22190702 ns/iter (+/- 1993435) +test update/vec_u64_single_write ... bench: 8692683 ns/iter (+/- 4590014) diff --git a/rs/execution_environment/benches/baseline/SYSTEM_API_INSPECT_MESSAGE.min b/rs/execution_environment/benches/baseline/SYSTEM_API_INSPECT_MESSAGE.min index 889290555a5..c37cea21a39 100644 --- a/rs/execution_environment/benches/baseline/SYSTEM_API_INSPECT_MESSAGE.min +++ b/rs/execution_environment/benches/baseline/SYSTEM_API_INSPECT_MESSAGE.min @@ -1,8 +1,8 @@ -test inspect/wasm32/ic0_msg_method_name_size() ... bench: 65877208 ns/iter (+/- 1218359) -test inspect/wasm64/ic0_msg_method_name_size() ... bench: 66841896 ns/iter (+/- 1971593) -test inspect/wasm32/ic0_msg_method_name_copy()/1B ... bench: 138709734 ns/iter (+/- 275624) -test inspect/wasm64/ic0_msg_method_name_copy()/1B ... bench: 131839098 ns/iter (+/- 855364) -test inspect/wasm32/ic0_msg_method_name_copy()/20B ... bench: 138374162 ns/iter (+/- 941122) -test inspect/wasm64/ic0_msg_method_name_copy()/20B ... bench: 131297956 ns/iter (+/- 251756) -test inspect/wasm32/ic0_accept_message()* ... bench: 247139 ns/iter (+/- 16621) -test inspect/wasm64/ic0_accept_message()* ... bench: 271364 ns/iter (+/- 9733) +test inspect/wasm32/ic0_msg_method_name_size() ... bench: 72737865 ns/iter (+/- 1466769) +test inspect/wasm64/ic0_msg_method_name_size() ... bench: 72767795 ns/iter (+/- 279724) +test inspect/wasm32/ic0_msg_method_name_copy()/1B ... bench: 141751664 ns/iter (+/- 971902) +test inspect/wasm64/ic0_msg_method_name_copy()/1B ... bench: 142874967 ns/iter (+/- 1149247) +test inspect/wasm32/ic0_msg_method_name_copy()/20B ... bench: 144715404 ns/iter (+/- 817340) +test inspect/wasm64/ic0_msg_method_name_copy()/20B ... bench: 142166041 ns/iter (+/- 725890) +test inspect/wasm32/ic0_accept_message()* ... bench: 204756 ns/iter (+/- 15831) +test inspect/wasm64/ic0_accept_message()* ... bench: 215108 ns/iter (+/- 24071) diff --git a/rs/execution_environment/benches/baseline/SYSTEM_API_QUERY.min b/rs/execution_environment/benches/baseline/SYSTEM_API_QUERY.min index ba56c48e1c6..5392aca9657 100644 --- a/rs/execution_environment/benches/baseline/SYSTEM_API_QUERY.min +++ b/rs/execution_environment/benches/baseline/SYSTEM_API_QUERY.min @@ -1,6 +1,6 @@ -test query/wasm32/ic0_data_certificate_size() ... bench: 72913485 ns/iter (+/- 3834225) -test query/wasm64/ic0_data_certificate_size() ... bench: 63723135 ns/iter (+/- 1625884) -test query/wasm32/ic0_data_certificate_copy()/1B ... bench: 136711857 ns/iter (+/- 2092315) -test query/wasm64/ic0_data_certificate_copy()/1B ... bench: 132831153 ns/iter (+/- 1216644) -test query/wasm32/ic0_data_certificate_copy()/64B ... bench: 137184214 ns/iter (+/- 1243589) -test query/wasm64/ic0_data_certificate_copy()/64B ... bench: 131097070 ns/iter (+/- 2197032) +test query/wasm32/ic0_data_certificate_size() ... bench: 73674568 ns/iter (+/- 3247289) +test query/wasm64/ic0_data_certificate_size() ... bench: 73594055 ns/iter (+/- 1665261) +test query/wasm32/ic0_data_certificate_copy()/1B ... bench: 144269499 ns/iter (+/- 2702785) +test query/wasm64/ic0_data_certificate_copy()/1B ... bench: 139803934 ns/iter (+/- 3726063) +test query/wasm32/ic0_data_certificate_copy()/64B ... bench: 142428176 ns/iter (+/- 1922216) +test query/wasm64/ic0_data_certificate_copy()/64B ... bench: 139980020 ns/iter (+/- 2928015) diff --git a/rs/execution_environment/benches/baseline/SYSTEM_API_UPDATE.min b/rs/execution_environment/benches/baseline/SYSTEM_API_UPDATE.min index eb0d67ba751..d4ff61198e3 100644 --- a/rs/execution_environment/benches/baseline/SYSTEM_API_UPDATE.min +++ b/rs/execution_environment/benches/baseline/SYSTEM_API_UPDATE.min @@ -1,102 +1,104 @@ -test update/wasm32/baseline/empty test* ... bench: 281461 ns/iter (+/- 5532) -test update/wasm64/baseline/empty test* ... bench: 285022 ns/iter (+/- 15883) -test update/wasm32/baseline/empty loop ... bench: 2723222 ns/iter (+/- 8951) -test update/wasm64/baseline/empty loop ... bench: 2739133 ns/iter (+/- 30444) -test update/wasm32/baseline/adds ... bench: 2780773 ns/iter (+/- 13582) -test update/wasm64/baseline/adds ... bench: 2801088 ns/iter (+/- 59034) -test update/wasm32/ic0_msg_caller_size() ... bench: 80697215 ns/iter (+/- 180896) -test update/wasm64/ic0_msg_caller_size() ... bench: 81323235 ns/iter (+/- 38913) -test update/wasm32/ic0_msg_caller_copy()/1B ... bench: 136660032 ns/iter (+/- 3500358) -test update/wasm64/ic0_msg_caller_copy()/1B ... bench: 150783799 ns/iter (+/- 282823) -test update/wasm32/ic0_msg_caller_copy()/10B ... bench: 139244761 ns/iter (+/- 1826727) -test update/wasm364/ic0_msg_caller_copy()/10B ... bench: 150888828 ns/iter (+/- 622483) -test update/wasm32/ic0_msg_arg_data_size() ... bench: 66112545 ns/iter (+/- 1489075) -test update/wasm64/ic0_msg_arg_data_size() ... bench: 64778774 ns/iter (+/- 391657) -test update/wasm32/ic0_msg_arg_data_copy()/1B ... bench: 148752839 ns/iter (+/- 772062) -test update/wasm64/ic0_msg_arg_data_copy()/1B ... bench: 151531495 ns/iter (+/- 276936) -test update/wasm32/ic0_msg_arg_data_copy()/1K ... bench: 166747194 ns/iter (+/- 391609) -test update/wasm64/ic0_msg_arg_data_copy()/1K ... bench: 162470332 ns/iter (+/- 134125) -test update/wasm32/ic0_msg_reply()* ... bench: 258573 ns/iter (+/- 24349) -test update/wasm64/ic0_msg_reply()* ... bench: 298892 ns/iter (+/- 15823) -test update/wasm32/ic0_msg_reply_data_append()/1B ... bench: 140712293 ns/iter (+/- 1162685) -test update/wasm64/ic0_msg_reply_data_append()/1B ... bench: 138487402 ns/iter (+/- 1122809) -test update/wasm32/ic0_msg_reply_data_append()/2B ... bench: 140983728 ns/iter (+/- 686243) -test update/wasm64/ic0_msg_reply_data_append()/2B ... bench: 137568935 ns/iter (+/- 1203421) -test update/wasm32/ic0_msg_reject()* ... bench: 277172 ns/iter (+/- 14840) -test update/wasm64/ic0_msg_reject()* ... bench: 297614 ns/iter (+/- 27548) -test update/wasm32/ic0_canister_self_size() ... bench: 75647257 ns/iter (+/- 476299) -test update/wasm64/ic0_canister_self_size() ... bench: 69754990 ns/iter (+/- 836033) -test update/wasm32/ic0_canister_self_copy()/1B ... bench: 152397170 ns/iter (+/- 395613) -test update/wasm64/ic0_canister_self_copy()/1B ... bench: 144575326 ns/iter (+/- 334825) -test update/wasm32/ic0_canister_self_copy()/10B ... bench: 155057994 ns/iter (+/- 260885) -test update/wasm64/ic0_canister_self_copy()/10B ... bench: 147139326 ns/iter (+/- 637477) -test update/wasm32/ic0_debug_print()/1B ... bench: 190811507 ns/iter (+/- 853887) -test update/wasm64/ic0_debug_print()/1B ... bench: 194558832 ns/iter (+/- 250401) -test update/wasm32/ic0_debug_print()/1K ... bench: 206376037 ns/iter (+/- 343151) -test update/wasm64/ic0_debug_print()/1K ... bench: 204891830 ns/iter (+/- 220238) -test update/wasm32/ic0_call_new() ... bench: 273429955 ns/iter (+/- 750981) -test update/wasm64/ic0_call_new() ... bench: 279183541 ns/iter (+/- 1028932) -test update/wasm32/call_new+ic0_call_cycles_add() ... bench: 426125262 ns/iter (+/- 1021604) -test update/wasm32/call_new+ic0_call_data_append()/1B ... bench: 463752233 ns/iter (+/- 1341032) -test update/wasm64/call_new+ic0_call_data_append()/1B ... bench: 462893841 ns/iter (+/- 1536467) -test update/wasm32/call_new+ic0_call_data_append()/1K ... bench: 473481604 ns/iter (+/- 761164) -test update/wasm64/call_new+ic0_call_data_append()/1K ... bench: 475775943 ns/iter (+/- 1340787) -test update/wasm32/call_new+ic0_call_on_cleanup() ... bench: 351524842 ns/iter (+/- 2631504) -test update/wasm64/call_new+ic0_call_on_cleanup() ... bench: 360276867 ns/iter (+/- 1883543) -test update/wasm32/call_new+ic0_call_cycles_add128() ... bench: 425726252 ns/iter (+/- 1623521) -test update/wasm64/call_new+ic0_call_cycles_add128() ... bench: 428493329 ns/iter (+/- 2281971) -test update/wasm32/call_new+ic0_call_perform() ... bench: 1825886124 ns/iter (+/- 68498405) -test update/wasm64/call_new+ic0_call_perform() ... bench: 1873084146 ns/iter (+/- 94571643) -test update/wasm32/ic0_stable64_size() ... bench: 2761338 ns/iter (+/- 37356) -test update/wasm64/ic0_stable64_size() ... bench: 2749988 ns/iter (+/- 83183) -test update/wasm32/call_new+ic0_call_with_best_effort_response() ... bench: 351224552 ns/iter (+/- 1382744) -test update/wasm64/call_new+ic0_call_with_best_effort_response() ... bench: 360946615 ns/iter (+/- 1704546) -test update/wasm32/ic0_stable_size() ... bench: 3393283 ns/iter (+/- 92103) -test update/wasm32/ic0_stable_grow() ... bench: 187570553 ns/iter (+/- 582839) -test update/wasm32/ic0_stable64_grow() ... bench: 186236666 ns/iter (+/- 750802) -test update/wasm64/ic0_stable64_grow() ... bench: 183141091 ns/iter (+/- 904667) -test update/wasm32/ic0_stable_read()/1B ... bench: 23308937 ns/iter (+/- 28534) -test update/wasm32/ic0_stable64_read()/1B ... bench: 24544782 ns/iter (+/- 65093) -test update/wasm64/ic0_stable64_read()/1B ... bench: 23871089 ns/iter (+/- 177059) -test update/wasm32/ic0_stable_read()/1K ... bench: 37252866 ns/iter (+/- 154843) -test update/wasm32/ic0_stable64_read()/1K ... bench: 38161163 ns/iter (+/- 235557) -test update/wasm64/ic0_stable64_read()/1K ... bench: 37716724 ns/iter (+/- 43968) -test update/wasm32/ic0_stable_write()/1B ... bench: 46331078 ns/iter (+/- 198118) -test update/wasm32/ic0_stable64_write()/1B ... bench: 46749070 ns/iter (+/- 167110) -test update/wasm64/ic0_stable64_write()/1B ... bench: 46396547 ns/iter (+/- 288565) -test update/wasm32/ic0_stable_write()/1K ... bench: 54563051 ns/iter (+/- 124826) -test update/wasm32/ic0_stable64_write()/1K ... bench: 54900647 ns/iter (+/- 349555) -test update/wasm64/ic0_stable64_write()/1K ... bench: 54826985 ns/iter (+/- 78172) -test update/wasm32/ic0_time() ... bench: 67378320 ns/iter (+/- 790379) -test update/wasm64/ic0_time() ... bench: 74550865 ns/iter (+/- 111044) -test update/wasm32/ic0_global_timer_set() ... bench: 73280498 ns/iter (+/- 172815) -test update/wasm64/ic0_global_timer_set() ... bench: 64932035 ns/iter (+/- 250815) -test update/wasm32/ic0_performance_counter() ... bench: 77882890 ns/iter (+/- 1733728) -test update/wasm64/ic0_performance_counter() ... bench: 72274806 ns/iter (+/- 299482) -test update/wasm32/ic0_canister_cycle_balance() ... bench: 72841321 ns/iter (+/- 479715) -test update/wasm32/ic0_canister_cycle_balance128() ... bench: 140553952 ns/iter (+/- 826885) -test update/wasm64/ic0_canister_cycle_balance128() ... bench: 136150656 ns/iter (+/- 1002688) -test update/wasm32/ic0_msg_cycles_available() ... bench: 73346198 ns/iter (+/- 357559) -test update/wasm32/ic0_msg_cycles_available128() ... bench: 143438002 ns/iter (+/- 522877) -test update/wasm64/ic0_msg_cycles_available128() ... bench: 140730136 ns/iter (+/- 973812) -test update/wasm32/ic0_msg_cycles_accept() ... bench: 80283273 ns/iter (+/- 176845) -test update/wasm32/ic0_msg_cycles_accept128() ... bench: 156499971 ns/iter (+/- 437065) -test update/wasm64/ic0_msg_cycles_accept128() ... bench: 157332013 ns/iter (+/- 2176589) -test update/wasm32/ic0_data_certificate_present() ... bench: 67935921 ns/iter (+/- 704043) -test update/wasm64/ic0_data_certificate_present() ... bench: 75084831 ns/iter (+/- 221131) -test update/wasm32/ic0_certified_data_set()/1B ... bench: 177747985 ns/iter (+/- 1528484) -test update/wasm64/ic0_certified_data_set()/1B ... bench: 165481121 ns/iter (+/- 301957) -test update/wasm32/ic0_certified_data_set()/32B ... bench: 177345089 ns/iter (+/- 819318) -test update/wasm64/ic0_certified_data_set()/32B ... bench: 167320905 ns/iter (+/- 186210) -test update/wasm32/ic0_canister_status() ... bench: 66343647 ns/iter (+/- 727169) -test update/wasm64/ic0_canister_status() ... bench: 63768936 ns/iter (+/- 578488) -test update/wasm32/ic0_mint_cycles() ... bench: 49786539 ns/iter (+/- 644438) -test update/wasm64/ic0_mint_cycles() ... bench: 46257547 ns/iter (+/- 34344) -test update/wasm32/ic0_is_controller() ... bench: 153236549 ns/iter (+/- 2098881) -test update/wasm64/ic0_is_controller() ... bench: 187651314 ns/iter (+/- 330197) -test update/wasm32/ic0_in_replicated_execution() ... bench: 62837039 ns/iter (+/- 216528) -test update/wasm64/ic0_in_replicated_execution() ... bench: 61587095 ns/iter (+/- 689846) -test update/wasm32/ic0_cycles_burn128() ... bench: 167587504 ns/iter (+/- 529133) -test update/wasm64/ic0_cycles_burn128() ... bench: 171333907 ns/iter (+/- 2941750) -test update/wasm32/ic0_msg_deadline() ... bench: 66839004 ns/iter (+/- 522317) -test update/wasm64/ic0_msg_deadline() ... bench: 65016848 ns/iter (+/- 126380) +test update/wasm32/baseline/empty test* ... bench: 237609 ns/iter (+/- 10540) +test update/wasm64/baseline/empty test* ... bench: 264087 ns/iter (+/- 17947) +test update/wasm32/baseline/empty loop ... bench: 2721048 ns/iter (+/- 88678) +test update/wasm64/baseline/empty loop ... bench: 2709529 ns/iter (+/- 129665) +test update/wasm32/baseline/adds ... bench: 2768043 ns/iter (+/- 104641) +test update/wasm64/baseline/adds ... bench: 2742414 ns/iter (+/- 35807) +test update/wasm32/ic0_msg_caller_size() ... bench: 80937565 ns/iter (+/- 1075227) +test update/wasm64/ic0_msg_caller_size() ... bench: 80906864 ns/iter (+/- 860439) +test update/wasm32/ic0_msg_caller_copy()/1B ... bench: 136233139 ns/iter (+/- 1434249) +test update/wasm64/ic0_msg_caller_copy()/1B ... bench: 146697948 ns/iter (+/- 938204) +test update/wasm32/ic0_msg_caller_copy()/10B ... bench: 139536648 ns/iter (+/- 1279219) +test update/wasm364/ic0_msg_caller_copy()/10B ... bench: 146664081 ns/iter (+/- 938071) +test update/wasm32/ic0_msg_arg_data_size() ... bench: 76339107 ns/iter (+/- 589641) +test update/wasm64/ic0_msg_arg_data_size() ... bench: 73862185 ns/iter (+/- 1388044) +test update/wasm32/ic0_msg_arg_data_copy()/1B ... bench: 147315456 ns/iter (+/- 1753351) +test update/wasm64/ic0_msg_arg_data_copy()/1B ... bench: 143699602 ns/iter (+/- 1600069) +test update/wasm32/ic0_msg_arg_data_copy()/1K ... bench: 159757000 ns/iter (+/- 2062192) +test update/wasm64/ic0_msg_arg_data_copy()/1K ... bench: 157916818 ns/iter (+/- 513687) +test update/wasm32/ic0_msg_reply()* ... bench: 231164 ns/iter (+/- 26892) +test update/wasm64/ic0_msg_reply()* ... bench: 246782 ns/iter (+/- 18061) +test update/wasm32/ic0_msg_reply_data_append()/1B ... bench: 153893177 ns/iter (+/- 950498) +test update/wasm64/ic0_msg_reply_data_append()/1B ... bench: 146340873 ns/iter (+/- 2088299) +test update/wasm32/ic0_msg_reply_data_append()/2B ... bench: 158102861 ns/iter (+/- 1279895) +test update/wasm64/ic0_msg_reply_data_append()/2B ... bench: 158055792 ns/iter (+/- 2185087) +test update/wasm32/ic0_msg_reject()* ... bench: 237126 ns/iter (+/- 17862) +test update/wasm64/ic0_msg_reject()* ... bench: 263369 ns/iter (+/- 12276) +test update/wasm32/ic0_canister_self_size() ... bench: 82334334 ns/iter (+/- 1204805) +test update/wasm64/ic0_canister_self_size() ... bench: 71062787 ns/iter (+/- 1168027) +test update/wasm32/ic0_canister_self_copy()/1B ... bench: 139613745 ns/iter (+/- 825392) +test update/wasm64/ic0_canister_self_copy()/1B ... bench: 131385870 ns/iter (+/- 1236567) +test update/wasm32/ic0_canister_self_copy()/10B ... bench: 141053308 ns/iter (+/- 1185722) +test update/wasm64/ic0_canister_self_copy()/10B ... bench: 133098408 ns/iter (+/- 1097174) +test update/wasm32/ic0_debug_print()/1B ... bench: 183711101 ns/iter (+/- 1197045) +test update/wasm64/ic0_debug_print()/1B ... bench: 182704215 ns/iter (+/- 1217166) +test update/wasm32/ic0_debug_print()/1K ... bench: 201383187 ns/iter (+/- 604098) +test update/wasm64/ic0_debug_print()/1K ... bench: 200982665 ns/iter (+/- 655759) +test update/wasm32/ic0_call_new() ... bench: 278275493 ns/iter (+/- 1239850) +test update/wasm64/ic0_call_new() ... bench: 268527474 ns/iter (+/- 1091810) +test update/wasm32/call_new+ic0_call_cycles_add() ... bench: 428497251 ns/iter (+/- 3020791) +test update/wasm32/call_new+ic0_call_data_append()/1B ... bench: 467199765 ns/iter (+/- 2624297) +test update/wasm64/call_new+ic0_call_data_append()/1B ... bench: 459317299 ns/iter (+/- 2479881) +test update/wasm32/call_new+ic0_call_data_append()/1K ... bench: 474438607 ns/iter (+/- 2442286) +test update/wasm64/call_new+ic0_call_data_append()/1K ... bench: 465767624 ns/iter (+/- 3139386) +test update/wasm32/call_new+ic0_call_on_cleanup() ... bench: 361506172 ns/iter (+/- 1795302) +test update/wasm64/call_new+ic0_call_on_cleanup() ... bench: 351714874 ns/iter (+/- 2947687) +test update/wasm32/call_new+ic0_call_cycles_add128() ... bench: 434925294 ns/iter (+/- 2182739) +test update/wasm64/call_new+ic0_call_cycles_add128() ... bench: 427117055 ns/iter (+/- 2434942) +test update/wasm32/call_new+ic0_call_perform() ... bench: 1844925560 ns/iter (+/- 51378187) +test update/wasm64/call_new+ic0_call_perform() ... bench: 1826992053 ns/iter (+/- 70388379) +test update/wasm32/ic0_stable64_size() ... bench: 2681655 ns/iter (+/- 56333) +test update/wasm64/ic0_stable64_size() ... bench: 2671270 ns/iter (+/- 47131) +test update/wasm32/call_new+ic0_call_with_best_effort_response() ... bench: 359666058 ns/iter (+/- 2596676) +test update/wasm64/call_new+ic0_call_with_best_effort_response() ... bench: 345423772 ns/iter (+/- 1943349) +test update/wasm32/ic0_stable_size() ... bench: 3293611 ns/iter (+/- 234281) +test update/wasm32/ic0_stable_grow() ... bench: 191825538 ns/iter (+/- 1531357) +test update/wasm32/ic0_stable64_grow() ... bench: 193355500 ns/iter (+/- 1694902) +test update/wasm64/ic0_stable64_grow() ... bench: 193414094 ns/iter (+/- 2072001) +test update/wasm32/ic0_stable_read()/1B ... bench: 28046098 ns/iter (+/- 613015) +test update/wasm32/ic0_stable64_read()/1B ... bench: 28660264 ns/iter (+/- 131882) +test update/wasm64/ic0_stable64_read()/1B ... bench: 28566361 ns/iter (+/- 945871) +test update/wasm32/ic0_stable_read()/1K ... bench: 40960218 ns/iter (+/- 194087) +test update/wasm32/ic0_stable64_read()/1K ... bench: 42266301 ns/iter (+/- 290121) +test update/wasm64/ic0_stable64_read()/1K ... bench: 41471626 ns/iter (+/- 180645) +test update/wasm32/ic0_stable_write()/1B ... bench: 43619079 ns/iter (+/- 141927) +test update/wasm32/ic0_stable64_write()/1B ... bench: 44040104 ns/iter (+/- 814978) +test update/wasm64/ic0_stable64_write()/1B ... bench: 43682229 ns/iter (+/- 425458) +test update/wasm32/ic0_stable_write()/1K ... bench: 58076308 ns/iter (+/- 297290) +test update/wasm32/ic0_stable64_write()/1K ... bench: 58511660 ns/iter (+/- 1002908) +test update/wasm64/ic0_stable64_write()/1K ... bench: 58515994 ns/iter (+/- 404659) +test update/wasm32/ic0_time() ... bench: 74208482 ns/iter (+/- 1023774) +test update/wasm64/ic0_time() ... bench: 70705310 ns/iter (+/- 975020) +test update/wasm32/ic0_global_timer_set() ... bench: 75468842 ns/iter (+/- 1228727) +test update/wasm64/ic0_global_timer_set() ... bench: 79196085 ns/iter (+/- 1063288) +test update/wasm32/ic0_performance_counter() ... bench: 95645500 ns/iter (+/- 561867) +test update/wasm64/ic0_performance_counter() ... bench: 98539044 ns/iter (+/- 964784) +test update/wasm32/ic0_canister_cycle_balance() ... bench: 78381131 ns/iter (+/- 1419670) +test update/wasm32/ic0_canister_cycle_balance128() ... bench: 139607781 ns/iter (+/- 1572420) +test update/wasm64/ic0_canister_cycle_balance128() ... bench: 139162450 ns/iter (+/- 1756167) +test update/wasm32/ic0_msg_cycles_available() ... bench: 77506173 ns/iter (+/- 1430557) +test update/wasm32/ic0_msg_cycles_available128() ... bench: 135546219 ns/iter (+/- 1838431) +test update/wasm64/ic0_msg_cycles_available128() ... bench: 139496276 ns/iter (+/- 1096060) +test update/wasm32/ic0_msg_cycles_accept() ... bench: 81053098 ns/iter (+/- 1467549) +test update/wasm32/ic0_msg_cycles_accept128() ... bench: 152931345 ns/iter (+/- 907352) +test update/wasm64/ic0_msg_cycles_accept128() ... bench: 151463113 ns/iter (+/- 1159981) +test update/wasm32/ic0_data_certificate_present() ... bench: 79458305 ns/iter (+/- 1278453) +test update/wasm64/ic0_data_certificate_present() ... bench: 75584213 ns/iter (+/- 1438989) +test update/wasm32/ic0_certified_data_set()/1B ... bench: 158871515 ns/iter (+/- 1134883) +test update/wasm64/ic0_certified_data_set()/1B ... bench: 164280303 ns/iter (+/- 1365282) +test update/wasm32/ic0_certified_data_set()/32B ... bench: 160591444 ns/iter (+/- 546110) +test update/wasm64/ic0_certified_data_set()/32B ... bench: 164184060 ns/iter (+/- 1593798) +test update/wasm32/ic0_canister_status() ... bench: 71234731 ns/iter (+/- 713440) +test update/wasm64/ic0_canister_status() ... bench: 71356454 ns/iter (+/- 1048305) +test update/wasm32/ic0_mint_cycles() ... bench: 47821386 ns/iter (+/- 669031) +test update/wasm64/ic0_mint_cycles() ... bench: 47970492 ns/iter (+/- 865935) +test update/wasm32/ic0_mint_cycles128() ... bench: 110214570 ns/iter (+/- 280023) +test update/wasm64/ic0_mint_cycles128() ... bench: 111702153 ns/iter (+/- 836581) +test update/wasm32/ic0_is_controller() ... bench: 165161637 ns/iter (+/- 865338) +test update/wasm64/ic0_is_controller() ... bench: 168621589 ns/iter (+/- 2240947) +test update/wasm32/ic0_in_replicated_execution() ... bench: 69012981 ns/iter (+/- 821369) +test update/wasm64/ic0_in_replicated_execution() ... bench: 70017006 ns/iter (+/- 1257225) +test update/wasm32/ic0_cycles_burn128() ... bench: 152467972 ns/iter (+/- 1132850) +test update/wasm64/ic0_cycles_burn128() ... bench: 160342212 ns/iter (+/- 966475) +test update/wasm32/ic0_msg_deadline() ... bench: 81475473 ns/iter (+/- 1569000) +test update/wasm64/ic0_msg_deadline() ... bench: 80947212 ns/iter (+/- 710207) diff --git a/rs/execution_environment/benches/baseline/WASM_INSTRUCTIONS.min b/rs/execution_environment/benches/baseline/WASM_INSTRUCTIONS.min index 22abcecf5de..105bb78ef5f 100644 --- a/rs/execution_environment/benches/baseline/WASM_INSTRUCTIONS.min +++ b/rs/execution_environment/benches/baseline/WASM_INSTRUCTIONS.min @@ -1,1704 +1,1704 @@ -test wasm_instructions/wasm32/overhead ... bench: 281721 ns/iter (+/- 17205) -test wasm_instructions/wasm32/overhead/confirmation ... bench: 2436672 ns/iter (+/- 45811) -test wasm_instructions/wasm64/overhead ... bench: 301477 ns/iter (+/- 33661) -test wasm_instructions/wasm64/overhead/confirmation ... bench: 2442529 ns/iter (+/- 112021) -test wasm_instructions/wasm32/const/i32.const ... bench: 2415244 ns/iter (+/- 29082) -test wasm_instructions/wasm32/const/i32.const/confirmation ... bench: 4612908 ns/iter (+/- 30825) -test wasm_instructions/wasm64/const/i32.const ... bench: 2436563 ns/iter (+/- 23037) -test wasm_instructions/wasm64/const/i32.const/confirmation ... bench: 4630259 ns/iter (+/- 35992) -test wasm_instructions/wasm32/const/i64.const ... bench: 2453507 ns/iter (+/- 23189) -test wasm_instructions/wasm32/const/i64.const/confirmation ... bench: 4617679 ns/iter (+/- 27780) -test wasm_instructions/wasm64/const/i64.const ... bench: 2471985 ns/iter (+/- 22865) -test wasm_instructions/wasm64/const/i64.const/confirmation ... bench: 4620661 ns/iter (+/- 25769) -test wasm_instructions/wasm32/const/f32.const ... bench: 3065182 ns/iter (+/- 30661) -test wasm_instructions/wasm32/const/f32.const/confirmation ... bench: 5844362 ns/iter (+/- 30176) -test wasm_instructions/wasm64/const/f32.const ... bench: 3042669 ns/iter (+/- 28736) -test wasm_instructions/wasm64/const/f32.const/confirmation ... bench: 5888724 ns/iter (+/- 79118) -test wasm_instructions/wasm32/const/f64.const ... bench: 4816721 ns/iter (+/- 33033) -test wasm_instructions/wasm32/const/f64.const/confirmation ... bench: 8830261 ns/iter (+/- 28921) -test wasm_instructions/wasm64/const/f64.const ... bench: 4644000 ns/iter (+/- 167223) -test wasm_instructions/wasm64/const/f64.const/confirmation ... bench: 8955261 ns/iter (+/- 350471) -test wasm_instructions/wasm32/iunop/i32.clz ... bench: 2409780 ns/iter (+/- 17125) -test wasm_instructions/wasm32/iunop/i32.clz/confirmation ... bench: 4575840 ns/iter (+/- 31817) -test wasm_instructions/wasm64/iunop/i32.clz ... bench: 2435066 ns/iter (+/- 5891) -test wasm_instructions/wasm64/iunop/i32.clz/confirmation ... bench: 4630301 ns/iter (+/- 24235) -test wasm_instructions/wasm32/iunop/i32.ctz ... bench: 2453449 ns/iter (+/- 136143) -test wasm_instructions/wasm32/iunop/i32.ctz/confirmation ... bench: 4632466 ns/iter (+/- 65174) -test wasm_instructions/wasm64/iunop/i32.ctz ... bench: 2524579 ns/iter (+/- 33079) -test wasm_instructions/wasm64/iunop/i32.ctz/confirmation ... bench: 4634171 ns/iter (+/- 32345) -test wasm_instructions/wasm32/iunop/i32.popcnt ... bench: 2497718 ns/iter (+/- 89413) -test wasm_instructions/wasm32/iunop/i32.popcnt/confirmation ... bench: 4638552 ns/iter (+/- 186895) -test wasm_instructions/wasm64/iunop/i32.popcnt ... bench: 2441751 ns/iter (+/- 27741) -test wasm_instructions/wasm64/iunop/i32.popcnt/confirmation ... bench: 4644952 ns/iter (+/- 41197) -test wasm_instructions/wasm32/iunop/i64.clz ... bench: 2415162 ns/iter (+/- 63226) -test wasm_instructions/wasm32/iunop/i64.clz/confirmation ... bench: 4605782 ns/iter (+/- 63289) -test wasm_instructions/wasm64/iunop/i64.clz ... bench: 2478367 ns/iter (+/- 85779) -test wasm_instructions/wasm64/iunop/i64.clz/confirmation ... bench: 4623630 ns/iter (+/- 51878) -test wasm_instructions/wasm32/iunop/i64.ctz ... bench: 2421429 ns/iter (+/- 12248) -test wasm_instructions/wasm32/iunop/i64.ctz/confirmation ... bench: 4578318 ns/iter (+/- 36469) -test wasm_instructions/wasm64/iunop/i64.ctz ... bench: 2533064 ns/iter (+/- 22834) -test wasm_instructions/wasm64/iunop/i64.ctz/confirmation ... bench: 4620642 ns/iter (+/- 25054) -test wasm_instructions/wasm32/iunop/i64.popcnt ... bench: 2437446 ns/iter (+/- 180837) -test wasm_instructions/wasm32/iunop/i64.popcnt/confirmation ... bench: 4613415 ns/iter (+/- 53657) -test wasm_instructions/wasm64/iunop/i64.popcnt ... bench: 2531431 ns/iter (+/- 29827) -test wasm_instructions/wasm64/iunop/i64.popcnt/confirmation ... bench: 4630162 ns/iter (+/- 26198) -test wasm_instructions/wasm32/funop/f32.abs ... bench: 3489909 ns/iter (+/- 243498) -test wasm_instructions/wasm32/funop/f32.abs/confirmation ... bench: 6791191 ns/iter (+/- 76659) -test wasm_instructions/wasm64/funop/f32.abs ... bench: 3614198 ns/iter (+/- 48681) -test wasm_instructions/wasm64/funop/f32.abs/confirmation ... bench: 6779728 ns/iter (+/- 150612) -test wasm_instructions/wasm32/funop/f32.neg ... bench: 3539101 ns/iter (+/- 23356) -test wasm_instructions/wasm32/funop/f32.neg/confirmation ... bench: 6729740 ns/iter (+/- 50813) -test wasm_instructions/wasm64/funop/f32.neg ... bench: 3526361 ns/iter (+/- 16263) -test wasm_instructions/wasm64/funop/f32.neg/confirmation ... bench: 6741560 ns/iter (+/- 75523) -test wasm_instructions/wasm32/funop/f64.abs ... bench: 5336481 ns/iter (+/- 24258) -test wasm_instructions/wasm32/funop/f64.abs/confirmation ... bench: 9962320 ns/iter (+/- 37893) -test wasm_instructions/wasm64/funop/f64.abs ... bench: 5179378 ns/iter (+/- 301871) -test wasm_instructions/wasm64/funop/f64.abs/confirmation ... bench: 9970584 ns/iter (+/- 52173) -test wasm_instructions/wasm32/funop/f64.neg ... bench: 5322241 ns/iter (+/- 18648) -test wasm_instructions/wasm32/funop/f64.neg/confirmation ... bench: 9916654 ns/iter (+/- 85137) -test wasm_instructions/wasm64/funop/f64.neg ... bench: 5343590 ns/iter (+/- 257471) -test wasm_instructions/wasm64/funop/f64.neg/confirmation ... bench: 9996788 ns/iter (+/- 32221) -test wasm_instructions/wasm32/funop/f32.ceil ... bench: 5285398 ns/iter (+/- 644422) -test wasm_instructions/wasm32/funop/f32.ceil/confirmation ... bench: 10155159 ns/iter (+/- 18811) -test wasm_instructions/wasm64/funop/f32.ceil ... bench: 5272390 ns/iter (+/- 37937) -test wasm_instructions/wasm64/funop/f32.ceil/confirmation ... bench: 10277693 ns/iter (+/- 1043400) -test wasm_instructions/wasm32/funop/f32.floor ... bench: 5278639 ns/iter (+/- 38472) -test wasm_instructions/wasm32/funop/f32.floor/confirmation ... bench: 10295924 ns/iter (+/- 17952) -test wasm_instructions/wasm64/funop/f32.floor ... bench: 5489215 ns/iter (+/- 583441) -test wasm_instructions/wasm64/funop/f32.floor/confirmation ... bench: 10648930 ns/iter (+/- 48975) -test wasm_instructions/wasm32/funop/f32.trunc ... bench: 5430584 ns/iter (+/- 522456) -test wasm_instructions/wasm32/funop/f32.trunc/confirmation ... bench: 10331899 ns/iter (+/- 222766) -test wasm_instructions/wasm64/funop/f32.trunc ... bench: 5295673 ns/iter (+/- 116628) -test wasm_instructions/wasm64/funop/f32.trunc/confirmation ... bench: 10226462 ns/iter (+/- 225996) -test wasm_instructions/wasm32/funop/f32.nearest ... bench: 5468121 ns/iter (+/- 56057) -test wasm_instructions/wasm32/funop/f32.nearest/confirmation ... bench: 10236117 ns/iter (+/- 111898) -test wasm_instructions/wasm64/funop/f32.nearest ... bench: 5326201 ns/iter (+/- 42183) -test wasm_instructions/wasm64/funop/f32.nearest/confirmation ... bench: 10263183 ns/iter (+/- 473236) -test wasm_instructions/wasm32/funop/f64.ceil ... bench: 5970156 ns/iter (+/- 42080) -test wasm_instructions/wasm32/funop/f64.ceil/confirmation ... bench: 11904967 ns/iter (+/- 208672) -test wasm_instructions/wasm64/funop/f64.ceil ... bench: 6352253 ns/iter (+/- 30025) -test wasm_instructions/wasm64/funop/f64.ceil/confirmation ... bench: 12133015 ns/iter (+/- 294409) -test wasm_instructions/wasm32/funop/f64.floor ... bench: 5964056 ns/iter (+/- 215985) -test wasm_instructions/wasm32/funop/f64.floor/confirmation ... bench: 11843369 ns/iter (+/- 176533) -test wasm_instructions/wasm64/funop/f64.floor ... bench: 6352545 ns/iter (+/- 36938) -test wasm_instructions/wasm64/funop/f64.floor/confirmation ... bench: 11720955 ns/iter (+/- 252406) -test wasm_instructions/wasm32/funop/f64.trunc ... bench: 5943268 ns/iter (+/- 36841) -test wasm_instructions/wasm32/funop/f64.trunc/confirmation ... bench: 11897358 ns/iter (+/- 71278) -test wasm_instructions/wasm64/funop/f64.trunc ... bench: 5989088 ns/iter (+/- 29736) -test wasm_instructions/wasm64/funop/f64.trunc/confirmation ... bench: 11715660 ns/iter (+/- 15347) -test wasm_instructions/wasm32/funop/f64.nearest ... bench: 6337678 ns/iter (+/- 309111) -test wasm_instructions/wasm32/funop/f64.nearest/confirmation ... bench: 12215281 ns/iter (+/- 282703) -test wasm_instructions/wasm64/funop/f64.nearest ... bench: 6087004 ns/iter (+/- 48899) -test wasm_instructions/wasm64/funop/f64.nearest/confirmation ... bench: 11530554 ns/iter (+/- 258640) -test wasm_instructions/wasm32/funop/f32.sqrt ... bench: 12084239 ns/iter (+/- 33050) -test wasm_instructions/wasm32/funop/f32.sqrt/confirmation ... bench: 24253313 ns/iter (+/- 118498) -test wasm_instructions/wasm64/funop/f32.sqrt ... bench: 12097455 ns/iter (+/- 31708) -test wasm_instructions/wasm64/funop/f32.sqrt/confirmation ... bench: 23904871 ns/iter (+/- 272019) -test wasm_instructions/wasm32/funop/f64.sqrt ... bench: 19207180 ns/iter (+/- 187846) -test wasm_instructions/wasm32/funop/f64.sqrt/confirmation ... bench: 38442493 ns/iter (+/- 105102) -test wasm_instructions/wasm64/funop/f64.sqrt ... bench: 19304767 ns/iter (+/- 585679) -test wasm_instructions/wasm64/funop/f64.sqrt/confirmation ... bench: 38470927 ns/iter (+/- 153116) -test wasm_instructions/wasm32/ibinop/i32.add ... bench: 2406001 ns/iter (+/- 25269) -test wasm_instructions/wasm32/ibinop/i32.add/confirmation ... bench: 4617444 ns/iter (+/- 12122) -test wasm_instructions/wasm64/ibinop/i32.add ... bench: 2471100 ns/iter (+/- 27233) -test wasm_instructions/wasm64/ibinop/i32.add/confirmation ... bench: 4623662 ns/iter (+/- 179979) -test wasm_instructions/wasm32/ibinop/i32.sub ... bench: 2410379 ns/iter (+/- 122500) -test wasm_instructions/wasm32/ibinop/i32.sub/confirmation ... bench: 4594114 ns/iter (+/- 40705) -test wasm_instructions/wasm64/ibinop/i32.sub ... bench: 2435770 ns/iter (+/- 28255) -test wasm_instructions/wasm64/ibinop/i32.sub/confirmation ... bench: 4630267 ns/iter (+/- 64921) -test wasm_instructions/wasm32/ibinop/i32.mul ... bench: 2453707 ns/iter (+/- 42491) -test wasm_instructions/wasm32/ibinop/i32.mul/confirmation ... bench: 4589206 ns/iter (+/- 63335) -test wasm_instructions/wasm64/ibinop/i32.mul ... bench: 2465438 ns/iter (+/- 104079) -test wasm_instructions/wasm64/ibinop/i32.mul/confirmation ... bench: 4626439 ns/iter (+/- 19391) -test wasm_instructions/wasm32/ibinop/i32.and ... bench: 2524300 ns/iter (+/- 26903) -test wasm_instructions/wasm32/ibinop/i32.and/confirmation ... bench: 4615232 ns/iter (+/- 25989) -test wasm_instructions/wasm64/ibinop/i32.and ... bench: 2489252 ns/iter (+/- 30909) -test wasm_instructions/wasm64/ibinop/i32.and/confirmation ... bench: 4578798 ns/iter (+/- 67735) -test wasm_instructions/wasm32/ibinop/i32.or ... bench: 2418606 ns/iter (+/- 13537) -test wasm_instructions/wasm32/ibinop/i32.or/confirmation ... bench: 4621343 ns/iter (+/- 20023) -test wasm_instructions/wasm64/ibinop/i32.or ... bench: 2423721 ns/iter (+/- 38125) -test wasm_instructions/wasm64/ibinop/i32.or/confirmation ... bench: 4631644 ns/iter (+/- 32179) -test wasm_instructions/wasm32/ibinop/i32.xor ... bench: 2405306 ns/iter (+/- 21452) -test wasm_instructions/wasm32/ibinop/i32.xor/confirmation ... bench: 4570277 ns/iter (+/- 15538) -test wasm_instructions/wasm64/ibinop/i32.xor ... bench: 2453643 ns/iter (+/- 27839) -test wasm_instructions/wasm64/ibinop/i32.xor/confirmation ... bench: 4633107 ns/iter (+/- 42870) -test wasm_instructions/wasm32/ibinop/i32.shl ... bench: 2407397 ns/iter (+/- 26831) -test wasm_instructions/wasm32/ibinop/i32.shl/confirmation ... bench: 4614520 ns/iter (+/- 32502) -test wasm_instructions/wasm64/ibinop/i32.shl ... bench: 2512603 ns/iter (+/- 21582) -test wasm_instructions/wasm64/ibinop/i32.shl/confirmation ... bench: 4631971 ns/iter (+/- 32355) -test wasm_instructions/wasm32/ibinop/i32.shr_s ... bench: 2405138 ns/iter (+/- 21192) -test wasm_instructions/wasm32/ibinop/i32.shr_s/confirmation ... bench: 4582283 ns/iter (+/- 43886) -test wasm_instructions/wasm64/ibinop/i32.shr_s ... bench: 2507818 ns/iter (+/- 38650) -test wasm_instructions/wasm64/ibinop/i32.shr_s/confirmation ... bench: 4618943 ns/iter (+/- 26422) -test wasm_instructions/wasm32/ibinop/i32.shr_u ... bench: 2481725 ns/iter (+/- 50476) -test wasm_instructions/wasm32/ibinop/i32.shr_u/confirmation ... bench: 4624328 ns/iter (+/- 75024) -test wasm_instructions/wasm64/ibinop/i32.shr_u ... bench: 2466529 ns/iter (+/- 40345) -test wasm_instructions/wasm64/ibinop/i32.shr_u/confirmation ... bench: 4631680 ns/iter (+/- 17795) -test wasm_instructions/wasm32/ibinop/i32.rotl ... bench: 2412139 ns/iter (+/- 52944) -test wasm_instructions/wasm32/ibinop/i32.rotl/confirmation ... bench: 4608153 ns/iter (+/- 64353) -test wasm_instructions/wasm64/ibinop/i32.rotl ... bench: 2423277 ns/iter (+/- 21586) -test wasm_instructions/wasm64/ibinop/i32.rotl/confirmation ... bench: 4587058 ns/iter (+/- 25933) -test wasm_instructions/wasm32/ibinop/i32.rotr ... bench: 2430969 ns/iter (+/- 14454) -test wasm_instructions/wasm32/ibinop/i32.rotr/confirmation ... bench: 4572626 ns/iter (+/- 51774) -test wasm_instructions/wasm64/ibinop/i32.rotr ... bench: 2523555 ns/iter (+/- 190508) -test wasm_instructions/wasm64/ibinop/i32.rotr/confirmation ... bench: 4648514 ns/iter (+/- 44406) -test wasm_instructions/wasm32/ibinop/i64.add ... bench: 2451076 ns/iter (+/- 32019) -test wasm_instructions/wasm32/ibinop/i64.add/confirmation ... bench: 4606396 ns/iter (+/- 35441) -test wasm_instructions/wasm64/ibinop/i64.add ... bench: 2447162 ns/iter (+/- 23658) -test wasm_instructions/wasm64/ibinop/i64.add/confirmation ... bench: 4609245 ns/iter (+/- 22720) -test wasm_instructions/wasm32/ibinop/i64.sub ... bench: 2415481 ns/iter (+/- 14964) -test wasm_instructions/wasm32/ibinop/i64.sub/confirmation ... bench: 4620436 ns/iter (+/- 43996) -test wasm_instructions/wasm64/ibinop/i64.sub ... bench: 2537663 ns/iter (+/- 59263) -test wasm_instructions/wasm64/ibinop/i64.sub/confirmation ... bench: 4616715 ns/iter (+/- 45955) -test wasm_instructions/wasm32/ibinop/i64.mul ... bench: 2461024 ns/iter (+/- 50965) -test wasm_instructions/wasm32/ibinop/i64.mul/confirmation ... bench: 4572156 ns/iter (+/- 27879) -test wasm_instructions/wasm64/ibinop/i64.mul ... bench: 2509411 ns/iter (+/- 49070) -test wasm_instructions/wasm64/ibinop/i64.mul/confirmation ... bench: 4592683 ns/iter (+/- 31071) -test wasm_instructions/wasm32/ibinop/i64.and ... bench: 2412337 ns/iter (+/- 12168) -test wasm_instructions/wasm32/ibinop/i64.and/confirmation ... bench: 4617578 ns/iter (+/- 232370) -test wasm_instructions/wasm64/ibinop/i64.and ... bench: 2420236 ns/iter (+/- 6357) -test wasm_instructions/wasm64/ibinop/i64.and/confirmation ... bench: 4644013 ns/iter (+/- 31230) -test wasm_instructions/wasm32/ibinop/i64.or ... bench: 2429848 ns/iter (+/- 132819) -test wasm_instructions/wasm32/ibinop/i64.or/confirmation ... bench: 4614639 ns/iter (+/- 20749) -test wasm_instructions/wasm64/ibinop/i64.or ... bench: 2444187 ns/iter (+/- 101265) -test wasm_instructions/wasm64/ibinop/i64.or/confirmation ... bench: 4633986 ns/iter (+/- 40289) -test wasm_instructions/wasm32/ibinop/i64.xor ... bench: 2429902 ns/iter (+/- 178523) -test wasm_instructions/wasm32/ibinop/i64.xor/confirmation ... bench: 4617091 ns/iter (+/- 36153) -test wasm_instructions/wasm64/ibinop/i64.xor ... bench: 2432495 ns/iter (+/- 27629) -test wasm_instructions/wasm64/ibinop/i64.xor/confirmation ... bench: 4641455 ns/iter (+/- 56260) -test wasm_instructions/wasm32/ibinop/i64.shl ... bench: 2449648 ns/iter (+/- 39927) -test wasm_instructions/wasm32/ibinop/i64.shl/confirmation ... bench: 4632137 ns/iter (+/- 195532) -test wasm_instructions/wasm64/ibinop/i64.shl ... bench: 2455411 ns/iter (+/- 176620) -test wasm_instructions/wasm64/ibinop/i64.shl/confirmation ... bench: 4650805 ns/iter (+/- 58860) -test wasm_instructions/wasm32/ibinop/i64.shr_s ... bench: 2418147 ns/iter (+/- 59484) -test wasm_instructions/wasm32/ibinop/i64.shr_s/confirmation ... bench: 4559733 ns/iter (+/- 406552) -test wasm_instructions/wasm64/ibinop/i64.shr_s ... bench: 2461312 ns/iter (+/- 125156) -test wasm_instructions/wasm64/ibinop/i64.shr_s/confirmation ... bench: 4636549 ns/iter (+/- 48880) -test wasm_instructions/wasm32/ibinop/i64.shr_u ... bench: 2470002 ns/iter (+/- 146958) -test wasm_instructions/wasm32/ibinop/i64.shr_u/confirmation ... bench: 4619860 ns/iter (+/- 87373) -test wasm_instructions/wasm64/ibinop/i64.shr_u ... bench: 2454040 ns/iter (+/- 48985) -test wasm_instructions/wasm64/ibinop/i64.shr_u/confirmation ... bench: 4627545 ns/iter (+/- 10111) -test wasm_instructions/wasm32/ibinop/i64.rotl ... bench: 2431418 ns/iter (+/- 206123) -test wasm_instructions/wasm32/ibinop/i64.rotl/confirmation ... bench: 4570054 ns/iter (+/- 28732) -test wasm_instructions/wasm64/ibinop/i64.rotl ... bench: 2436074 ns/iter (+/- 133478) -test wasm_instructions/wasm64/ibinop/i64.rotl/confirmation ... bench: 4590146 ns/iter (+/- 42343) -test wasm_instructions/wasm32/ibinop/i64.rotr ... bench: 2457877 ns/iter (+/- 16152) -test wasm_instructions/wasm32/ibinop/i64.rotr/confirmation ... bench: 4611714 ns/iter (+/- 44079) -test wasm_instructions/wasm64/ibinop/i64.rotr ... bench: 2418225 ns/iter (+/- 28401) -test wasm_instructions/wasm64/ibinop/i64.rotr/confirmation ... bench: 4639057 ns/iter (+/- 13043) -test wasm_instructions/wasm32/ibinop/i32.div_s ... bench: 49268848 ns/iter (+/- 635248) -test wasm_instructions/wasm32/ibinop/i32.div_s/confirmation ... bench: 98193146 ns/iter (+/- 497170) -test wasm_instructions/wasm64/ibinop/i32.div_s ... bench: 49355715 ns/iter (+/- 77528) -test wasm_instructions/wasm64/ibinop/i32.div_s/confirmation ... bench: 98187036 ns/iter (+/- 42595) -test wasm_instructions/wasm32/ibinop/i32.div_u ... bench: 49326433 ns/iter (+/- 123400) -test wasm_instructions/wasm32/ibinop/i32.div_u/confirmation ... bench: 98146509 ns/iter (+/- 28032) -test wasm_instructions/wasm64/ibinop/i32.div_u ... bench: 49326264 ns/iter (+/- 41481) -test wasm_instructions/wasm64/ibinop/i32.div_u/confirmation ... bench: 98221706 ns/iter (+/- 525685) -test wasm_instructions/wasm32/ibinop/i32.rem_s ... bench: 49290159 ns/iter (+/- 40401) -test wasm_instructions/wasm32/ibinop/i32.rem_s/confirmation ... bench: 98177178 ns/iter (+/- 23878) -test wasm_instructions/wasm64/ibinop/i32.rem_s ... bench: 49376326 ns/iter (+/- 676915) -test wasm_instructions/wasm64/ibinop/i32.rem_s/confirmation ... bench: 98242116 ns/iter (+/- 353785) -test wasm_instructions/wasm32/ibinop/i32.rem_u ... bench: 49354010 ns/iter (+/- 937920) -test wasm_instructions/wasm32/ibinop/i32.rem_u/confirmation ... bench: 98120735 ns/iter (+/- 117261) -test wasm_instructions/wasm64/ibinop/i32.rem_u ... bench: 49298293 ns/iter (+/- 188827) -test wasm_instructions/wasm64/ibinop/i32.rem_u/confirmation ... bench: 98200155 ns/iter (+/- 28467) -test wasm_instructions/wasm32/ibinop/i64.div_s ... bench: 49312849 ns/iter (+/- 511311) -test wasm_instructions/wasm32/ibinop/i64.div_s/confirmation ... bench: 98225416 ns/iter (+/- 91005) -test wasm_instructions/wasm64/ibinop/i64.div_s ... bench: 49289997 ns/iter (+/- 272901) -test wasm_instructions/wasm64/ibinop/i64.div_s/confirmation ... bench: 98144119 ns/iter (+/- 568762) -test wasm_instructions/wasm32/ibinop/i64.div_u ... bench: 49390648 ns/iter (+/- 36381) -test wasm_instructions/wasm32/ibinop/i64.div_u/confirmation ... bench: 98198477 ns/iter (+/- 673081) -test wasm_instructions/wasm64/ibinop/i64.div_u ... bench: 49315691 ns/iter (+/- 96956) -test wasm_instructions/wasm64/ibinop/i64.div_u/confirmation ... bench: 98168806 ns/iter (+/- 334367) -test wasm_instructions/wasm32/ibinop/i64.rem_s ... bench: 49322106 ns/iter (+/- 235073) -test wasm_instructions/wasm32/ibinop/i64.rem_s/confirmation ... bench: 98198131 ns/iter (+/- 16813) -test wasm_instructions/wasm64/ibinop/i64.rem_s ... bench: 49306176 ns/iter (+/- 621066) -test wasm_instructions/wasm64/ibinop/i64.rem_s/confirmation ... bench: 98195970 ns/iter (+/- 117179) -test wasm_instructions/wasm32/ibinop/i64.rem_u ... bench: 49301231 ns/iter (+/- 69897) -test wasm_instructions/wasm32/ibinop/i64.rem_u/confirmation ... bench: 98168083 ns/iter (+/- 19996) -test wasm_instructions/wasm64/ibinop/i64.rem_u ... bench: 49327311 ns/iter (+/- 713086) -test wasm_instructions/wasm64/ibinop/i64.rem_u/confirmation ... bench: 98213047 ns/iter (+/- 550642) -test wasm_instructions/wasm32/fbinop/f32.add ... bench: 4939240 ns/iter (+/- 32706) -test wasm_instructions/wasm32/fbinop/f32.add/confirmation ... bench: 9822109 ns/iter (+/- 72539) -test wasm_instructions/wasm64/fbinop/f32.add ... bench: 4940771 ns/iter (+/- 65066) -test wasm_instructions/wasm64/fbinop/f32.add/confirmation ... bench: 9416369 ns/iter (+/- 136608) -test wasm_instructions/wasm32/fbinop/f32.sub ... bench: 5061385 ns/iter (+/- 33479) -test wasm_instructions/wasm32/fbinop/f32.sub/confirmation ... bench: 9358312 ns/iter (+/- 64748) -test wasm_instructions/wasm64/fbinop/f32.sub ... bench: 4914416 ns/iter (+/- 44518) -test wasm_instructions/wasm64/fbinop/f32.sub/confirmation ... bench: 9640578 ns/iter (+/- 190273) -test wasm_instructions/wasm32/fbinop/f32.mul ... bench: 5054517 ns/iter (+/- 48427) -test wasm_instructions/wasm32/fbinop/f32.mul/confirmation ... bench: 9444434 ns/iter (+/- 103632) -test wasm_instructions/wasm64/fbinop/f32.mul ... bench: 5084015 ns/iter (+/- 29072) -test wasm_instructions/wasm64/fbinop/f32.mul/confirmation ... bench: 9394222 ns/iter (+/- 209341) -test wasm_instructions/wasm32/fbinop/f64.add ... bench: 5928033 ns/iter (+/- 95343) -test wasm_instructions/wasm32/fbinop/f64.add/confirmation ... bench: 11247566 ns/iter (+/- 15308) -test wasm_instructions/wasm64/fbinop/f64.add ... bench: 5832635 ns/iter (+/- 58198) -test wasm_instructions/wasm64/fbinop/f64.add/confirmation ... bench: 11335312 ns/iter (+/- 667522) -test wasm_instructions/wasm32/fbinop/f64.sub ... bench: 5851247 ns/iter (+/- 83088) -test wasm_instructions/wasm32/fbinop/f64.sub/confirmation ... bench: 11431499 ns/iter (+/- 52091) -test wasm_instructions/wasm64/fbinop/f64.sub ... bench: 5833978 ns/iter (+/- 360363) -test wasm_instructions/wasm64/fbinop/f64.sub/confirmation ... bench: 11329709 ns/iter (+/- 110342) -test wasm_instructions/wasm32/fbinop/f64.mul ... bench: 5806337 ns/iter (+/- 51307) -test wasm_instructions/wasm32/fbinop/f64.mul/confirmation ... bench: 11269153 ns/iter (+/- 536541) -test wasm_instructions/wasm64/fbinop/f64.mul ... bench: 5842303 ns/iter (+/- 56395) -test wasm_instructions/wasm64/fbinop/f64.mul/confirmation ... bench: 11310388 ns/iter (+/- 356464) -test wasm_instructions/wasm32/fbinop/f32.div ... bench: 8140168 ns/iter (+/- 55397) -test wasm_instructions/wasm32/fbinop/f32.div/confirmation ... bench: 16292681 ns/iter (+/- 211295) -test wasm_instructions/wasm64/fbinop/f32.div ... bench: 8239060 ns/iter (+/- 18363) -test wasm_instructions/wasm64/fbinop/f32.div/confirmation ... bench: 16574591 ns/iter (+/- 1481873) -test wasm_instructions/wasm32/fbinop/f64.div ... bench: 11030241 ns/iter (+/- 703748) -test wasm_instructions/wasm32/fbinop/f64.div/confirmation ... bench: 21713785 ns/iter (+/- 35100) -test wasm_instructions/wasm64/fbinop/f64.div ... bench: 11157693 ns/iter (+/- 87967) -test wasm_instructions/wasm64/fbinop/f64.div/confirmation ... bench: 21696425 ns/iter (+/- 39307) -test wasm_instructions/wasm32/fbinop/f32.min ... bench: 46604428 ns/iter (+/- 5288444) -test wasm_instructions/wasm32/fbinop/f32.min/confirmation ... bench: 114368124 ns/iter (+/- 129233) -test wasm_instructions/wasm64/fbinop/f32.min ... bench: 47400406 ns/iter (+/- 5850090) -test wasm_instructions/wasm64/fbinop/f32.min/confirmation ... bench: 114552304 ns/iter (+/- 147978) -test wasm_instructions/wasm32/fbinop/f32.max ... bench: 47983374 ns/iter (+/- 980422) -test wasm_instructions/wasm32/fbinop/f32.max/confirmation ... bench: 114622830 ns/iter (+/- 267419) -test wasm_instructions/wasm64/fbinop/f32.max ... bench: 46971198 ns/iter (+/- 1022040) -test wasm_instructions/wasm64/fbinop/f32.max/confirmation ... bench: 114686497 ns/iter (+/- 145304) -test wasm_instructions/wasm32/fbinop/f64.min ... bench: 48178360 ns/iter (+/- 2305919) -test wasm_instructions/wasm32/fbinop/f64.min/confirmation ... bench: 117235913 ns/iter (+/- 61729) -test wasm_instructions/wasm64/fbinop/f64.min ... bench: 36111340 ns/iter (+/- 7457305) -test wasm_instructions/wasm64/fbinop/f64.min/confirmation ... bench: 117327043 ns/iter (+/- 88369) -test wasm_instructions/wasm32/fbinop/f64.max ... bench: 49154716 ns/iter (+/- 322011) -test wasm_instructions/wasm32/fbinop/f64.max/confirmation ... bench: 117329556 ns/iter (+/- 105236) -test wasm_instructions/wasm64/fbinop/f64.max ... bench: 45601350 ns/iter (+/- 5591137) -test wasm_instructions/wasm64/fbinop/f64.max/confirmation ... bench: 117200601 ns/iter (+/- 803654) -test wasm_instructions/wasm32/fbinop/f32.copysign ... bench: 4598104 ns/iter (+/- 15922) -test wasm_instructions/wasm32/fbinop/f32.copysign/confirmation ... bench: 8858339 ns/iter (+/- 68474) -test wasm_instructions/wasm64/fbinop/f32.copysign ... bench: 4627214 ns/iter (+/- 25624) -test wasm_instructions/wasm64/fbinop/f32.copysign/confirmation ... bench: 8879130 ns/iter (+/- 85345) -test wasm_instructions/wasm32/fbinop/f64.copysign ... bench: 6816920 ns/iter (+/- 161024) -test wasm_instructions/wasm32/fbinop/f64.copysign/confirmation ... bench: 13251066 ns/iter (+/- 52425) -test wasm_instructions/wasm64/fbinop/f64.copysign ... bench: 6969117 ns/iter (+/- 86625) -test wasm_instructions/wasm64/fbinop/f64.copysign/confirmation ... bench: 13263156 ns/iter (+/- 188643) -test wasm_instructions/wasm32/itestop/i32.eqz ... bench: 2769096 ns/iter (+/- 157983) -test wasm_instructions/wasm32/itestop/i32.eqz/confirmation ... bench: 5324970 ns/iter (+/- 23591) -test wasm_instructions/wasm64/itestop/i32.eqz ... bench: 2800833 ns/iter (+/- 27297) -test wasm_instructions/wasm64/itestop/i32.eqz/confirmation ... bench: 5336048 ns/iter (+/- 3892) -test wasm_instructions/wasm32/itestop/i64.eqz ... bench: 2670430 ns/iter (+/- 57664) -test wasm_instructions/wasm32/itestop/i64.eqz/confirmation ... bench: 5075978 ns/iter (+/- 32894) -test wasm_instructions/wasm64/itestop/i64.eqz ... bench: 2672435 ns/iter (+/- 9822) -test wasm_instructions/wasm64/itestop/i64.eqz/confirmation ... bench: 5074802 ns/iter (+/- 34114) -test wasm_instructions/wasm32/irelop/i32.eq ... bench: 2637583 ns/iter (+/- 7517) -test wasm_instructions/wasm32/irelop/i32.eq/confirmation ... bench: 5038958 ns/iter (+/- 11109) -test wasm_instructions/wasm64/irelop/i32.eq ... bench: 2682502 ns/iter (+/- 114944) -test wasm_instructions/wasm64/irelop/i32.eq/confirmation ... bench: 5030123 ns/iter (+/- 21874) -test wasm_instructions/wasm32/irelop/i32.ne ... bench: 2660822 ns/iter (+/- 6736) -test wasm_instructions/wasm32/irelop/i32.ne/confirmation ... bench: 5070686 ns/iter (+/- 31101) -test wasm_instructions/wasm64/irelop/i32.ne ... bench: 2656617 ns/iter (+/- 15191) -test wasm_instructions/wasm64/irelop/i32.ne/confirmation ... bench: 5076909 ns/iter (+/- 448207) -test wasm_instructions/wasm32/irelop/i32.lt_s ... bench: 2640846 ns/iter (+/- 55692) -test wasm_instructions/wasm32/irelop/i32.lt_s/confirmation ... bench: 5037576 ns/iter (+/- 379359) -test wasm_instructions/wasm64/irelop/i32.lt_s ... bench: 2734325 ns/iter (+/- 30145) -test wasm_instructions/wasm64/irelop/i32.lt_s/confirmation ... bench: 5102799 ns/iter (+/- 238892) -test wasm_instructions/wasm32/irelop/i32.lt_u ... bench: 2744517 ns/iter (+/- 46108) -test wasm_instructions/wasm32/irelop/i32.lt_u/confirmation ... bench: 5061512 ns/iter (+/- 106770) -test wasm_instructions/wasm64/irelop/i32.lt_u ... bench: 2683547 ns/iter (+/- 118285) -test wasm_instructions/wasm64/irelop/i32.lt_u/confirmation ... bench: 5083609 ns/iter (+/- 54776) -test wasm_instructions/wasm32/irelop/i32.gt_s ... bench: 2850472 ns/iter (+/- 6868) -test wasm_instructions/wasm32/irelop/i32.gt_s/confirmation ... bench: 5082198 ns/iter (+/- 18916) -test wasm_instructions/wasm64/irelop/i32.gt_s ... bench: 2707588 ns/iter (+/- 41776) -test wasm_instructions/wasm64/irelop/i32.gt_s/confirmation ... bench: 5070475 ns/iter (+/- 57631) -test wasm_instructions/wasm32/irelop/i32.gt_u ... bench: 2668196 ns/iter (+/- 36501) -test wasm_instructions/wasm32/irelop/i32.gt_u/confirmation ... bench: 5094734 ns/iter (+/- 9845) -test wasm_instructions/wasm64/irelop/i32.gt_u ... bench: 2670234 ns/iter (+/- 22399) -test wasm_instructions/wasm64/irelop/i32.gt_u/confirmation ... bench: 5071213 ns/iter (+/- 19530) -test wasm_instructions/wasm32/irelop/i32.le_s ... bench: 2673234 ns/iter (+/- 32215) -test wasm_instructions/wasm32/irelop/i32.le_s/confirmation ... bench: 5068634 ns/iter (+/- 18605) -test wasm_instructions/wasm64/irelop/i32.le_s ... bench: 2673420 ns/iter (+/- 27684) -test wasm_instructions/wasm64/irelop/i32.le_s/confirmation ... bench: 5084725 ns/iter (+/- 42821) -test wasm_instructions/wasm32/irelop/i32.le_u ... bench: 2735312 ns/iter (+/- 48200) -test wasm_instructions/wasm32/irelop/i32.le_u/confirmation ... bench: 5099680 ns/iter (+/- 25692) -test wasm_instructions/wasm64/irelop/i32.le_u ... bench: 2670578 ns/iter (+/- 48729) -test wasm_instructions/wasm64/irelop/i32.le_u/confirmation ... bench: 5086740 ns/iter (+/- 77494) -test wasm_instructions/wasm32/irelop/i32.ge_s ... bench: 2701879 ns/iter (+/- 35664) -test wasm_instructions/wasm32/irelop/i32.ge_s/confirmation ... bench: 5083494 ns/iter (+/- 85845) -test wasm_instructions/wasm64/irelop/i32.ge_s ... bench: 2667170 ns/iter (+/- 23385) -test wasm_instructions/wasm64/irelop/i32.ge_s/confirmation ... bench: 5095508 ns/iter (+/- 63086) -test wasm_instructions/wasm32/irelop/i32.ge_u ... bench: 2710183 ns/iter (+/- 26083) -test wasm_instructions/wasm32/irelop/i32.ge_u/confirmation ... bench: 5055200 ns/iter (+/- 36866) -test wasm_instructions/wasm64/irelop/i32.ge_u ... bench: 2916815 ns/iter (+/- 18875) -test wasm_instructions/wasm64/irelop/i32.ge_u/confirmation ... bench: 5111353 ns/iter (+/- 120640) -test wasm_instructions/wasm32/irelop/i64.eq ... bench: 2675283 ns/iter (+/- 44568) -test wasm_instructions/wasm32/irelop/i64.eq/confirmation ... bench: 5102690 ns/iter (+/- 57631) -test wasm_instructions/wasm64/irelop/i64.eq ... bench: 2666956 ns/iter (+/- 25878) -test wasm_instructions/wasm64/irelop/i64.eq/confirmation ... bench: 5090540 ns/iter (+/- 23007) -test wasm_instructions/wasm32/irelop/i64.ne ... bench: 2675004 ns/iter (+/- 31774) -test wasm_instructions/wasm32/irelop/i64.ne/confirmation ... bench: 5075688 ns/iter (+/- 72773) -test wasm_instructions/wasm64/irelop/i64.ne ... bench: 2677934 ns/iter (+/- 16216) -test wasm_instructions/wasm64/irelop/i64.ne/confirmation ... bench: 5121348 ns/iter (+/- 17290) -test wasm_instructions/wasm32/irelop/i64.lt_s ... bench: 2696826 ns/iter (+/- 59886) -test wasm_instructions/wasm32/irelop/i64.lt_s/confirmation ... bench: 5112274 ns/iter (+/- 81533) -test wasm_instructions/wasm64/irelop/i64.lt_s ... bench: 2692876 ns/iter (+/- 51164) -test wasm_instructions/wasm64/irelop/i64.lt_s/confirmation ... bench: 5111110 ns/iter (+/- 34747) -test wasm_instructions/wasm32/irelop/i64.lt_u ... bench: 2675535 ns/iter (+/- 30861) -test wasm_instructions/wasm32/irelop/i64.lt_u/confirmation ... bench: 5078467 ns/iter (+/- 66883) -test wasm_instructions/wasm64/irelop/i64.lt_u ... bench: 2683282 ns/iter (+/- 16445) -test wasm_instructions/wasm64/irelop/i64.lt_u/confirmation ... bench: 5109701 ns/iter (+/- 72616) -test wasm_instructions/wasm32/irelop/i64.gt_s ... bench: 2658036 ns/iter (+/- 159607) -test wasm_instructions/wasm32/irelop/i64.gt_s/confirmation ... bench: 5088769 ns/iter (+/- 35544) -test wasm_instructions/wasm64/irelop/i64.gt_s ... bench: 2664268 ns/iter (+/- 25387) -test wasm_instructions/wasm64/irelop/i64.gt_s/confirmation ... bench: 5071421 ns/iter (+/- 62039) -test wasm_instructions/wasm32/irelop/i64.gt_u ... bench: 2671533 ns/iter (+/- 143919) -test wasm_instructions/wasm32/irelop/i64.gt_u/confirmation ... bench: 5104027 ns/iter (+/- 49350) -test wasm_instructions/wasm64/irelop/i64.gt_u ... bench: 2688138 ns/iter (+/- 57001) -test wasm_instructions/wasm64/irelop/i64.gt_u/confirmation ... bench: 5132535 ns/iter (+/- 196826) -test wasm_instructions/wasm32/irelop/i64.le_s ... bench: 2655747 ns/iter (+/- 42932) -test wasm_instructions/wasm32/irelop/i64.le_s/confirmation ... bench: 5078223 ns/iter (+/- 20173) -test wasm_instructions/wasm64/irelop/i64.le_s ... bench: 2871139 ns/iter (+/- 46188) -test wasm_instructions/wasm64/irelop/i64.le_s/confirmation ... bench: 5089263 ns/iter (+/- 23917) -test wasm_instructions/wasm32/irelop/i64.le_u ... bench: 2684386 ns/iter (+/- 32636) -test wasm_instructions/wasm32/irelop/i64.le_u/confirmation ... bench: 5096297 ns/iter (+/- 56343) -test wasm_instructions/wasm64/irelop/i64.le_u ... bench: 2744003 ns/iter (+/- 25057) -test wasm_instructions/wasm64/irelop/i64.le_u/confirmation ... bench: 5086560 ns/iter (+/- 21396) -test wasm_instructions/wasm32/irelop/i64.ge_s ... bench: 2662125 ns/iter (+/- 15318) -test wasm_instructions/wasm32/irelop/i64.ge_s/confirmation ... bench: 5069029 ns/iter (+/- 54751) -test wasm_instructions/wasm64/irelop/i64.ge_s ... bench: 2672144 ns/iter (+/- 7707) -test wasm_instructions/wasm64/irelop/i64.ge_s/confirmation ... bench: 5082129 ns/iter (+/- 14632) -test wasm_instructions/wasm32/irelop/i64.ge_u ... bench: 2663391 ns/iter (+/- 40503) -test wasm_instructions/wasm32/irelop/i64.ge_u/confirmation ... bench: 5081829 ns/iter (+/- 29012) -test wasm_instructions/wasm64/irelop/i64.ge_u ... bench: 2693664 ns/iter (+/- 60288) -test wasm_instructions/wasm64/irelop/i64.ge_u/confirmation ... bench: 5156475 ns/iter (+/- 53893) -test wasm_instructions/wasm32/frelop/f32.eq ... bench: 5060165 ns/iter (+/- 45289) -test wasm_instructions/wasm32/frelop/f32.eq/confirmation ... bench: 9536438 ns/iter (+/- 2379) -test wasm_instructions/wasm64/frelop/f32.eq ... bench: 5003880 ns/iter (+/- 13243) -test wasm_instructions/wasm64/frelop/f32.eq/confirmation ... bench: 9647293 ns/iter (+/- 15220) -test wasm_instructions/wasm32/frelop/f32.ne ... bench: 4977774 ns/iter (+/- 48481) -test wasm_instructions/wasm32/frelop/f32.ne/confirmation ... bench: 9542661 ns/iter (+/- 6964) -test wasm_instructions/wasm64/frelop/f32.ne ... bench: 4978623 ns/iter (+/- 20019) -test wasm_instructions/wasm64/frelop/f32.ne/confirmation ... bench: 9566471 ns/iter (+/- 140162) -test wasm_instructions/wasm32/frelop/f64.eq ... bench: 4999213 ns/iter (+/- 299698) -test wasm_instructions/wasm32/frelop/f64.eq/confirmation ... bench: 9648434 ns/iter (+/- 83165) -test wasm_instructions/wasm64/frelop/f64.eq ... bench: 5010156 ns/iter (+/- 31901) -test wasm_instructions/wasm64/frelop/f64.eq/confirmation ... bench: 9538513 ns/iter (+/- 77630) -test wasm_instructions/wasm32/frelop/f64.ne ... bench: 4978005 ns/iter (+/- 120986) -test wasm_instructions/wasm32/frelop/f64.ne/confirmation ... bench: 9532388 ns/iter (+/- 73596) -test wasm_instructions/wasm64/frelop/f64.ne ... bench: 4941503 ns/iter (+/- 46157) -test wasm_instructions/wasm64/frelop/f64.ne/confirmation ... bench: 9702050 ns/iter (+/- 36705) -test wasm_instructions/wasm32/frelop/f32.lt ... bench: 3338897 ns/iter (+/- 96115) -test wasm_instructions/wasm32/frelop/f32.lt/confirmation ... bench: 6338283 ns/iter (+/- 153816) -test wasm_instructions/wasm64/frelop/f32.lt ... bench: 3364253 ns/iter (+/- 36463) -test wasm_instructions/wasm64/frelop/f32.lt/confirmation ... bench: 6407031 ns/iter (+/- 37945) -test wasm_instructions/wasm32/frelop/f32.gt ... bench: 3383015 ns/iter (+/- 61426) -test wasm_instructions/wasm32/frelop/f32.gt/confirmation ... bench: 6358403 ns/iter (+/- 72609) -test wasm_instructions/wasm64/frelop/f32.gt ... bench: 3343130 ns/iter (+/- 72346) -test wasm_instructions/wasm64/frelop/f32.gt/confirmation ... bench: 6434533 ns/iter (+/- 55145) -test wasm_instructions/wasm32/frelop/f32.le ... bench: 3318248 ns/iter (+/- 160750) -test wasm_instructions/wasm32/frelop/f32.le/confirmation ... bench: 6357969 ns/iter (+/- 22853) -test wasm_instructions/wasm64/frelop/f32.le ... bench: 3347876 ns/iter (+/- 20948) -test wasm_instructions/wasm64/frelop/f32.le/confirmation ... bench: 6401613 ns/iter (+/- 59752) -test wasm_instructions/wasm32/frelop/f32.ge ... bench: 3330250 ns/iter (+/- 13113) -test wasm_instructions/wasm32/frelop/f32.ge/confirmation ... bench: 6342347 ns/iter (+/- 26676) -test wasm_instructions/wasm64/frelop/f32.ge ... bench: 3350896 ns/iter (+/- 48670) -test wasm_instructions/wasm64/frelop/f32.ge/confirmation ... bench: 6344131 ns/iter (+/- 42091) -test wasm_instructions/wasm32/frelop/f64.lt ... bench: 3346755 ns/iter (+/- 198180) -test wasm_instructions/wasm32/frelop/f64.lt/confirmation ... bench: 6364458 ns/iter (+/- 30531) -test wasm_instructions/wasm64/frelop/f64.lt ... bench: 3324357 ns/iter (+/- 268065) -test wasm_instructions/wasm64/frelop/f64.lt/confirmation ... bench: 6419650 ns/iter (+/- 93154) -test wasm_instructions/wasm32/frelop/f64.gt ... bench: 3353241 ns/iter (+/- 30231) -test wasm_instructions/wasm32/frelop/f64.gt/confirmation ... bench: 6399013 ns/iter (+/- 69646) -test wasm_instructions/wasm64/frelop/f64.gt ... bench: 3479828 ns/iter (+/- 37603) -test wasm_instructions/wasm64/frelop/f64.gt/confirmation ... bench: 6349602 ns/iter (+/- 65657) -test wasm_instructions/wasm32/frelop/f64.le ... bench: 3332272 ns/iter (+/- 105361) -test wasm_instructions/wasm32/frelop/f64.le/confirmation ... bench: 6357663 ns/iter (+/- 624566) -test wasm_instructions/wasm64/frelop/f64.le ... bench: 3364948 ns/iter (+/- 48581) -test wasm_instructions/wasm64/frelop/f64.le/confirmation ... bench: 6350448 ns/iter (+/- 28191) -test wasm_instructions/wasm32/frelop/f64.ge ... bench: 3339762 ns/iter (+/- 47045) -test wasm_instructions/wasm32/frelop/f64.ge/confirmation ... bench: 6348439 ns/iter (+/- 397697) -test wasm_instructions/wasm64/frelop/f64.ge ... bench: 3366964 ns/iter (+/- 14341) -test wasm_instructions/wasm64/frelop/f64.ge/confirmation ... bench: 6354662 ns/iter (+/- 67228) -test wasm_instructions/wasm32/cvtop/i32.extend8_s ... bench: 2480584 ns/iter (+/- 42484) -test wasm_instructions/wasm32/cvtop/i32.extend8_s/confirmation ... bench: 4563025 ns/iter (+/- 79084) -test wasm_instructions/wasm64/cvtop/i32.extend8_s ... bench: 2484357 ns/iter (+/- 52763) -test wasm_instructions/wasm64/cvtop/i32.extend8_s/confirmation ... bench: 4626475 ns/iter (+/- 24445) -test wasm_instructions/wasm32/cvtop/i32.extend16_s ... bench: 2490437 ns/iter (+/- 209816) -test wasm_instructions/wasm32/cvtop/i32.extend16_s/confirmation ... bench: 4636574 ns/iter (+/- 42162) -test wasm_instructions/wasm64/cvtop/i32.extend16_s ... bench: 2410990 ns/iter (+/- 29958) -test wasm_instructions/wasm64/cvtop/i32.extend16_s/confirmation ... bench: 4609622 ns/iter (+/- 79625) -test wasm_instructions/wasm32/cvtop/i64.extend8_s ... bench: 2399587 ns/iter (+/- 10771) -test wasm_instructions/wasm32/cvtop/i64.extend8_s/confirmation ... bench: 4611303 ns/iter (+/- 330925) -test wasm_instructions/wasm64/cvtop/i64.extend8_s ... bench: 2486412 ns/iter (+/- 63721) -test wasm_instructions/wasm64/cvtop/i64.extend8_s/confirmation ... bench: 4637672 ns/iter (+/- 46674) -test wasm_instructions/wasm32/cvtop/i64.extend16_s ... bench: 2411187 ns/iter (+/- 22489) -test wasm_instructions/wasm32/cvtop/i64.extend16_s/confirmation ... bench: 4614991 ns/iter (+/- 23356) -test wasm_instructions/wasm64/cvtop/i64.extend16_s ... bench: 2451260 ns/iter (+/- 36781) -test wasm_instructions/wasm64/cvtop/i64.extend16_s/confirmation ... bench: 4593326 ns/iter (+/- 33613) -test wasm_instructions/wasm32/cvtop/f32.convert_i32_s ... bench: 2701567 ns/iter (+/- 35809) -test wasm_instructions/wasm32/cvtop/f32.convert_i32_s/confirmation ... bench: 5151665 ns/iter (+/- 59493) -test wasm_instructions/wasm64/cvtop/f32.convert_i32_s ... bench: 2697892 ns/iter (+/- 27406) -test wasm_instructions/wasm64/cvtop/f32.convert_i32_s/confirmation ... bench: 5175595 ns/iter (+/- 60110) -test wasm_instructions/wasm32/cvtop/f32.convert_i64_s ... bench: 2770846 ns/iter (+/- 202735) -test wasm_instructions/wasm32/cvtop/f32.convert_i64_s/confirmation ... bench: 5164054 ns/iter (+/- 39865) -test wasm_instructions/wasm64/cvtop/f32.convert_i64_s ... bench: 2742136 ns/iter (+/- 50592) -test wasm_instructions/wasm64/cvtop/f32.convert_i64_s/confirmation ... bench: 5176963 ns/iter (+/- 13350) -test wasm_instructions/wasm32/cvtop/f64.convert_i32_s ... bench: 2713327 ns/iter (+/- 55166) -test wasm_instructions/wasm32/cvtop/f64.convert_i32_s/confirmation ... bench: 5117502 ns/iter (+/- 20238) -test wasm_instructions/wasm64/cvtop/f64.convert_i32_s ... bench: 2731171 ns/iter (+/- 54895) -test wasm_instructions/wasm64/cvtop/f64.convert_i32_s/confirmation ... bench: 5153336 ns/iter (+/- 45579) -test wasm_instructions/wasm32/cvtop/f64.convert_i64_s ... bench: 2695962 ns/iter (+/- 16194) -test wasm_instructions/wasm32/cvtop/f64.convert_i64_s/confirmation ... bench: 5094355 ns/iter (+/- 366858) -test wasm_instructions/wasm64/cvtop/f64.convert_i64_s ... bench: 2721204 ns/iter (+/- 197323) -test wasm_instructions/wasm64/cvtop/f64.convert_i64_s/confirmation ... bench: 5145739 ns/iter (+/- 16333) -test wasm_instructions/wasm32/cvtop/i64.extend32_s ... bench: 2395364 ns/iter (+/- 11756) -test wasm_instructions/wasm32/cvtop/i64.extend32_s/confirmation ... bench: 4604219 ns/iter (+/- 10418) -test wasm_instructions/wasm64/cvtop/i64.extend32_s ... bench: 2459389 ns/iter (+/- 51049) -test wasm_instructions/wasm64/cvtop/i64.extend32_s/confirmation ... bench: 4575628 ns/iter (+/- 6741) -test wasm_instructions/wasm32/cvtop/i32.wrap_i64 ... bench: 2439280 ns/iter (+/- 136603) -test wasm_instructions/wasm32/cvtop/i32.wrap_i64/confirmation ... bench: 4592032 ns/iter (+/- 44386) -test wasm_instructions/wasm64/cvtop/i32.wrap_i64 ... bench: 2428006 ns/iter (+/- 15997) -test wasm_instructions/wasm64/cvtop/i32.wrap_i64/confirmation ... bench: 4632619 ns/iter (+/- 18038) -test wasm_instructions/wasm32/cvtop/i64.extend_i32_s ... bench: 2427858 ns/iter (+/- 66550) -test wasm_instructions/wasm32/cvtop/i64.extend_i32_s/confirmation ... bench: 4619309 ns/iter (+/- 498336) -test wasm_instructions/wasm64/cvtop/i64.extend_i32_s ... bench: 2493757 ns/iter (+/- 162519) -test wasm_instructions/wasm64/cvtop/i64.extend_i32_s/confirmation ... bench: 4628151 ns/iter (+/- 30728) -test wasm_instructions/wasm32/cvtop/i64.extend_i32_u ... bench: 2415274 ns/iter (+/- 15701) -test wasm_instructions/wasm32/cvtop/i64.extend_i32_u/confirmation ... bench: 4612375 ns/iter (+/- 7372) -test wasm_instructions/wasm64/cvtop/i64.extend_i32_u ... bench: 2493065 ns/iter (+/- 96242) -test wasm_instructions/wasm64/cvtop/i64.extend_i32_u/confirmation ... bench: 4602925 ns/iter (+/- 29963) -test wasm_instructions/wasm32/cvtop/f32.demote_f64 ... bench: 5425701 ns/iter (+/- 62874) -test wasm_instructions/wasm32/cvtop/f32.demote_f64/confirmation ... bench: 10548360 ns/iter (+/- 40391) -test wasm_instructions/wasm64/cvtop/f32.demote_f64 ... bench: 5448842 ns/iter (+/- 97789) -test wasm_instructions/wasm64/cvtop/f32.demote_f64/confirmation ... bench: 10516232 ns/iter (+/- 59464) -test wasm_instructions/wasm32/cvtop/f64.promote_f32 ... bench: 6212819 ns/iter (+/- 32937) -test wasm_instructions/wasm32/cvtop/f64.promote_f32/confirmation ... bench: 12117067 ns/iter (+/- 161569) -test wasm_instructions/wasm64/cvtop/f64.promote_f32 ... bench: 6417519 ns/iter (+/- 15165) -test wasm_instructions/wasm64/cvtop/f64.promote_f32/confirmation ... bench: 12125485 ns/iter (+/- 130282) -test wasm_instructions/wasm32/cvtop/f32.reinterpret_i32 ... bench: 2427434 ns/iter (+/- 57850) -test wasm_instructions/wasm32/cvtop/f32.reinterpret_i32/confirmation ... bench: 4616109 ns/iter (+/- 28034) -test wasm_instructions/wasm64/cvtop/f32.reinterpret_i32 ... bench: 2463183 ns/iter (+/- 18453) -test wasm_instructions/wasm64/cvtop/f32.reinterpret_i32/confirmation ... bench: 4644997 ns/iter (+/- 52768) -test wasm_instructions/wasm32/cvtop/f64.reinterpret_i64 ... bench: 2458221 ns/iter (+/- 32958) -test wasm_instructions/wasm32/cvtop/f64.reinterpret_i64/confirmation ... bench: 4622836 ns/iter (+/- 29309) -test wasm_instructions/wasm64/cvtop/f64.reinterpret_i64 ... bench: 2470606 ns/iter (+/- 47298) -test wasm_instructions/wasm64/cvtop/f64.reinterpret_i64/confirmation ... bench: 4687514 ns/iter (+/- 34566) -test wasm_instructions/wasm32/cvtop/f32.convert_i32_u ... bench: 3344289 ns/iter (+/- 28221) -test wasm_instructions/wasm32/cvtop/f32.convert_i32_u/confirmation ... bench: 5959653 ns/iter (+/- 64894) -test wasm_instructions/wasm64/cvtop/f32.convert_i32_u ... bench: 3255523 ns/iter (+/- 70198) -test wasm_instructions/wasm64/cvtop/f32.convert_i32_u/confirmation ... bench: 5990564 ns/iter (+/- 82999) -test wasm_instructions/wasm32/cvtop/f64.convert_i32_u ... bench: 3194162 ns/iter (+/- 29557) -test wasm_instructions/wasm32/cvtop/f64.convert_i32_u/confirmation ... bench: 5975215 ns/iter (+/- 96737) -test wasm_instructions/wasm64/cvtop/f64.convert_i32_u ... bench: 3137616 ns/iter (+/- 29686) -test wasm_instructions/wasm64/cvtop/f64.convert_i32_u/confirmation ... bench: 5964593 ns/iter (+/- 351214) -test wasm_instructions/wasm32/cvtop/i32.reinterpret_f32 ... bench: 2971160 ns/iter (+/- 13494) -test wasm_instructions/wasm32/cvtop/i32.reinterpret_f32/confirmation ... bench: 5652541 ns/iter (+/- 32948) -test wasm_instructions/wasm64/cvtop/i32.reinterpret_f32 ... bench: 3023286 ns/iter (+/- 62649) -test wasm_instructions/wasm64/cvtop/i32.reinterpret_f32/confirmation ... bench: 5734746 ns/iter (+/- 143869) -test wasm_instructions/wasm32/cvtop/i64.reinterpret_f64 ... bench: 2951125 ns/iter (+/- 106724) -test wasm_instructions/wasm32/cvtop/i64.reinterpret_f64/confirmation ... bench: 5651159 ns/iter (+/- 1024255) -test wasm_instructions/wasm64/cvtop/i64.reinterpret_f64 ... bench: 2968062 ns/iter (+/- 145421) -test wasm_instructions/wasm64/cvtop/i64.reinterpret_f64/confirmation ... bench: 5680424 ns/iter (+/- 32069) -test wasm_instructions/wasm32/cvtop/i32.trunc_f32_s ... bench: 56396107 ns/iter (+/- 856749) -test wasm_instructions/wasm32/cvtop/i32.trunc_f32_s/confirmation ... bench: 124800527 ns/iter (+/- 800276) -test wasm_instructions/wasm64/cvtop/i32.trunc_f32_s ... bench: 57217602 ns/iter (+/- 615014) -test wasm_instructions/wasm64/cvtop/i32.trunc_f32_s/confirmation ... bench: 125190358 ns/iter (+/- 810452) -test wasm_instructions/wasm32/cvtop/i32.trunc_f32_u ... bench: 55113603 ns/iter (+/- 62824) -test wasm_instructions/wasm32/cvtop/i32.trunc_f32_u/confirmation ... bench: 120557068 ns/iter (+/- 905118) -test wasm_instructions/wasm64/cvtop/i32.trunc_f32_u ... bench: 55299476 ns/iter (+/- 109353) -test wasm_instructions/wasm64/cvtop/i32.trunc_f32_u/confirmation ... bench: 121014251 ns/iter (+/- 493680) -test wasm_instructions/wasm32/cvtop/i32.trunc_f64_s ... bench: 52675324 ns/iter (+/- 1048080) -test wasm_instructions/wasm32/cvtop/i32.trunc_f64_s/confirmation ... bench: 119442979 ns/iter (+/- 595376) -test wasm_instructions/wasm64/cvtop/i32.trunc_f64_s ... bench: 52720905 ns/iter (+/- 1859331) -test wasm_instructions/wasm64/cvtop/i32.trunc_f64_s/confirmation ... bench: 119501904 ns/iter (+/- 257877) -test wasm_instructions/wasm32/cvtop/i32.trunc_f64_u ... bench: 58676911 ns/iter (+/- 1575514) -test wasm_instructions/wasm32/cvtop/i32.trunc_f64_u/confirmation ... bench: 123404414 ns/iter (+/- 298031) -test wasm_instructions/wasm64/cvtop/i32.trunc_f64_u ... bench: 59021700 ns/iter (+/- 895473) -test wasm_instructions/wasm64/cvtop/i32.trunc_f64_u/confirmation ... bench: 122956632 ns/iter (+/- 131748) -test wasm_instructions/wasm32/cvtop/i64.trunc_f32_s ... bench: 55564416 ns/iter (+/- 1179970) -test wasm_instructions/wasm32/cvtop/i64.trunc_f32_s/confirmation ... bench: 124907787 ns/iter (+/- 1544413) -test wasm_instructions/wasm64/cvtop/i64.trunc_f32_s ... bench: 57155156 ns/iter (+/- 420207) -test wasm_instructions/wasm64/cvtop/i64.trunc_f32_s/confirmation ... bench: 125303260 ns/iter (+/- 988139) -test wasm_instructions/wasm32/cvtop/i64.trunc_f32_u ... bench: 57577144 ns/iter (+/- 724017) -test wasm_instructions/wasm32/cvtop/i64.trunc_f32_u/confirmation ... bench: 119659976 ns/iter (+/- 795450) -test wasm_instructions/wasm64/cvtop/i64.trunc_f32_u ... bench: 57128751 ns/iter (+/- 861177) -test wasm_instructions/wasm64/cvtop/i64.trunc_f32_u/confirmation ... bench: 118984722 ns/iter (+/- 788224) -test wasm_instructions/wasm32/cvtop/i64.trunc_f64_s ... bench: 52690861 ns/iter (+/- 396899) -test wasm_instructions/wasm32/cvtop/i64.trunc_f64_s/confirmation ... bench: 118460002 ns/iter (+/- 322767) -test wasm_instructions/wasm64/cvtop/i64.trunc_f64_s ... bench: 52730947 ns/iter (+/- 550059) -test wasm_instructions/wasm64/cvtop/i64.trunc_f64_s/confirmation ... bench: 118859203 ns/iter (+/- 945899) -test wasm_instructions/wasm32/cvtop/i64.trunc_f64_u ... bench: 59150799 ns/iter (+/- 478325) -test wasm_instructions/wasm32/cvtop/i64.trunc_f64_u/confirmation ... bench: 122073048 ns/iter (+/- 1211374) -test wasm_instructions/wasm64/cvtop/i64.trunc_f64_u ... bench: 59515846 ns/iter (+/- 593426) -test wasm_instructions/wasm64/cvtop/i64.trunc_f64_u/confirmation ... bench: 122403137 ns/iter (+/- 774380) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_s ... bench: 51744251 ns/iter (+/- 465040) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_s/confirmation ... bench: 114324503 ns/iter (+/- 533388) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_s ... bench: 51294002 ns/iter (+/- 1866961) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_s/confirmation ... bench: 114282801 ns/iter (+/- 628467) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_s ... bench: 59525242 ns/iter (+/- 66572) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_s/confirmation ... bench: 116775473 ns/iter (+/- 2800366) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_s ... bench: 59495712 ns/iter (+/- 148377) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_s/confirmation ... bench: 113376880 ns/iter (+/- 1816761) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_u ... bench: 108191932 ns/iter (+/- 49833) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_u/confirmation ... bench: 236271508 ns/iter (+/- 146337) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_u ... bench: 108010352 ns/iter (+/- 166185) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_u/confirmation ... bench: 236946164 ns/iter (+/- 103050) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_u ... bench: 110179745 ns/iter (+/- 263737) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_u/confirmation ... bench: 242377989 ns/iter (+/- 60842) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_u ... bench: 110302412 ns/iter (+/- 340125) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_u/confirmation ... bench: 242337981 ns/iter (+/- 939492) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_u ... bench: 108443260 ns/iter (+/- 680527) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_u/confirmation ... bench: 241244163 ns/iter (+/- 253197) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_u ... bench: 108467196 ns/iter (+/- 114149) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_u/confirmation ... bench: 241375186 ns/iter (+/- 33825) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_u ... bench: 110084201 ns/iter (+/- 353258) -test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_u/confirmation ... bench: 245363592 ns/iter (+/- 69796) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_u ... bench: 109730970 ns/iter (+/- 85169) -test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_u/confirmation ... bench: 245034615 ns/iter (+/- 766489) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_s ... bench: 40567399 ns/iter (+/- 1308565) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_s/confirmation ... bench: 118256162 ns/iter (+/- 760278) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_s ... bench: 41883309 ns/iter (+/- 261612) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_s/confirmation ... bench: 118480519 ns/iter (+/- 93108) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_s ... bench: 44495296 ns/iter (+/- 485649) -test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_s/confirmation ... bench: 118106390 ns/iter (+/- 136371) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_s ... bench: 44974745 ns/iter (+/- 645762) -test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_s/confirmation ... bench: 118077725 ns/iter (+/- 60182) -test wasm_instructions/wasm32/cvtop/f32.convert_i64_u ... bench: 31839662 ns/iter (+/- 205404) -test wasm_instructions/wasm32/cvtop/f32.convert_i64_u/confirmation ... bench: 67651450 ns/iter (+/- 380966) -test wasm_instructions/wasm64/cvtop/f32.convert_i64_u ... bench: 31794101 ns/iter (+/- 429022) -test wasm_instructions/wasm64/cvtop/f32.convert_i64_u/confirmation ... bench: 67982425 ns/iter (+/- 1565392) -test wasm_instructions/wasm32/cvtop/f64.convert_i64_u ... bench: 32414001 ns/iter (+/- 606954) -test wasm_instructions/wasm32/cvtop/f64.convert_i64_u/confirmation ... bench: 68000971 ns/iter (+/- 561576) -test wasm_instructions/wasm64/cvtop/f64.convert_i64_u ... bench: 31537213 ns/iter (+/- 192453) -test wasm_instructions/wasm64/cvtop/f64.convert_i64_u/confirmation ... bench: 67711228 ns/iter (+/- 352043) -test wasm_instructions/wasm32/refop/ref.func ... bench: 164170064 ns/iter (+/- 190016) -test wasm_instructions/wasm32/refop/ref.func/confirmation ... bench: 323975159 ns/iter (+/- 642862) -test wasm_instructions/wasm64/refop/ref.func ... bench: 164018025 ns/iter (+/- 215076) -test wasm_instructions/wasm64/refop/ref.func/confirmation ... bench: 324781943 ns/iter (+/- 288747) -test wasm_instructions/wasm32/refop/ref.is_null-ref.func ... bench: 161587143 ns/iter (+/- 373886) -test wasm_instructions/wasm32/refop/ref.is_null-ref.func/confirmation ... bench: 326310046 ns/iter (+/- 878551) -test wasm_instructions/wasm64/refop/ref.is_null-ref.func ... bench: 161887880 ns/iter (+/- 165577) -test wasm_instructions/wasm64/refop/ref.is_null-ref.func/confirmation ... bench: 326535809 ns/iter (+/- 864990) -test wasm_instructions/wasm32/varop/local.get ... bench: 2411279 ns/iter (+/- 32674) -test wasm_instructions/wasm32/varop/local.get/confirmation ... bench: 4601679 ns/iter (+/- 51788) -test wasm_instructions/wasm64/varop/local.get ... bench: 2437031 ns/iter (+/- 73289) -test wasm_instructions/wasm64/varop/local.get/confirmation ... bench: 4630339 ns/iter (+/- 39977) -test wasm_instructions/wasm32/varop/global.get ... bench: 2431581 ns/iter (+/- 45566) -test wasm_instructions/wasm32/varop/global.get/confirmation ... bench: 4766455 ns/iter (+/- 27790) -test wasm_instructions/wasm64/varop/global.get ... bench: 2447111 ns/iter (+/- 55228) -test wasm_instructions/wasm64/varop/global.get/confirmation ... bench: 4660353 ns/iter (+/- 39854) -test wasm_instructions/wasm32/varop/global.set ... bench: 2475873 ns/iter (+/- 32113) -test wasm_instructions/wasm32/varop/global.set/confirmation ... bench: 4578253 ns/iter (+/- 41627) -test wasm_instructions/wasm64/varop/global.set ... bench: 2447914 ns/iter (+/- 48477) -test wasm_instructions/wasm64/varop/global.set/confirmation ... bench: 4632767 ns/iter (+/- 38586) -test wasm_instructions/wasm32/varop/local.tee ... bench: 2455872 ns/iter (+/- 50472) -test wasm_instructions/wasm32/varop/local.tee/confirmation ... bench: 4617265 ns/iter (+/- 16542) -test wasm_instructions/wasm64/varop/local.tee ... bench: 2429390 ns/iter (+/- 18416) -test wasm_instructions/wasm64/varop/local.tee/confirmation ... bench: 4626494 ns/iter (+/- 318349) -test wasm_instructions/wasm32/tabop/table.get ... bench: 7537668 ns/iter (+/- 549210) -test wasm_instructions/wasm32/tabop/table.get/confirmation ... bench: 14374974 ns/iter (+/- 2560061) -test wasm_instructions/wasm64/tabop/table.get ... bench: 7531863 ns/iter (+/- 638602) -test wasm_instructions/wasm64/tabop/table.get/confirmation ... bench: 14729537 ns/iter (+/- 30329) -test wasm_instructions/wasm32/tabop/table.size ... bench: 2430032 ns/iter (+/- 41288) -test wasm_instructions/wasm32/tabop/table.size/confirmation ... bench: 4635674 ns/iter (+/- 22157) -test wasm_instructions/wasm64/tabop/table.size ... bench: 2518503 ns/iter (+/- 48198) -test wasm_instructions/wasm64/tabop/table.size/confirmation ... bench: 4646363 ns/iter (+/- 29250) -test wasm_instructions/wasm32/memop/i32.load ... bench: 3130550 ns/iter (+/- 17239) -test wasm_instructions/wasm32/memop/i32.load/confirmation ... bench: 5857831 ns/iter (+/- 46622) -test wasm_instructions/wasm64/memop/i32.load ... bench: 4921826 ns/iter (+/- 13269) -test wasm_instructions/wasm64/memop/i32.load/confirmation ... bench: 9540130 ns/iter (+/- 52073) -test wasm_instructions/wasm32/memop/i64.load ... bench: 3185200 ns/iter (+/- 287696) -test wasm_instructions/wasm32/memop/i64.load/confirmation ... bench: 6011206 ns/iter (+/- 27974) -test wasm_instructions/wasm64/memop/i64.load ... bench: 4983605 ns/iter (+/- 323864) -test wasm_instructions/wasm64/memop/i64.load/confirmation ... bench: 9604194 ns/iter (+/- 32423) -test wasm_instructions/wasm32/memop/f32.load ... bench: 3613027 ns/iter (+/- 34376) -test wasm_instructions/wasm32/memop/f32.load/confirmation ... bench: 6986915 ns/iter (+/- 110973) -test wasm_instructions/wasm64/memop/f32.load ... bench: 5590987 ns/iter (+/- 153261) -test wasm_instructions/wasm64/memop/f32.load/confirmation ... bench: 10487568 ns/iter (+/- 52510) -test wasm_instructions/wasm32/memop/f64.load ... bench: 3696619 ns/iter (+/- 41677) -test wasm_instructions/wasm32/memop/f64.load/confirmation ... bench: 6951316 ns/iter (+/- 31281) -test wasm_instructions/wasm64/memop/f64.load ... bench: 5408170 ns/iter (+/- 52470) -test wasm_instructions/wasm64/memop/f64.load/confirmation ... bench: 10583134 ns/iter (+/- 135000) -test wasm_instructions/wasm32/memop/i32.store ... bench: 3191755 ns/iter (+/- 183565) -test wasm_instructions/wasm32/memop/i32.store/confirmation ... bench: 6147243 ns/iter (+/- 48760) -test wasm_instructions/wasm64/memop/i32.store ... bench: 4007275 ns/iter (+/- 31136) -test wasm_instructions/wasm64/memop/i32.store/confirmation ... bench: 7579926 ns/iter (+/- 28996) -test wasm_instructions/wasm32/memop/i64.store ... bench: 3168943 ns/iter (+/- 37346) -test wasm_instructions/wasm32/memop/i64.store/confirmation ... bench: 6112964 ns/iter (+/- 240803) -test wasm_instructions/wasm64/memop/i64.store ... bench: 4058326 ns/iter (+/- 22543) -test wasm_instructions/wasm64/memop/i64.store/confirmation ... bench: 7657207 ns/iter (+/- 23468) -test wasm_instructions/wasm32/memop/f32.store ... bench: 3167289 ns/iter (+/- 46815) -test wasm_instructions/wasm32/memop/f32.store/confirmation ... bench: 6060328 ns/iter (+/- 36391) -test wasm_instructions/wasm64/memop/f32.store ... bench: 4204463 ns/iter (+/- 243441) -test wasm_instructions/wasm64/memop/f32.store/confirmation ... bench: 8034371 ns/iter (+/- 18762) -test wasm_instructions/wasm32/memop/f64.store ... bench: 3204699 ns/iter (+/- 35635) -test wasm_instructions/wasm32/memop/f64.store/confirmation ... bench: 6041077 ns/iter (+/- 146338) -test wasm_instructions/wasm64/memop/f64.store ... bench: 4229581 ns/iter (+/- 29522) -test wasm_instructions/wasm64/memop/f64.store/confirmation ... bench: 8016910 ns/iter (+/- 69820) -test wasm_instructions/wasm32/memop/i32.load8_s ... bench: 3325969 ns/iter (+/- 53570) -test wasm_instructions/wasm32/memop/i32.load8_s/confirmation ... bench: 6523883 ns/iter (+/- 6984) -test wasm_instructions/wasm64/memop/i32.load8_s ... bench: 5053304 ns/iter (+/- 32950) -test wasm_instructions/wasm64/memop/i32.load8_s/confirmation ... bench: 10128924 ns/iter (+/- 28572) -test wasm_instructions/wasm32/memop/i32.load8_u ... bench: 3323480 ns/iter (+/- 37805) -test wasm_instructions/wasm32/memop/i32.load8_u/confirmation ... bench: 6339086 ns/iter (+/- 39970) -test wasm_instructions/wasm64/memop/i32.load8_u ... bench: 5209985 ns/iter (+/- 5767) -test wasm_instructions/wasm64/memop/i32.load8_u/confirmation ... bench: 9767495 ns/iter (+/- 728322) -test wasm_instructions/wasm32/memop/i32.load16_s ... bench: 3311508 ns/iter (+/- 25512) -test wasm_instructions/wasm32/memop/i32.load16_s/confirmation ... bench: 6348181 ns/iter (+/- 63123) -test wasm_instructions/wasm64/memop/i32.load16_s ... bench: 5092578 ns/iter (+/- 138773) -test wasm_instructions/wasm64/memop/i32.load16_s/confirmation ... bench: 9822489 ns/iter (+/- 228715) -test wasm_instructions/wasm32/memop/i32.load16_u ... bench: 3304782 ns/iter (+/- 32345) -test wasm_instructions/wasm32/memop/i32.load16_u/confirmation ... bench: 6260628 ns/iter (+/- 41601) -test wasm_instructions/wasm64/memop/i32.load16_u ... bench: 5161572 ns/iter (+/- 71229) -test wasm_instructions/wasm64/memop/i32.load16_u/confirmation ... bench: 9900212 ns/iter (+/- 31531) -test wasm_instructions/wasm32/memop/i64.load8_s ... bench: 3333168 ns/iter (+/- 20390) -test wasm_instructions/wasm32/memop/i64.load8_s/confirmation ... bench: 6255196 ns/iter (+/- 45695) -test wasm_instructions/wasm64/memop/i64.load8_s ... bench: 5142924 ns/iter (+/- 41649) -test wasm_instructions/wasm64/memop/i64.load8_s/confirmation ... bench: 9873736 ns/iter (+/- 50275) -test wasm_instructions/wasm32/memop/i64.load8_u ... bench: 3320559 ns/iter (+/- 38398) -test wasm_instructions/wasm32/memop/i64.load8_u/confirmation ... bench: 6267224 ns/iter (+/- 71990) -test wasm_instructions/wasm64/memop/i64.load8_u ... bench: 5115963 ns/iter (+/- 85862) -test wasm_instructions/wasm64/memop/i64.load8_u/confirmation ... bench: 10155677 ns/iter (+/- 130673) -test wasm_instructions/wasm32/memop/i64.load16_s ... bench: 3310913 ns/iter (+/- 27657) -test wasm_instructions/wasm32/memop/i64.load16_s/confirmation ... bench: 6273192 ns/iter (+/- 51046) -test wasm_instructions/wasm64/memop/i64.load16_s ... bench: 5076510 ns/iter (+/- 42747) -test wasm_instructions/wasm64/memop/i64.load16_s/confirmation ... bench: 9982808 ns/iter (+/- 145004) -test wasm_instructions/wasm32/memop/i64.load16_u ... bench: 3368604 ns/iter (+/- 56603) -test wasm_instructions/wasm32/memop/i64.load16_u/confirmation ... bench: 6266532 ns/iter (+/- 191712) -test wasm_instructions/wasm64/memop/i64.load16_u ... bench: 5118331 ns/iter (+/- 42271) -test wasm_instructions/wasm64/memop/i64.load16_u/confirmation ... bench: 9737316 ns/iter (+/- 229077) -test wasm_instructions/wasm32/memop/i64.load32_s ... bench: 3176513 ns/iter (+/- 56237) -test wasm_instructions/wasm32/memop/i64.load32_s/confirmation ... bench: 6098605 ns/iter (+/- 49977) -test wasm_instructions/wasm64/memop/i64.load32_s ... bench: 4989225 ns/iter (+/- 60577) -test wasm_instructions/wasm64/memop/i64.load32_s/confirmation ... bench: 9634012 ns/iter (+/- 234748) -test wasm_instructions/wasm32/memop/i64.load32_u ... bench: 3145952 ns/iter (+/- 19398) -test wasm_instructions/wasm32/memop/i64.load32_u/confirmation ... bench: 5821330 ns/iter (+/- 19787) -test wasm_instructions/wasm64/memop/i64.load32_u ... bench: 4858869 ns/iter (+/- 7641) -test wasm_instructions/wasm64/memop/i64.load32_u/confirmation ... bench: 9660536 ns/iter (+/- 184014) -test wasm_instructions/wasm32/memop/i32.store8 ... bench: 3226451 ns/iter (+/- 283781) -test wasm_instructions/wasm32/memop/i32.store8/confirmation ... bench: 6106069 ns/iter (+/- 99449) -test wasm_instructions/wasm64/memop/i32.store8 ... bench: 3961543 ns/iter (+/- 26007) -test wasm_instructions/wasm64/memop/i32.store8/confirmation ... bench: 7875188 ns/iter (+/- 55540) -test wasm_instructions/wasm32/memop/i32.store16 ... bench: 3293386 ns/iter (+/- 51190) -test wasm_instructions/wasm32/memop/i32.store16/confirmation ... bench: 6067966 ns/iter (+/- 5759) -test wasm_instructions/wasm64/memop/i32.store16 ... bench: 4153257 ns/iter (+/- 6252) -test wasm_instructions/wasm64/memop/i32.store16/confirmation ... bench: 7940636 ns/iter (+/- 19114) -test wasm_instructions/wasm32/memop/i64.store8 ... bench: 3255496 ns/iter (+/- 74698) -test wasm_instructions/wasm32/memop/i64.store8/confirmation ... bench: 6109670 ns/iter (+/- 62164) -test wasm_instructions/wasm64/memop/i64.store8 ... bench: 3998531 ns/iter (+/- 13550) -test wasm_instructions/wasm64/memop/i64.store8/confirmation ... bench: 7674058 ns/iter (+/- 20085) -test wasm_instructions/wasm32/memop/i64.store16 ... bench: 3264157 ns/iter (+/- 37629) -test wasm_instructions/wasm32/memop/i64.store16/confirmation ... bench: 6071619 ns/iter (+/- 30867) -test wasm_instructions/wasm64/memop/i64.store16 ... bench: 4164943 ns/iter (+/- 69325) -test wasm_instructions/wasm64/memop/i64.store16/confirmation ... bench: 8201503 ns/iter (+/- 21056) -test wasm_instructions/wasm32/memop/i64.store32 ... bench: 3206773 ns/iter (+/- 21003) -test wasm_instructions/wasm32/memop/i64.store32/confirmation ... bench: 6163302 ns/iter (+/- 49127) -test wasm_instructions/wasm64/memop/i64.store32 ... bench: 4002998 ns/iter (+/- 35023) -test wasm_instructions/wasm64/memop/i64.store32/confirmation ... bench: 7666424 ns/iter (+/- 50499) -test wasm_instructions/wasm32/memop/memory.size ... bench: 2989673 ns/iter (+/- 22597) -test wasm_instructions/wasm32/memop/memory.size/confirmation ... bench: 5712070 ns/iter (+/- 38488) -test wasm_instructions/wasm64/memop/memory.size ... bench: 2994220 ns/iter (+/- 21071) -test wasm_instructions/wasm64/memop/memory.size/confirmation ... bench: 5649833 ns/iter (+/- 7620) -test wasm_instructions/wasm32/memop/memory.grow ... bench: 970123825 ns/iter (+/- 3491725) -test wasm_instructions/wasm32/memop/memory.grow/confirmation ... bench: 1896932839 ns/iter (+/- 7466239) -test wasm_instructions/wasm64/memop/memory.grow ... bench: 924156015 ns/iter (+/- 7254870) -test wasm_instructions/wasm64/memop/memory.grow/confirmation ... bench: 1866826163 ns/iter (+/- 15442733) -test wasm_instructions/wasm32/memop/memory.fill ... bench: 192307573 ns/iter (+/- 95555) -test wasm_instructions/wasm32/memop/memory.fill/confirmation ... bench: 393398932 ns/iter (+/- 1633878) -test wasm_instructions/wasm64/memop/memory.fill ... bench: 191277787 ns/iter (+/- 640393) -test wasm_instructions/wasm64/memop/memory.fill/confirmation ... bench: 393595612 ns/iter (+/- 308837) -test wasm_instructions/wasm32/memop/memory.copy ... bench: 217213802 ns/iter (+/- 840852) -test wasm_instructions/wasm32/memop/memory.copy/confirmation ... bench: 430399940 ns/iter (+/- 339624) -test wasm_instructions/wasm64/memop/memory.copy ... bench: 216964424 ns/iter (+/- 600978) -test wasm_instructions/wasm64/memop/memory.copy/confirmation ... bench: 426147721 ns/iter (+/- 1424647) -test wasm_instructions/wasm32/ctrlop/select ... bench: 4909705 ns/iter (+/- 12450) -test wasm_instructions/wasm32/ctrlop/select/confirmation ... bench: 9486582 ns/iter (+/- 267821) -test wasm_instructions/wasm64/ctrlop/select ... bench: 4936738 ns/iter (+/- 27491) -test wasm_instructions/wasm64/ctrlop/select/confirmation ... bench: 9513743 ns/iter (+/- 304726) -test wasm_instructions/wasm32/ctrlop/call ... bench: 41209282 ns/iter (+/- 335861) -test wasm_instructions/wasm32/ctrlop/call/confirmation ... bench: 79281777 ns/iter (+/- 99019) -test wasm_instructions/wasm64/ctrlop/call ... bench: 41824297 ns/iter (+/- 231856) -test wasm_instructions/wasm64/ctrlop/call/confirmation ... bench: 79318728 ns/iter (+/- 790191) -test wasm_instructions/wasm32/ctrlop/call_indirect ... bench: 60496483 ns/iter (+/- 87962) -test wasm_instructions/wasm32/ctrlop/call_indirect/confirmation ... bench: 163476460 ns/iter (+/- 829547) -test wasm_instructions/wasm64/ctrlop/call_indirect ... bench: 61549763 ns/iter (+/- 166368) -test wasm_instructions/wasm64/ctrlop/call_indirect/confirmation ... bench: 162612275 ns/iter (+/- 631749) -test wasm_instructions/wasm32/ctrlop/recursive_return_call* ... bench: 218997632 ns/iter (+/- 45021091) -test wasm_instructions/wasm32/ctrlop/recursive_return_call*/confirmation ... bench: 602405030 ns/iter (+/- 72234639) -test wasm_instructions/wasm64/ctrlop/recursive_return_call* ... bench: 219125971 ns/iter (+/- 14376302) -test wasm_instructions/wasm64/ctrlop/recursive_return_call*/confirmation ... bench: 453495172 ns/iter (+/- 72486415) -test wasm_instructions/wasm32/ctrlop/recursive_call* ... bench: 255607503 ns/iter (+/- 199450) -test wasm_instructions/wasm32/ctrlop/recursive_call*/confirmation ... bench: 528652382 ns/iter (+/- 383264) -test wasm_instructions/wasm64/ctrlop/recursive_call* ... bench: 255544984 ns/iter (+/- 119359) -test wasm_instructions/wasm64/ctrlop/recursive_call*/confirmation ... bench: 528087493 ns/iter (+/- 2687126) -test wasm_instructions/wasm32/vconst/v128.const ... bench: 2725823 ns/iter (+/- 78288) -test wasm_instructions/wasm32/vconst/v128.const/confirmation ... bench: 5163581 ns/iter (+/- 66311) -test wasm_instructions/wasm64/vconst/v128.const ... bench: 2717298 ns/iter (+/- 31976) -test wasm_instructions/wasm64/vconst/v128.const/confirmation ... bench: 5163415 ns/iter (+/- 43971) -test wasm_instructions/wasm32/vconst/v128.const_add_locals ... bench: 2432032 ns/iter (+/- 117097) -test wasm_instructions/wasm32/vconst/v128.const_add_locals/confirmation ... bench: 4630605 ns/iter (+/- 36403) -test wasm_instructions/wasm64/vconst/v128.const_add_locals ... bench: 2468500 ns/iter (+/- 25468) -test wasm_instructions/wasm64/vconst/v128.const_add_locals/confirmation ... bench: 4671799 ns/iter (+/- 64467) -test wasm_instructions/wasm32/vconst/v128.const_add_constants ... bench: 4332863 ns/iter (+/- 77751) -test wasm_instructions/wasm32/vconst/v128.const_add_constants/confirmation ... bench: 8572916 ns/iter (+/- 31359) -test wasm_instructions/wasm64/vconst/v128.const_add_constants ... bench: 4566715 ns/iter (+/- 42305) -test wasm_instructions/wasm64/vconst/v128.const_add_constants/confirmation ... bench: 8382104 ns/iter (+/- 16768) -test wasm_instructions/wasm32/vvunop/v128.not ... bench: 2698779 ns/iter (+/- 19951) -test wasm_instructions/wasm32/vvunop/v128.not/confirmation ... bench: 5642142 ns/iter (+/- 30717) -test wasm_instructions/wasm64/vvunop/v128.not ... bench: 2720064 ns/iter (+/- 31328) -test wasm_instructions/wasm64/vvunop/v128.not/confirmation ... bench: 5659875 ns/iter (+/- 22868) -test wasm_instructions/wasm32/vvbinop/v128.and ... bench: 2420820 ns/iter (+/- 139981) -test wasm_instructions/wasm32/vvbinop/v128.and/confirmation ... bench: 4626546 ns/iter (+/- 29115) -test wasm_instructions/wasm64/vvbinop/v128.and ... bench: 2504062 ns/iter (+/- 39648) -test wasm_instructions/wasm64/vvbinop/v128.and/confirmation ... bench: 4618069 ns/iter (+/- 33660) -test wasm_instructions/wasm32/vvbinop/v128.andnot ... bench: 2433498 ns/iter (+/- 30210) -test wasm_instructions/wasm32/vvbinop/v128.andnot/confirmation ... bench: 4565614 ns/iter (+/- 12364) -test wasm_instructions/wasm64/vvbinop/v128.andnot ... bench: 2470661 ns/iter (+/- 37257) -test wasm_instructions/wasm64/vvbinop/v128.andnot/confirmation ... bench: 4632297 ns/iter (+/- 30836) -test wasm_instructions/wasm32/vvbinop/v128.or ... bench: 2484876 ns/iter (+/- 94286) -test wasm_instructions/wasm32/vvbinop/v128.or/confirmation ... bench: 4617246 ns/iter (+/- 70340) -test wasm_instructions/wasm64/vvbinop/v128.or ... bench: 2454632 ns/iter (+/- 52142) -test wasm_instructions/wasm64/vvbinop/v128.or/confirmation ... bench: 4630357 ns/iter (+/- 25652) -test wasm_instructions/wasm32/vvbinop/v128.xor ... bench: 2460783 ns/iter (+/- 20586) -test wasm_instructions/wasm32/vvbinop/v128.xor/confirmation ... bench: 4623693 ns/iter (+/- 15527) -test wasm_instructions/wasm64/vvbinop/v128.xor ... bench: 2459066 ns/iter (+/- 86362) -test wasm_instructions/wasm64/vvbinop/v128.xor/confirmation ... bench: 4640181 ns/iter (+/- 181105) -test wasm_instructions/wasm32/vvternop/v128.bitselect ... bench: 3098382 ns/iter (+/- 72884) -test wasm_instructions/wasm32/vvternop/v128.bitselect/confirmation ... bench: 5940235 ns/iter (+/- 57875) -test wasm_instructions/wasm64/vvternop/v128.bitselect ... bench: 3176687 ns/iter (+/- 28513) -test wasm_instructions/wasm64/vvternop/v128.bitselect/confirmation ... bench: 5958425 ns/iter (+/- 30609) -test wasm_instructions/wasm32/vvtestop/v128.any_true ... bench: 3543686 ns/iter (+/- 36282) -test wasm_instructions/wasm32/vvtestop/v128.any_true/confirmation ... bench: 6752268 ns/iter (+/- 327450) -test wasm_instructions/wasm64/vvtestop/v128.any_true ... bench: 3614924 ns/iter (+/- 45832) -test wasm_instructions/wasm64/vvtestop/v128.any_true/confirmation ... bench: 6765590 ns/iter (+/- 36094) -test wasm_instructions/wasm32/vshuffle/i8x16.shuffle ... bench: 6757518 ns/iter (+/- 303864) -test wasm_instructions/wasm32/vshuffle/i8x16.shuffle/confirmation ... bench: 13419310 ns/iter (+/- 1023078) -test wasm_instructions/wasm64/vshuffle/i8x16.shuffle ... bench: 6767973 ns/iter (+/- 58843) -test wasm_instructions/wasm64/vshuffle/i8x16.shuffle/confirmation ... bench: 13344981 ns/iter (+/- 452548) -test wasm_instructions/wasm32/vswizzle/i8x16.swizzle ... bench: 3320210 ns/iter (+/- 48981) -test wasm_instructions/wasm32/vswizzle/i8x16.swizzle/confirmation ... bench: 6849141 ns/iter (+/- 12806) -test wasm_instructions/wasm64/vswizzle/i8x16.swizzle ... bench: 3305274 ns/iter (+/- 44508) -test wasm_instructions/wasm64/vswizzle/i8x16.swizzle/confirmation ... bench: 6565879 ns/iter (+/- 249155) -test wasm_instructions/wasm32/vsplat/i8x16.splat ... bench: 2877572 ns/iter (+/- 196219) -test wasm_instructions/wasm32/vsplat/i8x16.splat/confirmation ... bench: 5629072 ns/iter (+/- 35899) -test wasm_instructions/wasm64/vsplat/i8x16.splat ... bench: 2888450 ns/iter (+/- 54993) -test wasm_instructions/wasm64/vsplat/i8x16.splat/confirmation ... bench: 5471554 ns/iter (+/- 36087) -test wasm_instructions/wasm32/vsplat/i16x8.splat ... bench: 2849595 ns/iter (+/- 51883) -test wasm_instructions/wasm32/vsplat/i16x8.splat/confirmation ... bench: 5400474 ns/iter (+/- 47732) -test wasm_instructions/wasm64/vsplat/i16x8.splat ... bench: 2859374 ns/iter (+/- 39529) -test wasm_instructions/wasm64/vsplat/i16x8.splat/confirmation ... bench: 5449924 ns/iter (+/- 30709) -test wasm_instructions/wasm32/vsplat/i32x4.splat ... bench: 2912776 ns/iter (+/- 11826) -test wasm_instructions/wasm32/vsplat/i32x4.splat/confirmation ... bench: 5536120 ns/iter (+/- 54366) -test wasm_instructions/wasm64/vsplat/i32x4.splat ... bench: 2873866 ns/iter (+/- 32522) -test wasm_instructions/wasm64/vsplat/i32x4.splat/confirmation ... bench: 5545044 ns/iter (+/- 39300) -test wasm_instructions/wasm32/vsplat/i64x2.splat ... bench: 2881872 ns/iter (+/- 28840) -test wasm_instructions/wasm32/vsplat/i64x2.splat/confirmation ... bench: 5473629 ns/iter (+/- 74895) -test wasm_instructions/wasm64/vsplat/i64x2.splat ... bench: 2914871 ns/iter (+/- 33215) -test wasm_instructions/wasm64/vsplat/i64x2.splat/confirmation ... bench: 5459210 ns/iter (+/- 37396) -test wasm_instructions/wasm32/vsplat/f32x4.splat ... bench: 2439528 ns/iter (+/- 15636) -test wasm_instructions/wasm32/vsplat/f32x4.splat/confirmation ... bench: 4635401 ns/iter (+/- 20351) -test wasm_instructions/wasm64/vsplat/f32x4.splat ... bench: 2438222 ns/iter (+/- 28477) -test wasm_instructions/wasm64/vsplat/f32x4.splat/confirmation ... bench: 4632867 ns/iter (+/- 32203) -test wasm_instructions/wasm32/vsplat/f64x2.splat ... bench: 2422716 ns/iter (+/- 27084) -test wasm_instructions/wasm32/vsplat/f64x2.splat/confirmation ... bench: 4628622 ns/iter (+/- 36461) -test wasm_instructions/wasm64/vsplat/f64x2.splat ... bench: 2447449 ns/iter (+/- 161278) -test wasm_instructions/wasm64/vsplat/f64x2.splat/confirmation ... bench: 4629204 ns/iter (+/- 70033) -test wasm_instructions/wasm32/vextlane/i32x4.extract_lane ... bench: 2437917 ns/iter (+/- 7398) -test wasm_instructions/wasm32/vextlane/i32x4.extract_lane/confirmation ... bench: 4604638 ns/iter (+/- 29051) -test wasm_instructions/wasm64/vextlane/i32x4.extract_lane ... bench: 2452163 ns/iter (+/- 212653) -test wasm_instructions/wasm64/vextlane/i32x4.extract_lane/confirmation ... bench: 4586994 ns/iter (+/- 20708) -test wasm_instructions/wasm32/vextlane/i64x2.extract_lane ... bench: 2475641 ns/iter (+/- 21261) -test wasm_instructions/wasm32/vextlane/i64x2.extract_lane/confirmation ... bench: 4620271 ns/iter (+/- 7423) -test wasm_instructions/wasm64/vextlane/i64x2.extract_lane ... bench: 2429491 ns/iter (+/- 50129) -test wasm_instructions/wasm64/vextlane/i64x2.extract_lane/confirmation ... bench: 4589936 ns/iter (+/- 338705) -test wasm_instructions/wasm32/vextlane/f32x4.extract_lane ... bench: 2469865 ns/iter (+/- 75472) -test wasm_instructions/wasm32/vextlane/f32x4.extract_lane/confirmation ... bench: 4635396 ns/iter (+/- 184405) -test wasm_instructions/wasm64/vextlane/f32x4.extract_lane ... bench: 2462522 ns/iter (+/- 142369) -test wasm_instructions/wasm64/vextlane/f32x4.extract_lane/confirmation ... bench: 4651569 ns/iter (+/- 44160) -test wasm_instructions/wasm32/vextlane/f64x2.extract_lane ... bench: 2424226 ns/iter (+/- 25322) -test wasm_instructions/wasm32/vextlane/f64x2.extract_lane/confirmation ... bench: 4637736 ns/iter (+/- 48914) -test wasm_instructions/wasm64/vextlane/f64x2.extract_lane ... bench: 2455975 ns/iter (+/- 28576) -test wasm_instructions/wasm64/vextlane/f64x2.extract_lane/confirmation ... bench: 4625234 ns/iter (+/- 20528) -test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_s ... bench: 3339076 ns/iter (+/- 27057) -test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_s/confirmation ... bench: 6280564 ns/iter (+/- 279137) -test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_s ... bench: 3332099 ns/iter (+/- 33770) -test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_s/confirmation ... bench: 6318859 ns/iter (+/- 44761) -test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_u ... bench: 3317287 ns/iter (+/- 18985) -test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_u/confirmation ... bench: 6309642 ns/iter (+/- 13130) -test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_u ... bench: 3308973 ns/iter (+/- 293812) -test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_u/confirmation ... bench: 6285465 ns/iter (+/- 43509) -test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_s ... bench: 3441225 ns/iter (+/- 38489) -test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_s/confirmation ... bench: 6304038 ns/iter (+/- 17643) -test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_s ... bench: 3298766 ns/iter (+/- 31077) -test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_s/confirmation ... bench: 6356647 ns/iter (+/- 33581) -test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_u ... bench: 3285546 ns/iter (+/- 244197) -test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_u/confirmation ... bench: 6339554 ns/iter (+/- 15890) -test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_u ... bench: 3304243 ns/iter (+/- 49173) -test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_u/confirmation ... bench: 6323850 ns/iter (+/- 25538) -test wasm_instructions/wasm32/vreplane/i8x16.replace_lane ... bench: 2494382 ns/iter (+/- 38002) -test wasm_instructions/wasm32/vreplane/i8x16.replace_lane/confirmation ... bench: 5572652 ns/iter (+/- 48483) -test wasm_instructions/wasm64/vreplane/i8x16.replace_lane ... bench: 3203437 ns/iter (+/- 242652) -test wasm_instructions/wasm64/vreplane/i8x16.replace_lane/confirmation ... bench: 5179266 ns/iter (+/- 107402) -test wasm_instructions/wasm32/vreplane/i16x8.replace_lane ... bench: 2444234 ns/iter (+/- 55601) -test wasm_instructions/wasm32/vreplane/i16x8.replace_lane/confirmation ... bench: 5536614 ns/iter (+/- 73532) -test wasm_instructions/wasm64/vreplane/i16x8.replace_lane ... bench: 2487357 ns/iter (+/- 43312) -test wasm_instructions/wasm64/vreplane/i16x8.replace_lane/confirmation ... bench: 5928810 ns/iter (+/- 72930) -test wasm_instructions/wasm32/vreplane/i32x4.replace_lane ... bench: 3164199 ns/iter (+/- 96688) -test wasm_instructions/wasm32/vreplane/i32x4.replace_lane/confirmation ... bench: 5354497 ns/iter (+/- 18723) -test wasm_instructions/wasm64/vreplane/i32x4.replace_lane ... bench: 2570819 ns/iter (+/- 19917) -test wasm_instructions/wasm64/vreplane/i32x4.replace_lane/confirmation ... bench: 6072332 ns/iter (+/- 35969) -test wasm_instructions/wasm32/vreplane/i64x2.replace_lane ... bench: 2511276 ns/iter (+/- 33163) -test wasm_instructions/wasm32/vreplane/i64x2.replace_lane/confirmation ... bench: 5496579 ns/iter (+/- 26360) -test wasm_instructions/wasm64/vreplane/i64x2.replace_lane ... bench: 2515801 ns/iter (+/- 51703) -test wasm_instructions/wasm64/vreplane/i64x2.replace_lane/confirmation ... bench: 4654110 ns/iter (+/- 52528) -test wasm_instructions/wasm32/vreplane/f32x4.replace_lane ... bench: 2433951 ns/iter (+/- 6870) -test wasm_instructions/wasm32/vreplane/f32x4.replace_lane/confirmation ... bench: 4631519 ns/iter (+/- 631607) -test wasm_instructions/wasm64/vreplane/f32x4.replace_lane ... bench: 2492256 ns/iter (+/- 40567) -test wasm_instructions/wasm64/vreplane/f32x4.replace_lane/confirmation ... bench: 4636240 ns/iter (+/- 8167) -test wasm_instructions/wasm32/vreplane/f64x2.replace_lane ... bench: 2430617 ns/iter (+/- 10006) -test wasm_instructions/wasm32/vreplane/f64x2.replace_lane/confirmation ... bench: 4580190 ns/iter (+/- 6510) -test wasm_instructions/wasm64/vreplane/f64x2.replace_lane ... bench: 2416678 ns/iter (+/- 8052) -test wasm_instructions/wasm64/vreplane/f64x2.replace_lane/confirmation ... bench: 4589810 ns/iter (+/- 29534) -test wasm_instructions/wasm32/virelop/i8x16.eq ... bench: 2403296 ns/iter (+/- 7444) -test wasm_instructions/wasm32/virelop/i8x16.eq/confirmation ... bench: 4645993 ns/iter (+/- 28946) -test wasm_instructions/wasm64/virelop/i8x16.eq ... bench: 2616346 ns/iter (+/- 176946) -test wasm_instructions/wasm64/virelop/i8x16.eq/confirmation ... bench: 4589067 ns/iter (+/- 14856) -test wasm_instructions/wasm32/virelop/i8x16.ne ... bench: 3130708 ns/iter (+/- 222253) -test wasm_instructions/wasm32/virelop/i8x16.ne/confirmation ... bench: 5952577 ns/iter (+/- 35044) -test wasm_instructions/wasm64/virelop/i8x16.ne ... bench: 3205527 ns/iter (+/- 196174) -test wasm_instructions/wasm64/virelop/i8x16.ne/confirmation ... bench: 6128509 ns/iter (+/- 409708) -test wasm_instructions/wasm32/virelop/i8x16.lt_s ... bench: 2431277 ns/iter (+/- 14051) -test wasm_instructions/wasm32/virelop/i8x16.lt_s/confirmation ... bench: 4587150 ns/iter (+/- 19723) -test wasm_instructions/wasm64/virelop/i8x16.lt_s ... bench: 2469182 ns/iter (+/- 25200) -test wasm_instructions/wasm64/virelop/i8x16.lt_s/confirmation ... bench: 4633820 ns/iter (+/- 25567) -test wasm_instructions/wasm32/virelop/i8x16.gt_s ... bench: 2420120 ns/iter (+/- 15573) -test wasm_instructions/wasm32/virelop/i8x16.gt_s/confirmation ... bench: 4608773 ns/iter (+/- 100055) -test wasm_instructions/wasm64/virelop/i8x16.gt_s ... bench: 2523600 ns/iter (+/- 29613) -test wasm_instructions/wasm64/virelop/i8x16.gt_s/confirmation ... bench: 4598675 ns/iter (+/- 524957) -test wasm_instructions/wasm32/virelop/i8x16.le_s ... bench: 2708170 ns/iter (+/- 111776) -test wasm_instructions/wasm32/virelop/i8x16.le_s/confirmation ... bench: 5695364 ns/iter (+/- 34819) -test wasm_instructions/wasm64/virelop/i8x16.le_s ... bench: 2706997 ns/iter (+/- 64766) -test wasm_instructions/wasm64/virelop/i8x16.le_s/confirmation ... bench: 5702982 ns/iter (+/- 27046) -test wasm_instructions/wasm32/virelop/i8x16.le_u ... bench: 2701233 ns/iter (+/- 14787) -test wasm_instructions/wasm32/virelop/i8x16.le_u/confirmation ... bench: 5140419 ns/iter (+/- 35892) -test wasm_instructions/wasm64/virelop/i8x16.le_u ... bench: 2742214 ns/iter (+/- 37245) -test wasm_instructions/wasm64/virelop/i8x16.le_u/confirmation ... bench: 5182381 ns/iter (+/- 37794) -test wasm_instructions/wasm32/virelop/i8x16.ge_s ... bench: 2701498 ns/iter (+/- 270140) -test wasm_instructions/wasm32/virelop/i8x16.ge_s/confirmation ... bench: 5640420 ns/iter (+/- 288099) -test wasm_instructions/wasm64/virelop/i8x16.ge_s ... bench: 2711271 ns/iter (+/- 322684) -test wasm_instructions/wasm64/virelop/i8x16.ge_s/confirmation ... bench: 5692610 ns/iter (+/- 38249) -test wasm_instructions/wasm32/virelop/i8x16.ge_u ... bench: 2691184 ns/iter (+/- 8528) -test wasm_instructions/wasm32/virelop/i8x16.ge_u/confirmation ... bench: 5152441 ns/iter (+/- 53406) -test wasm_instructions/wasm64/virelop/i8x16.ge_u ... bench: 2710911 ns/iter (+/- 18976) -test wasm_instructions/wasm64/virelop/i8x16.ge_u/confirmation ... bench: 5197849 ns/iter (+/- 54889) -test wasm_instructions/wasm32/virelop/i16x8.eq ... bench: 2409758 ns/iter (+/- 13242) -test wasm_instructions/wasm32/virelop/i16x8.eq/confirmation ... bench: 4633450 ns/iter (+/- 56897) -test wasm_instructions/wasm64/virelop/i16x8.eq ... bench: 2435718 ns/iter (+/- 21307) -test wasm_instructions/wasm64/virelop/i16x8.eq/confirmation ... bench: 4614618 ns/iter (+/- 64204) -test wasm_instructions/wasm32/virelop/i16x8.ne ... bench: 3179212 ns/iter (+/- 231016) -test wasm_instructions/wasm32/virelop/i16x8.ne/confirmation ... bench: 5995968 ns/iter (+/- 50046) -test wasm_instructions/wasm64/virelop/i16x8.ne ... bench: 3186708 ns/iter (+/- 29432) -test wasm_instructions/wasm64/virelop/i16x8.ne/confirmation ... bench: 6048690 ns/iter (+/- 82894) -test wasm_instructions/wasm32/virelop/i16x8.lt_s ... bench: 2422712 ns/iter (+/- 8133) -test wasm_instructions/wasm32/virelop/i16x8.lt_s/confirmation ... bench: 4634316 ns/iter (+/- 48081) -test wasm_instructions/wasm64/virelop/i16x8.lt_s ... bench: 2439323 ns/iter (+/- 15241) -test wasm_instructions/wasm64/virelop/i16x8.lt_s/confirmation ... bench: 4646610 ns/iter (+/- 24698) -test wasm_instructions/wasm32/virelop/i16x8.gt_s ... bench: 2495064 ns/iter (+/- 212583) -test wasm_instructions/wasm32/virelop/i16x8.gt_s/confirmation ... bench: 4631305 ns/iter (+/- 47475) -test wasm_instructions/wasm64/virelop/i16x8.gt_s ... bench: 2475924 ns/iter (+/- 111013) -test wasm_instructions/wasm64/virelop/i16x8.gt_s/confirmation ... bench: 4608059 ns/iter (+/- 27660) -test wasm_instructions/wasm32/virelop/i16x8.le_s ... bench: 2709051 ns/iter (+/- 27172) -test wasm_instructions/wasm32/virelop/i16x8.le_s/confirmation ... bench: 5176895 ns/iter (+/- 67467) -test wasm_instructions/wasm64/virelop/i16x8.le_s ... bench: 2772359 ns/iter (+/- 50032) -test wasm_instructions/wasm64/virelop/i16x8.le_s/confirmation ... bench: 5158516 ns/iter (+/- 51788) -test wasm_instructions/wasm32/virelop/i16x8.le_u ... bench: 2728722 ns/iter (+/- 35198) -test wasm_instructions/wasm32/virelop/i16x8.le_u/confirmation ... bench: 5697169 ns/iter (+/- 103749) -test wasm_instructions/wasm64/virelop/i16x8.le_u ... bench: 2757745 ns/iter (+/- 39005) -test wasm_instructions/wasm64/virelop/i16x8.le_u/confirmation ... bench: 5697948 ns/iter (+/- 243485) -test wasm_instructions/wasm32/virelop/i16x8.ge_s ... bench: 2749450 ns/iter (+/- 28900) -test wasm_instructions/wasm32/virelop/i16x8.ge_s/confirmation ... bench: 5160329 ns/iter (+/- 121069) -test wasm_instructions/wasm64/virelop/i16x8.ge_s ... bench: 2714730 ns/iter (+/- 44734) -test wasm_instructions/wasm64/virelop/i16x8.ge_s/confirmation ... bench: 5174668 ns/iter (+/- 80474) -test wasm_instructions/wasm32/virelop/i16x8.ge_u ... bench: 2714335 ns/iter (+/- 20585) -test wasm_instructions/wasm32/virelop/i16x8.ge_u/confirmation ... bench: 5652670 ns/iter (+/- 31752) -test wasm_instructions/wasm64/virelop/i16x8.ge_u ... bench: 2769970 ns/iter (+/- 9748) -test wasm_instructions/wasm64/virelop/i16x8.ge_u/confirmation ... bench: 5705844 ns/iter (+/- 30422) -test wasm_instructions/wasm32/virelop/i32x4.eq ... bench: 2437562 ns/iter (+/- 4550) -test wasm_instructions/wasm32/virelop/i32x4.eq/confirmation ... bench: 4630831 ns/iter (+/- 36045) -test wasm_instructions/wasm64/virelop/i32x4.eq ... bench: 2495983 ns/iter (+/- 91172) -test wasm_instructions/wasm64/virelop/i32x4.eq/confirmation ... bench: 4589717 ns/iter (+/- 61231) -test wasm_instructions/wasm32/virelop/i32x4.ne ... bench: 3135058 ns/iter (+/- 25417) -test wasm_instructions/wasm32/virelop/i32x4.ne/confirmation ... bench: 5964117 ns/iter (+/- 30386) -test wasm_instructions/wasm64/virelop/i32x4.ne ... bench: 3142160 ns/iter (+/- 49799) -test wasm_instructions/wasm64/virelop/i32x4.ne/confirmation ... bench: 5976735 ns/iter (+/- 70306) -test wasm_instructions/wasm32/virelop/i32x4.lt_s ... bench: 2490366 ns/iter (+/- 162668) -test wasm_instructions/wasm32/virelop/i32x4.lt_s/confirmation ... bench: 4629054 ns/iter (+/- 71571) -test wasm_instructions/wasm64/virelop/i32x4.lt_s ... bench: 2472794 ns/iter (+/- 106147) -test wasm_instructions/wasm64/virelop/i32x4.lt_s/confirmation ... bench: 4647924 ns/iter (+/- 75292) -test wasm_instructions/wasm32/virelop/i32x4.gt_s ... bench: 2468840 ns/iter (+/- 43826) -test wasm_instructions/wasm32/virelop/i32x4.gt_s/confirmation ... bench: 4626906 ns/iter (+/- 42647) -test wasm_instructions/wasm64/virelop/i32x4.gt_s ... bench: 2426607 ns/iter (+/- 28462) -test wasm_instructions/wasm64/virelop/i32x4.gt_s/confirmation ... bench: 4707216 ns/iter (+/- 93444) -test wasm_instructions/wasm32/virelop/i32x4.le_s ... bench: 2771897 ns/iter (+/- 25334) -test wasm_instructions/wasm32/virelop/i32x4.le_s/confirmation ... bench: 5708690 ns/iter (+/- 56959) -test wasm_instructions/wasm64/virelop/i32x4.le_s ... bench: 2722493 ns/iter (+/- 20719) -test wasm_instructions/wasm64/virelop/i32x4.le_s/confirmation ... bench: 5704869 ns/iter (+/- 8214) -test wasm_instructions/wasm32/virelop/i32x4.le_u ... bench: 2784323 ns/iter (+/- 15038) -test wasm_instructions/wasm32/virelop/i32x4.le_u/confirmation ... bench: 5687584 ns/iter (+/- 59039) -test wasm_instructions/wasm64/virelop/i32x4.le_u ... bench: 2710573 ns/iter (+/- 27893) -test wasm_instructions/wasm64/virelop/i32x4.le_u/confirmation ... bench: 5695055 ns/iter (+/- 30059) -test wasm_instructions/wasm32/virelop/i32x4.ge_s ... bench: 2718556 ns/iter (+/- 19782) -test wasm_instructions/wasm32/virelop/i32x4.ge_s/confirmation ... bench: 5701527 ns/iter (+/- 92273) -test wasm_instructions/wasm64/virelop/i32x4.ge_s ... bench: 2711333 ns/iter (+/- 17831) -test wasm_instructions/wasm64/virelop/i32x4.ge_s/confirmation ... bench: 5701587 ns/iter (+/- 49160) -test wasm_instructions/wasm32/virelop/i32x4.ge_u ... bench: 2789963 ns/iter (+/- 37628) -test wasm_instructions/wasm32/virelop/i32x4.ge_u/confirmation ... bench: 5663284 ns/iter (+/- 73936) -test wasm_instructions/wasm64/virelop/i32x4.ge_u ... bench: 2729559 ns/iter (+/- 27474) -test wasm_instructions/wasm64/virelop/i32x4.ge_u/confirmation ... bench: 5716657 ns/iter (+/- 63923) -test wasm_instructions/wasm32/virelop/i64x2.eq ... bench: 2451800 ns/iter (+/- 101247) -test wasm_instructions/wasm32/virelop/i64x2.eq/confirmation ... bench: 4634047 ns/iter (+/- 68682) -test wasm_instructions/wasm64/virelop/i64x2.eq ... bench: 2465192 ns/iter (+/- 19337) -test wasm_instructions/wasm64/virelop/i64x2.eq/confirmation ... bench: 4632126 ns/iter (+/- 26928) -test wasm_instructions/wasm32/virelop/i64x2.ne ... bench: 3336840 ns/iter (+/- 159272) -test wasm_instructions/wasm32/virelop/i64x2.ne/confirmation ... bench: 6421935 ns/iter (+/- 26827) -test wasm_instructions/wasm64/virelop/i64x2.ne ... bench: 3274627 ns/iter (+/- 32606) -test wasm_instructions/wasm64/virelop/i64x2.ne/confirmation ... bench: 6234711 ns/iter (+/- 11511) -test wasm_instructions/wasm32/virelop/i64x2.lt_s ... bench: 2422661 ns/iter (+/- 16053) -test wasm_instructions/wasm32/virelop/i64x2.lt_s/confirmation ... bench: 4642991 ns/iter (+/- 37626) -test wasm_instructions/wasm64/virelop/i64x2.lt_s ... bench: 2493491 ns/iter (+/- 155284) -test wasm_instructions/wasm64/virelop/i64x2.lt_s/confirmation ... bench: 4657585 ns/iter (+/- 36601) -test wasm_instructions/wasm32/virelop/i64x2.gt_s ... bench: 2447912 ns/iter (+/- 34623) -test wasm_instructions/wasm32/virelop/i64x2.gt_s/confirmation ... bench: 4592252 ns/iter (+/- 93256) -test wasm_instructions/wasm64/virelop/i64x2.gt_s ... bench: 2437473 ns/iter (+/- 4613) -test wasm_instructions/wasm64/virelop/i64x2.gt_s/confirmation ... bench: 4631807 ns/iter (+/- 29875) -test wasm_instructions/wasm32/virelop/i64x2.le_s ... bench: 3241162 ns/iter (+/- 24824) -test wasm_instructions/wasm32/virelop/i64x2.le_s/confirmation ... bench: 6247445 ns/iter (+/- 15611) -test wasm_instructions/wasm64/virelop/i64x2.le_s ... bench: 3293464 ns/iter (+/- 142519) -test wasm_instructions/wasm64/virelop/i64x2.le_s/confirmation ... bench: 6230680 ns/iter (+/- 17895) -test wasm_instructions/wasm32/virelop/i64x2.ge_s ... bench: 3256601 ns/iter (+/- 218980) -test wasm_instructions/wasm32/virelop/i64x2.ge_s/confirmation ... bench: 6281323 ns/iter (+/- 25357) -test wasm_instructions/wasm64/virelop/i64x2.ge_s ... bench: 3302589 ns/iter (+/- 34632) -test wasm_instructions/wasm64/virelop/i64x2.ge_s/confirmation ... bench: 6225939 ns/iter (+/- 57522) -test wasm_instructions/wasm32/virelop/i8x16.lt_u ... bench: 4630468 ns/iter (+/- 10826) -test wasm_instructions/wasm32/virelop/i8x16.lt_u/confirmation ... bench: 8892774 ns/iter (+/- 24423) -test wasm_instructions/wasm64/virelop/i8x16.lt_u ... bench: 4643983 ns/iter (+/- 28525) -test wasm_instructions/wasm64/virelop/i8x16.lt_u/confirmation ... bench: 8886555 ns/iter (+/- 68598) -test wasm_instructions/wasm32/virelop/i8x16.gt_u ... bench: 4641976 ns/iter (+/- 75799) -test wasm_instructions/wasm32/virelop/i8x16.gt_u/confirmation ... bench: 8847318 ns/iter (+/- 8459) -test wasm_instructions/wasm64/virelop/i8x16.gt_u ... bench: 4635786 ns/iter (+/- 35560) -test wasm_instructions/wasm64/virelop/i8x16.gt_u/confirmation ... bench: 8859528 ns/iter (+/- 20704) -test wasm_instructions/wasm32/virelop/i16x8.lt_u ... bench: 4685978 ns/iter (+/- 33544) -test wasm_instructions/wasm32/virelop/i16x8.lt_u/confirmation ... bench: 8832455 ns/iter (+/- 2917) -test wasm_instructions/wasm64/virelop/i16x8.lt_u ... bench: 4829486 ns/iter (+/- 48774) -test wasm_instructions/wasm64/virelop/i16x8.lt_u/confirmation ... bench: 8902310 ns/iter (+/- 75380) -test wasm_instructions/wasm32/virelop/i16x8.gt_u ... bench: 4552369 ns/iter (+/- 23854) -test wasm_instructions/wasm32/virelop/i16x8.gt_u/confirmation ... bench: 8912615 ns/iter (+/- 54871) -test wasm_instructions/wasm64/virelop/i16x8.gt_u ... bench: 4995847 ns/iter (+/- 11467) -test wasm_instructions/wasm64/virelop/i16x8.gt_u/confirmation ... bench: 8843545 ns/iter (+/- 32297) -test wasm_instructions/wasm32/virelop/i32x4.lt_u ... bench: 4621485 ns/iter (+/- 40818) -test wasm_instructions/wasm32/virelop/i32x4.lt_u/confirmation ... bench: 8841915 ns/iter (+/- 26399) -test wasm_instructions/wasm64/virelop/i32x4.lt_u ... bench: 4661971 ns/iter (+/- 55157) -test wasm_instructions/wasm64/virelop/i32x4.lt_u/confirmation ... bench: 8847855 ns/iter (+/- 37830) -test wasm_instructions/wasm32/virelop/i32x4.gt_u ... bench: 4568619 ns/iter (+/- 21668) -test wasm_instructions/wasm32/virelop/i32x4.gt_u/confirmation ... bench: 8886528 ns/iter (+/- 136125) -test wasm_instructions/wasm64/virelop/i32x4.gt_u ... bench: 4658609 ns/iter (+/- 26170) -test wasm_instructions/wasm64/virelop/i32x4.gt_u/confirmation ... bench: 8889213 ns/iter (+/- 68052) -test wasm_instructions/wasm32/vfrelop/f32x4.eq ... bench: 2451821 ns/iter (+/- 30155) -test wasm_instructions/wasm32/vfrelop/f32x4.eq/confirmation ... bench: 4635701 ns/iter (+/- 76176) -test wasm_instructions/wasm64/vfrelop/f32x4.eq ... bench: 2456926 ns/iter (+/- 22483) -test wasm_instructions/wasm64/vfrelop/f32x4.eq/confirmation ... bench: 4636133 ns/iter (+/- 53182) -test wasm_instructions/wasm32/vfrelop/f32x4.ne ... bench: 2459504 ns/iter (+/- 10819) -test wasm_instructions/wasm32/vfrelop/f32x4.ne/confirmation ... bench: 4632411 ns/iter (+/- 28807) -test wasm_instructions/wasm64/vfrelop/f32x4.ne ... bench: 2466279 ns/iter (+/- 57733) -test wasm_instructions/wasm64/vfrelop/f32x4.ne/confirmation ... bench: 4647944 ns/iter (+/- 341288) -test wasm_instructions/wasm32/vfrelop/f32x4.lt ... bench: 2443138 ns/iter (+/- 170629) -test wasm_instructions/wasm32/vfrelop/f32x4.lt/confirmation ... bench: 4604905 ns/iter (+/- 31523) -test wasm_instructions/wasm64/vfrelop/f32x4.lt ... bench: 2425888 ns/iter (+/- 272013) -test wasm_instructions/wasm64/vfrelop/f32x4.lt/confirmation ... bench: 4620923 ns/iter (+/- 108552) -test wasm_instructions/wasm32/vfrelop/f32x4.gt ... bench: 2436943 ns/iter (+/- 20277) -test wasm_instructions/wasm32/vfrelop/f32x4.gt/confirmation ... bench: 4606904 ns/iter (+/- 36682) -test wasm_instructions/wasm64/vfrelop/f32x4.gt ... bench: 2513215 ns/iter (+/- 132539) -test wasm_instructions/wasm64/vfrelop/f32x4.gt/confirmation ... bench: 4626530 ns/iter (+/- 22978) -test wasm_instructions/wasm32/vfrelop/f32x4.le ... bench: 2456431 ns/iter (+/- 9665) -test wasm_instructions/wasm32/vfrelop/f32x4.le/confirmation ... bench: 4572107 ns/iter (+/- 39438) -test wasm_instructions/wasm64/vfrelop/f32x4.le ... bench: 2437939 ns/iter (+/- 17604) -test wasm_instructions/wasm64/vfrelop/f32x4.le/confirmation ... bench: 4633973 ns/iter (+/- 38230) -test wasm_instructions/wasm32/vfrelop/f32x4.ge ... bench: 2452501 ns/iter (+/- 167351) -test wasm_instructions/wasm32/vfrelop/f32x4.ge/confirmation ... bench: 4657968 ns/iter (+/- 36061) -test wasm_instructions/wasm64/vfrelop/f32x4.ge ... bench: 2429008 ns/iter (+/- 15200) -test wasm_instructions/wasm64/vfrelop/f32x4.ge/confirmation ... bench: 4654951 ns/iter (+/- 56310) -test wasm_instructions/wasm32/vfrelop/f64x2.eq ... bench: 2419407 ns/iter (+/- 2764) -test wasm_instructions/wasm32/vfrelop/f64x2.eq/confirmation ... bench: 4622983 ns/iter (+/- 79929) -test wasm_instructions/wasm64/vfrelop/f64x2.eq ... bench: 2422088 ns/iter (+/- 17162) -test wasm_instructions/wasm64/vfrelop/f64x2.eq/confirmation ... bench: 4580965 ns/iter (+/- 138154) -test wasm_instructions/wasm32/vfrelop/f64x2.ne ... bench: 2456731 ns/iter (+/- 43166) -test wasm_instructions/wasm32/vfrelop/f64x2.ne/confirmation ... bench: 4606863 ns/iter (+/- 74742) -test wasm_instructions/wasm64/vfrelop/f64x2.ne ... bench: 2458241 ns/iter (+/- 20395) -test wasm_instructions/wasm64/vfrelop/f64x2.ne/confirmation ... bench: 4648081 ns/iter (+/- 39215) -test wasm_instructions/wasm32/vfrelop/f64x2.lt ... bench: 2415282 ns/iter (+/- 43109) -test wasm_instructions/wasm32/vfrelop/f64x2.lt/confirmation ... bench: 4647959 ns/iter (+/- 25068) -test wasm_instructions/wasm64/vfrelop/f64x2.lt ... bench: 2451249 ns/iter (+/- 17749) -test wasm_instructions/wasm64/vfrelop/f64x2.lt/confirmation ... bench: 4640634 ns/iter (+/- 33552) -test wasm_instructions/wasm32/vfrelop/f64x2.gt ... bench: 2681995 ns/iter (+/- 148213) -test wasm_instructions/wasm32/vfrelop/f64x2.gt/confirmation ... bench: 4633942 ns/iter (+/- 28273) -test wasm_instructions/wasm64/vfrelop/f64x2.gt ... bench: 2477479 ns/iter (+/- 20339) -test wasm_instructions/wasm64/vfrelop/f64x2.gt/confirmation ... bench: 4695181 ns/iter (+/- 26861) -test wasm_instructions/wasm32/vfrelop/f64x2.le ... bench: 2428990 ns/iter (+/- 21640) -test wasm_instructions/wasm32/vfrelop/f64x2.le/confirmation ... bench: 4635026 ns/iter (+/- 51667) -test wasm_instructions/wasm64/vfrelop/f64x2.le ... bench: 2553159 ns/iter (+/- 32289) -test wasm_instructions/wasm64/vfrelop/f64x2.le/confirmation ... bench: 4632434 ns/iter (+/- 28655) -test wasm_instructions/wasm32/vfrelop/f64x2.ge ... bench: 2487530 ns/iter (+/- 84506) -test wasm_instructions/wasm32/vfrelop/f64x2.ge/confirmation ... bench: 4631508 ns/iter (+/- 300162) -test wasm_instructions/wasm64/vfrelop/f64x2.ge ... bench: 2450326 ns/iter (+/- 25187) -test wasm_instructions/wasm64/vfrelop/f64x2.ge/confirmation ... bench: 4579212 ns/iter (+/- 235462) -test wasm_instructions/wasm32/viunop/i8x16.abs ... bench: 2430727 ns/iter (+/- 20045) -test wasm_instructions/wasm32/viunop/i8x16.abs/confirmation ... bench: 4566134 ns/iter (+/- 41115) -test wasm_instructions/wasm64/viunop/i8x16.abs ... bench: 2459938 ns/iter (+/- 5252) -test wasm_instructions/wasm64/viunop/i8x16.abs/confirmation ... bench: 4594065 ns/iter (+/- 323803) -test wasm_instructions/wasm32/viunop/i16x8.abs ... bench: 2432768 ns/iter (+/- 3665) -test wasm_instructions/wasm32/viunop/i16x8.abs/confirmation ... bench: 4625994 ns/iter (+/- 9478) -test wasm_instructions/wasm64/viunop/i16x8.abs ... bench: 2461701 ns/iter (+/- 11809) -test wasm_instructions/wasm64/viunop/i16x8.abs/confirmation ... bench: 4614443 ns/iter (+/- 60491) -test wasm_instructions/wasm32/viunop/i32x4.abs ... bench: 2434233 ns/iter (+/- 49323) -test wasm_instructions/wasm32/viunop/i32x4.abs/confirmation ... bench: 4569320 ns/iter (+/- 54880) -test wasm_instructions/wasm64/viunop/i32x4.abs ... bench: 2423066 ns/iter (+/- 6772) -test wasm_instructions/wasm64/viunop/i32x4.abs/confirmation ... bench: 4614282 ns/iter (+/- 45150) -test wasm_instructions/wasm32/viunop/i64x2.abs ... bench: 3528642 ns/iter (+/- 32856) -test wasm_instructions/wasm32/viunop/i64x2.abs/confirmation ... bench: 6778046 ns/iter (+/- 82621) -test wasm_instructions/wasm64/viunop/i64x2.abs ... bench: 3588754 ns/iter (+/- 96845) -test wasm_instructions/wasm64/viunop/i64x2.abs/confirmation ... bench: 6806786 ns/iter (+/- 64925) -test wasm_instructions/wasm32/viunop/i8x16.neg ... bench: 2797683 ns/iter (+/- 166090) -test wasm_instructions/wasm32/viunop/i8x16.neg/confirmation ... bench: 5703968 ns/iter (+/- 71865) -test wasm_instructions/wasm64/viunop/i8x16.neg ... bench: 2772544 ns/iter (+/- 37868) -test wasm_instructions/wasm64/viunop/i8x16.neg/confirmation ... bench: 5700022 ns/iter (+/- 27980) -test wasm_instructions/wasm32/viunop/i16x8.neg ... bench: 2708258 ns/iter (+/- 92088) -test wasm_instructions/wasm32/viunop/i16x8.neg/confirmation ... bench: 5705768 ns/iter (+/- 84382) -test wasm_instructions/wasm64/viunop/i16x8.neg ... bench: 2705697 ns/iter (+/- 28284) -test wasm_instructions/wasm64/viunop/i16x8.neg/confirmation ... bench: 5732488 ns/iter (+/- 66078) -test wasm_instructions/wasm32/viunop/i32x4.neg ... bench: 2683213 ns/iter (+/- 8725) -test wasm_instructions/wasm32/viunop/i32x4.neg/confirmation ... bench: 5701386 ns/iter (+/- 46559) -test wasm_instructions/wasm64/viunop/i32x4.neg ... bench: 2706323 ns/iter (+/- 10801) -test wasm_instructions/wasm64/viunop/i32x4.neg/confirmation ... bench: 5709511 ns/iter (+/- 145035) -test wasm_instructions/wasm32/viunop/i64x2.neg ... bench: 2684522 ns/iter (+/- 111757) -test wasm_instructions/wasm32/viunop/i64x2.neg/confirmation ... bench: 5682625 ns/iter (+/- 34301) -test wasm_instructions/wasm64/viunop/i64x2.neg ... bench: 2732258 ns/iter (+/- 54100) -test wasm_instructions/wasm64/viunop/i64x2.neg/confirmation ... bench: 5685088 ns/iter (+/- 37975) -test wasm_instructions/wasm32/viunop/i8x16.popcnt ... bench: 8935149 ns/iter (+/- 693948) -test wasm_instructions/wasm32/viunop/i8x16.popcnt/confirmation ... bench: 18873199 ns/iter (+/- 659996) -test wasm_instructions/wasm64/viunop/i8x16.popcnt ... bench: 9053503 ns/iter (+/- 778968) -test wasm_instructions/wasm64/viunop/i8x16.popcnt/confirmation ... bench: 18264345 ns/iter (+/- 1403020) -test wasm_instructions/wasm32/vq15mulr/i16x8.q15mulr_sat_s ... bench: 3991585 ns/iter (+/- 28637) -test wasm_instructions/wasm32/vq15mulr/i16x8.q15mulr_sat_s/confirmation ... bench: 8024026 ns/iter (+/- 71115) -test wasm_instructions/wasm64/vq15mulr/i16x8.q15mulr_sat_s ... bench: 3882564 ns/iter (+/- 163277) -test wasm_instructions/wasm64/vq15mulr/i16x8.q15mulr_sat_s/confirmation ... bench: 7977660 ns/iter (+/- 582630) -test wasm_instructions/wasm32/vdot/i32x4.dot_i16x8_s ... bench: 2416713 ns/iter (+/- 10960) -test wasm_instructions/wasm32/vdot/i32x4.dot_i16x8_s/confirmation ... bench: 4583387 ns/iter (+/- 293651) -test wasm_instructions/wasm64/vdot/i32x4.dot_i16x8_s ... bench: 2465168 ns/iter (+/- 36636) -test wasm_instructions/wasm64/vdot/i32x4.dot_i16x8_s/confirmation ... bench: 4609459 ns/iter (+/- 74948) -test wasm_instructions/wasm32/vfunop/f32x4.abs ... bench: 4659140 ns/iter (+/- 60021) -test wasm_instructions/wasm32/vfunop/f32x4.abs/confirmation ... bench: 8966970 ns/iter (+/- 192789) -test wasm_instructions/wasm64/vfunop/f32x4.abs ... bench: 4737696 ns/iter (+/- 376064) -test wasm_instructions/wasm64/vfunop/f32x4.abs/confirmation ... bench: 8876139 ns/iter (+/- 30034) -test wasm_instructions/wasm32/vfunop/f32x4.neg ... bench: 4621688 ns/iter (+/- 461716) -test wasm_instructions/wasm32/vfunop/f32x4.neg/confirmation ... bench: 8894964 ns/iter (+/- 37936) -test wasm_instructions/wasm64/vfunop/f32x4.neg ... bench: 4648628 ns/iter (+/- 74467) -test wasm_instructions/wasm64/vfunop/f32x4.neg/confirmation ... bench: 8855677 ns/iter (+/- 17146) -test wasm_instructions/wasm32/vfunop/f64x2.abs ... bench: 4623581 ns/iter (+/- 33026) -test wasm_instructions/wasm32/vfunop/f64x2.abs/confirmation ... bench: 8837970 ns/iter (+/- 23660) -test wasm_instructions/wasm64/vfunop/f64x2.abs ... bench: 4653441 ns/iter (+/- 70164) -test wasm_instructions/wasm64/vfunop/f64x2.abs/confirmation ... bench: 8842779 ns/iter (+/- 2794) -test wasm_instructions/wasm32/vfunop/f64x2.neg ... bench: 4655839 ns/iter (+/- 261057) -test wasm_instructions/wasm32/vfunop/f64x2.neg/confirmation ... bench: 8973428 ns/iter (+/- 73832) -test wasm_instructions/wasm64/vfunop/f64x2.neg ... bench: 4649021 ns/iter (+/- 27588) -test wasm_instructions/wasm64/vfunop/f64x2.neg/confirmation ... bench: 8905876 ns/iter (+/- 214658) -test wasm_instructions/wasm32/vfunop/f32x4.ceil ... bench: 5161823 ns/iter (+/- 20092) -test wasm_instructions/wasm32/vfunop/f32x4.ceil/confirmation ... bench: 11203287 ns/iter (+/- 355537) -test wasm_instructions/wasm64/vfunop/f32x4.ceil ... bench: 5619084 ns/iter (+/- 46309) -test wasm_instructions/wasm64/vfunop/f32x4.ceil/confirmation ... bench: 11403797 ns/iter (+/- 383281) -test wasm_instructions/wasm32/vfunop/f32x4.floor ... bench: 5419549 ns/iter (+/- 43350) -test wasm_instructions/wasm32/vfunop/f32x4.floor/confirmation ... bench: 11779147 ns/iter (+/- 118169) -test wasm_instructions/wasm64/vfunop/f32x4.floor ... bench: 5179451 ns/iter (+/- 269877) -test wasm_instructions/wasm64/vfunop/f32x4.floor/confirmation ... bench: 11565104 ns/iter (+/- 171212) -test wasm_instructions/wasm32/vfunop/f32x4.trunc ... bench: 5156243 ns/iter (+/- 10475) -test wasm_instructions/wasm32/vfunop/f32x4.trunc/confirmation ... bench: 10668630 ns/iter (+/- 40513) -test wasm_instructions/wasm64/vfunop/f32x4.trunc ... bench: 5210277 ns/iter (+/- 136717) -test wasm_instructions/wasm64/vfunop/f32x4.trunc/confirmation ... bench: 11347432 ns/iter (+/- 369564) -test wasm_instructions/wasm32/vfunop/f32x4.nearest ... bench: 5411886 ns/iter (+/- 47651) -test wasm_instructions/wasm32/vfunop/f32x4.nearest/confirmation ... bench: 11054119 ns/iter (+/- 374402) -test wasm_instructions/wasm64/vfunop/f32x4.nearest ... bench: 5249996 ns/iter (+/- 11896) -test wasm_instructions/wasm64/vfunop/f32x4.nearest/confirmation ... bench: 11735279 ns/iter (+/- 495610) -test wasm_instructions/wasm32/vfunop/f64x2.ceil ... bench: 5366698 ns/iter (+/- 8986) -test wasm_instructions/wasm32/vfunop/f64x2.ceil/confirmation ... bench: 10826159 ns/iter (+/- 342347) -test wasm_instructions/wasm64/vfunop/f64x2.ceil ... bench: 5208865 ns/iter (+/- 6277) -test wasm_instructions/wasm64/vfunop/f64x2.ceil/confirmation ... bench: 11165218 ns/iter (+/- 327180) -test wasm_instructions/wasm32/vfunop/f64x2.floor ... bench: 5295752 ns/iter (+/- 37826) -test wasm_instructions/wasm32/vfunop/f64x2.floor/confirmation ... bench: 11464221 ns/iter (+/- 270262) -test wasm_instructions/wasm64/vfunop/f64x2.floor ... bench: 5149258 ns/iter (+/- 233563) -test wasm_instructions/wasm64/vfunop/f64x2.floor/confirmation ... bench: 11692963 ns/iter (+/- 302258) -test wasm_instructions/wasm32/vfunop/f64x2.trunc ... bench: 5375910 ns/iter (+/- 136479) -test wasm_instructions/wasm32/vfunop/f64x2.trunc/confirmation ... bench: 11331086 ns/iter (+/- 390511) -test wasm_instructions/wasm64/vfunop/f64x2.trunc ... bench: 5138691 ns/iter (+/- 7737) -test wasm_instructions/wasm64/vfunop/f64x2.trunc/confirmation ... bench: 11140053 ns/iter (+/- 41793) -test wasm_instructions/wasm32/vfunop/f64x2.nearest ... bench: 5226492 ns/iter (+/- 422515) -test wasm_instructions/wasm32/vfunop/f64x2.nearest/confirmation ... bench: 12047405 ns/iter (+/- 345827) -test wasm_instructions/wasm64/vfunop/f64x2.nearest ... bench: 5232433 ns/iter (+/- 323444) -test wasm_instructions/wasm64/vfunop/f64x2.nearest/confirmation ... bench: 11435759 ns/iter (+/- 269295) -test wasm_instructions/wasm32/vfunop/f32x4.sqrt ... bench: 12087109 ns/iter (+/- 32158) -test wasm_instructions/wasm32/vfunop/f32x4.sqrt/confirmation ... bench: 23917892 ns/iter (+/- 286796) -test wasm_instructions/wasm64/vfunop/f32x4.sqrt ... bench: 12056508 ns/iter (+/- 18885) -test wasm_instructions/wasm64/vfunop/f32x4.sqrt/confirmation ... bench: 23851215 ns/iter (+/- 115223) -test wasm_instructions/wasm32/vfunop/f64x2.sqrt ... bench: 29005046 ns/iter (+/- 531670) -test wasm_instructions/wasm32/vfunop/f64x2.sqrt/confirmation ... bench: 57564553 ns/iter (+/- 569907) -test wasm_instructions/wasm64/vfunop/f64x2.sqrt ... bench: 28999021 ns/iter (+/- 578190) -test wasm_instructions/wasm64/vfunop/f64x2.sqrt/confirmation ... bench: 57799759 ns/iter (+/- 263344) -test wasm_instructions/wasm32/vitestop/i8x16.all_true ... bench: 4079749 ns/iter (+/- 69356) -test wasm_instructions/wasm32/vitestop/i8x16.all_true/confirmation ... bench: 7813531 ns/iter (+/- 33301) -test wasm_instructions/wasm64/vitestop/i8x16.all_true ... bench: 4262759 ns/iter (+/- 52927) -test wasm_instructions/wasm64/vitestop/i8x16.all_true/confirmation ... bench: 7775717 ns/iter (+/- 58236) -test wasm_instructions/wasm32/vitestop/i16x8.all_true ... bench: 4240713 ns/iter (+/- 33810) -test wasm_instructions/wasm32/vitestop/i16x8.all_true/confirmation ... bench: 7808818 ns/iter (+/- 62767) -test wasm_instructions/wasm64/vitestop/i16x8.all_true ... bench: 4073240 ns/iter (+/- 18554) -test wasm_instructions/wasm64/vitestop/i16x8.all_true/confirmation ... bench: 7821404 ns/iter (+/- 58568) -test wasm_instructions/wasm32/vitestop/i32x4.all_true ... bench: 4064614 ns/iter (+/- 31973) -test wasm_instructions/wasm32/vitestop/i32x4.all_true/confirmation ... bench: 7808638 ns/iter (+/- 117899) -test wasm_instructions/wasm64/vitestop/i32x4.all_true ... bench: 4408943 ns/iter (+/- 228563) -test wasm_instructions/wasm64/vitestop/i32x4.all_true/confirmation ... bench: 7794707 ns/iter (+/- 55996) -test wasm_instructions/wasm32/vitestop/i64x2.all_true ... bench: 4197513 ns/iter (+/- 70299) -test wasm_instructions/wasm32/vitestop/i64x2.all_true/confirmation ... bench: 8046977 ns/iter (+/- 6333) -test wasm_instructions/wasm64/vitestop/i64x2.all_true ... bench: 4220501 ns/iter (+/- 55256) -test wasm_instructions/wasm64/vitestop/i64x2.all_true/confirmation ... bench: 8077089 ns/iter (+/- 24303) -test wasm_instructions/wasm32/vbitmask/i8x16.bitmask ... bench: 2971139 ns/iter (+/- 31680) -test wasm_instructions/wasm32/vbitmask/i8x16.bitmask/confirmation ... bench: 5656057 ns/iter (+/- 63342) -test wasm_instructions/wasm64/vbitmask/i8x16.bitmask ... bench: 3065096 ns/iter (+/- 24988) -test wasm_instructions/wasm64/vbitmask/i8x16.bitmask/confirmation ... bench: 5689418 ns/iter (+/- 110319) -test wasm_instructions/wasm32/vbitmask/i16x8.bitmask ... bench: 3238848 ns/iter (+/- 15753) -test wasm_instructions/wasm32/vbitmask/i16x8.bitmask/confirmation ... bench: 6159314 ns/iter (+/- 45969) -test wasm_instructions/wasm64/vbitmask/i16x8.bitmask ... bench: 3253186 ns/iter (+/- 35618) -test wasm_instructions/wasm64/vbitmask/i16x8.bitmask/confirmation ... bench: 6185936 ns/iter (+/- 38062) -test wasm_instructions/wasm32/vbitmask/i32x4.bitmask ... bench: 2997033 ns/iter (+/- 17267) -test wasm_instructions/wasm32/vbitmask/i32x4.bitmask/confirmation ... bench: 5660817 ns/iter (+/- 14585) -test wasm_instructions/wasm64/vbitmask/i32x4.bitmask ... bench: 2981453 ns/iter (+/- 28697) -test wasm_instructions/wasm64/vbitmask/i32x4.bitmask/confirmation ... bench: 5704024 ns/iter (+/- 21268) -test wasm_instructions/wasm32/vbitmask/i64x2.bitmask ... bench: 2976281 ns/iter (+/- 29544) -test wasm_instructions/wasm32/vbitmask/i64x2.bitmask/confirmation ... bench: 5654459 ns/iter (+/- 48800) -test wasm_instructions/wasm64/vbitmask/i64x2.bitmask ... bench: 3004934 ns/iter (+/- 25387) -test wasm_instructions/wasm64/vbitmask/i64x2.bitmask/confirmation ... bench: 5682292 ns/iter (+/- 100865) -test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_s ... bench: 2472273 ns/iter (+/- 22285) -test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_s/confirmation ... bench: 4650180 ns/iter (+/- 58074) -test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_s ... bench: 2499268 ns/iter (+/- 125216) -test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_s/confirmation ... bench: 4617440 ns/iter (+/- 59222) -test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_u ... bench: 2414244 ns/iter (+/- 22991) -test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_u/confirmation ... bench: 4631271 ns/iter (+/- 20146) -test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_u ... bench: 2427648 ns/iter (+/- 13242) -test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_u/confirmation ... bench: 4632245 ns/iter (+/- 55834) -test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_s ... bench: 2497971 ns/iter (+/- 53602) -test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_s/confirmation ... bench: 4632215 ns/iter (+/- 37675) -test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_s ... bench: 2452166 ns/iter (+/- 56484) -test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_s/confirmation ... bench: 4618243 ns/iter (+/- 50293) -test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_u ... bench: 2488275 ns/iter (+/- 39915) -test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_u/confirmation ... bench: 4627780 ns/iter (+/- 14850) -test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_u ... bench: 2526775 ns/iter (+/- 29380) -test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_u/confirmation ... bench: 4604458 ns/iter (+/- 19231) -test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_s ... bench: 2515995 ns/iter (+/- 17031) -test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_s/confirmation ... bench: 4628557 ns/iter (+/- 36445) -test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_s ... bench: 2442262 ns/iter (+/- 28392) -test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_s/confirmation ... bench: 4660735 ns/iter (+/- 22188) -test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_u ... bench: 2415382 ns/iter (+/- 38477) -test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_u/confirmation ... bench: 4674767 ns/iter (+/- 21755) -test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_u ... bench: 2464596 ns/iter (+/- 41300) -test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_u/confirmation ... bench: 4633822 ns/iter (+/- 42542) -test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_s ... bench: 2459136 ns/iter (+/- 45463) -test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_s/confirmation ... bench: 4651029 ns/iter (+/- 38551) -test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_s ... bench: 2456423 ns/iter (+/- 12885) -test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_s/confirmation ... bench: 4640604 ns/iter (+/- 41849) -test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_u ... bench: 2454712 ns/iter (+/- 95711) -test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_u/confirmation ... bench: 4630610 ns/iter (+/- 48791) -test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_u ... bench: 2473700 ns/iter (+/- 27990) -test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_u/confirmation ... bench: 4603851 ns/iter (+/- 293203) -test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_s ... bench: 2431815 ns/iter (+/- 35563) -test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_s/confirmation ... bench: 4629549 ns/iter (+/- 22235) -test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_s ... bench: 2429157 ns/iter (+/- 51717) -test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_s/confirmation ... bench: 4638789 ns/iter (+/- 55722) -test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_u ... bench: 2436748 ns/iter (+/- 26809) -test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_u/confirmation ... bench: 4565488 ns/iter (+/- 37151) -test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_u ... bench: 2443392 ns/iter (+/- 282536) -test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_u/confirmation ... bench: 4635569 ns/iter (+/- 92472) -test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_s ... bench: 3546679 ns/iter (+/- 34938) -test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_s/confirmation ... bench: 6699382 ns/iter (+/- 415632) -test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_s ... bench: 3561455 ns/iter (+/- 29356) -test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_s/confirmation ... bench: 6771462 ns/iter (+/- 11511) -test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_u ... bench: 2732942 ns/iter (+/- 26610) -test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_u/confirmation ... bench: 5640633 ns/iter (+/- 47833) -test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_u ... bench: 2693897 ns/iter (+/- 12741) -test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_u/confirmation ... bench: 5726350 ns/iter (+/- 151562) -test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_s ... bench: 3585869 ns/iter (+/- 200642) -test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_s/confirmation ... bench: 6766726 ns/iter (+/- 84525) -test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_s ... bench: 3575432 ns/iter (+/- 37893) -test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_s/confirmation ... bench: 6731178 ns/iter (+/- 58527) -test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_u ... bench: 2757752 ns/iter (+/- 47027) -test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_u/confirmation ... bench: 5671348 ns/iter (+/- 28540) -test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_u ... bench: 2711383 ns/iter (+/- 42180) -test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_u/confirmation ... bench: 5692466 ns/iter (+/- 259395) -test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_s ... bench: 3575805 ns/iter (+/- 62461) -test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_s/confirmation ... bench: 6763652 ns/iter (+/- 40861) -test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_s ... bench: 3560379 ns/iter (+/- 24962) -test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_s/confirmation ... bench: 6777609 ns/iter (+/- 78204) -test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_u ... bench: 2744701 ns/iter (+/- 48217) -test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_u/confirmation ... bench: 5693585 ns/iter (+/- 109002) -test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_u ... bench: 2704564 ns/iter (+/- 2348) -test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_u/confirmation ... bench: 5723490 ns/iter (+/- 31184) -test wasm_instructions/wasm32/vishiftop/i16x8.shl ... bench: 4643270 ns/iter (+/- 140848) -test wasm_instructions/wasm32/vishiftop/i16x8.shl/confirmation ... bench: 8915674 ns/iter (+/- 66101) -test wasm_instructions/wasm64/vishiftop/i16x8.shl ... bench: 4684382 ns/iter (+/- 45407) -test wasm_instructions/wasm64/vishiftop/i16x8.shl/confirmation ... bench: 9063641 ns/iter (+/- 48265) -test wasm_instructions/wasm32/vishiftop/i16x8.shr_s ... bench: 4823690 ns/iter (+/- 21917) -test wasm_instructions/wasm32/vishiftop/i16x8.shr_s/confirmation ... bench: 9020681 ns/iter (+/- 47625) -test wasm_instructions/wasm64/vishiftop/i16x8.shr_s ... bench: 4839100 ns/iter (+/- 126060) -test wasm_instructions/wasm64/vishiftop/i16x8.shr_s/confirmation ... bench: 9054987 ns/iter (+/- 49851) -test wasm_instructions/wasm32/vishiftop/i16x8.shr_u ... bench: 4634896 ns/iter (+/- 31768) -test wasm_instructions/wasm32/vishiftop/i16x8.shr_u/confirmation ... bench: 9053283 ns/iter (+/- 16429) -test wasm_instructions/wasm64/vishiftop/i16x8.shr_u ... bench: 4869374 ns/iter (+/- 63607) -test wasm_instructions/wasm64/vishiftop/i16x8.shr_u/confirmation ... bench: 8959907 ns/iter (+/- 75456) -test wasm_instructions/wasm32/vishiftop/i32x4.shl ... bench: 4789630 ns/iter (+/- 89662) -test wasm_instructions/wasm32/vishiftop/i32x4.shl/confirmation ... bench: 9027275 ns/iter (+/- 60879) -test wasm_instructions/wasm64/vishiftop/i32x4.shl ... bench: 4816525 ns/iter (+/- 47384) -test wasm_instructions/wasm64/vishiftop/i32x4.shl/confirmation ... bench: 9014856 ns/iter (+/- 17685) -test wasm_instructions/wasm32/vishiftop/i32x4.shr_s ... bench: 4641485 ns/iter (+/- 14879) -test wasm_instructions/wasm32/vishiftop/i32x4.shr_s/confirmation ... bench: 8857277 ns/iter (+/- 41913) -test wasm_instructions/wasm64/vishiftop/i32x4.shr_s ... bench: 4654443 ns/iter (+/- 49074) -test wasm_instructions/wasm64/vishiftop/i32x4.shr_s/confirmation ... bench: 9018883 ns/iter (+/- 505126) -test wasm_instructions/wasm32/vishiftop/i32x4.shr_u ... bench: 4662408 ns/iter (+/- 30536) -test wasm_instructions/wasm32/vishiftop/i32x4.shr_u/confirmation ... bench: 9083111 ns/iter (+/- 35812) -test wasm_instructions/wasm64/vishiftop/i32x4.shr_u ... bench: 4881138 ns/iter (+/- 42596) -test wasm_instructions/wasm64/vishiftop/i32x4.shr_u/confirmation ... bench: 9043612 ns/iter (+/- 32671) -test wasm_instructions/wasm32/vishiftop/i64x2.shl ... bench: 4800041 ns/iter (+/- 40352) -test wasm_instructions/wasm32/vishiftop/i64x2.shl/confirmation ... bench: 9051811 ns/iter (+/- 31101) -test wasm_instructions/wasm64/vishiftop/i64x2.shl ... bench: 4845798 ns/iter (+/- 76076) -test wasm_instructions/wasm64/vishiftop/i64x2.shl/confirmation ... bench: 9012695 ns/iter (+/- 44410) -test wasm_instructions/wasm32/vishiftop/i64x2.shr_u ... bench: 4636340 ns/iter (+/- 30720) -test wasm_instructions/wasm32/vishiftop/i64x2.shr_u/confirmation ... bench: 8873021 ns/iter (+/- 142995) -test wasm_instructions/wasm64/vishiftop/i64x2.shr_u ... bench: 4718467 ns/iter (+/- 93294) -test wasm_instructions/wasm64/vishiftop/i64x2.shr_u/confirmation ... bench: 8863767 ns/iter (+/- 31400) -test wasm_instructions/wasm32/vishiftop/i8x16.shl ... bench: 6790445 ns/iter (+/- 46791) -test wasm_instructions/wasm32/vishiftop/i8x16.shl/confirmation ... bench: 13236711 ns/iter (+/- 329759) -test wasm_instructions/wasm64/vishiftop/i8x16.shl ... bench: 6745312 ns/iter (+/- 60337) -test wasm_instructions/wasm64/vishiftop/i8x16.shl/confirmation ... bench: 13142741 ns/iter (+/- 336663) -test wasm_instructions/wasm32/vishiftop/i8x16.shr_s ... bench: 7908538 ns/iter (+/- 31377) -test wasm_instructions/wasm32/vishiftop/i8x16.shr_s/confirmation ... bench: 14892383 ns/iter (+/- 36737) -test wasm_instructions/wasm64/vishiftop/i8x16.shr_s ... bench: 7412901 ns/iter (+/- 36900) -test wasm_instructions/wasm64/vishiftop/i8x16.shr_s/confirmation ... bench: 14921909 ns/iter (+/- 248301) -test wasm_instructions/wasm32/vishiftop/i8x16.shr_u ... bench: 5995978 ns/iter (+/- 318401) -test wasm_instructions/wasm32/vishiftop/i8x16.shr_u/confirmation ... bench: 11348111 ns/iter (+/- 56493) -test wasm_instructions/wasm64/vishiftop/i8x16.shr_u ... bench: 5857592 ns/iter (+/- 79559) -test wasm_instructions/wasm64/vishiftop/i8x16.shr_u/confirmation ... bench: 11417889 ns/iter (+/- 179916) -test wasm_instructions/wasm32/vishiftop/i64x2.shr_s ... bench: 8770125 ns/iter (+/- 42946) -test wasm_instructions/wasm32/vishiftop/i64x2.shr_s/confirmation ... bench: 17158333 ns/iter (+/- 155205) -test wasm_instructions/wasm64/vishiftop/i64x2.shr_s ... bench: 8877200 ns/iter (+/- 68674) -test wasm_instructions/wasm64/vishiftop/i64x2.shr_s/confirmation ... bench: 17571705 ns/iter (+/- 18145) -test wasm_instructions/wasm32/vibinop/i8x16.add ... bench: 2430401 ns/iter (+/- 28700) -test wasm_instructions/wasm32/vibinop/i8x16.add/confirmation ... bench: 4616337 ns/iter (+/- 23107) -test wasm_instructions/wasm64/vibinop/i8x16.add ... bench: 2659911 ns/iter (+/- 42791) -test wasm_instructions/wasm64/vibinop/i8x16.add/confirmation ... bench: 4725824 ns/iter (+/- 23895) -test wasm_instructions/wasm32/vibinop/i8x16.sub ... bench: 2495324 ns/iter (+/- 19010) -test wasm_instructions/wasm32/vibinop/i8x16.sub/confirmation ... bench: 4649092 ns/iter (+/- 31905) -test wasm_instructions/wasm64/vibinop/i8x16.sub ... bench: 2517136 ns/iter (+/- 35179) -test wasm_instructions/wasm64/vibinop/i8x16.sub/confirmation ... bench: 4645142 ns/iter (+/- 19539) -test wasm_instructions/wasm32/vibinop/i16x8.add ... bench: 2416654 ns/iter (+/- 94743) -test wasm_instructions/wasm32/vibinop/i16x8.add/confirmation ... bench: 4611082 ns/iter (+/- 29968) -test wasm_instructions/wasm64/vibinop/i16x8.add ... bench: 2424953 ns/iter (+/- 18833) -test wasm_instructions/wasm64/vibinop/i16x8.add/confirmation ... bench: 4641115 ns/iter (+/- 28230) -test wasm_instructions/wasm32/vibinop/i16x8.sub ... bench: 2434667 ns/iter (+/- 37230) -test wasm_instructions/wasm32/vibinop/i16x8.sub/confirmation ... bench: 4628061 ns/iter (+/- 5414) -test wasm_instructions/wasm64/vibinop/i16x8.sub ... bench: 2485867 ns/iter (+/- 45535) -test wasm_instructions/wasm64/vibinop/i16x8.sub/confirmation ... bench: 4628611 ns/iter (+/- 63170) -test wasm_instructions/wasm32/vibinop/i32x4.add ... bench: 2455672 ns/iter (+/- 18504) -test wasm_instructions/wasm32/vibinop/i32x4.add/confirmation ... bench: 4625389 ns/iter (+/- 13230) -test wasm_instructions/wasm64/vibinop/i32x4.add ... bench: 2463639 ns/iter (+/- 232053) -test wasm_instructions/wasm64/vibinop/i32x4.add/confirmation ... bench: 4586093 ns/iter (+/- 31214) -test wasm_instructions/wasm32/vibinop/i32x4.sub ... bench: 2465223 ns/iter (+/- 23569) -test wasm_instructions/wasm32/vibinop/i32x4.sub/confirmation ... bench: 4635559 ns/iter (+/- 25792) -test wasm_instructions/wasm64/vibinop/i32x4.sub ... bench: 2482643 ns/iter (+/- 29783) -test wasm_instructions/wasm64/vibinop/i32x4.sub/confirmation ... bench: 4640883 ns/iter (+/- 63151) -test wasm_instructions/wasm32/vibinop/i64x2.add ... bench: 2422729 ns/iter (+/- 39177) -test wasm_instructions/wasm32/vibinop/i64x2.add/confirmation ... bench: 4583713 ns/iter (+/- 113255) -test wasm_instructions/wasm64/vibinop/i64x2.add ... bench: 2424856 ns/iter (+/- 10485) -test wasm_instructions/wasm64/vibinop/i64x2.add/confirmation ... bench: 4617869 ns/iter (+/- 31384) -test wasm_instructions/wasm32/vibinop/i64x2.sub ... bench: 2469956 ns/iter (+/- 46710) -test wasm_instructions/wasm32/vibinop/i64x2.sub/confirmation ... bench: 4660962 ns/iter (+/- 63179) -test wasm_instructions/wasm64/vibinop/i64x2.sub ... bench: 2501027 ns/iter (+/- 27248) -test wasm_instructions/wasm64/vibinop/i64x2.sub/confirmation ... bench: 4649175 ns/iter (+/- 28956) -test wasm_instructions/wasm32/viminmaxop/i8x16.min_s ... bench: 2512268 ns/iter (+/- 24537) -test wasm_instructions/wasm32/viminmaxop/i8x16.min_s/confirmation ... bench: 4574311 ns/iter (+/- 6241) -test wasm_instructions/wasm64/viminmaxop/i8x16.min_s ... bench: 2492386 ns/iter (+/- 217564) -test wasm_instructions/wasm64/viminmaxop/i8x16.min_s/confirmation ... bench: 4640988 ns/iter (+/- 61154) -test wasm_instructions/wasm32/viminmaxop/i8x16.min_u ... bench: 2438964 ns/iter (+/- 46318) -test wasm_instructions/wasm32/viminmaxop/i8x16.min_u/confirmation ... bench: 4622965 ns/iter (+/- 75340) -test wasm_instructions/wasm64/viminmaxop/i8x16.min_u ... bench: 2445273 ns/iter (+/- 14072) -test wasm_instructions/wasm64/viminmaxop/i8x16.min_u/confirmation ... bench: 4622393 ns/iter (+/- 19125) -test wasm_instructions/wasm32/viminmaxop/i8x16.max_s ... bench: 2431377 ns/iter (+/- 11491) -test wasm_instructions/wasm32/viminmaxop/i8x16.max_s/confirmation ... bench: 4583480 ns/iter (+/- 49516) -test wasm_instructions/wasm64/viminmaxop/i8x16.max_s ... bench: 2456850 ns/iter (+/- 18561) -test wasm_instructions/wasm64/viminmaxop/i8x16.max_s/confirmation ... bench: 4610626 ns/iter (+/- 40239) -test wasm_instructions/wasm32/viminmaxop/i8x16.max_u ... bench: 2508529 ns/iter (+/- 12771) -test wasm_instructions/wasm32/viminmaxop/i8x16.max_u/confirmation ... bench: 4633061 ns/iter (+/- 48129) -test wasm_instructions/wasm64/viminmaxop/i8x16.max_u ... bench: 2470475 ns/iter (+/- 36176) -test wasm_instructions/wasm64/viminmaxop/i8x16.max_u/confirmation ... bench: 4666413 ns/iter (+/- 39465) -test wasm_instructions/wasm32/viminmaxop/i16x8.min_s ... bench: 2434086 ns/iter (+/- 52197) -test wasm_instructions/wasm32/viminmaxop/i16x8.min_s/confirmation ... bench: 4575555 ns/iter (+/- 49199) -test wasm_instructions/wasm64/viminmaxop/i16x8.min_s ... bench: 2427759 ns/iter (+/- 109595) -test wasm_instructions/wasm64/viminmaxop/i16x8.min_s/confirmation ... bench: 4626232 ns/iter (+/- 39310) -test wasm_instructions/wasm32/viminmaxop/i16x8.min_u ... bench: 2434195 ns/iter (+/- 17846) -test wasm_instructions/wasm32/viminmaxop/i16x8.min_u/confirmation ... bench: 4641605 ns/iter (+/- 24717) -test wasm_instructions/wasm64/viminmaxop/i16x8.min_u ... bench: 2439285 ns/iter (+/- 23904) -test wasm_instructions/wasm64/viminmaxop/i16x8.min_u/confirmation ... bench: 4582893 ns/iter (+/- 17007) -test wasm_instructions/wasm32/viminmaxop/i16x8.max_s ... bench: 2429135 ns/iter (+/- 17155) -test wasm_instructions/wasm32/viminmaxop/i16x8.max_s/confirmation ... bench: 4635572 ns/iter (+/- 42715) -test wasm_instructions/wasm64/viminmaxop/i16x8.max_s ... bench: 2514677 ns/iter (+/- 25110) -test wasm_instructions/wasm64/viminmaxop/i16x8.max_s/confirmation ... bench: 4645651 ns/iter (+/- 55816) -test wasm_instructions/wasm32/viminmaxop/i16x8.max_u ... bench: 2430840 ns/iter (+/- 21383) -test wasm_instructions/wasm32/viminmaxop/i16x8.max_u/confirmation ... bench: 4589089 ns/iter (+/- 27538) -test wasm_instructions/wasm64/viminmaxop/i16x8.max_u ... bench: 2449689 ns/iter (+/- 164493) -test wasm_instructions/wasm64/viminmaxop/i16x8.max_u/confirmation ... bench: 4604762 ns/iter (+/- 69136) -test wasm_instructions/wasm32/viminmaxop/i32x4.min_s ... bench: 2445765 ns/iter (+/- 19269) -test wasm_instructions/wasm32/viminmaxop/i32x4.min_s/confirmation ... bench: 4627667 ns/iter (+/- 26266) -test wasm_instructions/wasm64/viminmaxop/i32x4.min_s ... bench: 2549811 ns/iter (+/- 9765) -test wasm_instructions/wasm64/viminmaxop/i32x4.min_s/confirmation ... bench: 4662080 ns/iter (+/- 26317) -test wasm_instructions/wasm32/viminmaxop/i32x4.min_u ... bench: 2424560 ns/iter (+/- 26569) -test wasm_instructions/wasm32/viminmaxop/i32x4.min_u/confirmation ... bench: 4627561 ns/iter (+/- 45204) -test wasm_instructions/wasm64/viminmaxop/i32x4.min_u ... bench: 2424255 ns/iter (+/- 19222) -test wasm_instructions/wasm64/viminmaxop/i32x4.min_u/confirmation ... bench: 4636572 ns/iter (+/- 33375) -test wasm_instructions/wasm32/viminmaxop/i32x4.max_s ... bench: 2450489 ns/iter (+/- 31423) -test wasm_instructions/wasm32/viminmaxop/i32x4.max_s/confirmation ... bench: 4584113 ns/iter (+/- 45964) -test wasm_instructions/wasm64/viminmaxop/i32x4.max_s ... bench: 2477605 ns/iter (+/- 21726) -test wasm_instructions/wasm64/viminmaxop/i32x4.max_s/confirmation ... bench: 4634208 ns/iter (+/- 94664) -test wasm_instructions/wasm32/viminmaxop/i32x4.max_u ... bench: 2411871 ns/iter (+/- 17849) -test wasm_instructions/wasm32/viminmaxop/i32x4.max_u/confirmation ... bench: 4565433 ns/iter (+/- 57977) -test wasm_instructions/wasm64/viminmaxop/i32x4.max_u ... bench: 2464219 ns/iter (+/- 52678) -test wasm_instructions/wasm64/viminmaxop/i32x4.max_u/confirmation ... bench: 4640776 ns/iter (+/- 21959) -test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_s ... bench: 2452650 ns/iter (+/- 20407) -test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_s/confirmation ... bench: 4624514 ns/iter (+/- 93800) -test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_s ... bench: 2483653 ns/iter (+/- 13257) -test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_s/confirmation ... bench: 4650738 ns/iter (+/- 48833) -test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_u ... bench: 2416467 ns/iter (+/- 65680) -test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_u/confirmation ... bench: 4621649 ns/iter (+/- 26862) -test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_u ... bench: 2455841 ns/iter (+/- 51260) -test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_u/confirmation ... bench: 4625367 ns/iter (+/- 33351) -test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_s ... bench: 2420993 ns/iter (+/- 22906) -test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_s/confirmation ... bench: 4662775 ns/iter (+/- 27615) -test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_s ... bench: 2511773 ns/iter (+/- 54792) -test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_s/confirmation ... bench: 4647470 ns/iter (+/- 46689) -test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_u ... bench: 2410279 ns/iter (+/- 23457) -test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_u/confirmation ... bench: 4600116 ns/iter (+/- 23933) -test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_u ... bench: 2444031 ns/iter (+/- 52003) -test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_u/confirmation ... bench: 4626113 ns/iter (+/- 51513) -test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_s ... bench: 2514079 ns/iter (+/- 131034) -test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_s/confirmation ... bench: 4596655 ns/iter (+/- 53262) -test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_s ... bench: 2514247 ns/iter (+/- 33215) -test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_s/confirmation ... bench: 4642989 ns/iter (+/- 22764) -test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_u ... bench: 2416175 ns/iter (+/- 6685) -test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_u/confirmation ... bench: 4636905 ns/iter (+/- 104437) -test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_u ... bench: 2426886 ns/iter (+/- 11943) -test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_u/confirmation ... bench: 4663325 ns/iter (+/- 15478) -test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_s ... bench: 2414228 ns/iter (+/- 8365) -test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_s/confirmation ... bench: 4617233 ns/iter (+/- 24136) -test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_s ... bench: 2442790 ns/iter (+/- 42749) -test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_s/confirmation ... bench: 4634436 ns/iter (+/- 19719) -test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_u ... bench: 2421845 ns/iter (+/- 69870) -test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_u/confirmation ... bench: 4630851 ns/iter (+/- 38656) -test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_u ... bench: 2440559 ns/iter (+/- 28705) -test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_u/confirmation ... bench: 4632888 ns/iter (+/- 54796) -test wasm_instructions/wasm32/vimul/i16x8.mul ... bench: 2646509 ns/iter (+/- 27127) -test wasm_instructions/wasm32/vimul/i16x8.mul/confirmation ... bench: 4621101 ns/iter (+/- 245465) -test wasm_instructions/wasm64/vimul/i16x8.mul ... bench: 2427418 ns/iter (+/- 128706) -test wasm_instructions/wasm64/vimul/i16x8.mul/confirmation ... bench: 4628587 ns/iter (+/- 49922) -test wasm_instructions/wasm32/vimul/i32x4.mul ... bench: 4597825 ns/iter (+/- 68170) -test wasm_instructions/wasm32/vimul/i32x4.mul/confirmation ... bench: 8845946 ns/iter (+/- 69411) -test wasm_instructions/wasm64/vimul/i32x4.mul ... bench: 4644260 ns/iter (+/- 22960) -test wasm_instructions/wasm64/vimul/i32x4.mul/confirmation ... bench: 8898007 ns/iter (+/- 30108) -test wasm_instructions/wasm32/vimul/i64x2.mul ... bench: 8935071 ns/iter (+/- 995516) -test wasm_instructions/wasm32/vimul/i64x2.mul/confirmation ... bench: 17474125 ns/iter (+/- 864514) -test wasm_instructions/wasm64/vimul/i64x2.mul ... bench: 8848545 ns/iter (+/- 11414) -test wasm_instructions/wasm64/vimul/i64x2.mul/confirmation ... bench: 17415224 ns/iter (+/- 104057) -test wasm_instructions/wasm32/vavgr/i8x16.avgr_u ... bench: 2473648 ns/iter (+/- 23530) -test wasm_instructions/wasm32/vavgr/i8x16.avgr_u/confirmation ... bench: 4627670 ns/iter (+/- 120009) -test wasm_instructions/wasm64/vavgr/i8x16.avgr_u ... bench: 2454077 ns/iter (+/- 47672) -test wasm_instructions/wasm64/vavgr/i8x16.avgr_u/confirmation ... bench: 4627314 ns/iter (+/- 22921) -test wasm_instructions/wasm32/vavgr/i16x8.avgr_u ... bench: 2502922 ns/iter (+/- 37603) -test wasm_instructions/wasm32/vavgr/i16x8.avgr_u/confirmation ... bench: 4627194 ns/iter (+/- 25174) -test wasm_instructions/wasm64/vavgr/i16x8.avgr_u ... bench: 2439577 ns/iter (+/- 13087) -test wasm_instructions/wasm64/vavgr/i16x8.avgr_u/confirmation ... bench: 4616620 ns/iter (+/- 23792) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_s ... bench: 3589126 ns/iter (+/- 35602) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_s/confirmation ... bench: 6769758 ns/iter (+/- 114828) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_s ... bench: 3553238 ns/iter (+/- 23050) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_s/confirmation ... bench: 6808693 ns/iter (+/- 40736) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_s ... bench: 3575668 ns/iter (+/- 16977) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_s/confirmation ... bench: 6764343 ns/iter (+/- 50768) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_s ... bench: 3514096 ns/iter (+/- 213330) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_s/confirmation ... bench: 6762858 ns/iter (+/- 65538) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_s ... bench: 3560692 ns/iter (+/- 39152) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_s/confirmation ... bench: 6960728 ns/iter (+/- 237326) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_s ... bench: 3586521 ns/iter (+/- 19850) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_s/confirmation ... bench: 6962006 ns/iter (+/- 276785) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_u ... bench: 3568009 ns/iter (+/- 13068) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_u/confirmation ... bench: 6824895 ns/iter (+/- 65499) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_u ... bench: 3685930 ns/iter (+/- 25205) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_u/confirmation ... bench: 6808344 ns/iter (+/- 40453) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_u ... bench: 3543952 ns/iter (+/- 52350) -test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_u/confirmation ... bench: 6974207 ns/iter (+/- 54623) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_u ... bench: 3560750 ns/iter (+/- 23275) -test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_u/confirmation ... bench: 6954076 ns/iter (+/- 31844) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_s ... bench: 5859968 ns/iter (+/- 25613) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_s/confirmation ... bench: 11204878 ns/iter (+/- 376725) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_s ... bench: 5870351 ns/iter (+/- 36545) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_s/confirmation ... bench: 11046231 ns/iter (+/- 256779) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_u ... bench: 3612521 ns/iter (+/- 40770) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_u/confirmation ... bench: 6813376 ns/iter (+/- 37919) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_u ... bench: 3692391 ns/iter (+/- 36004) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_u/confirmation ... bench: 6772294 ns/iter (+/- 9042) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_u ... bench: 4629098 ns/iter (+/- 10042) -test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_u/confirmation ... bench: 8874449 ns/iter (+/- 30010) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_u ... bench: 4640941 ns/iter (+/- 36006) -test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_u/confirmation ... bench: 8847925 ns/iter (+/- 113932) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_s ... bench: 4654145 ns/iter (+/- 295891) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_s/confirmation ... bench: 8860042 ns/iter (+/- 143160) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_s ... bench: 4627799 ns/iter (+/- 270964) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_s/confirmation ... bench: 8906117 ns/iter (+/- 43467) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_s ... bench: 4661833 ns/iter (+/- 25165) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_s/confirmation ... bench: 8848761 ns/iter (+/- 41606) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_s ... bench: 4660280 ns/iter (+/- 309051) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_s/confirmation ... bench: 8873090 ns/iter (+/- 47644) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_u ... bench: 4624397 ns/iter (+/- 19432) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_u/confirmation ... bench: 8889841 ns/iter (+/- 29370) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_u ... bench: 4646367 ns/iter (+/- 282054) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_u/confirmation ... bench: 8911387 ns/iter (+/- 49566) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_u ... bench: 4636106 ns/iter (+/- 52489) -test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_u/confirmation ... bench: 8896197 ns/iter (+/- 171497) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_u ... bench: 4665303 ns/iter (+/- 63201) -test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_u/confirmation ... bench: 8965458 ns/iter (+/- 85774) -test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_s ... bench: 3449729 ns/iter (+/- 23693) -test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_s/confirmation ... bench: 6996891 ns/iter (+/- 45249) -test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_s ... bench: 3411400 ns/iter (+/- 267614) -test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_s/confirmation ... bench: 6928250 ns/iter (+/- 185587) -test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_u ... bench: 4639855 ns/iter (+/- 382468) -test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_u/confirmation ... bench: 8889318 ns/iter (+/- 29705) -test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_u ... bench: 4633652 ns/iter (+/- 170382) -test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_u/confirmation ... bench: 9051636 ns/iter (+/- 301164) -test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_s ... bench: 2771559 ns/iter (+/- 39349) -test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_s/confirmation ... bench: 5460396 ns/iter (+/- 113153) -test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_s ... bench: 2738757 ns/iter (+/- 155620) -test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_s/confirmation ... bench: 5800588 ns/iter (+/- 218858) -test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_u ... bench: 6878167 ns/iter (+/- 30514) -test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_u/confirmation ... bench: 16295818 ns/iter (+/- 360011) -test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_u ... bench: 7124707 ns/iter (+/- 10950) -test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_u/confirmation ... bench: 15824782 ns/iter (+/- 543245) -test wasm_instructions/wasm32/vfbinop/f32x4.add ... bench: 5033988 ns/iter (+/- 345832) -test wasm_instructions/wasm32/vfbinop/f32x4.add/confirmation ... bench: 10514999 ns/iter (+/- 452700) -test wasm_instructions/wasm64/vfbinop/f32x4.add ... bench: 5472442 ns/iter (+/- 17062) -test wasm_instructions/wasm64/vfbinop/f32x4.add/confirmation ... bench: 10758270 ns/iter (+/- 348956) -test wasm_instructions/wasm32/vfbinop/f32x4.sub ... bench: 5022336 ns/iter (+/- 5323) -test wasm_instructions/wasm32/vfbinop/f32x4.sub/confirmation ... bench: 10838493 ns/iter (+/- 347676) -test wasm_instructions/wasm64/vfbinop/f32x4.sub ... bench: 5238761 ns/iter (+/- 443026) -test wasm_instructions/wasm64/vfbinop/f32x4.sub/confirmation ... bench: 10537842 ns/iter (+/- 38167) -test wasm_instructions/wasm32/vfbinop/f32x4.mul ... bench: 5055629 ns/iter (+/- 31001) -test wasm_instructions/wasm32/vfbinop/f32x4.mul/confirmation ... bench: 10472068 ns/iter (+/- 207951) -test wasm_instructions/wasm64/vfbinop/f32x4.mul ... bench: 5278069 ns/iter (+/- 38745) -test wasm_instructions/wasm64/vfbinop/f32x4.mul/confirmation ... bench: 10609136 ns/iter (+/- 345814) -test wasm_instructions/wasm32/vfbinop/f64x2.add ... bench: 5042392 ns/iter (+/- 10973) -test wasm_instructions/wasm32/vfbinop/f64x2.add/confirmation ... bench: 10252904 ns/iter (+/- 242943) -test wasm_instructions/wasm64/vfbinop/f64x2.add ... bench: 5076232 ns/iter (+/- 20516) -test wasm_instructions/wasm64/vfbinop/f64x2.add/confirmation ... bench: 10734186 ns/iter (+/- 486017) -test wasm_instructions/wasm32/vfbinop/f64x2.sub ... bench: 5031958 ns/iter (+/- 15466) -test wasm_instructions/wasm32/vfbinop/f64x2.sub/confirmation ... bench: 10623655 ns/iter (+/- 418913) -test wasm_instructions/wasm64/vfbinop/f64x2.sub ... bench: 5076175 ns/iter (+/- 34385) -test wasm_instructions/wasm64/vfbinop/f64x2.sub/confirmation ... bench: 10918960 ns/iter (+/- 35922) -test wasm_instructions/wasm32/vfbinop/f64x2.mul ... bench: 5110920 ns/iter (+/- 396937) -test wasm_instructions/wasm32/vfbinop/f64x2.mul/confirmation ... bench: 10998988 ns/iter (+/- 504577) -test wasm_instructions/wasm64/vfbinop/f64x2.mul ... bench: 5456682 ns/iter (+/- 168156) -test wasm_instructions/wasm64/vfbinop/f64x2.mul/confirmation ... bench: 10974076 ns/iter (+/- 204528) -test wasm_instructions/wasm32/vfbinop/f32x4.div ... bench: 20647079 ns/iter (+/- 52068) -test wasm_instructions/wasm32/vfbinop/f32x4.div/confirmation ... bench: 41151322 ns/iter (+/- 49377) -test wasm_instructions/wasm64/vfbinop/f32x4.div ... bench: 20713824 ns/iter (+/- 47404) -test wasm_instructions/wasm64/vfbinop/f32x4.div/confirmation ... bench: 41229969 ns/iter (+/- 11123) -test wasm_instructions/wasm32/vfbinop/f64x2.div ... bench: 22789956 ns/iter (+/- 442152) -test wasm_instructions/wasm32/vfbinop/f64x2.div/confirmation ... bench: 45290417 ns/iter (+/- 968524) -test wasm_instructions/wasm64/vfbinop/f64x2.div ... bench: 22829206 ns/iter (+/- 78705) -test wasm_instructions/wasm64/vfbinop/f64x2.div/confirmation ... bench: 45478842 ns/iter (+/- 339480) -test wasm_instructions/wasm32/vfbinop/f32x4.min ... bench: 8889449 ns/iter (+/- 371969) -test wasm_instructions/wasm32/vfbinop/f32x4.min/confirmation ... bench: 18934010 ns/iter (+/- 126051) -test wasm_instructions/wasm64/vfbinop/f32x4.min ... bench: 9116853 ns/iter (+/- 156947) -test wasm_instructions/wasm64/vfbinop/f32x4.min/confirmation ... bench: 17618122 ns/iter (+/- 466249) -test wasm_instructions/wasm32/vfbinop/f32x4.max ... bench: 9666897 ns/iter (+/- 249163) -test wasm_instructions/wasm32/vfbinop/f32x4.max/confirmation ... bench: 20178741 ns/iter (+/- 770906) -test wasm_instructions/wasm64/vfbinop/f32x4.max ... bench: 10233954 ns/iter (+/- 147632) -test wasm_instructions/wasm64/vfbinop/f32x4.max/confirmation ... bench: 19142696 ns/iter (+/- 215999) -test wasm_instructions/wasm32/vfbinop/f64x2.min ... bench: 8638318 ns/iter (+/- 48945) -test wasm_instructions/wasm32/vfbinop/f64x2.min/confirmation ... bench: 18167308 ns/iter (+/- 747896) -test wasm_instructions/wasm64/vfbinop/f64x2.min ... bench: 8781130 ns/iter (+/- 416014) -test wasm_instructions/wasm64/vfbinop/f64x2.min/confirmation ... bench: 18211294 ns/iter (+/- 918383) -test wasm_instructions/wasm32/vfbinop/f64x2.max ... bench: 9997270 ns/iter (+/- 393384) -test wasm_instructions/wasm32/vfbinop/f64x2.max/confirmation ... bench: 20726525 ns/iter (+/- 669674) -test wasm_instructions/wasm64/vfbinop/f64x2.max ... bench: 10603879 ns/iter (+/- 756602) -test wasm_instructions/wasm64/vfbinop/f64x2.max/confirmation ... bench: 20791967 ns/iter (+/- 150429) -test wasm_instructions/wasm32/vfbinop/f32x4.pmin ... bench: 2422244 ns/iter (+/- 193468) -test wasm_instructions/wasm32/vfbinop/f32x4.pmin/confirmation ... bench: 4625875 ns/iter (+/- 51318) -test wasm_instructions/wasm64/vfbinop/f32x4.pmin ... bench: 2457672 ns/iter (+/- 31052) -test wasm_instructions/wasm64/vfbinop/f32x4.pmin/confirmation ... bench: 4619077 ns/iter (+/- 57603) -test wasm_instructions/wasm32/vfbinop/f32x4.pmax ... bench: 2484176 ns/iter (+/- 46184) -test wasm_instructions/wasm32/vfbinop/f32x4.pmax/confirmation ... bench: 4591710 ns/iter (+/- 43574) -test wasm_instructions/wasm64/vfbinop/f32x4.pmax ... bench: 2435502 ns/iter (+/- 44816) -test wasm_instructions/wasm64/vfbinop/f32x4.pmax/confirmation ... bench: 4626168 ns/iter (+/- 35705) -test wasm_instructions/wasm32/vfbinop/f64x2.pmin ... bench: 2483959 ns/iter (+/- 28614) -test wasm_instructions/wasm32/vfbinop/f64x2.pmin/confirmation ... bench: 4623391 ns/iter (+/- 46218) -test wasm_instructions/wasm64/vfbinop/f64x2.pmin ... bench: 2445263 ns/iter (+/- 19091) -test wasm_instructions/wasm64/vfbinop/f64x2.pmin/confirmation ... bench: 4628394 ns/iter (+/- 41394) -test wasm_instructions/wasm32/vfbinop/f64x2.pmax ... bench: 2658351 ns/iter (+/- 16724) -test wasm_instructions/wasm32/vfbinop/f64x2.pmax/confirmation ... bench: 4623250 ns/iter (+/- 38731) -test wasm_instructions/wasm64/vfbinop/f64x2.pmax ... bench: 2475409 ns/iter (+/- 36290) -test wasm_instructions/wasm64/vfbinop/f64x2.pmax/confirmation ... bench: 4635921 ns/iter (+/- 27290) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_s ... bench: 5891033 ns/iter (+/- 266921) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_s/confirmation ... bench: 11054103 ns/iter (+/- 71351) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_s ... bench: 5768846 ns/iter (+/- 35697) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_s/confirmation ... bench: 11423616 ns/iter (+/- 411367) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_s_zero ... bench: 4668542 ns/iter (+/- 43929) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_s_zero/confirmation ... bench: 10746948 ns/iter (+/- 405440) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_s_zero ... bench: 4769567 ns/iter (+/- 30684) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_s_zero/confirmation ... bench: 10047618 ns/iter (+/- 681686) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_u ... bench: 10262432 ns/iter (+/- 66729) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_u/confirmation ... bench: 20774290 ns/iter (+/- 560458) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_u ... bench: 10155288 ns/iter (+/- 99863) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_u/confirmation ... bench: 20268257 ns/iter (+/- 560303) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_u_zero ... bench: 7233299 ns/iter (+/- 19112) -test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_u_zero/confirmation ... bench: 15056009 ns/iter (+/- 1429274) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_u_zero ... bench: 6706113 ns/iter (+/- 392933) -test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_u_zero/confirmation ... bench: 15907461 ns/iter (+/- 877535) -test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_s ... bench: 2609554 ns/iter (+/- 17641) -test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_s/confirmation ... bench: 4654253 ns/iter (+/- 35685) -test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_s ... bench: 2487028 ns/iter (+/- 38016) -test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_s/confirmation ... bench: 4595628 ns/iter (+/- 28482) -test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_s ... bench: 2595031 ns/iter (+/- 188073) -test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_s/confirmation ... bench: 4628363 ns/iter (+/- 33213) -test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_s ... bench: 2430209 ns/iter (+/- 39284) -test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_s/confirmation ... bench: 4648005 ns/iter (+/- 60549) -test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_u ... bench: 10699887 ns/iter (+/- 219492) -test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_u/confirmation ... bench: 21249552 ns/iter (+/- 72316) -test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_u ... bench: 10699544 ns/iter (+/- 99840) -test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_u/confirmation ... bench: 21529055 ns/iter (+/- 118112) -test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_u ... bench: 4660364 ns/iter (+/- 14842) -test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_u/confirmation ... bench: 10264686 ns/iter (+/- 178665) -test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_u ... bench: 4590263 ns/iter (+/- 107436) -test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_u/confirmation ... bench: 10692690 ns/iter (+/- 320723) -test wasm_instructions/wasm32/vdemote/f32x4.demote_f64x2_zero ... bench: 5390824 ns/iter (+/- 403500) -test wasm_instructions/wasm32/vdemote/f32x4.demote_f64x2_zero/confirmation ... bench: 10735341 ns/iter (+/- 362935) -test wasm_instructions/wasm64/vdemote/f32x4.demote_f64x2_zero ... bench: 5224696 ns/iter (+/- 92782) -test wasm_instructions/wasm64/vdemote/f32x4.demote_f64x2_zero/confirmation ... bench: 11224452 ns/iter (+/- 443805) -test wasm_instructions/wasm32/vpromote/f64x2.promote_low_f32x4 ... bench: 5314777 ns/iter (+/- 50215) -test wasm_instructions/wasm32/vpromote/f64x2.promote_low_f32x4/confirmation ... bench: 10630275 ns/iter (+/- 307743) -test wasm_instructions/wasm64/vpromote/f64x2.promote_low_f32x4 ... bench: 5176408 ns/iter (+/- 24007) -test wasm_instructions/wasm64/vpromote/f64x2.promote_low_f32x4/confirmation ... bench: 10838949 ns/iter (+/- 310978) -test wasm_instructions/wasm32/vvar/local.get ... bench: 2437444 ns/iter (+/- 41743) -test wasm_instructions/wasm32/vvar/local.get/confirmation ... bench: 4630549 ns/iter (+/- 38096) -test wasm_instructions/wasm64/vvar/local.get ... bench: 2460747 ns/iter (+/- 284770) -test wasm_instructions/wasm64/vvar/local.get/confirmation ... bench: 4649188 ns/iter (+/- 38228) -test wasm_instructions/wasm32/vvar/global.get ... bench: 17378092 ns/iter (+/- 24770) -test wasm_instructions/wasm32/vvar/global.get/confirmation ... bench: 34376983 ns/iter (+/- 39036) -test wasm_instructions/wasm64/vvar/global.get ... bench: 17447715 ns/iter (+/- 594219) -test wasm_instructions/wasm64/vvar/global.get/confirmation ... bench: 34437359 ns/iter (+/- 70037) -test wasm_instructions/wasm32/vvar/local.set ... bench: 2412243 ns/iter (+/- 14341) -test wasm_instructions/wasm32/vvar/local.set/confirmation ... bench: 4620159 ns/iter (+/- 39527) -test wasm_instructions/wasm64/vvar/local.set ... bench: 2459989 ns/iter (+/- 52377) -test wasm_instructions/wasm64/vvar/local.set/confirmation ... bench: 4590415 ns/iter (+/- 69477) -test wasm_instructions/wasm32/vvar/global.set ... bench: 2415984 ns/iter (+/- 216095) -test wasm_instructions/wasm32/vvar/global.set/confirmation ... bench: 4571985 ns/iter (+/- 63794) -test wasm_instructions/wasm64/vvar/global.set ... bench: 2513841 ns/iter (+/- 45382) -test wasm_instructions/wasm64/vvar/global.set/confirmation ... bench: 4644546 ns/iter (+/- 36137) -test wasm_instructions/wasm32/vvar/local.tee ... bench: 2440981 ns/iter (+/- 50147) -test wasm_instructions/wasm32/vvar/local.tee/confirmation ... bench: 4573284 ns/iter (+/- 67410) -test wasm_instructions/wasm64/vvar/local.tee ... bench: 2464954 ns/iter (+/- 11407) -test wasm_instructions/wasm64/vvar/local.tee/confirmation ... bench: 4593839 ns/iter (+/- 22910) -test wasm_instructions/wasm32/vmem/v128.load ... bench: 3682507 ns/iter (+/- 51686) -test wasm_instructions/wasm32/vmem/v128.load/confirmation ... bench: 6947057 ns/iter (+/- 30172) -test wasm_instructions/wasm64/vmem/v128.load ... bench: 5596394 ns/iter (+/- 29455) -test wasm_instructions/wasm64/vmem/v128.load/confirmation ... bench: 10448210 ns/iter (+/- 296669) -test wasm_instructions/wasm32/vmem/v128.load_unaligned ... bench: 3655256 ns/iter (+/- 36310) -test wasm_instructions/wasm32/vmem/v128.load_unaligned/confirmation ... bench: 6902693 ns/iter (+/- 162810) -test wasm_instructions/wasm64/vmem/v128.load_unaligned ... bench: 5610537 ns/iter (+/- 21799) -test wasm_instructions/wasm64/vmem/v128.load_unaligned/confirmation ... bench: 10527805 ns/iter (+/- 34738) -test wasm_instructions/wasm32/vmem/v128.store ... bench: 3229315 ns/iter (+/- 36141) -test wasm_instructions/wasm32/vmem/v128.store/confirmation ... bench: 6026504 ns/iter (+/- 41706) -test wasm_instructions/wasm64/vmem/v128.store ... bench: 4219332 ns/iter (+/- 40653) -test wasm_instructions/wasm64/vmem/v128.store/confirmation ... bench: 8182595 ns/iter (+/- 35859) -test wasm_instructions/wasm32/vmem/v128.store_unaligned ... bench: 3209427 ns/iter (+/- 177700) -test wasm_instructions/wasm32/vmem/v128.store_unaligned/confirmation ... bench: 6003017 ns/iter (+/- 78103) -test wasm_instructions/wasm64/vmem/v128.store_unaligned ... bench: 4279375 ns/iter (+/- 401678) -test wasm_instructions/wasm64/vmem/v128.store_unaligned/confirmation ... bench: 8047101 ns/iter (+/- 36866) -test wasm_instructions/wasm32/vmem/v128.load8x8_s ... bench: 3729599 ns/iter (+/- 24069) -test wasm_instructions/wasm32/vmem/v128.load8x8_s/confirmation ... bench: 7004412 ns/iter (+/- 18623) -test wasm_instructions/wasm64/vmem/v128.load8x8_s ... bench: 5418335 ns/iter (+/- 342076) -test wasm_instructions/wasm64/vmem/v128.load8x8_s/confirmation ... bench: 10586834 ns/iter (+/- 46923) -test wasm_instructions/wasm32/vmem/v128.load8x8_u ... bench: 3698369 ns/iter (+/- 135979) -test wasm_instructions/wasm32/vmem/v128.load8x8_u/confirmation ... bench: 7020913 ns/iter (+/- 50377) -test wasm_instructions/wasm64/vmem/v128.load8x8_u ... bench: 5563080 ns/iter (+/- 61257) -test wasm_instructions/wasm64/vmem/v128.load8x8_u/confirmation ... bench: 10593877 ns/iter (+/- 152109) -test wasm_instructions/wasm32/vmem/v128.load16x4_s ... bench: 3777395 ns/iter (+/- 34273) -test wasm_instructions/wasm32/vmem/v128.load16x4_s/confirmation ... bench: 7067328 ns/iter (+/- 53580) -test wasm_instructions/wasm64/vmem/v128.load16x4_s ... bench: 5433627 ns/iter (+/- 40231) -test wasm_instructions/wasm64/vmem/v128.load16x4_s/confirmation ... bench: 10677819 ns/iter (+/- 173898) -test wasm_instructions/wasm32/vmem/v128.load16x4_u ... bench: 3902920 ns/iter (+/- 35460) -test wasm_instructions/wasm32/vmem/v128.load16x4_u/confirmation ... bench: 7093573 ns/iter (+/- 50201) -test wasm_instructions/wasm64/vmem/v128.load16x4_u ... bench: 5484179 ns/iter (+/- 73106) -test wasm_instructions/wasm64/vmem/v128.load16x4_u/confirmation ... bench: 10831970 ns/iter (+/- 69540) -test wasm_instructions/wasm32/vmem/v128.load32x2_s ... bench: 3988774 ns/iter (+/- 37474) -test wasm_instructions/wasm32/vmem/v128.load32x2_s/confirmation ... bench: 7113534 ns/iter (+/- 38976) -test wasm_instructions/wasm64/vmem/v128.load32x2_s ... bench: 5622727 ns/iter (+/- 20841) -test wasm_instructions/wasm64/vmem/v128.load32x2_s/confirmation ... bench: 10628094 ns/iter (+/- 371961) -test wasm_instructions/wasm32/vmem/v128.load32x2_u ... bench: 3725236 ns/iter (+/- 47970) -test wasm_instructions/wasm32/vmem/v128.load32x2_u/confirmation ... bench: 7066098 ns/iter (+/- 91186) -test wasm_instructions/wasm64/vmem/v128.load32x2_u ... bench: 5689022 ns/iter (+/- 97406) -test wasm_instructions/wasm64/vmem/v128.load32x2_u/confirmation ... bench: 10597187 ns/iter (+/- 180873) -test wasm_instructions/wasm32/vmem/v128.load32_zero ... bench: 3623447 ns/iter (+/- 94593) -test wasm_instructions/wasm32/vmem/v128.load32_zero/confirmation ... bench: 6962521 ns/iter (+/- 41761) -test wasm_instructions/wasm64/vmem/v128.load32_zero ... bench: 5461128 ns/iter (+/- 265231) -test wasm_instructions/wasm64/vmem/v128.load32_zero/confirmation ... bench: 10528534 ns/iter (+/- 229886) -test wasm_instructions/wasm32/vmem/v128.load64_zero ... bench: 3819340 ns/iter (+/- 26688) -test wasm_instructions/wasm32/vmem/v128.load64_zero/confirmation ... bench: 7035165 ns/iter (+/- 59758) -test wasm_instructions/wasm64/vmem/v128.load64_zero ... bench: 5405078 ns/iter (+/- 53876) -test wasm_instructions/wasm64/vmem/v128.load64_zero/confirmation ... bench: 10496706 ns/iter (+/- 58715) -test wasm_instructions/wasm32/vmem/v128.load8_splat ... bench: 3770445 ns/iter (+/- 158038) -test wasm_instructions/wasm32/vmem/v128.load8_splat/confirmation ... bench: 7074173 ns/iter (+/- 84107) -test wasm_instructions/wasm64/vmem/v128.load8_splat ... bench: 5548120 ns/iter (+/- 14806) -test wasm_instructions/wasm64/vmem/v128.load8_splat/confirmation ... bench: 10678530 ns/iter (+/- 70379) -test wasm_instructions/wasm32/vmem/v128.load16_splat ... bench: 3783711 ns/iter (+/- 28666) -test wasm_instructions/wasm32/vmem/v128.load16_splat/confirmation ... bench: 7002309 ns/iter (+/- 22424) -test wasm_instructions/wasm64/vmem/v128.load16_splat ... bench: 5495399 ns/iter (+/- 50252) -test wasm_instructions/wasm64/vmem/v128.load16_splat/confirmation ... bench: 10576538 ns/iter (+/- 144728) -test wasm_instructions/wasm32/vmem/v128.load32_splat ... bench: 3725284 ns/iter (+/- 27155) -test wasm_instructions/wasm32/vmem/v128.load32_splat/confirmation ... bench: 7238871 ns/iter (+/- 45700) -test wasm_instructions/wasm64/vmem/v128.load32_splat ... bench: 5605424 ns/iter (+/- 89594) -test wasm_instructions/wasm64/vmem/v128.load32_splat/confirmation ... bench: 10875291 ns/iter (+/- 227885) -test wasm_instructions/wasm32/vmem/v128.load64_splat ... bench: 3694125 ns/iter (+/- 51052) -test wasm_instructions/wasm32/vmem/v128.load64_splat/confirmation ... bench: 6959131 ns/iter (+/- 70518) -test wasm_instructions/wasm64/vmem/v128.load64_splat ... bench: 5410269 ns/iter (+/- 113411) -test wasm_instructions/wasm64/vmem/v128.load64_splat/confirmation ... bench: 10365809 ns/iter (+/- 16951) -test wasm_instructions/wasm32/vmem/v128.load8_lane ... bench: 3856525 ns/iter (+/- 25247) -test wasm_instructions/wasm32/vmem/v128.load8_lane/confirmation ... bench: 7342704 ns/iter (+/- 12062) -test wasm_instructions/wasm64/vmem/v128.load8_lane ... bench: 5649505 ns/iter (+/- 425696) -test wasm_instructions/wasm64/vmem/v128.load8_lane/confirmation ... bench: 11110676 ns/iter (+/- 42721) -test wasm_instructions/wasm32/vmem/v128.load16_lane ... bench: 3823720 ns/iter (+/- 39115) -test wasm_instructions/wasm32/vmem/v128.load16_lane/confirmation ... bench: 7241841 ns/iter (+/- 59501) -test wasm_instructions/wasm64/vmem/v128.load16_lane ... bench: 5551825 ns/iter (+/- 9560) -test wasm_instructions/wasm64/vmem/v128.load16_lane/confirmation ... bench: 10764672 ns/iter (+/- 50228) -test wasm_instructions/wasm32/vmem/v128.load32_lane ... bench: 3863946 ns/iter (+/- 59090) -test wasm_instructions/wasm32/vmem/v128.load32_lane/confirmation ... bench: 7336258 ns/iter (+/- 100896) -test wasm_instructions/wasm64/vmem/v128.load32_lane ... bench: 5884117 ns/iter (+/- 48627) -test wasm_instructions/wasm64/vmem/v128.load32_lane/confirmation ... bench: 10787373 ns/iter (+/- 168726) -test wasm_instructions/wasm32/vmem/v128.load64_lane ... bench: 3849765 ns/iter (+/- 37153) -test wasm_instructions/wasm32/vmem/v128.load64_lane/confirmation ... bench: 7366924 ns/iter (+/- 187448) -test wasm_instructions/wasm64/vmem/v128.load64_lane ... bench: 5620217 ns/iter (+/- 17585) -test wasm_instructions/wasm64/vmem/v128.load64_lane/confirmation ... bench: 10947634 ns/iter (+/- 391958) -test wasm_instructions/wasm32/vmem/v128.store8_lane ... bench: 3096206 ns/iter (+/- 170631) -test wasm_instructions/wasm32/vmem/v128.store8_lane/confirmation ... bench: 5931169 ns/iter (+/- 19200) -test wasm_instructions/wasm64/vmem/v128.store8_lane ... bench: 4640527 ns/iter (+/- 24937) -test wasm_instructions/wasm64/vmem/v128.store8_lane/confirmation ... bench: 8432655 ns/iter (+/- 11471) -test wasm_instructions/wasm32/vmem/v128.store16_lane ... bench: 3193934 ns/iter (+/- 24277) -test wasm_instructions/wasm32/vmem/v128.store16_lane/confirmation ... bench: 5913484 ns/iter (+/- 7232) -test wasm_instructions/wasm64/vmem/v128.store16_lane ... bench: 4419929 ns/iter (+/- 39637) -test wasm_instructions/wasm64/vmem/v128.store16_lane/confirmation ... bench: 8448007 ns/iter (+/- 151677) -test wasm_instructions/wasm32/vmem/v128.store32_lane ... bench: 3130276 ns/iter (+/- 237161) -test wasm_instructions/wasm32/vmem/v128.store32_lane/confirmation ... bench: 5996558 ns/iter (+/- 29811) -test wasm_instructions/wasm64/vmem/v128.store32_lane ... bench: 4422555 ns/iter (+/- 466551) -test wasm_instructions/wasm64/vmem/v128.store32_lane/confirmation ... bench: 8425291 ns/iter (+/- 22551) -test wasm_instructions/wasm32/vmem/v128.store64_lane ... bench: 3228062 ns/iter (+/- 12852) -test wasm_instructions/wasm32/vmem/v128.store64_lane/confirmation ... bench: 5982422 ns/iter (+/- 45658) -test wasm_instructions/wasm64/vmem/v128.store64_lane ... bench: 4441606 ns/iter (+/- 24847) -test wasm_instructions/wasm64/vmem/v128.store64_lane/confirmation ... bench: 8450296 ns/iter (+/- 39624) +test wasm_instructions/wasm32/overhead ... bench: 248204 ns/iter (+/- 17621) +test wasm_instructions/wasm32/overhead/confirmation ... bench: 2406637 ns/iter (+/- 150457) +test wasm_instructions/wasm64/overhead ... bench: 264607 ns/iter (+/- 17153) +test wasm_instructions/wasm64/overhead/confirmation ... bench: 2353089 ns/iter (+/- 56636) +test wasm_instructions/wasm32/const/i32.const ... bench: 2365907 ns/iter (+/- 84956) +test wasm_instructions/wasm32/const/i32.const/confirmation ... bench: 4573491 ns/iter (+/- 347708) +test wasm_instructions/wasm64/const/i32.const ... bench: 2394974 ns/iter (+/- 75890) +test wasm_instructions/wasm64/const/i32.const/confirmation ... bench: 4531972 ns/iter (+/- 372668) +test wasm_instructions/wasm32/const/i64.const ... bench: 2380950 ns/iter (+/- 110122) +test wasm_instructions/wasm32/const/i64.const/confirmation ... bench: 4564083 ns/iter (+/- 347326) +test wasm_instructions/wasm64/const/i64.const ... bench: 2390484 ns/iter (+/- 150392) +test wasm_instructions/wasm64/const/i64.const/confirmation ... bench: 4578533 ns/iter (+/- 402417) +test wasm_instructions/wasm32/const/f32.const ... bench: 2967801 ns/iter (+/- 160846) +test wasm_instructions/wasm32/const/f32.const/confirmation ... bench: 5944467 ns/iter (+/- 34182) +test wasm_instructions/wasm64/const/f32.const ... bench: 3022993 ns/iter (+/- 172115) +test wasm_instructions/wasm64/const/f32.const/confirmation ... bench: 5760930 ns/iter (+/- 420357) +test wasm_instructions/wasm32/const/f64.const ... bench: 4572233 ns/iter (+/- 200526) +test wasm_instructions/wasm32/const/f64.const/confirmation ... bench: 8860290 ns/iter (+/- 37779) +test wasm_instructions/wasm64/const/f64.const ... bench: 4587780 ns/iter (+/- 334478) +test wasm_instructions/wasm64/const/f64.const/confirmation ... bench: 8841605 ns/iter (+/- 48888) +test wasm_instructions/wasm32/iunop/i32.clz ... bench: 2385685 ns/iter (+/- 145077) +test wasm_instructions/wasm32/iunop/i32.clz/confirmation ... bench: 4576239 ns/iter (+/- 244614) +test wasm_instructions/wasm64/iunop/i32.clz ... bench: 2362762 ns/iter (+/- 27750) +test wasm_instructions/wasm64/iunop/i32.clz/confirmation ... bench: 4562586 ns/iter (+/- 490919) +test wasm_instructions/wasm32/iunop/i32.ctz ... bench: 2373175 ns/iter (+/- 168924) +test wasm_instructions/wasm32/iunop/i32.ctz/confirmation ... bench: 4532503 ns/iter (+/- 511838) +test wasm_instructions/wasm64/iunop/i32.ctz ... bench: 2408803 ns/iter (+/- 126275) +test wasm_instructions/wasm64/iunop/i32.ctz/confirmation ... bench: 4600022 ns/iter (+/- 318946) +test wasm_instructions/wasm32/iunop/i32.popcnt ... bench: 2368171 ns/iter (+/- 10200) +test wasm_instructions/wasm32/iunop/i32.popcnt/confirmation ... bench: 4576668 ns/iter (+/- 220452) +test wasm_instructions/wasm64/iunop/i32.popcnt ... bench: 2376709 ns/iter (+/- 144516) +test wasm_instructions/wasm64/iunop/i32.popcnt/confirmation ... bench: 4561779 ns/iter (+/- 30342) +test wasm_instructions/wasm32/iunop/i64.clz ... bench: 2350769 ns/iter (+/- 98361) +test wasm_instructions/wasm32/iunop/i64.clz/confirmation ... bench: 4540871 ns/iter (+/- 423666) +test wasm_instructions/wasm64/iunop/i64.clz ... bench: 2437721 ns/iter (+/- 18046) +test wasm_instructions/wasm64/iunop/i64.clz/confirmation ... bench: 4567146 ns/iter (+/- 361023) +test wasm_instructions/wasm32/iunop/i64.ctz ... bench: 2399298 ns/iter (+/- 52523) +test wasm_instructions/wasm32/iunop/i64.ctz/confirmation ... bench: 4654737 ns/iter (+/- 50519) +test wasm_instructions/wasm64/iunop/i64.ctz ... bench: 2378427 ns/iter (+/- 61860) +test wasm_instructions/wasm64/iunop/i64.ctz/confirmation ... bench: 4539743 ns/iter (+/- 292140) +test wasm_instructions/wasm32/iunop/i64.popcnt ... bench: 2392343 ns/iter (+/- 171297) +test wasm_instructions/wasm32/iunop/i64.popcnt/confirmation ... bench: 4557570 ns/iter (+/- 191769) +test wasm_instructions/wasm64/iunop/i64.popcnt ... bench: 2402381 ns/iter (+/- 34562) +test wasm_instructions/wasm64/iunop/i64.popcnt/confirmation ... bench: 4569009 ns/iter (+/- 357645) +test wasm_instructions/wasm32/funop/f32.abs ... bench: 3450160 ns/iter (+/- 451292) +test wasm_instructions/wasm32/funop/f32.abs/confirmation ... bench: 6675470 ns/iter (+/- 102825) +test wasm_instructions/wasm64/funop/f32.abs ... bench: 3442119 ns/iter (+/- 398054) +test wasm_instructions/wasm64/funop/f32.abs/confirmation ... bench: 6685673 ns/iter (+/- 841663) +test wasm_instructions/wasm32/funop/f32.neg ... bench: 3496834 ns/iter (+/- 138706) +test wasm_instructions/wasm32/funop/f32.neg/confirmation ... bench: 6745212 ns/iter (+/- 302436) +test wasm_instructions/wasm64/funop/f32.neg ... bench: 3459536 ns/iter (+/- 170174) +test wasm_instructions/wasm64/funop/f32.neg/confirmation ... bench: 6689456 ns/iter (+/- 239752) +test wasm_instructions/wasm32/funop/f64.abs ... bench: 5083917 ns/iter (+/- 36697) +test wasm_instructions/wasm32/funop/f64.abs/confirmation ... bench: 10336099 ns/iter (+/- 33983) +test wasm_instructions/wasm64/funop/f64.abs ... bench: 5105983 ns/iter (+/- 320871) +test wasm_instructions/wasm64/funop/f64.abs/confirmation ... bench: 9922486 ns/iter (+/- 588980) +test wasm_instructions/wasm32/funop/f64.neg ... bench: 5104996 ns/iter (+/- 78592) +test wasm_instructions/wasm32/funop/f64.neg/confirmation ... bench: 10033049 ns/iter (+/- 343161) +test wasm_instructions/wasm64/funop/f64.neg ... bench: 5114261 ns/iter (+/- 12046) +test wasm_instructions/wasm64/funop/f64.neg/confirmation ... bench: 9914035 ns/iter (+/- 64684) +test wasm_instructions/wasm32/funop/f32.ceil ... bench: 5331261 ns/iter (+/- 33751) +test wasm_instructions/wasm32/funop/f32.ceil/confirmation ... bench: 10231147 ns/iter (+/- 247762) +test wasm_instructions/wasm64/funop/f32.ceil ... bench: 5249852 ns/iter (+/- 73052) +test wasm_instructions/wasm64/funop/f32.ceil/confirmation ... bench: 10791399 ns/iter (+/- 139962) +test wasm_instructions/wasm32/funop/f32.floor ... bench: 5281915 ns/iter (+/- 72179) +test wasm_instructions/wasm32/funop/f32.floor/confirmation ... bench: 10383841 ns/iter (+/- 65231) +test wasm_instructions/wasm64/funop/f32.floor ... bench: 5270914 ns/iter (+/- 261891) +test wasm_instructions/wasm64/funop/f32.floor/confirmation ... bench: 10371089 ns/iter (+/- 623754) +test wasm_instructions/wasm32/funop/f32.trunc ... bench: 5213386 ns/iter (+/- 522444) +test wasm_instructions/wasm32/funop/f32.trunc/confirmation ... bench: 10462018 ns/iter (+/- 181009) +test wasm_instructions/wasm64/funop/f32.trunc ... bench: 5378802 ns/iter (+/- 288949) +test wasm_instructions/wasm64/funop/f32.trunc/confirmation ... bench: 10447342 ns/iter (+/- 63309) +test wasm_instructions/wasm32/funop/f32.nearest ... bench: 5226136 ns/iter (+/- 117747) +test wasm_instructions/wasm32/funop/f32.nearest/confirmation ... bench: 10133146 ns/iter (+/- 481677) +test wasm_instructions/wasm64/funop/f32.nearest ... bench: 5235604 ns/iter (+/- 503535) +test wasm_instructions/wasm64/funop/f32.nearest/confirmation ... bench: 10169476 ns/iter (+/- 61228) +test wasm_instructions/wasm32/funop/f64.ceil ... bench: 5923356 ns/iter (+/- 305000) +test wasm_instructions/wasm32/funop/f64.ceil/confirmation ... bench: 11617546 ns/iter (+/- 100080) +test wasm_instructions/wasm64/funop/f64.ceil ... bench: 5908758 ns/iter (+/- 40073) +test wasm_instructions/wasm64/funop/f64.ceil/confirmation ... bench: 12158075 ns/iter (+/- 957491) +test wasm_instructions/wasm32/funop/f64.floor ... bench: 5886181 ns/iter (+/- 413820) +test wasm_instructions/wasm32/funop/f64.floor/confirmation ... bench: 11533582 ns/iter (+/- 355183) +test wasm_instructions/wasm64/funop/f64.floor ... bench: 5924156 ns/iter (+/- 48267) +test wasm_instructions/wasm64/funop/f64.floor/confirmation ... bench: 11827228 ns/iter (+/- 35974) +test wasm_instructions/wasm32/funop/f64.trunc ... bench: 5992530 ns/iter (+/- 129640) +test wasm_instructions/wasm32/funop/f64.trunc/confirmation ... bench: 11531502 ns/iter (+/- 64544) +test wasm_instructions/wasm64/funop/f64.trunc ... bench: 5942819 ns/iter (+/- 311684) +test wasm_instructions/wasm64/funop/f64.trunc/confirmation ... bench: 11805743 ns/iter (+/- 129917) +test wasm_instructions/wasm32/funop/f64.nearest ... bench: 5900828 ns/iter (+/- 308552) +test wasm_instructions/wasm32/funop/f64.nearest/confirmation ... bench: 11640364 ns/iter (+/- 916389) +test wasm_instructions/wasm64/funop/f64.nearest ... bench: 5942542 ns/iter (+/- 21428) +test wasm_instructions/wasm64/funop/f64.nearest/confirmation ... bench: 11825088 ns/iter (+/- 41615) +test wasm_instructions/wasm32/funop/f32.sqrt ... bench: 12019078 ns/iter (+/- 961196) +test wasm_instructions/wasm32/funop/f32.sqrt/confirmation ... bench: 23788690 ns/iter (+/- 40689) +test wasm_instructions/wasm64/funop/f32.sqrt ... bench: 12051003 ns/iter (+/- 470855) +test wasm_instructions/wasm64/funop/f32.sqrt/confirmation ... bench: 24025128 ns/iter (+/- 727768) +test wasm_instructions/wasm32/funop/f64.sqrt ... bench: 19235322 ns/iter (+/- 683362) +test wasm_instructions/wasm32/funop/f64.sqrt/confirmation ... bench: 38735012 ns/iter (+/- 323641) +test wasm_instructions/wasm64/funop/f64.sqrt ... bench: 19242184 ns/iter (+/- 774219) +test wasm_instructions/wasm64/funop/f64.sqrt/confirmation ... bench: 36793804 ns/iter (+/- 762998) +test wasm_instructions/wasm32/ibinop/i32.add ... bench: 2377303 ns/iter (+/- 111108) +test wasm_instructions/wasm32/ibinop/i32.add/confirmation ... bench: 4566326 ns/iter (+/- 329584) +test wasm_instructions/wasm64/ibinop/i32.add ... bench: 2408907 ns/iter (+/- 21186) +test wasm_instructions/wasm64/ibinop/i32.add/confirmation ... bench: 4554109 ns/iter (+/- 555119) +test wasm_instructions/wasm32/ibinop/i32.sub ... bench: 2404107 ns/iter (+/- 139131) +test wasm_instructions/wasm32/ibinop/i32.sub/confirmation ... bench: 4578249 ns/iter (+/- 154879) +test wasm_instructions/wasm64/ibinop/i32.sub ... bench: 2365408 ns/iter (+/- 34080) +test wasm_instructions/wasm64/ibinop/i32.sub/confirmation ... bench: 4550471 ns/iter (+/- 261743) +test wasm_instructions/wasm32/ibinop/i32.mul ... bench: 2382985 ns/iter (+/- 35906) +test wasm_instructions/wasm32/ibinop/i32.mul/confirmation ... bench: 4687739 ns/iter (+/- 59982) +test wasm_instructions/wasm64/ibinop/i32.mul ... bench: 2359706 ns/iter (+/- 90861) +test wasm_instructions/wasm64/ibinop/i32.mul/confirmation ... bench: 4562876 ns/iter (+/- 332995) +test wasm_instructions/wasm32/ibinop/i32.and ... bench: 2381066 ns/iter (+/- 117867) +test wasm_instructions/wasm32/ibinop/i32.and/confirmation ... bench: 4604055 ns/iter (+/- 114514) +test wasm_instructions/wasm64/ibinop/i32.and ... bench: 2391951 ns/iter (+/- 201328) +test wasm_instructions/wasm64/ibinop/i32.and/confirmation ... bench: 4601132 ns/iter (+/- 27551) +test wasm_instructions/wasm32/ibinop/i32.or ... bench: 2383785 ns/iter (+/- 11487) +test wasm_instructions/wasm32/ibinop/i32.or/confirmation ... bench: 4562054 ns/iter (+/- 686642) +test wasm_instructions/wasm64/ibinop/i32.or ... bench: 2391424 ns/iter (+/- 112300) +test wasm_instructions/wasm64/ibinop/i32.or/confirmation ... bench: 4563618 ns/iter (+/- 365067) +test wasm_instructions/wasm32/ibinop/i32.xor ... bench: 2403413 ns/iter (+/- 125445) +test wasm_instructions/wasm32/ibinop/i32.xor/confirmation ... bench: 4529161 ns/iter (+/- 275928) +test wasm_instructions/wasm64/ibinop/i32.xor ... bench: 2395292 ns/iter (+/- 31591) +test wasm_instructions/wasm64/ibinop/i32.xor/confirmation ... bench: 4598361 ns/iter (+/- 27550) +test wasm_instructions/wasm32/ibinop/i32.shl ... bench: 2376973 ns/iter (+/- 36473) +test wasm_instructions/wasm32/ibinop/i32.shl/confirmation ... bench: 4543131 ns/iter (+/- 109985) +test wasm_instructions/wasm64/ibinop/i32.shl ... bench: 2415333 ns/iter (+/- 11483) +test wasm_instructions/wasm64/ibinop/i32.shl/confirmation ... bench: 4581174 ns/iter (+/- 339290) +test wasm_instructions/wasm32/ibinop/i32.shr_s ... bench: 2382769 ns/iter (+/- 118415) +test wasm_instructions/wasm32/ibinop/i32.shr_s/confirmation ... bench: 4579864 ns/iter (+/- 15434) +test wasm_instructions/wasm64/ibinop/i32.shr_s ... bench: 2377989 ns/iter (+/- 141011) +test wasm_instructions/wasm64/ibinop/i32.shr_s/confirmation ... bench: 4570983 ns/iter (+/- 462010) +test wasm_instructions/wasm32/ibinop/i32.shr_u ... bench: 2373822 ns/iter (+/- 189204) +test wasm_instructions/wasm32/ibinop/i32.shr_u/confirmation ... bench: 4530168 ns/iter (+/- 669846) +test wasm_instructions/wasm64/ibinop/i32.shr_u ... bench: 2386728 ns/iter (+/- 89920) +test wasm_instructions/wasm64/ibinop/i32.shr_u/confirmation ... bench: 4558739 ns/iter (+/- 129717) +test wasm_instructions/wasm32/ibinop/i32.rotl ... bench: 2342547 ns/iter (+/- 10453) +test wasm_instructions/wasm32/ibinop/i32.rotl/confirmation ... bench: 4563569 ns/iter (+/- 24605) +test wasm_instructions/wasm64/ibinop/i32.rotl ... bench: 2437363 ns/iter (+/- 87976) +test wasm_instructions/wasm64/ibinop/i32.rotl/confirmation ... bench: 4588888 ns/iter (+/- 111060) +test wasm_instructions/wasm32/ibinop/i32.rotr ... bench: 2400941 ns/iter (+/- 25983) +test wasm_instructions/wasm32/ibinop/i32.rotr/confirmation ... bench: 4540493 ns/iter (+/- 606664) +test wasm_instructions/wasm64/ibinop/i32.rotr ... bench: 2390065 ns/iter (+/- 143360) +test wasm_instructions/wasm64/ibinop/i32.rotr/confirmation ... bench: 4573276 ns/iter (+/- 282945) +test wasm_instructions/wasm32/ibinop/i64.add ... bench: 2429296 ns/iter (+/- 49074) +test wasm_instructions/wasm32/ibinop/i64.add/confirmation ... bench: 4562513 ns/iter (+/- 29221) +test wasm_instructions/wasm64/ibinop/i64.add ... bench: 2409404 ns/iter (+/- 19479) +test wasm_instructions/wasm64/ibinop/i64.add/confirmation ... bench: 4580372 ns/iter (+/- 505232) +test wasm_instructions/wasm32/ibinop/i64.sub ... bench: 2394165 ns/iter (+/- 133981) +test wasm_instructions/wasm32/ibinop/i64.sub/confirmation ... bench: 4594414 ns/iter (+/- 71861) +test wasm_instructions/wasm64/ibinop/i64.sub ... bench: 2366229 ns/iter (+/- 22840) +test wasm_instructions/wasm64/ibinop/i64.sub/confirmation ... bench: 4578276 ns/iter (+/- 286176) +test wasm_instructions/wasm32/ibinop/i64.mul ... bench: 2371910 ns/iter (+/- 148111) +test wasm_instructions/wasm32/ibinop/i64.mul/confirmation ... bench: 4591277 ns/iter (+/- 15119) +test wasm_instructions/wasm64/ibinop/i64.mul ... bench: 2396054 ns/iter (+/- 41730) +test wasm_instructions/wasm64/ibinop/i64.mul/confirmation ... bench: 4570514 ns/iter (+/- 514942) +test wasm_instructions/wasm32/ibinop/i64.and ... bench: 2408674 ns/iter (+/- 61186) +test wasm_instructions/wasm32/ibinop/i64.and/confirmation ... bench: 4561709 ns/iter (+/- 295191) +test wasm_instructions/wasm64/ibinop/i64.and ... bench: 2410742 ns/iter (+/- 14762) +test wasm_instructions/wasm64/ibinop/i64.and/confirmation ... bench: 4548901 ns/iter (+/- 393895) +test wasm_instructions/wasm32/ibinop/i64.or ... bench: 2375360 ns/iter (+/- 238753) +test wasm_instructions/wasm32/ibinop/i64.or/confirmation ... bench: 4530678 ns/iter (+/- 454048) +test wasm_instructions/wasm64/ibinop/i64.or ... bench: 2417340 ns/iter (+/- 260843) +test wasm_instructions/wasm64/ibinop/i64.or/confirmation ... bench: 4585764 ns/iter (+/- 35935) +test wasm_instructions/wasm32/ibinop/i64.xor ... bench: 2342803 ns/iter (+/- 19488) +test wasm_instructions/wasm32/ibinop/i64.xor/confirmation ... bench: 4588737 ns/iter (+/- 52021) +test wasm_instructions/wasm64/ibinop/i64.xor ... bench: 2404971 ns/iter (+/- 36316) +test wasm_instructions/wasm64/ibinop/i64.xor/confirmation ... bench: 4663678 ns/iter (+/- 420517) +test wasm_instructions/wasm32/ibinop/i64.shl ... bench: 2388754 ns/iter (+/- 197702) +test wasm_instructions/wasm32/ibinop/i64.shl/confirmation ... bench: 4564203 ns/iter (+/- 29007) +test wasm_instructions/wasm64/ibinop/i64.shl ... bench: 2379261 ns/iter (+/- 102845) +test wasm_instructions/wasm64/ibinop/i64.shl/confirmation ... bench: 4640495 ns/iter (+/- 292972) +test wasm_instructions/wasm32/ibinop/i64.shr_s ... bench: 2370987 ns/iter (+/- 151658) +test wasm_instructions/wasm32/ibinop/i64.shr_s/confirmation ... bench: 4638730 ns/iter (+/- 34479) +test wasm_instructions/wasm64/ibinop/i64.shr_s ... bench: 2447423 ns/iter (+/- 111339) +test wasm_instructions/wasm64/ibinop/i64.shr_s/confirmation ... bench: 4573027 ns/iter (+/- 681289) +test wasm_instructions/wasm32/ibinop/i64.shr_u ... bench: 2429865 ns/iter (+/- 31065) +test wasm_instructions/wasm32/ibinop/i64.shr_u/confirmation ... bench: 4562983 ns/iter (+/- 40260) +test wasm_instructions/wasm64/ibinop/i64.shr_u ... bench: 2402524 ns/iter (+/- 270533) +test wasm_instructions/wasm64/ibinop/i64.shr_u/confirmation ... bench: 4566333 ns/iter (+/- 265927) +test wasm_instructions/wasm32/ibinop/i64.rotl ... bench: 2415441 ns/iter (+/- 140496) +test wasm_instructions/wasm32/ibinop/i64.rotl/confirmation ... bench: 4553314 ns/iter (+/- 310570) +test wasm_instructions/wasm64/ibinop/i64.rotl ... bench: 2420006 ns/iter (+/- 61812) +test wasm_instructions/wasm64/ibinop/i64.rotl/confirmation ... bench: 4571742 ns/iter (+/- 33228) +test wasm_instructions/wasm32/ibinop/i64.rotr ... bench: 2375826 ns/iter (+/- 22910) +test wasm_instructions/wasm32/ibinop/i64.rotr/confirmation ... bench: 4564148 ns/iter (+/- 20901) +test wasm_instructions/wasm64/ibinop/i64.rotr ... bench: 2379038 ns/iter (+/- 8139) +test wasm_instructions/wasm64/ibinop/i64.rotr/confirmation ... bench: 4574663 ns/iter (+/- 320869) +test wasm_instructions/wasm32/ibinop/i32.div_s ... bench: 49232726 ns/iter (+/- 35067) +test wasm_instructions/wasm32/ibinop/i32.div_s/confirmation ... bench: 98188793 ns/iter (+/- 235774) +test wasm_instructions/wasm64/ibinop/i32.div_s ... bench: 49206192 ns/iter (+/- 688301) +test wasm_instructions/wasm64/ibinop/i32.div_s/confirmation ... bench: 98187618 ns/iter (+/- 515744) +test wasm_instructions/wasm32/ibinop/i32.div_u ... bench: 49245638 ns/iter (+/- 102214) +test wasm_instructions/wasm32/ibinop/i32.div_u/confirmation ... bench: 98171348 ns/iter (+/- 61369) +test wasm_instructions/wasm64/ibinop/i32.div_u ... bench: 49239256 ns/iter (+/- 232304) +test wasm_instructions/wasm64/ibinop/i32.div_u/confirmation ... bench: 98157936 ns/iter (+/- 372190) +test wasm_instructions/wasm32/ibinop/i32.rem_s ... bench: 49219176 ns/iter (+/- 744077) +test wasm_instructions/wasm32/ibinop/i32.rem_s/confirmation ... bench: 98186268 ns/iter (+/- 75133) +test wasm_instructions/wasm64/ibinop/i32.rem_s ... bench: 49243052 ns/iter (+/- 660561) +test wasm_instructions/wasm64/ibinop/i32.rem_s/confirmation ... bench: 98242893 ns/iter (+/- 229386) +test wasm_instructions/wasm32/ibinop/i32.rem_u ... bench: 49240792 ns/iter (+/- 30048) +test wasm_instructions/wasm32/ibinop/i32.rem_u/confirmation ... bench: 98146985 ns/iter (+/- 47615) +test wasm_instructions/wasm64/ibinop/i32.rem_u ... bench: 49239671 ns/iter (+/- 873442) +test wasm_instructions/wasm64/ibinop/i32.rem_u/confirmation ... bench: 98161742 ns/iter (+/- 38852) +test wasm_instructions/wasm32/ibinop/i64.div_s ... bench: 49211808 ns/iter (+/- 594986) +test wasm_instructions/wasm32/ibinop/i64.div_s/confirmation ... bench: 98170567 ns/iter (+/- 1036049) +test wasm_instructions/wasm64/ibinop/i64.div_s ... bench: 49254003 ns/iter (+/- 658623) +test wasm_instructions/wasm64/ibinop/i64.div_s/confirmation ... bench: 98169024 ns/iter (+/- 129183) +test wasm_instructions/wasm32/ibinop/i64.div_u ... bench: 49255492 ns/iter (+/- 1078465) +test wasm_instructions/wasm32/ibinop/i64.div_u/confirmation ... bench: 98125908 ns/iter (+/- 429709) +test wasm_instructions/wasm64/ibinop/i64.div_u ... bench: 49249328 ns/iter (+/- 742284) +test wasm_instructions/wasm64/ibinop/i64.div_u/confirmation ... bench: 98156640 ns/iter (+/- 119262) +test wasm_instructions/wasm32/ibinop/i64.rem_s ... bench: 49249292 ns/iter (+/- 907927) +test wasm_instructions/wasm32/ibinop/i64.rem_s/confirmation ... bench: 98174742 ns/iter (+/- 50854) +test wasm_instructions/wasm64/ibinop/i64.rem_s ... bench: 49261748 ns/iter (+/- 1063427) +test wasm_instructions/wasm64/ibinop/i64.rem_s/confirmation ... bench: 98211452 ns/iter (+/- 75220) +test wasm_instructions/wasm32/ibinop/i64.rem_u ... bench: 49246617 ns/iter (+/- 673347) +test wasm_instructions/wasm32/ibinop/i64.rem_u/confirmation ... bench: 98150516 ns/iter (+/- 267862) +test wasm_instructions/wasm64/ibinop/i64.rem_u ... bench: 49257894 ns/iter (+/- 1048403) +test wasm_instructions/wasm64/ibinop/i64.rem_u/confirmation ... bench: 98175009 ns/iter (+/- 244366) +test wasm_instructions/wasm32/fbinop/f32.add ... bench: 4808294 ns/iter (+/- 434258) +test wasm_instructions/wasm32/fbinop/f32.add/confirmation ... bench: 9453893 ns/iter (+/- 72351) +test wasm_instructions/wasm64/fbinop/f32.add ... bench: 4861283 ns/iter (+/- 18302) +test wasm_instructions/wasm64/fbinop/f32.add/confirmation ... bench: 9672330 ns/iter (+/- 35191) +test wasm_instructions/wasm32/fbinop/f32.sub ... bench: 4882765 ns/iter (+/- 550698) +test wasm_instructions/wasm32/fbinop/f32.sub/confirmation ... bench: 9994513 ns/iter (+/- 46205) +test wasm_instructions/wasm64/fbinop/f32.sub ... bench: 4828761 ns/iter (+/- 22268) +test wasm_instructions/wasm64/fbinop/f32.sub/confirmation ... bench: 9535535 ns/iter (+/- 697005) +test wasm_instructions/wasm32/fbinop/f32.mul ... bench: 4796438 ns/iter (+/- 83165) +test wasm_instructions/wasm32/fbinop/f32.mul/confirmation ... bench: 9546703 ns/iter (+/- 889233) +test wasm_instructions/wasm64/fbinop/f32.mul ... bench: 4935115 ns/iter (+/- 42429) +test wasm_instructions/wasm64/fbinop/f32.mul/confirmation ... bench: 9369603 ns/iter (+/- 344580) +test wasm_instructions/wasm32/fbinop/f64.add ... bench: 5774691 ns/iter (+/- 24514) +test wasm_instructions/wasm32/fbinop/f64.add/confirmation ... bench: 11612768 ns/iter (+/- 235612) +test wasm_instructions/wasm64/fbinop/f64.add ... bench: 5793883 ns/iter (+/- 30400) +test wasm_instructions/wasm64/fbinop/f64.add/confirmation ... bench: 11569748 ns/iter (+/- 45757) +test wasm_instructions/wasm32/fbinop/f64.sub ... bench: 5778566 ns/iter (+/- 357689) +test wasm_instructions/wasm32/fbinop/f64.sub/confirmation ... bench: 11353548 ns/iter (+/- 47749) +test wasm_instructions/wasm64/fbinop/f64.sub ... bench: 5873797 ns/iter (+/- 44800) +test wasm_instructions/wasm64/fbinop/f64.sub/confirmation ... bench: 11297867 ns/iter (+/- 95599) +test wasm_instructions/wasm32/fbinop/f64.mul ... bench: 5817162 ns/iter (+/- 359190) +test wasm_instructions/wasm32/fbinop/f64.mul/confirmation ... bench: 11443774 ns/iter (+/- 388755) +test wasm_instructions/wasm64/fbinop/f64.mul ... bench: 5767708 ns/iter (+/- 14818) +test wasm_instructions/wasm64/fbinop/f64.mul/confirmation ... bench: 11563025 ns/iter (+/- 53552) +test wasm_instructions/wasm32/fbinop/f32.div ... bench: 7967091 ns/iter (+/- 44752) +test wasm_instructions/wasm32/fbinop/f32.div/confirmation ... bench: 15462374 ns/iter (+/- 89011) +test wasm_instructions/wasm64/fbinop/f32.div ... bench: 8452900 ns/iter (+/- 415232) +test wasm_instructions/wasm64/fbinop/f32.div/confirmation ... bench: 15652747 ns/iter (+/- 624595) +test wasm_instructions/wasm32/fbinop/f64.div ... bench: 10947112 ns/iter (+/- 19070) +test wasm_instructions/wasm32/fbinop/f64.div/confirmation ... bench: 21601469 ns/iter (+/- 358353) +test wasm_instructions/wasm64/fbinop/f64.div ... bench: 10974269 ns/iter (+/- 17416) +test wasm_instructions/wasm64/fbinop/f64.div/confirmation ... bench: 21755790 ns/iter (+/- 97968) +test wasm_instructions/wasm32/fbinop/f32.min ... bench: 51395667 ns/iter (+/- 505676) +test wasm_instructions/wasm32/fbinop/f32.min/confirmation ... bench: 121067317 ns/iter (+/- 716718) +test wasm_instructions/wasm64/fbinop/f32.min ... bench: 51550485 ns/iter (+/- 164503) +test wasm_instructions/wasm64/fbinop/f32.min/confirmation ... bench: 121240965 ns/iter (+/- 760405) +test wasm_instructions/wasm32/fbinop/f32.max ... bench: 51366361 ns/iter (+/- 900039) +test wasm_instructions/wasm32/fbinop/f32.max/confirmation ... bench: 121560984 ns/iter (+/- 300531) +test wasm_instructions/wasm64/fbinop/f32.max ... bench: 51513009 ns/iter (+/- 1016671) +test wasm_instructions/wasm64/fbinop/f32.max/confirmation ... bench: 121460865 ns/iter (+/- 629770) +test wasm_instructions/wasm32/fbinop/f64.min ... bench: 52024465 ns/iter (+/- 1345238) +test wasm_instructions/wasm32/fbinop/f64.min/confirmation ... bench: 123472674 ns/iter (+/- 687878) +test wasm_instructions/wasm64/fbinop/f64.min ... bench: 51897893 ns/iter (+/- 355956) +test wasm_instructions/wasm64/fbinop/f64.min/confirmation ... bench: 123100578 ns/iter (+/- 322661) +test wasm_instructions/wasm32/fbinop/f64.max ... bench: 52159242 ns/iter (+/- 253864) +test wasm_instructions/wasm32/fbinop/f64.max/confirmation ... bench: 123650365 ns/iter (+/- 321496) +test wasm_instructions/wasm64/fbinop/f64.max ... bench: 52016739 ns/iter (+/- 755423) +test wasm_instructions/wasm64/fbinop/f64.max/confirmation ... bench: 123586093 ns/iter (+/- 301644) +test wasm_instructions/wasm32/fbinop/f32.copysign ... bench: 4576257 ns/iter (+/- 39827) +test wasm_instructions/wasm32/fbinop/f32.copysign/confirmation ... bench: 8876597 ns/iter (+/- 51113) +test wasm_instructions/wasm64/fbinop/f32.copysign ... bench: 4552946 ns/iter (+/- 625539) +test wasm_instructions/wasm64/fbinop/f32.copysign/confirmation ... bench: 8845947 ns/iter (+/- 982468) +test wasm_instructions/wasm32/fbinop/f64.copysign ... bench: 6709319 ns/iter (+/- 243006) +test wasm_instructions/wasm32/fbinop/f64.copysign/confirmation ... bench: 13120587 ns/iter (+/- 68716) +test wasm_instructions/wasm64/fbinop/f64.copysign ... bench: 6715606 ns/iter (+/- 473928) +test wasm_instructions/wasm64/fbinop/f64.copysign/confirmation ... bench: 13377973 ns/iter (+/- 315081) +test wasm_instructions/wasm32/itestop/i32.eqz ... bench: 2741152 ns/iter (+/- 17499) +test wasm_instructions/wasm32/itestop/i32.eqz/confirmation ... bench: 5259052 ns/iter (+/- 780627) +test wasm_instructions/wasm64/itestop/i32.eqz ... bench: 2782509 ns/iter (+/- 14610) +test wasm_instructions/wasm64/itestop/i32.eqz/confirmation ... bench: 5258509 ns/iter (+/- 292958) +test wasm_instructions/wasm32/itestop/i64.eqz ... bench: 2603130 ns/iter (+/- 98482) +test wasm_instructions/wasm32/itestop/i64.eqz/confirmation ... bench: 5053350 ns/iter (+/- 354316) +test wasm_instructions/wasm64/itestop/i64.eqz ... bench: 2623218 ns/iter (+/- 269506) +test wasm_instructions/wasm64/itestop/i64.eqz/confirmation ... bench: 5011129 ns/iter (+/- 353303) +test wasm_instructions/wasm32/irelop/i32.eq ... bench: 2603046 ns/iter (+/- 116162) +test wasm_instructions/wasm32/irelop/i32.eq/confirmation ... bench: 4992351 ns/iter (+/- 331471) +test wasm_instructions/wasm64/irelop/i32.eq ... bench: 2672653 ns/iter (+/- 38686) +test wasm_instructions/wasm64/irelop/i32.eq/confirmation ... bench: 5037507 ns/iter (+/- 34217) +test wasm_instructions/wasm32/irelop/i32.ne ... bench: 2612438 ns/iter (+/- 43615) +test wasm_instructions/wasm32/irelop/i32.ne/confirmation ... bench: 5075075 ns/iter (+/- 130765) +test wasm_instructions/wasm64/irelop/i32.ne ... bench: 2619017 ns/iter (+/- 161387) +test wasm_instructions/wasm64/irelop/i32.ne/confirmation ... bench: 5028584 ns/iter (+/- 77047) +test wasm_instructions/wasm32/irelop/i32.lt_s ... bench: 2617563 ns/iter (+/- 128761) +test wasm_instructions/wasm32/irelop/i32.lt_s/confirmation ... bench: 5024139 ns/iter (+/- 119173) +test wasm_instructions/wasm64/irelop/i32.lt_s ... bench: 2591842 ns/iter (+/- 20789) +test wasm_instructions/wasm64/irelop/i32.lt_s/confirmation ... bench: 5015738 ns/iter (+/- 239105) +test wasm_instructions/wasm32/irelop/i32.lt_u ... bench: 2648089 ns/iter (+/- 17421) +test wasm_instructions/wasm32/irelop/i32.lt_u/confirmation ... bench: 5182630 ns/iter (+/- 37805) +test wasm_instructions/wasm64/irelop/i32.lt_u ... bench: 2653401 ns/iter (+/- 206188) +test wasm_instructions/wasm64/irelop/i32.lt_u/confirmation ... bench: 5022106 ns/iter (+/- 444446) +test wasm_instructions/wasm32/irelop/i32.gt_s ... bench: 2589067 ns/iter (+/- 125613) +test wasm_instructions/wasm32/irelop/i32.gt_s/confirmation ... bench: 4986756 ns/iter (+/- 586760) +test wasm_instructions/wasm64/irelop/i32.gt_s ... bench: 2582656 ns/iter (+/- 12850) +test wasm_instructions/wasm64/irelop/i32.gt_s/confirmation ... bench: 5015214 ns/iter (+/- 282565) +test wasm_instructions/wasm32/irelop/i32.gt_u ... bench: 2565478 ns/iter (+/- 19318) +test wasm_instructions/wasm32/irelop/i32.gt_u/confirmation ... bench: 4956572 ns/iter (+/- 613842) +test wasm_instructions/wasm64/irelop/i32.gt_u ... bench: 2656240 ns/iter (+/- 258863) +test wasm_instructions/wasm64/irelop/i32.gt_u/confirmation ... bench: 5032266 ns/iter (+/- 23869) +test wasm_instructions/wasm32/irelop/i32.le_s ... bench: 2598399 ns/iter (+/- 24582) +test wasm_instructions/wasm32/irelop/i32.le_s/confirmation ... bench: 5004447 ns/iter (+/- 353989) +test wasm_instructions/wasm64/irelop/i32.le_s ... bench: 2602169 ns/iter (+/- 240058) +test wasm_instructions/wasm64/irelop/i32.le_s/confirmation ... bench: 5001411 ns/iter (+/- 610127) +test wasm_instructions/wasm32/irelop/i32.le_u ... bench: 2621931 ns/iter (+/- 183899) +test wasm_instructions/wasm32/irelop/i32.le_u/confirmation ... bench: 5040557 ns/iter (+/- 349071) +test wasm_instructions/wasm64/irelop/i32.le_u ... bench: 2599733 ns/iter (+/- 200800) +test wasm_instructions/wasm64/irelop/i32.le_u/confirmation ... bench: 5038184 ns/iter (+/- 103853) +test wasm_instructions/wasm32/irelop/i32.ge_s ... bench: 2598147 ns/iter (+/- 214611) +test wasm_instructions/wasm32/irelop/i32.ge_s/confirmation ... bench: 5038034 ns/iter (+/- 298899) +test wasm_instructions/wasm64/irelop/i32.ge_s ... bench: 2658801 ns/iter (+/- 32483) +test wasm_instructions/wasm64/irelop/i32.ge_s/confirmation ... bench: 5032667 ns/iter (+/- 687843) +test wasm_instructions/wasm32/irelop/i32.ge_u ... bench: 2631780 ns/iter (+/- 167901) +test wasm_instructions/wasm32/irelop/i32.ge_u/confirmation ... bench: 5014521 ns/iter (+/- 339856) +test wasm_instructions/wasm64/irelop/i32.ge_u ... bench: 2608743 ns/iter (+/- 30585) +test wasm_instructions/wasm64/irelop/i32.ge_u/confirmation ... bench: 5113301 ns/iter (+/- 46078) +test wasm_instructions/wasm32/irelop/i64.eq ... bench: 2655352 ns/iter (+/- 52082) +test wasm_instructions/wasm32/irelop/i64.eq/confirmation ... bench: 5041847 ns/iter (+/- 61137) +test wasm_instructions/wasm64/irelop/i64.eq ... bench: 2601433 ns/iter (+/- 190775) +test wasm_instructions/wasm64/irelop/i64.eq/confirmation ... bench: 5048025 ns/iter (+/- 37022) +test wasm_instructions/wasm32/irelop/i64.ne ... bench: 2600986 ns/iter (+/- 69450) +test wasm_instructions/wasm32/irelop/i64.ne/confirmation ... bench: 5021522 ns/iter (+/- 23026) +test wasm_instructions/wasm64/irelop/i64.ne ... bench: 2604374 ns/iter (+/- 35745) +test wasm_instructions/wasm64/irelop/i64.ne/confirmation ... bench: 5036579 ns/iter (+/- 123612) +test wasm_instructions/wasm32/irelop/i64.lt_s ... bench: 2613898 ns/iter (+/- 113114) +test wasm_instructions/wasm32/irelop/i64.lt_s/confirmation ... bench: 5068040 ns/iter (+/- 39787) +test wasm_instructions/wasm64/irelop/i64.lt_s ... bench: 2593855 ns/iter (+/- 129170) +test wasm_instructions/wasm64/irelop/i64.lt_s/confirmation ... bench: 4996561 ns/iter (+/- 479271) +test wasm_instructions/wasm32/irelop/i64.lt_u ... bench: 2606523 ns/iter (+/- 160745) +test wasm_instructions/wasm32/irelop/i64.lt_u/confirmation ... bench: 5022333 ns/iter (+/- 19782) +test wasm_instructions/wasm64/irelop/i64.lt_u ... bench: 2584132 ns/iter (+/- 17720) +test wasm_instructions/wasm64/irelop/i64.lt_u/confirmation ... bench: 5007033 ns/iter (+/- 505231) +test wasm_instructions/wasm32/irelop/i64.gt_s ... bench: 2596687 ns/iter (+/- 171135) +test wasm_instructions/wasm32/irelop/i64.gt_s/confirmation ... bench: 5017334 ns/iter (+/- 575906) +test wasm_instructions/wasm64/irelop/i64.gt_s ... bench: 2605335 ns/iter (+/- 12378) +test wasm_instructions/wasm64/irelop/i64.gt_s/confirmation ... bench: 4982713 ns/iter (+/- 429481) +test wasm_instructions/wasm32/irelop/i64.gt_u ... bench: 2569747 ns/iter (+/- 196109) +test wasm_instructions/wasm32/irelop/i64.gt_u/confirmation ... bench: 5055229 ns/iter (+/- 33197) +test wasm_instructions/wasm64/irelop/i64.gt_u ... bench: 2667126 ns/iter (+/- 47582) +test wasm_instructions/wasm64/irelop/i64.gt_u/confirmation ... bench: 5038634 ns/iter (+/- 742235) +test wasm_instructions/wasm32/irelop/i64.le_s ... bench: 2617160 ns/iter (+/- 153114) +test wasm_instructions/wasm32/irelop/i64.le_s/confirmation ... bench: 5030933 ns/iter (+/- 47719) +test wasm_instructions/wasm64/irelop/i64.le_s ... bench: 2632742 ns/iter (+/- 133531) +test wasm_instructions/wasm64/irelop/i64.le_s/confirmation ... bench: 5025392 ns/iter (+/- 37647) +test wasm_instructions/wasm32/irelop/i64.le_u ... bench: 2591371 ns/iter (+/- 218746) +test wasm_instructions/wasm32/irelop/i64.le_u/confirmation ... bench: 4983816 ns/iter (+/- 886737) +test wasm_instructions/wasm64/irelop/i64.le_u ... bench: 2618818 ns/iter (+/- 28645) +test wasm_instructions/wasm64/irelop/i64.le_u/confirmation ... bench: 5024249 ns/iter (+/- 399346) +test wasm_instructions/wasm32/irelop/i64.ge_s ... bench: 2659507 ns/iter (+/- 31482) +test wasm_instructions/wasm32/irelop/i64.ge_s/confirmation ... bench: 4996828 ns/iter (+/- 462607) +test wasm_instructions/wasm64/irelop/i64.ge_s ... bench: 2581706 ns/iter (+/- 120869) +test wasm_instructions/wasm64/irelop/i64.ge_s/confirmation ... bench: 5004723 ns/iter (+/- 505562) +test wasm_instructions/wasm32/irelop/i64.ge_u ... bench: 2647806 ns/iter (+/- 173296) +test wasm_instructions/wasm32/irelop/i64.ge_u/confirmation ... bench: 5025701 ns/iter (+/- 549751) +test wasm_instructions/wasm64/irelop/i64.ge_u ... bench: 2640236 ns/iter (+/- 207321) +test wasm_instructions/wasm64/irelop/i64.ge_u/confirmation ... bench: 5027772 ns/iter (+/- 22037) +test wasm_instructions/wasm32/frelop/f32.eq ... bench: 4874255 ns/iter (+/- 390809) +test wasm_instructions/wasm32/frelop/f32.eq/confirmation ... bench: 9572063 ns/iter (+/- 41685) +test wasm_instructions/wasm64/frelop/f32.eq ... bench: 4926979 ns/iter (+/- 325970) +test wasm_instructions/wasm64/frelop/f32.eq/confirmation ... bench: 9643044 ns/iter (+/- 230806) +test wasm_instructions/wasm32/frelop/f32.ne ... bench: 4926112 ns/iter (+/- 346013) +test wasm_instructions/wasm32/frelop/f32.ne/confirmation ... bench: 9532306 ns/iter (+/- 1080907) +test wasm_instructions/wasm64/frelop/f32.ne ... bench: 4925344 ns/iter (+/- 438537) +test wasm_instructions/wasm64/frelop/f32.ne/confirmation ... bench: 9559467 ns/iter (+/- 37049) +test wasm_instructions/wasm32/frelop/f64.eq ... bench: 4902056 ns/iter (+/- 770893) +test wasm_instructions/wasm32/frelop/f64.eq/confirmation ... bench: 9604763 ns/iter (+/- 866960) +test wasm_instructions/wasm64/frelop/f64.eq ... bench: 4885411 ns/iter (+/- 447907) +test wasm_instructions/wasm64/frelop/f64.eq/confirmation ... bench: 9573603 ns/iter (+/- 517458) +test wasm_instructions/wasm32/frelop/f64.ne ... bench: 4925307 ns/iter (+/- 36549) +test wasm_instructions/wasm32/frelop/f64.ne/confirmation ... bench: 9657389 ns/iter (+/- 69680) +test wasm_instructions/wasm64/frelop/f64.ne ... bench: 4922207 ns/iter (+/- 332712) +test wasm_instructions/wasm64/frelop/f64.ne/confirmation ... bench: 9659435 ns/iter (+/- 57566) +test wasm_instructions/wasm32/frelop/f32.lt ... bench: 3230443 ns/iter (+/- 330236) +test wasm_instructions/wasm32/frelop/f32.lt/confirmation ... bench: 6391077 ns/iter (+/- 64896) +test wasm_instructions/wasm64/frelop/f32.lt ... bench: 3321487 ns/iter (+/- 47157) +test wasm_instructions/wasm64/frelop/f32.lt/confirmation ... bench: 6306250 ns/iter (+/- 373552) +test wasm_instructions/wasm32/frelop/f32.gt ... bench: 3284293 ns/iter (+/- 273675) +test wasm_instructions/wasm32/frelop/f32.gt/confirmation ... bench: 6280448 ns/iter (+/- 128812) +test wasm_instructions/wasm64/frelop/f32.gt ... bench: 3267742 ns/iter (+/- 252374) +test wasm_instructions/wasm64/frelop/f32.gt/confirmation ... bench: 6386718 ns/iter (+/- 21488) +test wasm_instructions/wasm32/frelop/f32.le ... bench: 3251485 ns/iter (+/- 380828) +test wasm_instructions/wasm32/frelop/f32.le/confirmation ... bench: 6402770 ns/iter (+/- 26262) +test wasm_instructions/wasm64/frelop/f32.le ... bench: 3350118 ns/iter (+/- 29107) +test wasm_instructions/wasm64/frelop/f32.le/confirmation ... bench: 6328700 ns/iter (+/- 131282) +test wasm_instructions/wasm32/frelop/f32.ge ... bench: 3265192 ns/iter (+/- 76667) +test wasm_instructions/wasm32/frelop/f32.ge/confirmation ... bench: 6278599 ns/iter (+/- 256377) +test wasm_instructions/wasm64/frelop/f32.ge ... bench: 3255847 ns/iter (+/- 324323) +test wasm_instructions/wasm64/frelop/f32.ge/confirmation ... bench: 6314108 ns/iter (+/- 338757) +test wasm_instructions/wasm32/frelop/f64.lt ... bench: 3235373 ns/iter (+/- 304570) +test wasm_instructions/wasm32/frelop/f64.lt/confirmation ... bench: 6355331 ns/iter (+/- 40139) +test wasm_instructions/wasm64/frelop/f64.lt ... bench: 3287575 ns/iter (+/- 248879) +test wasm_instructions/wasm64/frelop/f64.lt/confirmation ... bench: 6308220 ns/iter (+/- 53725) +test wasm_instructions/wasm32/frelop/f64.gt ... bench: 3232685 ns/iter (+/- 28824) +test wasm_instructions/wasm32/frelop/f64.gt/confirmation ... bench: 6308118 ns/iter (+/- 31626) +test wasm_instructions/wasm64/frelop/f64.gt ... bench: 3297936 ns/iter (+/- 436823) +test wasm_instructions/wasm64/frelop/f64.gt/confirmation ... bench: 6296410 ns/iter (+/- 180736) +test wasm_instructions/wasm32/frelop/f64.le ... bench: 3271916 ns/iter (+/- 253126) +test wasm_instructions/wasm32/frelop/f64.le/confirmation ... bench: 6279157 ns/iter (+/- 274325) +test wasm_instructions/wasm64/frelop/f64.le ... bench: 3283582 ns/iter (+/- 175080) +test wasm_instructions/wasm64/frelop/f64.le/confirmation ... bench: 6283667 ns/iter (+/- 698686) +test wasm_instructions/wasm32/frelop/f64.ge ... bench: 3270929 ns/iter (+/- 186925) +test wasm_instructions/wasm32/frelop/f64.ge/confirmation ... bench: 6287237 ns/iter (+/- 33466) +test wasm_instructions/wasm64/frelop/f64.ge ... bench: 3273277 ns/iter (+/- 205641) +test wasm_instructions/wasm64/frelop/f64.ge/confirmation ... bench: 6393569 ns/iter (+/- 29550) +test wasm_instructions/wasm32/cvtop/i32.extend8_s ... bench: 2377357 ns/iter (+/- 29899) +test wasm_instructions/wasm32/cvtop/i32.extend8_s/confirmation ... bench: 4560916 ns/iter (+/- 48318) +test wasm_instructions/wasm64/cvtop/i32.extend8_s ... bench: 2400219 ns/iter (+/- 204062) +test wasm_instructions/wasm64/cvtop/i32.extend8_s/confirmation ... bench: 4599954 ns/iter (+/- 55857) +test wasm_instructions/wasm32/cvtop/i32.extend16_s ... bench: 2396978 ns/iter (+/- 12051) +test wasm_instructions/wasm32/cvtop/i32.extend16_s/confirmation ... bench: 4525017 ns/iter (+/- 312965) +test wasm_instructions/wasm64/cvtop/i32.extend16_s ... bench: 2375571 ns/iter (+/- 48149) +test wasm_instructions/wasm64/cvtop/i32.extend16_s/confirmation ... bench: 4572864 ns/iter (+/- 383521) +test wasm_instructions/wasm32/cvtop/i64.extend8_s ... bench: 2378565 ns/iter (+/- 177871) +test wasm_instructions/wasm32/cvtop/i64.extend8_s/confirmation ... bench: 4664694 ns/iter (+/- 69339) +test wasm_instructions/wasm64/cvtop/i64.extend8_s ... bench: 2405862 ns/iter (+/- 253879) +test wasm_instructions/wasm64/cvtop/i64.extend8_s/confirmation ... bench: 4574006 ns/iter (+/- 36017) +test wasm_instructions/wasm32/cvtop/i64.extend16_s ... bench: 2373315 ns/iter (+/- 148970) +test wasm_instructions/wasm32/cvtop/i64.extend16_s/confirmation ... bench: 4532140 ns/iter (+/- 447533) +test wasm_instructions/wasm64/cvtop/i64.extend16_s ... bench: 2445364 ns/iter (+/- 29174) +test wasm_instructions/wasm64/cvtop/i64.extend16_s/confirmation ... bench: 4606660 ns/iter (+/- 210340) +test wasm_instructions/wasm32/cvtop/f32.convert_i32_s ... bench: 2634108 ns/iter (+/- 61480) +test wasm_instructions/wasm32/cvtop/f32.convert_i32_s/confirmation ... bench: 5144649 ns/iter (+/- 47918) +test wasm_instructions/wasm64/cvtop/f32.convert_i32_s ... bench: 2642733 ns/iter (+/- 142165) +test wasm_instructions/wasm64/cvtop/f32.convert_i32_s/confirmation ... bench: 5128591 ns/iter (+/- 356619) +test wasm_instructions/wasm32/cvtop/f32.convert_i64_s ... bench: 2649494 ns/iter (+/- 123905) +test wasm_instructions/wasm32/cvtop/f32.convert_i64_s/confirmation ... bench: 5131016 ns/iter (+/- 455048) +test wasm_instructions/wasm64/cvtop/f32.convert_i64_s ... bench: 2627379 ns/iter (+/- 15540) +test wasm_instructions/wasm64/cvtop/f32.convert_i64_s/confirmation ... bench: 5157435 ns/iter (+/- 55079) +test wasm_instructions/wasm32/cvtop/f64.convert_i32_s ... bench: 2613026 ns/iter (+/- 26842) +test wasm_instructions/wasm32/cvtop/f64.convert_i32_s/confirmation ... bench: 5100223 ns/iter (+/- 603748) +test wasm_instructions/wasm64/cvtop/f64.convert_i32_s ... bench: 2675470 ns/iter (+/- 342789) +test wasm_instructions/wasm64/cvtop/f64.convert_i32_s/confirmation ... bench: 5082389 ns/iter (+/- 248497) +test wasm_instructions/wasm32/cvtop/f64.convert_i64_s ... bench: 2677422 ns/iter (+/- 46128) +test wasm_instructions/wasm32/cvtop/f64.convert_i64_s/confirmation ... bench: 5094301 ns/iter (+/- 385301) +test wasm_instructions/wasm64/cvtop/f64.convert_i64_s ... bench: 2619060 ns/iter (+/- 22199) +test wasm_instructions/wasm64/cvtop/f64.convert_i64_s/confirmation ... bench: 5128381 ns/iter (+/- 169827) +test wasm_instructions/wasm32/cvtop/i64.extend32_s ... bench: 2375721 ns/iter (+/- 114615) +test wasm_instructions/wasm32/cvtop/i64.extend32_s/confirmation ... bench: 4560551 ns/iter (+/- 298709) +test wasm_instructions/wasm64/cvtop/i64.extend32_s ... bench: 2351403 ns/iter (+/- 16190) +test wasm_instructions/wasm64/cvtop/i64.extend32_s/confirmation ... bench: 4628040 ns/iter (+/- 63020) +test wasm_instructions/wasm32/cvtop/i32.wrap_i64 ... bench: 2378629 ns/iter (+/- 57246) +test wasm_instructions/wasm32/cvtop/i32.wrap_i64/confirmation ... bench: 4559124 ns/iter (+/- 353187) +test wasm_instructions/wasm64/cvtop/i32.wrap_i64 ... bench: 2358086 ns/iter (+/- 45445) +test wasm_instructions/wasm64/cvtop/i32.wrap_i64/confirmation ... bench: 4580155 ns/iter (+/- 30019) +test wasm_instructions/wasm32/cvtop/i64.extend_i32_s ... bench: 2386106 ns/iter (+/- 177951) +test wasm_instructions/wasm32/cvtop/i64.extend_i32_s/confirmation ... bench: 4566456 ns/iter (+/- 241690) +test wasm_instructions/wasm64/cvtop/i64.extend_i32_s ... bench: 2420116 ns/iter (+/- 149256) +test wasm_instructions/wasm64/cvtop/i64.extend_i32_s/confirmation ... bench: 4604682 ns/iter (+/- 43992) +test wasm_instructions/wasm32/cvtop/i64.extend_i32_u ... bench: 2371691 ns/iter (+/- 214684) +test wasm_instructions/wasm32/cvtop/i64.extend_i32_u/confirmation ... bench: 4551558 ns/iter (+/- 206296) +test wasm_instructions/wasm64/cvtop/i64.extend_i32_u ... bench: 2366961 ns/iter (+/- 77613) +test wasm_instructions/wasm64/cvtop/i64.extend_i32_u/confirmation ... bench: 4628575 ns/iter (+/- 292796) +test wasm_instructions/wasm32/cvtop/f32.demote_f64 ... bench: 5358449 ns/iter (+/- 42456) +test wasm_instructions/wasm32/cvtop/f32.demote_f64/confirmation ... bench: 10409627 ns/iter (+/- 735375) +test wasm_instructions/wasm64/cvtop/f32.demote_f64 ... bench: 5384417 ns/iter (+/- 24119) +test wasm_instructions/wasm64/cvtop/f32.demote_f64/confirmation ... bench: 10547690 ns/iter (+/- 85774) +test wasm_instructions/wasm32/cvtop/f64.promote_f32 ... bench: 6188858 ns/iter (+/- 58976) +test wasm_instructions/wasm32/cvtop/f64.promote_f32/confirmation ... bench: 12771548 ns/iter (+/- 38831) +test wasm_instructions/wasm64/cvtop/f64.promote_f32 ... bench: 6174532 ns/iter (+/- 17345) +test wasm_instructions/wasm64/cvtop/f64.promote_f32/confirmation ... bench: 12174906 ns/iter (+/- 48420) +test wasm_instructions/wasm32/cvtop/f32.reinterpret_i32 ... bench: 2348793 ns/iter (+/- 21046) +test wasm_instructions/wasm32/cvtop/f32.reinterpret_i32/confirmation ... bench: 4565641 ns/iter (+/- 47210) +test wasm_instructions/wasm64/cvtop/f32.reinterpret_i32 ... bench: 2383769 ns/iter (+/- 205146) +test wasm_instructions/wasm64/cvtop/f32.reinterpret_i32/confirmation ... bench: 4657686 ns/iter (+/- 248273) +test wasm_instructions/wasm32/cvtop/f64.reinterpret_i64 ... bench: 2377475 ns/iter (+/- 202165) +test wasm_instructions/wasm32/cvtop/f64.reinterpret_i64/confirmation ... bench: 4562771 ns/iter (+/- 18091) +test wasm_instructions/wasm64/cvtop/f64.reinterpret_i64 ... bench: 2379085 ns/iter (+/- 33499) +test wasm_instructions/wasm64/cvtop/f64.reinterpret_i64/confirmation ... bench: 4585766 ns/iter (+/- 29441) +test wasm_instructions/wasm32/cvtop/f32.convert_i32_u ... bench: 3095165 ns/iter (+/- 199284) +test wasm_instructions/wasm32/cvtop/f32.convert_i32_u/confirmation ... bench: 5865545 ns/iter (+/- 422436) +test wasm_instructions/wasm64/cvtop/f32.convert_i32_u ... bench: 3094768 ns/iter (+/- 139816) +test wasm_instructions/wasm64/cvtop/f32.convert_i32_u/confirmation ... bench: 6021516 ns/iter (+/- 38875) +test wasm_instructions/wasm32/cvtop/f64.convert_i32_u ... bench: 3147485 ns/iter (+/- 68952) +test wasm_instructions/wasm32/cvtop/f64.convert_i32_u/confirmation ... bench: 5937311 ns/iter (+/- 472832) +test wasm_instructions/wasm64/cvtop/f64.convert_i32_u ... bench: 3113997 ns/iter (+/- 392249) +test wasm_instructions/wasm64/cvtop/f64.convert_i32_u/confirmation ... bench: 5905181 ns/iter (+/- 371279) +test wasm_instructions/wasm32/cvtop/i32.reinterpret_f32 ... bench: 2902329 ns/iter (+/- 22065) +test wasm_instructions/wasm32/cvtop/i32.reinterpret_f32/confirmation ... bench: 5597615 ns/iter (+/- 560473) +test wasm_instructions/wasm64/cvtop/i32.reinterpret_f32 ... bench: 2933185 ns/iter (+/- 254663) +test wasm_instructions/wasm64/cvtop/i32.reinterpret_f32/confirmation ... bench: 5652958 ns/iter (+/- 368933) +test wasm_instructions/wasm32/cvtop/i64.reinterpret_f64 ... bench: 2941158 ns/iter (+/- 216043) +test wasm_instructions/wasm32/cvtop/i64.reinterpret_f64/confirmation ... bench: 5600971 ns/iter (+/- 774466) +test wasm_instructions/wasm64/cvtop/i64.reinterpret_f64 ... bench: 2942808 ns/iter (+/- 192745) +test wasm_instructions/wasm64/cvtop/i64.reinterpret_f64/confirmation ... bench: 5633294 ns/iter (+/- 276221) +test wasm_instructions/wasm32/cvtop/i32.trunc_f32_s ... bench: 56099132 ns/iter (+/- 2227105) +test wasm_instructions/wasm32/cvtop/i32.trunc_f32_s/confirmation ... bench: 125833620 ns/iter (+/- 919999) +test wasm_instructions/wasm64/cvtop/i32.trunc_f32_s ... bench: 56500664 ns/iter (+/- 1132868) +test wasm_instructions/wasm64/cvtop/i32.trunc_f32_s/confirmation ... bench: 125593162 ns/iter (+/- 1043108) +test wasm_instructions/wasm32/cvtop/i32.trunc_f32_u ... bench: 54082830 ns/iter (+/- 417515) +test wasm_instructions/wasm32/cvtop/i32.trunc_f32_u/confirmation ... bench: 120594617 ns/iter (+/- 957177) +test wasm_instructions/wasm64/cvtop/i32.trunc_f32_u ... bench: 54557767 ns/iter (+/- 449429) +test wasm_instructions/wasm64/cvtop/i32.trunc_f32_u/confirmation ... bench: 119866299 ns/iter (+/- 1112310) +test wasm_instructions/wasm32/cvtop/i32.trunc_f64_s ... bench: 52892522 ns/iter (+/- 1507681) +test wasm_instructions/wasm32/cvtop/i32.trunc_f64_s/confirmation ... bench: 119070563 ns/iter (+/- 4805906) +test wasm_instructions/wasm64/cvtop/i32.trunc_f64_s ... bench: 52023774 ns/iter (+/- 941880) +test wasm_instructions/wasm64/cvtop/i32.trunc_f64_s/confirmation ... bench: 119836473 ns/iter (+/- 1401319) +test wasm_instructions/wasm32/cvtop/i32.trunc_f64_u ... bench: 58003882 ns/iter (+/- 929344) +test wasm_instructions/wasm32/cvtop/i32.trunc_f64_u/confirmation ... bench: 122422941 ns/iter (+/- 1565471) +test wasm_instructions/wasm64/cvtop/i32.trunc_f64_u ... bench: 58288094 ns/iter (+/- 990583) +test wasm_instructions/wasm64/cvtop/i32.trunc_f64_u/confirmation ... bench: 122640937 ns/iter (+/- 1469340) +test wasm_instructions/wasm32/cvtop/i64.trunc_f32_s ... bench: 56706914 ns/iter (+/- 1604792) +test wasm_instructions/wasm32/cvtop/i64.trunc_f32_s/confirmation ... bench: 126239088 ns/iter (+/- 1021516) +test wasm_instructions/wasm64/cvtop/i64.trunc_f32_s ... bench: 56315819 ns/iter (+/- 1869999) +test wasm_instructions/wasm64/cvtop/i64.trunc_f32_s/confirmation ... bench: 126629197 ns/iter (+/- 792438) +test wasm_instructions/wasm32/cvtop/i64.trunc_f32_u ... bench: 56687308 ns/iter (+/- 959870) +test wasm_instructions/wasm32/cvtop/i64.trunc_f32_u/confirmation ... bench: 118666407 ns/iter (+/- 740543) +test wasm_instructions/wasm64/cvtop/i64.trunc_f32_u ... bench: 56374076 ns/iter (+/- 796323) +test wasm_instructions/wasm64/cvtop/i64.trunc_f32_u/confirmation ... bench: 119206092 ns/iter (+/- 1356040) +test wasm_instructions/wasm32/cvtop/i64.trunc_f64_s ... bench: 52150518 ns/iter (+/- 915173) +test wasm_instructions/wasm32/cvtop/i64.trunc_f64_s/confirmation ... bench: 119440672 ns/iter (+/- 1307993) +test wasm_instructions/wasm64/cvtop/i64.trunc_f64_s ... bench: 51745421 ns/iter (+/- 791508) +test wasm_instructions/wasm64/cvtop/i64.trunc_f64_s/confirmation ... bench: 118635961 ns/iter (+/- 1518378) +test wasm_instructions/wasm32/cvtop/i64.trunc_f64_u ... bench: 58312899 ns/iter (+/- 1018524) +test wasm_instructions/wasm32/cvtop/i64.trunc_f64_u/confirmation ... bench: 121928454 ns/iter (+/- 1211494) +test wasm_instructions/wasm64/cvtop/i64.trunc_f64_u ... bench: 57814450 ns/iter (+/- 819296) +test wasm_instructions/wasm64/cvtop/i64.trunc_f64_u/confirmation ... bench: 122046729 ns/iter (+/- 1903054) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_s ... bench: 50832458 ns/iter (+/- 2123428) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_s/confirmation ... bench: 113389286 ns/iter (+/- 1124780) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_s ... bench: 48303850 ns/iter (+/- 3054697) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_s/confirmation ... bench: 113752760 ns/iter (+/- 1125404) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_s ... bench: 59438166 ns/iter (+/- 999194) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_s/confirmation ... bench: 117200996 ns/iter (+/- 1440850) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_s ... bench: 59426348 ns/iter (+/- 834219) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_s/confirmation ... bench: 117817990 ns/iter (+/- 4124416) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_u ... bench: 107508736 ns/iter (+/- 893222) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_u/confirmation ... bench: 236838804 ns/iter (+/- 1320223) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_u ... bench: 107689150 ns/iter (+/- 514123) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_u/confirmation ... bench: 236493351 ns/iter (+/- 571080) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_u ... bench: 109951941 ns/iter (+/- 152191) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_u/confirmation ... bench: 242424826 ns/iter (+/- 764115) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_u ... bench: 109791696 ns/iter (+/- 346702) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_u/confirmation ... bench: 242390214 ns/iter (+/- 231528) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_u ... bench: 107971836 ns/iter (+/- 364163) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f32_u/confirmation ... bench: 241313223 ns/iter (+/- 674761) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_u ... bench: 108060969 ns/iter (+/- 567050) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f32_u/confirmation ... bench: 241479897 ns/iter (+/- 968002) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_u ... bench: 109283011 ns/iter (+/- 259256) +test wasm_instructions/wasm32/cvtop/i64.trunc_sat_f64_u/confirmation ... bench: 244949572 ns/iter (+/- 201864) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_u ... bench: 109268566 ns/iter (+/- 190857) +test wasm_instructions/wasm64/cvtop/i64.trunc_sat_f64_u/confirmation ... bench: 245227686 ns/iter (+/- 862902) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_s ... bench: 37773386 ns/iter (+/- 3151796) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f32_s/confirmation ... bench: 118552680 ns/iter (+/- 301206) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_s ... bench: 38455732 ns/iter (+/- 3279932) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f32_s/confirmation ... bench: 118437734 ns/iter (+/- 273866) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_s ... bench: 41285410 ns/iter (+/- 2524765) +test wasm_instructions/wasm32/cvtop/i32.trunc_sat_f64_s/confirmation ... bench: 118134892 ns/iter (+/- 505267) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_s ... bench: 39811692 ns/iter (+/- 2513760) +test wasm_instructions/wasm64/cvtop/i32.trunc_sat_f64_s/confirmation ... bench: 118090211 ns/iter (+/- 629467) +test wasm_instructions/wasm32/cvtop/f32.convert_i64_u ... bench: 31582601 ns/iter (+/- 1165929) +test wasm_instructions/wasm32/cvtop/f32.convert_i64_u/confirmation ... bench: 67806306 ns/iter (+/- 1033413) +test wasm_instructions/wasm64/cvtop/f32.convert_i64_u ... bench: 31292971 ns/iter (+/- 544463) +test wasm_instructions/wasm64/cvtop/f32.convert_i64_u/confirmation ... bench: 67705052 ns/iter (+/- 866674) +test wasm_instructions/wasm32/cvtop/f64.convert_i64_u ... bench: 31718634 ns/iter (+/- 586238) +test wasm_instructions/wasm32/cvtop/f64.convert_i64_u/confirmation ... bench: 67852266 ns/iter (+/- 1164483) +test wasm_instructions/wasm64/cvtop/f64.convert_i64_u ... bench: 31668718 ns/iter (+/- 452642) +test wasm_instructions/wasm64/cvtop/f64.convert_i64_u/confirmation ... bench: 67222103 ns/iter (+/- 957726) +test wasm_instructions/wasm32/refop/ref.func ... bench: 164650953 ns/iter (+/- 961537) +test wasm_instructions/wasm32/refop/ref.func/confirmation ... bench: 336016097 ns/iter (+/- 2022405) +test wasm_instructions/wasm64/refop/ref.func ... bench: 164592882 ns/iter (+/- 791969) +test wasm_instructions/wasm64/refop/ref.func/confirmation ... bench: 335887203 ns/iter (+/- 945672) +test wasm_instructions/wasm32/refop/ref.is_null-ref.func ... bench: 170577313 ns/iter (+/- 1552759) +test wasm_instructions/wasm32/refop/ref.is_null-ref.func/confirmation ... bench: 340465643 ns/iter (+/- 574609) +test wasm_instructions/wasm64/refop/ref.is_null-ref.func ... bench: 170664594 ns/iter (+/- 1675440) +test wasm_instructions/wasm64/refop/ref.is_null-ref.func/confirmation ... bench: 341109172 ns/iter (+/- 784072) +test wasm_instructions/wasm32/varop/local.get ... bench: 2357866 ns/iter (+/- 228324) +test wasm_instructions/wasm32/varop/local.get/confirmation ... bench: 4565906 ns/iter (+/- 29080) +test wasm_instructions/wasm64/varop/local.get ... bench: 2405339 ns/iter (+/- 108160) +test wasm_instructions/wasm64/varop/local.get/confirmation ... bench: 4547809 ns/iter (+/- 359768) +test wasm_instructions/wasm32/varop/global.get ... bench: 2391503 ns/iter (+/- 190779) +test wasm_instructions/wasm32/varop/global.get/confirmation ... bench: 4660216 ns/iter (+/- 26787) +test wasm_instructions/wasm64/varop/global.get ... bench: 2422807 ns/iter (+/- 14210) +test wasm_instructions/wasm64/varop/global.get/confirmation ... bench: 4574951 ns/iter (+/- 23997) +test wasm_instructions/wasm32/varop/global.set ... bench: 2422933 ns/iter (+/- 199710) +test wasm_instructions/wasm32/varop/global.set/confirmation ... bench: 4581277 ns/iter (+/- 339819) +test wasm_instructions/wasm64/varop/global.set ... bench: 2405098 ns/iter (+/- 171095) +test wasm_instructions/wasm64/varop/global.set/confirmation ... bench: 4578493 ns/iter (+/- 60646) +test wasm_instructions/wasm32/varop/local.tee ... bench: 2366377 ns/iter (+/- 6185) +test wasm_instructions/wasm32/varop/local.tee/confirmation ... bench: 4561734 ns/iter (+/- 269884) +test wasm_instructions/wasm64/varop/local.tee ... bench: 2357925 ns/iter (+/- 35987) +test wasm_instructions/wasm64/varop/local.tee/confirmation ... bench: 4551969 ns/iter (+/- 481116) +test wasm_instructions/wasm32/tabop/table.get ... bench: 7532873 ns/iter (+/- 117200) +test wasm_instructions/wasm32/tabop/table.get/confirmation ... bench: 14585128 ns/iter (+/- 187098) +test wasm_instructions/wasm64/tabop/table.get ... bench: 7340393 ns/iter (+/- 384413) +test wasm_instructions/wasm64/tabop/table.get/confirmation ... bench: 14939391 ns/iter (+/- 90454) +test wasm_instructions/wasm32/tabop/table.size ... bench: 2369300 ns/iter (+/- 102997) +test wasm_instructions/wasm32/tabop/table.size/confirmation ... bench: 4572326 ns/iter (+/- 22944) +test wasm_instructions/wasm64/tabop/table.size ... bench: 2397278 ns/iter (+/- 155482) +test wasm_instructions/wasm64/tabop/table.size/confirmation ... bench: 4530911 ns/iter (+/- 394475) +test wasm_instructions/wasm32/memop/i32.load ... bench: 3077526 ns/iter (+/- 177570) +test wasm_instructions/wasm32/memop/i32.load/confirmation ... bench: 5849267 ns/iter (+/- 40067) +test wasm_instructions/wasm64/memop/i32.load ... bench: 4948942 ns/iter (+/- 56842) +test wasm_instructions/wasm64/memop/i32.load/confirmation ... bench: 9754752 ns/iter (+/- 632555) +test wasm_instructions/wasm32/memop/i64.load ... bench: 3085842 ns/iter (+/- 19035) +test wasm_instructions/wasm32/memop/i64.load/confirmation ... bench: 5915708 ns/iter (+/- 488171) +test wasm_instructions/wasm64/memop/i64.load ... bench: 4976081 ns/iter (+/- 42656) +test wasm_instructions/wasm64/memop/i64.load/confirmation ... bench: 9562912 ns/iter (+/- 21866) +test wasm_instructions/wasm32/memop/f32.load ... bench: 3635262 ns/iter (+/- 323267) +test wasm_instructions/wasm32/memop/f32.load/confirmation ... bench: 6983211 ns/iter (+/- 37175) +test wasm_instructions/wasm64/memop/f32.load ... bench: 5357774 ns/iter (+/- 343152) +test wasm_instructions/wasm64/memop/f32.load/confirmation ... bench: 10464693 ns/iter (+/- 29945) +test wasm_instructions/wasm32/memop/f64.load ... bench: 3576287 ns/iter (+/- 375068) +test wasm_instructions/wasm32/memop/f64.load/confirmation ... bench: 6948269 ns/iter (+/- 375982) +test wasm_instructions/wasm64/memop/f64.load ... bench: 5349454 ns/iter (+/- 9272) +test wasm_instructions/wasm64/memop/f64.load/confirmation ... bench: 10480778 ns/iter (+/- 42950) +test wasm_instructions/wasm32/memop/i32.store ... bench: 3142345 ns/iter (+/- 162788) +test wasm_instructions/wasm32/memop/i32.store/confirmation ... bench: 6075952 ns/iter (+/- 243071) +test wasm_instructions/wasm64/memop/i32.store ... bench: 3924402 ns/iter (+/- 407187) +test wasm_instructions/wasm64/memop/i32.store/confirmation ... bench: 7681573 ns/iter (+/- 29581) +test wasm_instructions/wasm32/memop/i64.store ... bench: 3108819 ns/iter (+/- 121208) +test wasm_instructions/wasm32/memop/i64.store/confirmation ... bench: 6052514 ns/iter (+/- 460022) +test wasm_instructions/wasm64/memop/i64.store ... bench: 3982380 ns/iter (+/- 85817) +test wasm_instructions/wasm64/memop/i64.store/confirmation ... bench: 7681948 ns/iter (+/- 165213) +test wasm_instructions/wasm32/memop/f32.store ... bench: 3121256 ns/iter (+/- 14033) +test wasm_instructions/wasm32/memop/f32.store/confirmation ... bench: 5961902 ns/iter (+/- 332929) +test wasm_instructions/wasm64/memop/f32.store ... bench: 4167754 ns/iter (+/- 194038) +test wasm_instructions/wasm64/memop/f32.store/confirmation ... bench: 8006823 ns/iter (+/- 51399) +test wasm_instructions/wasm32/memop/f64.store ... bench: 3128496 ns/iter (+/- 234104) +test wasm_instructions/wasm32/memop/f64.store/confirmation ... bench: 5990710 ns/iter (+/- 276103) +test wasm_instructions/wasm64/memop/f64.store ... bench: 4154677 ns/iter (+/- 190662) +test wasm_instructions/wasm64/memop/f64.store/confirmation ... bench: 8053931 ns/iter (+/- 131407) +test wasm_instructions/wasm32/memop/i32.load8_s ... bench: 3302195 ns/iter (+/- 163515) +test wasm_instructions/wasm32/memop/i32.load8_s/confirmation ... bench: 6211191 ns/iter (+/- 444332) +test wasm_instructions/wasm64/memop/i32.load8_s ... bench: 5162717 ns/iter (+/- 28854) +test wasm_instructions/wasm64/memop/i32.load8_s/confirmation ... bench: 10116069 ns/iter (+/- 503308) +test wasm_instructions/wasm32/memop/i32.load8_u ... bench: 3225713 ns/iter (+/- 291700) +test wasm_instructions/wasm32/memop/i32.load8_u/confirmation ... bench: 6180292 ns/iter (+/- 516133) +test wasm_instructions/wasm64/memop/i32.load8_u ... bench: 5046307 ns/iter (+/- 60098) +test wasm_instructions/wasm64/memop/i32.load8_u/confirmation ... bench: 9826374 ns/iter (+/- 31042) +test wasm_instructions/wasm32/memop/i32.load16_s ... bench: 3236168 ns/iter (+/- 266866) +test wasm_instructions/wasm32/memop/i32.load16_s/confirmation ... bench: 6239439 ns/iter (+/- 74761) +test wasm_instructions/wasm64/memop/i32.load16_s ... bench: 5122201 ns/iter (+/- 50269) +test wasm_instructions/wasm64/memop/i32.load16_s/confirmation ... bench: 9775716 ns/iter (+/- 683299) +test wasm_instructions/wasm32/memop/i32.load16_u ... bench: 3276426 ns/iter (+/- 76252) +test wasm_instructions/wasm32/memop/i32.load16_u/confirmation ... bench: 6228026 ns/iter (+/- 253714) +test wasm_instructions/wasm64/memop/i32.load16_u ... bench: 4980885 ns/iter (+/- 492137) +test wasm_instructions/wasm64/memop/i32.load16_u/confirmation ... bench: 9701266 ns/iter (+/- 105899) +test wasm_instructions/wasm32/memop/i64.load8_s ... bench: 3228035 ns/iter (+/- 219770) +test wasm_instructions/wasm32/memop/i64.load8_s/confirmation ... bench: 6223696 ns/iter (+/- 609926) +test wasm_instructions/wasm64/memop/i64.load8_s ... bench: 5062335 ns/iter (+/- 382319) +test wasm_instructions/wasm64/memop/i64.load8_s/confirmation ... bench: 9836579 ns/iter (+/- 48328) +test wasm_instructions/wasm32/memop/i64.load8_u ... bench: 3230468 ns/iter (+/- 281622) +test wasm_instructions/wasm32/memop/i64.load8_u/confirmation ... bench: 6219816 ns/iter (+/- 236604) +test wasm_instructions/wasm64/memop/i64.load8_u ... bench: 5023771 ns/iter (+/- 631518) +test wasm_instructions/wasm64/memop/i64.load8_u/confirmation ... bench: 9690524 ns/iter (+/- 591541) +test wasm_instructions/wasm32/memop/i64.load16_s ... bench: 3247175 ns/iter (+/- 27965) +test wasm_instructions/wasm32/memop/i64.load16_s/confirmation ... bench: 6246977 ns/iter (+/- 317747) +test wasm_instructions/wasm64/memop/i64.load16_s ... bench: 5020886 ns/iter (+/- 309619) +test wasm_instructions/wasm64/memop/i64.load16_s/confirmation ... bench: 9829458 ns/iter (+/- 187081) +test wasm_instructions/wasm32/memop/i64.load16_u ... bench: 3233923 ns/iter (+/- 284246) +test wasm_instructions/wasm32/memop/i64.load16_u/confirmation ... bench: 6244401 ns/iter (+/- 45064) +test wasm_instructions/wasm64/memop/i64.load16_u ... bench: 5022706 ns/iter (+/- 675747) +test wasm_instructions/wasm64/memop/i64.load16_u/confirmation ... bench: 9812603 ns/iter (+/- 38434) +test wasm_instructions/wasm32/memop/i64.load32_s ... bench: 3118128 ns/iter (+/- 51220) +test wasm_instructions/wasm32/memop/i64.load32_s/confirmation ... bench: 5954830 ns/iter (+/- 9232) +test wasm_instructions/wasm64/memop/i64.load32_s ... bench: 4879253 ns/iter (+/- 42272) +test wasm_instructions/wasm64/memop/i64.load32_s/confirmation ... bench: 9572572 ns/iter (+/- 831333) +test wasm_instructions/wasm32/memop/i64.load32_u ... bench: 3044430 ns/iter (+/- 286495) +test wasm_instructions/wasm32/memop/i64.load32_u/confirmation ... bench: 5857768 ns/iter (+/- 144623) +test wasm_instructions/wasm64/memop/i64.load32_u ... bench: 4879478 ns/iter (+/- 104473) +test wasm_instructions/wasm64/memop/i64.load32_u/confirmation ... bench: 9492111 ns/iter (+/- 116288) +test wasm_instructions/wasm32/memop/i32.store8 ... bench: 3118652 ns/iter (+/- 169003) +test wasm_instructions/wasm32/memop/i32.store8/confirmation ... bench: 6078149 ns/iter (+/- 51781) +test wasm_instructions/wasm64/memop/i32.store8 ... bench: 3964906 ns/iter (+/- 409514) +test wasm_instructions/wasm64/memop/i32.store8/confirmation ... bench: 7575403 ns/iter (+/- 73831) +test wasm_instructions/wasm32/memop/i32.store16 ... bench: 3160265 ns/iter (+/- 242159) +test wasm_instructions/wasm32/memop/i32.store16/confirmation ... bench: 6008235 ns/iter (+/- 516781) +test wasm_instructions/wasm64/memop/i32.store16 ... bench: 4097297 ns/iter (+/- 46208) +test wasm_instructions/wasm64/memop/i32.store16/confirmation ... bench: 7948029 ns/iter (+/- 351576) +test wasm_instructions/wasm32/memop/i64.store8 ... bench: 3129634 ns/iter (+/- 298476) +test wasm_instructions/wasm32/memop/i64.store8/confirmation ... bench: 6099543 ns/iter (+/- 385646) +test wasm_instructions/wasm64/memop/i64.store8 ... bench: 3979013 ns/iter (+/- 156039) +test wasm_instructions/wasm64/memop/i64.store8/confirmation ... bench: 7602728 ns/iter (+/- 509778) +test wasm_instructions/wasm32/memop/i64.store16 ... bench: 3170490 ns/iter (+/- 286432) +test wasm_instructions/wasm32/memop/i64.store16/confirmation ... bench: 6031909 ns/iter (+/- 458896) +test wasm_instructions/wasm64/memop/i64.store16 ... bench: 4077304 ns/iter (+/- 398871) +test wasm_instructions/wasm64/memop/i64.store16/confirmation ... bench: 7828963 ns/iter (+/- 554192) +test wasm_instructions/wasm32/memop/i64.store32 ... bench: 3142448 ns/iter (+/- 24254) +test wasm_instructions/wasm32/memop/i64.store32/confirmation ... bench: 6071647 ns/iter (+/- 370204) +test wasm_instructions/wasm64/memop/i64.store32 ... bench: 4054311 ns/iter (+/- 28415) +test wasm_instructions/wasm64/memop/i64.store32/confirmation ... bench: 7588978 ns/iter (+/- 182609) +test wasm_instructions/wasm32/memop/memory.size ... bench: 2991371 ns/iter (+/- 47051) +test wasm_instructions/wasm32/memop/memory.size/confirmation ... bench: 5647330 ns/iter (+/- 382504) +test wasm_instructions/wasm64/memop/memory.size ... bench: 2954507 ns/iter (+/- 146481) +test wasm_instructions/wasm64/memop/memory.size/confirmation ... bench: 5634200 ns/iter (+/- 148640) +test wasm_instructions/wasm32/memop/memory.grow ... bench: 1033298206 ns/iter (+/- 7680775) +test wasm_instructions/wasm32/memop/memory.grow/confirmation ... bench: 2066071762 ns/iter (+/- 6293545) +test wasm_instructions/wasm64/memop/memory.grow ... bench: 1018203069 ns/iter (+/- 2983299) +test wasm_instructions/wasm64/memop/memory.grow/confirmation ... bench: 2068656063 ns/iter (+/- 9248784) +test wasm_instructions/wasm32/memop/memory.fill ... bench: 194734069 ns/iter (+/- 1048294) +test wasm_instructions/wasm32/memop/memory.fill/confirmation ... bench: 390022598 ns/iter (+/- 720028) +test wasm_instructions/wasm64/memop/memory.fill ... bench: 193959597 ns/iter (+/- 1062209) +test wasm_instructions/wasm64/memop/memory.fill/confirmation ... bench: 390338249 ns/iter (+/- 810184) +test wasm_instructions/wasm32/memop/memory.copy ... bench: 230872268 ns/iter (+/- 934114) +test wasm_instructions/wasm32/memop/memory.copy/confirmation ... bench: 470773353 ns/iter (+/- 1170770) +test wasm_instructions/wasm64/memop/memory.copy ... bench: 231695152 ns/iter (+/- 868500) +test wasm_instructions/wasm64/memop/memory.copy/confirmation ... bench: 469268285 ns/iter (+/- 1926959) +test wasm_instructions/wasm32/ctrlop/select ... bench: 4820394 ns/iter (+/- 451223) +test wasm_instructions/wasm32/ctrlop/select/confirmation ... bench: 9415599 ns/iter (+/- 306363) +test wasm_instructions/wasm64/ctrlop/select ... bench: 4861600 ns/iter (+/- 473271) +test wasm_instructions/wasm64/ctrlop/select/confirmation ... bench: 9430384 ns/iter (+/- 629795) +test wasm_instructions/wasm32/ctrlop/call ... bench: 33415124 ns/iter (+/- 296170) +test wasm_instructions/wasm32/ctrlop/call/confirmation ... bench: 83074321 ns/iter (+/- 333515) +test wasm_instructions/wasm64/ctrlop/call ... bench: 33038331 ns/iter (+/- 572241) +test wasm_instructions/wasm64/ctrlop/call/confirmation ... bench: 83001759 ns/iter (+/- 960800) +test wasm_instructions/wasm32/ctrlop/call_indirect ... bench: 52897689 ns/iter (+/- 904801) +test wasm_instructions/wasm32/ctrlop/call_indirect/confirmation ... bench: 157701564 ns/iter (+/- 1611919) +test wasm_instructions/wasm64/ctrlop/call_indirect ... bench: 51940797 ns/iter (+/- 1044485) +test wasm_instructions/wasm64/ctrlop/call_indirect/confirmation ... bench: 156817649 ns/iter (+/- 483702) +test wasm_instructions/wasm32/ctrlop/recursive_return_call* ... bench: 215277195 ns/iter (+/- 45711741) +test wasm_instructions/wasm32/ctrlop/recursive_return_call*/confirmation ... bench: 457252980 ns/iter (+/- 90341574) +test wasm_instructions/wasm64/ctrlop/recursive_return_call* ... bench: 215640068 ns/iter (+/- 23195984) +test wasm_instructions/wasm64/ctrlop/recursive_return_call*/confirmation ... bench: 455670936 ns/iter (+/- 80301603) +test wasm_instructions/wasm32/ctrlop/recursive_call* ... bench: 250467854 ns/iter (+/- 994254) +test wasm_instructions/wasm32/ctrlop/recursive_call*/confirmation ... bench: 530770233 ns/iter (+/- 30177704) +test wasm_instructions/wasm64/ctrlop/recursive_call* ... bench: 250289094 ns/iter (+/- 29752453) +test wasm_instructions/wasm64/ctrlop/recursive_call*/confirmation ... bench: 528653165 ns/iter (+/- 3224989) +test wasm_instructions/wasm32/vconst/v128.const ... bench: 2657384 ns/iter (+/- 39034) +test wasm_instructions/wasm32/vconst/v128.const/confirmation ... bench: 5089743 ns/iter (+/- 510175) +test wasm_instructions/wasm64/vconst/v128.const ... bench: 2658489 ns/iter (+/- 18787) +test wasm_instructions/wasm64/vconst/v128.const/confirmation ... bench: 5120119 ns/iter (+/- 59920) +test wasm_instructions/wasm32/vconst/v128.const_add_locals ... bench: 2424069 ns/iter (+/- 35032) +test wasm_instructions/wasm32/vconst/v128.const_add_locals/confirmation ... bench: 4598769 ns/iter (+/- 20655) +test wasm_instructions/wasm64/vconst/v128.const_add_locals ... bench: 2420196 ns/iter (+/- 173178) +test wasm_instructions/wasm64/vconst/v128.const_add_locals/confirmation ... bench: 4585212 ns/iter (+/- 518037) +test wasm_instructions/wasm32/vconst/v128.const_add_constants ... bench: 4298227 ns/iter (+/- 245826) +test wasm_instructions/wasm32/vconst/v128.const_add_constants/confirmation ... bench: 8314250 ns/iter (+/- 46583) +test wasm_instructions/wasm64/vconst/v128.const_add_constants ... bench: 4309028 ns/iter (+/- 71536) +test wasm_instructions/wasm64/vconst/v128.const_add_constants/confirmation ... bench: 8315714 ns/iter (+/- 1148987) +test wasm_instructions/wasm32/vvunop/v128.not ... bench: 2679006 ns/iter (+/- 61685) +test wasm_instructions/wasm32/vvunop/v128.not/confirmation ... bench: 5654623 ns/iter (+/- 58286) +test wasm_instructions/wasm64/vvunop/v128.not ... bench: 2666131 ns/iter (+/- 253028) +test wasm_instructions/wasm64/vvunop/v128.not/confirmation ... bench: 5651326 ns/iter (+/- 389259) +test wasm_instructions/wasm32/vvbinop/v128.and ... bench: 2395334 ns/iter (+/- 160794) +test wasm_instructions/wasm32/vvbinop/v128.and/confirmation ... bench: 4567854 ns/iter (+/- 25908) +test wasm_instructions/wasm64/vvbinop/v128.and ... bench: 2355174 ns/iter (+/- 7785) +test wasm_instructions/wasm64/vvbinop/v128.and/confirmation ... bench: 4567981 ns/iter (+/- 57478) +test wasm_instructions/wasm32/vvbinop/v128.andnot ... bench: 2353440 ns/iter (+/- 19224) +test wasm_instructions/wasm32/vvbinop/v128.andnot/confirmation ... bench: 4550391 ns/iter (+/- 433402) +test wasm_instructions/wasm64/vvbinop/v128.andnot ... bench: 2386346 ns/iter (+/- 11917) +test wasm_instructions/wasm64/vvbinop/v128.andnot/confirmation ... bench: 4576146 ns/iter (+/- 113051) +test wasm_instructions/wasm32/vvbinop/v128.or ... bench: 2381705 ns/iter (+/- 134977) +test wasm_instructions/wasm32/vvbinop/v128.or/confirmation ... bench: 4579608 ns/iter (+/- 21746) +test wasm_instructions/wasm64/vvbinop/v128.or ... bench: 2430296 ns/iter (+/- 19677) +test wasm_instructions/wasm64/vvbinop/v128.or/confirmation ... bench: 4562036 ns/iter (+/- 243884) +test wasm_instructions/wasm32/vvbinop/v128.xor ... bench: 2387534 ns/iter (+/- 178008) +test wasm_instructions/wasm32/vvbinop/v128.xor/confirmation ... bench: 4571596 ns/iter (+/- 186733) +test wasm_instructions/wasm64/vvbinop/v128.xor ... bench: 2373914 ns/iter (+/- 22820) +test wasm_instructions/wasm64/vvbinop/v128.xor/confirmation ... bench: 4544810 ns/iter (+/- 345532) +test wasm_instructions/wasm32/vvternop/v128.bitselect ... bench: 3074696 ns/iter (+/- 143791) +test wasm_instructions/wasm32/vvternop/v128.bitselect/confirmation ... bench: 5906864 ns/iter (+/- 349937) +test wasm_instructions/wasm64/vvternop/v128.bitselect ... bench: 3131600 ns/iter (+/- 168271) +test wasm_instructions/wasm64/vvternop/v128.bitselect/confirmation ... bench: 5906431 ns/iter (+/- 420411) +test wasm_instructions/wasm32/vvtestop/v128.any_true ... bench: 3491849 ns/iter (+/- 169697) +test wasm_instructions/wasm32/vvtestop/v128.any_true/confirmation ... bench: 6688693 ns/iter (+/- 458088) +test wasm_instructions/wasm64/vvtestop/v128.any_true ... bench: 3540567 ns/iter (+/- 18508) +test wasm_instructions/wasm64/vvtestop/v128.any_true/confirmation ... bench: 6720712 ns/iter (+/- 386797) +test wasm_instructions/wasm32/vshuffle/i8x16.shuffle ... bench: 6733787 ns/iter (+/- 159513) +test wasm_instructions/wasm32/vshuffle/i8x16.shuffle/confirmation ... bench: 13829462 ns/iter (+/- 499017) +test wasm_instructions/wasm64/vshuffle/i8x16.shuffle ... bench: 6725432 ns/iter (+/- 237961) +test wasm_instructions/wasm64/vshuffle/i8x16.shuffle/confirmation ... bench: 13173728 ns/iter (+/- 27307) +test wasm_instructions/wasm32/vswizzle/i8x16.swizzle ... bench: 3240783 ns/iter (+/- 269464) +test wasm_instructions/wasm32/vswizzle/i8x16.swizzle/confirmation ... bench: 6771881 ns/iter (+/- 747977) +test wasm_instructions/wasm64/vswizzle/i8x16.swizzle ... bench: 3249482 ns/iter (+/- 271242) +test wasm_instructions/wasm64/vswizzle/i8x16.swizzle/confirmation ... bench: 6839889 ns/iter (+/- 487903) +test wasm_instructions/wasm32/vsplat/i8x16.splat ... bench: 2854501 ns/iter (+/- 139110) +test wasm_instructions/wasm32/vsplat/i8x16.splat/confirmation ... bench: 5359399 ns/iter (+/- 320544) +test wasm_instructions/wasm64/vsplat/i8x16.splat ... bench: 2816069 ns/iter (+/- 190474) +test wasm_instructions/wasm64/vsplat/i8x16.splat/confirmation ... bench: 5403175 ns/iter (+/- 353617) +test wasm_instructions/wasm32/vsplat/i16x8.splat ... bench: 2778045 ns/iter (+/- 327568) +test wasm_instructions/wasm32/vsplat/i16x8.splat/confirmation ... bench: 5385135 ns/iter (+/- 315689) +test wasm_instructions/wasm64/vsplat/i16x8.splat ... bench: 2831526 ns/iter (+/- 38428) +test wasm_instructions/wasm64/vsplat/i16x8.splat/confirmation ... bench: 5397519 ns/iter (+/- 243185) +test wasm_instructions/wasm32/vsplat/i32x4.splat ... bench: 2810047 ns/iter (+/- 30253) +test wasm_instructions/wasm32/vsplat/i32x4.splat/confirmation ... bench: 5430910 ns/iter (+/- 50261) +test wasm_instructions/wasm64/vsplat/i32x4.splat ... bench: 2812380 ns/iter (+/- 167910) +test wasm_instructions/wasm64/vsplat/i32x4.splat/confirmation ... bench: 5480181 ns/iter (+/- 57237) +test wasm_instructions/wasm32/vsplat/i64x2.splat ... bench: 2801921 ns/iter (+/- 298104) +test wasm_instructions/wasm32/vsplat/i64x2.splat/confirmation ... bench: 5436118 ns/iter (+/- 335298) +test wasm_instructions/wasm64/vsplat/i64x2.splat ... bench: 2836662 ns/iter (+/- 138925) +test wasm_instructions/wasm64/vsplat/i64x2.splat/confirmation ... bench: 5436523 ns/iter (+/- 356900) +test wasm_instructions/wasm32/vsplat/f32x4.splat ... bench: 2409635 ns/iter (+/- 115235) +test wasm_instructions/wasm32/vsplat/f32x4.splat/confirmation ... bench: 4566889 ns/iter (+/- 490894) +test wasm_instructions/wasm64/vsplat/f32x4.splat ... bench: 2358726 ns/iter (+/- 124167) +test wasm_instructions/wasm64/vsplat/f32x4.splat/confirmation ... bench: 4589249 ns/iter (+/- 28487) +test wasm_instructions/wasm32/vsplat/f64x2.splat ... bench: 2397477 ns/iter (+/- 26037) +test wasm_instructions/wasm32/vsplat/f64x2.splat/confirmation ... bench: 4553606 ns/iter (+/- 522023) +test wasm_instructions/wasm64/vsplat/f64x2.splat ... bench: 2421014 ns/iter (+/- 143325) +test wasm_instructions/wasm64/vsplat/f64x2.splat/confirmation ... bench: 4627335 ns/iter (+/- 331964) +test wasm_instructions/wasm32/vextlane/i32x4.extract_lane ... bench: 2396019 ns/iter (+/- 70010) +test wasm_instructions/wasm32/vextlane/i32x4.extract_lane/confirmation ... bench: 4575706 ns/iter (+/- 149824) +test wasm_instructions/wasm64/vextlane/i32x4.extract_lane ... bench: 2376040 ns/iter (+/- 135181) +test wasm_instructions/wasm64/vextlane/i32x4.extract_lane/confirmation ... bench: 4536862 ns/iter (+/- 580133) +test wasm_instructions/wasm32/vextlane/i64x2.extract_lane ... bench: 2394388 ns/iter (+/- 118802) +test wasm_instructions/wasm32/vextlane/i64x2.extract_lane/confirmation ... bench: 4550226 ns/iter (+/- 316434) +test wasm_instructions/wasm64/vextlane/i64x2.extract_lane ... bench: 2392154 ns/iter (+/- 122711) +test wasm_instructions/wasm64/vextlane/i64x2.extract_lane/confirmation ... bench: 4566068 ns/iter (+/- 257026) +test wasm_instructions/wasm32/vextlane/f32x4.extract_lane ... bench: 2387095 ns/iter (+/- 17814) +test wasm_instructions/wasm32/vextlane/f32x4.extract_lane/confirmation ... bench: 4562863 ns/iter (+/- 453588) +test wasm_instructions/wasm64/vextlane/f32x4.extract_lane ... bench: 2433290 ns/iter (+/- 20182) +test wasm_instructions/wasm64/vextlane/f32x4.extract_lane/confirmation ... bench: 4577181 ns/iter (+/- 233063) +test wasm_instructions/wasm32/vextlane/f64x2.extract_lane ... bench: 2435909 ns/iter (+/- 39031) +test wasm_instructions/wasm32/vextlane/f64x2.extract_lane/confirmation ... bench: 4573679 ns/iter (+/- 264119) +test wasm_instructions/wasm64/vextlane/f64x2.extract_lane ... bench: 2393770 ns/iter (+/- 89748) +test wasm_instructions/wasm64/vextlane/f64x2.extract_lane/confirmation ... bench: 4623753 ns/iter (+/- 209035) +test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_s ... bench: 3247709 ns/iter (+/- 308865) +test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_s/confirmation ... bench: 6269374 ns/iter (+/- 61700) +test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_s ... bench: 3227466 ns/iter (+/- 330106) +test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_s/confirmation ... bench: 6291342 ns/iter (+/- 345393) +test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_u ... bench: 3239832 ns/iter (+/- 231067) +test wasm_instructions/wasm32/vextlane/i8x16.extract_lane_u/confirmation ... bench: 6253092 ns/iter (+/- 16288) +test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_u ... bench: 3229580 ns/iter (+/- 204819) +test wasm_instructions/wasm64/vextlane/i8x16.extract_lane_u/confirmation ... bench: 6249206 ns/iter (+/- 167064) +test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_s ... bench: 3247272 ns/iter (+/- 260412) +test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_s/confirmation ... bench: 6267227 ns/iter (+/- 87818) +test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_s ... bench: 3222359 ns/iter (+/- 214475) +test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_s/confirmation ... bench: 6252621 ns/iter (+/- 441934) +test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_u ... bench: 3246202 ns/iter (+/- 156312) +test wasm_instructions/wasm32/vextlane/i16x8.extract_lane_u/confirmation ... bench: 6257077 ns/iter (+/- 104611) +test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_u ... bench: 3277806 ns/iter (+/- 50995) +test wasm_instructions/wasm64/vextlane/i16x8.extract_lane_u/confirmation ... bench: 6267358 ns/iter (+/- 597141) +test wasm_instructions/wasm32/vreplane/i8x16.replace_lane ... bench: 3083314 ns/iter (+/- 181166) +test wasm_instructions/wasm32/vreplane/i8x16.replace_lane/confirmation ... bench: 5736807 ns/iter (+/- 831120) +test wasm_instructions/wasm64/vreplane/i8x16.replace_lane ... bench: 3162042 ns/iter (+/- 284492) +test wasm_instructions/wasm64/vreplane/i8x16.replace_lane/confirmation ... bench: 5498269 ns/iter (+/- 608755) +test wasm_instructions/wasm32/vreplane/i16x8.replace_lane ... bench: 3101718 ns/iter (+/- 99764) +test wasm_instructions/wasm32/vreplane/i16x8.replace_lane/confirmation ... bench: 5158342 ns/iter (+/- 25076) +test wasm_instructions/wasm64/vreplane/i16x8.replace_lane ... bench: 2853019 ns/iter (+/- 163334) +test wasm_instructions/wasm64/vreplane/i16x8.replace_lane/confirmation ... bench: 5247823 ns/iter (+/- 90922) +test wasm_instructions/wasm32/vreplane/i32x4.replace_lane ... bench: 3147208 ns/iter (+/- 107646) +test wasm_instructions/wasm32/vreplane/i32x4.replace_lane/confirmation ... bench: 5502872 ns/iter (+/- 712842) +test wasm_instructions/wasm64/vreplane/i32x4.replace_lane ... bench: 3137336 ns/iter (+/- 375462) +test wasm_instructions/wasm64/vreplane/i32x4.replace_lane/confirmation ... bench: 5653187 ns/iter (+/- 238604) +test wasm_instructions/wasm32/vreplane/i64x2.replace_lane ... bench: 2839179 ns/iter (+/- 105384) +test wasm_instructions/wasm32/vreplane/i64x2.replace_lane/confirmation ... bench: 5242261 ns/iter (+/- 64550) +test wasm_instructions/wasm64/vreplane/i64x2.replace_lane ... bench: 3068554 ns/iter (+/- 390492) +test wasm_instructions/wasm64/vreplane/i64x2.replace_lane/confirmation ... bench: 5449856 ns/iter (+/- 425720) +test wasm_instructions/wasm32/vreplane/f32x4.replace_lane ... bench: 2359303 ns/iter (+/- 131600) +test wasm_instructions/wasm32/vreplane/f32x4.replace_lane/confirmation ... bench: 4573321 ns/iter (+/- 235930) +test wasm_instructions/wasm64/vreplane/f32x4.replace_lane ... bench: 2400176 ns/iter (+/- 117459) +test wasm_instructions/wasm64/vreplane/f32x4.replace_lane/confirmation ... bench: 4594507 ns/iter (+/- 42384) +test wasm_instructions/wasm32/vreplane/f64x2.replace_lane ... bench: 2421309 ns/iter (+/- 115903) +test wasm_instructions/wasm32/vreplane/f64x2.replace_lane/confirmation ... bench: 4525408 ns/iter (+/- 446097) +test wasm_instructions/wasm64/vreplane/f64x2.replace_lane ... bench: 2468711 ns/iter (+/- 30253) +test wasm_instructions/wasm64/vreplane/f64x2.replace_lane/confirmation ... bench: 4565841 ns/iter (+/- 385976) +test wasm_instructions/wasm32/virelop/i8x16.eq ... bench: 2423591 ns/iter (+/- 164202) +test wasm_instructions/wasm32/virelop/i8x16.eq/confirmation ... bench: 4587755 ns/iter (+/- 470435) +test wasm_instructions/wasm64/virelop/i8x16.eq ... bench: 2419420 ns/iter (+/- 147538) +test wasm_instructions/wasm64/virelop/i8x16.eq/confirmation ... bench: 4563743 ns/iter (+/- 19691) +test wasm_instructions/wasm32/virelop/i8x16.ne ... bench: 3039185 ns/iter (+/- 274179) +test wasm_instructions/wasm32/virelop/i8x16.ne/confirmation ... bench: 6033797 ns/iter (+/- 38520) +test wasm_instructions/wasm64/virelop/i8x16.ne ... bench: 3072124 ns/iter (+/- 78602) +test wasm_instructions/wasm64/virelop/i8x16.ne/confirmation ... bench: 5927939 ns/iter (+/- 129987) +test wasm_instructions/wasm32/virelop/i8x16.lt_s ... bench: 2354111 ns/iter (+/- 36208) +test wasm_instructions/wasm32/virelop/i8x16.lt_s/confirmation ... bench: 4576634 ns/iter (+/- 528401) +test wasm_instructions/wasm64/virelop/i8x16.lt_s ... bench: 2379798 ns/iter (+/- 13413) +test wasm_instructions/wasm64/virelop/i8x16.lt_s/confirmation ... bench: 4564324 ns/iter (+/- 39523) +test wasm_instructions/wasm32/virelop/i8x16.gt_s ... bench: 2426412 ns/iter (+/- 146034) +test wasm_instructions/wasm32/virelop/i8x16.gt_s/confirmation ... bench: 4605249 ns/iter (+/- 19399) +test wasm_instructions/wasm64/virelop/i8x16.gt_s ... bench: 2364146 ns/iter (+/- 17825) +test wasm_instructions/wasm64/virelop/i8x16.gt_s/confirmation ... bench: 4634247 ns/iter (+/- 292374) +test wasm_instructions/wasm32/virelop/i8x16.le_s ... bench: 2645316 ns/iter (+/- 261996) +test wasm_instructions/wasm32/virelop/i8x16.le_s/confirmation ... bench: 5645180 ns/iter (+/- 412594) +test wasm_instructions/wasm64/virelop/i8x16.le_s ... bench: 2646178 ns/iter (+/- 191940) +test wasm_instructions/wasm64/virelop/i8x16.le_s/confirmation ... bench: 5648468 ns/iter (+/- 701663) +test wasm_instructions/wasm32/virelop/i8x16.le_u ... bench: 2726300 ns/iter (+/- 55579) +test wasm_instructions/wasm32/virelop/i8x16.le_u/confirmation ... bench: 5083585 ns/iter (+/- 639866) +test wasm_instructions/wasm64/virelop/i8x16.le_u ... bench: 2675279 ns/iter (+/- 256272) +test wasm_instructions/wasm64/virelop/i8x16.le_u/confirmation ... bench: 5220408 ns/iter (+/- 65624) +test wasm_instructions/wasm32/virelop/i8x16.ge_s ... bench: 2672395 ns/iter (+/- 214354) +test wasm_instructions/wasm32/virelop/i8x16.ge_s/confirmation ... bench: 5765062 ns/iter (+/- 44502) +test wasm_instructions/wasm64/virelop/i8x16.ge_s ... bench: 2685329 ns/iter (+/- 175309) +test wasm_instructions/wasm64/virelop/i8x16.ge_s/confirmation ... bench: 5639063 ns/iter (+/- 204958) +test wasm_instructions/wasm32/virelop/i8x16.ge_u ... bench: 2639794 ns/iter (+/- 154267) +test wasm_instructions/wasm32/virelop/i8x16.ge_u/confirmation ... bench: 5092423 ns/iter (+/- 650677) +test wasm_instructions/wasm64/virelop/i8x16.ge_u ... bench: 2628718 ns/iter (+/- 117619) +test wasm_instructions/wasm64/virelop/i8x16.ge_u/confirmation ... bench: 5224808 ns/iter (+/- 29441) +test wasm_instructions/wasm32/virelop/i16x8.eq ... bench: 2389984 ns/iter (+/- 25249) +test wasm_instructions/wasm32/virelop/i16x8.eq/confirmation ... bench: 4572979 ns/iter (+/- 19267) +test wasm_instructions/wasm64/virelop/i16x8.eq ... bench: 2407052 ns/iter (+/- 147446) +test wasm_instructions/wasm64/virelop/i16x8.eq/confirmation ... bench: 4615990 ns/iter (+/- 236638) +test wasm_instructions/wasm32/virelop/i16x8.ne ... bench: 3176170 ns/iter (+/- 29097) +test wasm_instructions/wasm32/virelop/i16x8.ne/confirmation ... bench: 6011038 ns/iter (+/- 351231) +test wasm_instructions/wasm64/virelop/i16x8.ne ... bench: 3100080 ns/iter (+/- 95528) +test wasm_instructions/wasm64/virelop/i16x8.ne/confirmation ... bench: 6021724 ns/iter (+/- 91204) +test wasm_instructions/wasm32/virelop/i16x8.lt_s ... bench: 2419082 ns/iter (+/- 12457) +test wasm_instructions/wasm32/virelop/i16x8.lt_s/confirmation ... bench: 4564606 ns/iter (+/- 424568) +test wasm_instructions/wasm64/virelop/i16x8.lt_s ... bench: 2395152 ns/iter (+/- 188868) +test wasm_instructions/wasm64/virelop/i16x8.lt_s/confirmation ... bench: 4582866 ns/iter (+/- 343754) +test wasm_instructions/wasm32/virelop/i16x8.gt_s ... bench: 2380850 ns/iter (+/- 135193) +test wasm_instructions/wasm32/virelop/i16x8.gt_s/confirmation ... bench: 4536595 ns/iter (+/- 281352) +test wasm_instructions/wasm64/virelop/i16x8.gt_s ... bench: 2385737 ns/iter (+/- 177273) +test wasm_instructions/wasm64/virelop/i16x8.gt_s/confirmation ... bench: 4547893 ns/iter (+/- 407752) +test wasm_instructions/wasm32/virelop/i16x8.le_s ... bench: 2697651 ns/iter (+/- 45499) +test wasm_instructions/wasm32/virelop/i16x8.le_s/confirmation ... bench: 5221926 ns/iter (+/- 374759) +test wasm_instructions/wasm64/virelop/i16x8.le_s ... bench: 2670943 ns/iter (+/- 203482) +test wasm_instructions/wasm64/virelop/i16x8.le_s/confirmation ... bench: 5120894 ns/iter (+/- 44551) +test wasm_instructions/wasm32/virelop/i16x8.le_u ... bench: 2665465 ns/iter (+/- 15711) +test wasm_instructions/wasm32/virelop/i16x8.le_u/confirmation ... bench: 5634122 ns/iter (+/- 243274) +test wasm_instructions/wasm64/virelop/i16x8.le_u ... bench: 2682665 ns/iter (+/- 27272) +test wasm_instructions/wasm64/virelop/i16x8.le_u/confirmation ... bench: 5644565 ns/iter (+/- 371536) +test wasm_instructions/wasm32/virelop/i16x8.ge_s ... bench: 2652298 ns/iter (+/- 59419) +test wasm_instructions/wasm32/virelop/i16x8.ge_s/confirmation ... bench: 5112589 ns/iter (+/- 27565) +test wasm_instructions/wasm64/virelop/i16x8.ge_s ... bench: 2700867 ns/iter (+/- 34546) +test wasm_instructions/wasm64/virelop/i16x8.ge_s/confirmation ... bench: 5113228 ns/iter (+/- 32659) +test wasm_instructions/wasm32/virelop/i16x8.ge_u ... bench: 2651401 ns/iter (+/- 313834) +test wasm_instructions/wasm32/virelop/i16x8.ge_u/confirmation ... bench: 5735152 ns/iter (+/- 62981) +test wasm_instructions/wasm64/virelop/i16x8.ge_u ... bench: 2658669 ns/iter (+/- 124132) +test wasm_instructions/wasm64/virelop/i16x8.ge_u/confirmation ... bench: 5641514 ns/iter (+/- 263002) +test wasm_instructions/wasm32/virelop/i32x4.eq ... bench: 2415341 ns/iter (+/- 217907) +test wasm_instructions/wasm32/virelop/i32x4.eq/confirmation ... bench: 4576351 ns/iter (+/- 202276) +test wasm_instructions/wasm64/virelop/i32x4.eq ... bench: 2426666 ns/iter (+/- 17060) +test wasm_instructions/wasm64/virelop/i32x4.eq/confirmation ... bench: 4545988 ns/iter (+/- 280960) +test wasm_instructions/wasm32/virelop/i32x4.ne ... bench: 3046279 ns/iter (+/- 330316) +test wasm_instructions/wasm32/virelop/i32x4.ne/confirmation ... bench: 6028194 ns/iter (+/- 246612) +test wasm_instructions/wasm64/virelop/i32x4.ne ... bench: 3074236 ns/iter (+/- 234788) +test wasm_instructions/wasm64/virelop/i32x4.ne/confirmation ... bench: 5910954 ns/iter (+/- 124669) +test wasm_instructions/wasm32/virelop/i32x4.lt_s ... bench: 2348892 ns/iter (+/- 113030) +test wasm_instructions/wasm32/virelop/i32x4.lt_s/confirmation ... bench: 4543444 ns/iter (+/- 304530) +test wasm_instructions/wasm64/virelop/i32x4.lt_s ... bench: 2396472 ns/iter (+/- 147862) +test wasm_instructions/wasm64/virelop/i32x4.lt_s/confirmation ... bench: 4562028 ns/iter (+/- 283336) +test wasm_instructions/wasm32/virelop/i32x4.gt_s ... bench: 2377080 ns/iter (+/- 36045) +test wasm_instructions/wasm32/virelop/i32x4.gt_s/confirmation ... bench: 4572429 ns/iter (+/- 323101) +test wasm_instructions/wasm64/virelop/i32x4.gt_s ... bench: 2405667 ns/iter (+/- 121337) +test wasm_instructions/wasm64/virelop/i32x4.gt_s/confirmation ... bench: 4527323 ns/iter (+/- 452151) +test wasm_instructions/wasm32/virelop/i32x4.le_s ... bench: 2668383 ns/iter (+/- 240835) +test wasm_instructions/wasm32/virelop/i32x4.le_s/confirmation ... bench: 5629645 ns/iter (+/- 247578) +test wasm_instructions/wasm64/virelop/i32x4.le_s ... bench: 2648038 ns/iter (+/- 221215) +test wasm_instructions/wasm64/virelop/i32x4.le_s/confirmation ... bench: 5647722 ns/iter (+/- 382635) +test wasm_instructions/wasm32/virelop/i32x4.le_u ... bench: 2716350 ns/iter (+/- 21055) +test wasm_instructions/wasm32/virelop/i32x4.le_u/confirmation ... bench: 5692821 ns/iter (+/- 51650) +test wasm_instructions/wasm64/virelop/i32x4.le_u ... bench: 2656759 ns/iter (+/- 12092) +test wasm_instructions/wasm64/virelop/i32x4.le_u/confirmation ... bench: 5677686 ns/iter (+/- 28200) +test wasm_instructions/wasm32/virelop/i32x4.ge_s ... bench: 2648842 ns/iter (+/- 32624) +test wasm_instructions/wasm32/virelop/i32x4.ge_s/confirmation ... bench: 5627575 ns/iter (+/- 459057) +test wasm_instructions/wasm64/virelop/i32x4.ge_s ... bench: 2657431 ns/iter (+/- 212853) +test wasm_instructions/wasm64/virelop/i32x4.ge_s/confirmation ... bench: 5646130 ns/iter (+/- 116943) +test wasm_instructions/wasm32/virelop/i32x4.ge_u ... bench: 2641352 ns/iter (+/- 122293) +test wasm_instructions/wasm32/virelop/i32x4.ge_u/confirmation ... bench: 5659328 ns/iter (+/- 618474) +test wasm_instructions/wasm64/virelop/i32x4.ge_u ... bench: 2666370 ns/iter (+/- 24762) +test wasm_instructions/wasm64/virelop/i32x4.ge_u/confirmation ... bench: 5631377 ns/iter (+/- 553701) +test wasm_instructions/wasm32/virelop/i64x2.eq ... bench: 2389339 ns/iter (+/- 87511) +test wasm_instructions/wasm32/virelop/i64x2.eq/confirmation ... bench: 4528467 ns/iter (+/- 318739) +test wasm_instructions/wasm64/virelop/i64x2.eq ... bench: 2376221 ns/iter (+/- 16040) +test wasm_instructions/wasm64/virelop/i64x2.eq/confirmation ... bench: 4594812 ns/iter (+/- 138919) +test wasm_instructions/wasm32/virelop/i64x2.ne ... bench: 3173707 ns/iter (+/- 425311) +test wasm_instructions/wasm32/virelop/i64x2.ne/confirmation ... bench: 6272291 ns/iter (+/- 266926) +test wasm_instructions/wasm64/virelop/i64x2.ne ... bench: 3230780 ns/iter (+/- 461892) +test wasm_instructions/wasm64/virelop/i64x2.ne/confirmation ... bench: 6179597 ns/iter (+/- 609089) +test wasm_instructions/wasm32/virelop/i64x2.lt_s ... bench: 2400307 ns/iter (+/- 225935) +test wasm_instructions/wasm32/virelop/i64x2.lt_s/confirmation ... bench: 4586982 ns/iter (+/- 24892) +test wasm_instructions/wasm64/virelop/i64x2.lt_s ... bench: 2417391 ns/iter (+/- 30721) +test wasm_instructions/wasm64/virelop/i64x2.lt_s/confirmation ... bench: 4573819 ns/iter (+/- 247314) +test wasm_instructions/wasm32/virelop/i64x2.gt_s ... bench: 2433669 ns/iter (+/- 81564) +test wasm_instructions/wasm32/virelop/i64x2.gt_s/confirmation ... bench: 4546249 ns/iter (+/- 60630) +test wasm_instructions/wasm64/virelop/i64x2.gt_s ... bench: 2403926 ns/iter (+/- 37738) +test wasm_instructions/wasm64/virelop/i64x2.gt_s/confirmation ... bench: 4587487 ns/iter (+/- 51973) +test wasm_instructions/wasm32/virelop/i64x2.le_s ... bench: 3222976 ns/iter (+/- 19876) +test wasm_instructions/wasm32/virelop/i64x2.le_s/confirmation ... bench: 6196975 ns/iter (+/- 406291) +test wasm_instructions/wasm64/virelop/i64x2.le_s ... bench: 3233285 ns/iter (+/- 401144) +test wasm_instructions/wasm64/virelop/i64x2.le_s/confirmation ... bench: 6259023 ns/iter (+/- 70857) +test wasm_instructions/wasm32/virelop/i64x2.ge_s ... bench: 3194670 ns/iter (+/- 311530) +test wasm_instructions/wasm32/virelop/i64x2.ge_s/confirmation ... bench: 6189072 ns/iter (+/- 24518) +test wasm_instructions/wasm64/virelop/i64x2.ge_s ... bench: 3211224 ns/iter (+/- 152651) +test wasm_instructions/wasm64/virelop/i64x2.ge_s/confirmation ... bench: 6172239 ns/iter (+/- 319484) +test wasm_instructions/wasm32/virelop/i8x16.lt_u ... bench: 4631220 ns/iter (+/- 350357) +test wasm_instructions/wasm32/virelop/i8x16.lt_u/confirmation ... bench: 8813736 ns/iter (+/- 657464) +test wasm_instructions/wasm64/virelop/i8x16.lt_u ... bench: 4582314 ns/iter (+/- 25720) +test wasm_instructions/wasm64/virelop/i8x16.lt_u/confirmation ... bench: 8961904 ns/iter (+/- 41184) +test wasm_instructions/wasm32/virelop/i8x16.gt_u ... bench: 4526412 ns/iter (+/- 310111) +test wasm_instructions/wasm32/virelop/i8x16.gt_u/confirmation ... bench: 8823876 ns/iter (+/- 134262) +test wasm_instructions/wasm64/virelop/i8x16.gt_u ... bench: 4551450 ns/iter (+/- 519480) +test wasm_instructions/wasm64/virelop/i8x16.gt_u/confirmation ... bench: 8921869 ns/iter (+/- 278724) +test wasm_instructions/wasm32/virelop/i16x8.lt_u ... bench: 4533305 ns/iter (+/- 228740) +test wasm_instructions/wasm32/virelop/i16x8.lt_u/confirmation ... bench: 8837147 ns/iter (+/- 21011) +test wasm_instructions/wasm64/virelop/i16x8.lt_u ... bench: 4561001 ns/iter (+/- 362942) +test wasm_instructions/wasm64/virelop/i16x8.lt_u/confirmation ... bench: 8825096 ns/iter (+/- 723878) +test wasm_instructions/wasm32/virelop/i16x8.gt_u ... bench: 4565881 ns/iter (+/- 12943) +test wasm_instructions/wasm32/virelop/i16x8.gt_u/confirmation ... bench: 8825761 ns/iter (+/- 16811) +test wasm_instructions/wasm64/virelop/i16x8.gt_u ... bench: 4559641 ns/iter (+/- 377417) +test wasm_instructions/wasm64/virelop/i16x8.gt_u/confirmation ... bench: 9003905 ns/iter (+/- 596066) +test wasm_instructions/wasm32/virelop/i32x4.lt_u ... bench: 4561706 ns/iter (+/- 54101) +test wasm_instructions/wasm32/virelop/i32x4.lt_u/confirmation ... bench: 8886798 ns/iter (+/- 226947) +test wasm_instructions/wasm64/virelop/i32x4.lt_u ... bench: 4623535 ns/iter (+/- 250320) +test wasm_instructions/wasm64/virelop/i32x4.lt_u/confirmation ... bench: 8931924 ns/iter (+/- 70121) +test wasm_instructions/wasm32/virelop/i32x4.gt_u ... bench: 4540245 ns/iter (+/- 277502) +test wasm_instructions/wasm32/virelop/i32x4.gt_u/confirmation ... bench: 8800706 ns/iter (+/- 673971) +test wasm_instructions/wasm64/virelop/i32x4.gt_u ... bench: 4544093 ns/iter (+/- 286729) +test wasm_instructions/wasm64/virelop/i32x4.gt_u/confirmation ... bench: 8887312 ns/iter (+/- 21089) +test wasm_instructions/wasm32/vfrelop/f32x4.eq ... bench: 2376566 ns/iter (+/- 45784) +test wasm_instructions/wasm32/vfrelop/f32x4.eq/confirmation ... bench: 4571001 ns/iter (+/- 197049) +test wasm_instructions/wasm64/vfrelop/f32x4.eq ... bench: 2389973 ns/iter (+/- 42246) +test wasm_instructions/wasm64/vfrelop/f32x4.eq/confirmation ... bench: 4610557 ns/iter (+/- 297263) +test wasm_instructions/wasm32/vfrelop/f32x4.ne ... bench: 2419321 ns/iter (+/- 158258) +test wasm_instructions/wasm32/vfrelop/f32x4.ne/confirmation ... bench: 4541965 ns/iter (+/- 214247) +test wasm_instructions/wasm64/vfrelop/f32x4.ne ... bench: 2448207 ns/iter (+/- 37040) +test wasm_instructions/wasm64/vfrelop/f32x4.ne/confirmation ... bench: 4556219 ns/iter (+/- 352333) +test wasm_instructions/wasm32/vfrelop/f32x4.lt ... bench: 2385852 ns/iter (+/- 210257) +test wasm_instructions/wasm32/vfrelop/f32x4.lt/confirmation ... bench: 4535418 ns/iter (+/- 401398) +test wasm_instructions/wasm64/vfrelop/f32x4.lt ... bench: 2443613 ns/iter (+/- 74039) +test wasm_instructions/wasm64/vfrelop/f32x4.lt/confirmation ... bench: 4597842 ns/iter (+/- 384932) +test wasm_instructions/wasm32/vfrelop/f32x4.gt ... bench: 2408028 ns/iter (+/- 96801) +test wasm_instructions/wasm32/vfrelop/f32x4.gt/confirmation ... bench: 4543279 ns/iter (+/- 480331) +test wasm_instructions/wasm64/vfrelop/f32x4.gt ... bench: 2390335 ns/iter (+/- 297396) +test wasm_instructions/wasm64/vfrelop/f32x4.gt/confirmation ... bench: 4636447 ns/iter (+/- 251729) +test wasm_instructions/wasm32/vfrelop/f32x4.le ... bench: 2393340 ns/iter (+/- 4832) +test wasm_instructions/wasm32/vfrelop/f32x4.le/confirmation ... bench: 4582694 ns/iter (+/- 34490) +test wasm_instructions/wasm64/vfrelop/f32x4.le ... bench: 2397194 ns/iter (+/- 12681) +test wasm_instructions/wasm64/vfrelop/f32x4.le/confirmation ... bench: 4588037 ns/iter (+/- 441836) +test wasm_instructions/wasm32/vfrelop/f32x4.ge ... bench: 2380289 ns/iter (+/- 139443) +test wasm_instructions/wasm32/vfrelop/f32x4.ge/confirmation ... bench: 4667831 ns/iter (+/- 147466) +test wasm_instructions/wasm64/vfrelop/f32x4.ge ... bench: 2386788 ns/iter (+/- 178596) +test wasm_instructions/wasm64/vfrelop/f32x4.ge/confirmation ... bench: 4593219 ns/iter (+/- 486144) +test wasm_instructions/wasm32/vfrelop/f64x2.eq ... bench: 2466416 ns/iter (+/- 137202) +test wasm_instructions/wasm32/vfrelop/f64x2.eq/confirmation ... bench: 4538233 ns/iter (+/- 21784) +test wasm_instructions/wasm64/vfrelop/f64x2.eq ... bench: 2419827 ns/iter (+/- 157384) +test wasm_instructions/wasm64/vfrelop/f64x2.eq/confirmation ... bench: 4562529 ns/iter (+/- 288449) +test wasm_instructions/wasm32/vfrelop/f64x2.ne ... bench: 2383595 ns/iter (+/- 26812) +test wasm_instructions/wasm32/vfrelop/f64x2.ne/confirmation ... bench: 4570294 ns/iter (+/- 149415) +test wasm_instructions/wasm64/vfrelop/f64x2.ne ... bench: 2415727 ns/iter (+/- 135989) +test wasm_instructions/wasm64/vfrelop/f64x2.ne/confirmation ... bench: 4561103 ns/iter (+/- 898975) +test wasm_instructions/wasm32/vfrelop/f64x2.lt ... bench: 2438275 ns/iter (+/- 17085) +test wasm_instructions/wasm32/vfrelop/f64x2.lt/confirmation ... bench: 4573709 ns/iter (+/- 33171) +test wasm_instructions/wasm64/vfrelop/f64x2.lt ... bench: 2380687 ns/iter (+/- 218052) +test wasm_instructions/wasm64/vfrelop/f64x2.lt/confirmation ... bench: 4594952 ns/iter (+/- 58678) +test wasm_instructions/wasm32/vfrelop/f64x2.gt ... bench: 2404358 ns/iter (+/- 59964) +test wasm_instructions/wasm32/vfrelop/f64x2.gt/confirmation ... bench: 4556656 ns/iter (+/- 303847) +test wasm_instructions/wasm64/vfrelop/f64x2.gt ... bench: 2394928 ns/iter (+/- 55455) +test wasm_instructions/wasm64/vfrelop/f64x2.gt/confirmation ... bench: 4548113 ns/iter (+/- 476164) +test wasm_instructions/wasm32/vfrelop/f64x2.le ... bench: 2388383 ns/iter (+/- 152612) +test wasm_instructions/wasm32/vfrelop/f64x2.le/confirmation ... bench: 4529256 ns/iter (+/- 753898) +test wasm_instructions/wasm64/vfrelop/f64x2.le ... bench: 2369138 ns/iter (+/- 62690) +test wasm_instructions/wasm64/vfrelop/f64x2.le/confirmation ... bench: 4592915 ns/iter (+/- 20032) +test wasm_instructions/wasm32/vfrelop/f64x2.ge ... bench: 2391249 ns/iter (+/- 148304) +test wasm_instructions/wasm32/vfrelop/f64x2.ge/confirmation ... bench: 4664963 ns/iter (+/- 29532) +test wasm_instructions/wasm64/vfrelop/f64x2.ge ... bench: 2384446 ns/iter (+/- 26475) +test wasm_instructions/wasm64/vfrelop/f64x2.ge/confirmation ... bench: 4566646 ns/iter (+/- 411059) +test wasm_instructions/wasm32/viunop/i8x16.abs ... bench: 2378035 ns/iter (+/- 60752) +test wasm_instructions/wasm32/viunop/i8x16.abs/confirmation ... bench: 4575509 ns/iter (+/- 565399) +test wasm_instructions/wasm64/viunop/i8x16.abs ... bench: 2384002 ns/iter (+/- 139015) +test wasm_instructions/wasm64/viunop/i8x16.abs/confirmation ... bench: 4573097 ns/iter (+/- 306050) +test wasm_instructions/wasm32/viunop/i16x8.abs ... bench: 2410310 ns/iter (+/- 21857) +test wasm_instructions/wasm32/viunop/i16x8.abs/confirmation ... bench: 4591977 ns/iter (+/- 53663) +test wasm_instructions/wasm64/viunop/i16x8.abs ... bench: 2429133 ns/iter (+/- 128605) +test wasm_instructions/wasm64/viunop/i16x8.abs/confirmation ... bench: 4564252 ns/iter (+/- 431199) +test wasm_instructions/wasm32/viunop/i32x4.abs ... bench: 2421906 ns/iter (+/- 21605) +test wasm_instructions/wasm32/viunop/i32x4.abs/confirmation ... bench: 4557524 ns/iter (+/- 335240) +test wasm_instructions/wasm64/viunop/i32x4.abs ... bench: 2382579 ns/iter (+/- 208946) +test wasm_instructions/wasm64/viunop/i32x4.abs/confirmation ... bench: 4560951 ns/iter (+/- 221090) +test wasm_instructions/wasm32/viunop/i64x2.abs ... bench: 3463272 ns/iter (+/- 274804) +test wasm_instructions/wasm32/viunop/i64x2.abs/confirmation ... bench: 6691811 ns/iter (+/- 554132) +test wasm_instructions/wasm64/viunop/i64x2.abs ... bench: 3458577 ns/iter (+/- 498912) +test wasm_instructions/wasm64/viunop/i64x2.abs/confirmation ... bench: 6727589 ns/iter (+/- 50393) +test wasm_instructions/wasm32/viunop/i8x16.neg ... bench: 2682397 ns/iter (+/- 33172) +test wasm_instructions/wasm32/viunop/i8x16.neg/confirmation ... bench: 5619692 ns/iter (+/- 655804) +test wasm_instructions/wasm64/viunop/i8x16.neg ... bench: 2697338 ns/iter (+/- 38968) +test wasm_instructions/wasm64/viunop/i8x16.neg/confirmation ... bench: 5711362 ns/iter (+/- 87575) +test wasm_instructions/wasm32/viunop/i16x8.neg ... bench: 2664850 ns/iter (+/- 121931) +test wasm_instructions/wasm32/viunop/i16x8.neg/confirmation ... bench: 5612804 ns/iter (+/- 609198) +test wasm_instructions/wasm64/viunop/i16x8.neg ... bench: 2654721 ns/iter (+/- 29759) +test wasm_instructions/wasm64/viunop/i16x8.neg/confirmation ... bench: 5664268 ns/iter (+/- 266489) +test wasm_instructions/wasm32/viunop/i32x4.neg ... bench: 2725039 ns/iter (+/- 31326) +test wasm_instructions/wasm32/viunop/i32x4.neg/confirmation ... bench: 5737902 ns/iter (+/- 20929) +test wasm_instructions/wasm64/viunop/i32x4.neg ... bench: 2708616 ns/iter (+/- 205007) +test wasm_instructions/wasm64/viunop/i32x4.neg/confirmation ... bench: 5636218 ns/iter (+/- 599664) +test wasm_instructions/wasm32/viunop/i64x2.neg ... bench: 2709108 ns/iter (+/- 33241) +test wasm_instructions/wasm32/viunop/i64x2.neg/confirmation ... bench: 5594756 ns/iter (+/- 370855) +test wasm_instructions/wasm64/viunop/i64x2.neg ... bench: 2650922 ns/iter (+/- 118528) +test wasm_instructions/wasm64/viunop/i64x2.neg/confirmation ... bench: 5756050 ns/iter (+/- 35612) +test wasm_instructions/wasm32/viunop/i8x16.popcnt ... bench: 7727225 ns/iter (+/- 139867) +test wasm_instructions/wasm32/viunop/i8x16.popcnt/confirmation ... bench: 18206624 ns/iter (+/- 842558) +test wasm_instructions/wasm64/viunop/i8x16.popcnt ... bench: 8490703 ns/iter (+/- 333294) +test wasm_instructions/wasm64/viunop/i8x16.popcnt/confirmation ... bench: 16746202 ns/iter (+/- 1716842) +test wasm_instructions/wasm32/vq15mulr/i16x8.q15mulr_sat_s ... bench: 3747186 ns/iter (+/- 310617) +test wasm_instructions/wasm32/vq15mulr/i16x8.q15mulr_sat_s/confirmation ... bench: 7836304 ns/iter (+/- 479723) +test wasm_instructions/wasm64/vq15mulr/i16x8.q15mulr_sat_s ... bench: 3768412 ns/iter (+/- 197838) +test wasm_instructions/wasm64/vq15mulr/i16x8.q15mulr_sat_s/confirmation ... bench: 7751662 ns/iter (+/- 197928) +test wasm_instructions/wasm32/vdot/i32x4.dot_i16x8_s ... bench: 2372298 ns/iter (+/- 142374) +test wasm_instructions/wasm32/vdot/i32x4.dot_i16x8_s/confirmation ... bench: 4571749 ns/iter (+/- 27791) +test wasm_instructions/wasm64/vdot/i32x4.dot_i16x8_s ... bench: 2442394 ns/iter (+/- 276564) +test wasm_instructions/wasm64/vdot/i32x4.dot_i16x8_s/confirmation ... bench: 4711927 ns/iter (+/- 33586) +test wasm_instructions/wasm32/vfunop/f32x4.abs ... bench: 4564871 ns/iter (+/- 251148) +test wasm_instructions/wasm32/vfunop/f32x4.abs/confirmation ... bench: 8838826 ns/iter (+/- 142911) +test wasm_instructions/wasm64/vfunop/f32x4.abs ... bench: 4575662 ns/iter (+/- 319525) +test wasm_instructions/wasm64/vfunop/f32x4.abs/confirmation ... bench: 8849167 ns/iter (+/- 120683) +test wasm_instructions/wasm32/vfunop/f32x4.neg ... bench: 4530551 ns/iter (+/- 481886) +test wasm_instructions/wasm32/vfunop/f32x4.neg/confirmation ... bench: 8833851 ns/iter (+/- 25168) +test wasm_instructions/wasm64/vfunop/f32x4.neg ... bench: 4549623 ns/iter (+/- 294236) +test wasm_instructions/wasm64/vfunop/f32x4.neg/confirmation ... bench: 8870253 ns/iter (+/- 37611) +test wasm_instructions/wasm32/vfunop/f64x2.abs ... bench: 4547589 ns/iter (+/- 221462) +test wasm_instructions/wasm32/vfunop/f64x2.abs/confirmation ... bench: 8821666 ns/iter (+/- 12166) +test wasm_instructions/wasm64/vfunop/f64x2.abs ... bench: 4606732 ns/iter (+/- 16983) +test wasm_instructions/wasm64/vfunop/f64x2.abs/confirmation ... bench: 8834067 ns/iter (+/- 1000766) +test wasm_instructions/wasm32/vfunop/f64x2.neg ... bench: 4596797 ns/iter (+/- 23889) +test wasm_instructions/wasm32/vfunop/f64x2.neg/confirmation ... bench: 8800366 ns/iter (+/- 354331) +test wasm_instructions/wasm64/vfunop/f64x2.neg ... bench: 4532620 ns/iter (+/- 267720) +test wasm_instructions/wasm64/vfunop/f64x2.neg/confirmation ... bench: 8879656 ns/iter (+/- 645625) +test wasm_instructions/wasm32/vfunop/f32x4.ceil ... bench: 5114666 ns/iter (+/- 456260) +test wasm_instructions/wasm32/vfunop/f32x4.ceil/confirmation ... bench: 10571460 ns/iter (+/- 43206) +test wasm_instructions/wasm64/vfunop/f32x4.ceil ... bench: 5216013 ns/iter (+/- 47807) +test wasm_instructions/wasm64/vfunop/f32x4.ceil/confirmation ... bench: 11235480 ns/iter (+/- 1129154) +test wasm_instructions/wasm32/vfunop/f32x4.floor ... bench: 5122093 ns/iter (+/- 28749) +test wasm_instructions/wasm32/vfunop/f32x4.floor/confirmation ... bench: 11888440 ns/iter (+/- 1912184) +test wasm_instructions/wasm64/vfunop/f32x4.floor ... bench: 5105886 ns/iter (+/- 311119) +test wasm_instructions/wasm64/vfunop/f32x4.floor/confirmation ... bench: 11781761 ns/iter (+/- 519732) +test wasm_instructions/wasm32/vfunop/f32x4.trunc ... bench: 5132891 ns/iter (+/- 101099) +test wasm_instructions/wasm32/vfunop/f32x4.trunc/confirmation ... bench: 10584799 ns/iter (+/- 514309) +test wasm_instructions/wasm64/vfunop/f32x4.trunc ... bench: 5178265 ns/iter (+/- 452689) +test wasm_instructions/wasm64/vfunop/f32x4.trunc/confirmation ... bench: 11063081 ns/iter (+/- 679242) +test wasm_instructions/wasm32/vfunop/f32x4.nearest ... bench: 5136566 ns/iter (+/- 292094) +test wasm_instructions/wasm32/vfunop/f32x4.nearest/confirmation ... bench: 10970794 ns/iter (+/- 105197) +test wasm_instructions/wasm64/vfunop/f32x4.nearest ... bench: 5167685 ns/iter (+/- 733609) +test wasm_instructions/wasm64/vfunop/f32x4.nearest/confirmation ... bench: 11402598 ns/iter (+/- 499701) +test wasm_instructions/wasm32/vfunop/f64x2.ceil ... bench: 5122299 ns/iter (+/- 471924) +test wasm_instructions/wasm32/vfunop/f64x2.ceil/confirmation ... bench: 10449632 ns/iter (+/- 630030) +test wasm_instructions/wasm64/vfunop/f64x2.ceil ... bench: 5115913 ns/iter (+/- 517655) +test wasm_instructions/wasm64/vfunop/f64x2.ceil/confirmation ... bench: 11388748 ns/iter (+/- 545685) +test wasm_instructions/wasm32/vfunop/f64x2.floor ... bench: 5162547 ns/iter (+/- 876648) +test wasm_instructions/wasm32/vfunop/f64x2.floor/confirmation ... bench: 11757011 ns/iter (+/- 490570) +test wasm_instructions/wasm64/vfunop/f64x2.floor ... bench: 5152032 ns/iter (+/- 288598) +test wasm_instructions/wasm64/vfunop/f64x2.floor/confirmation ... bench: 11630359 ns/iter (+/- 479742) +test wasm_instructions/wasm32/vfunop/f64x2.trunc ... bench: 5150987 ns/iter (+/- 237393) +test wasm_instructions/wasm32/vfunop/f64x2.trunc/confirmation ... bench: 11395414 ns/iter (+/- 425295) +test wasm_instructions/wasm64/vfunop/f64x2.trunc ... bench: 5193363 ns/iter (+/- 426934) +test wasm_instructions/wasm64/vfunop/f64x2.trunc/confirmation ... bench: 11267735 ns/iter (+/- 72939) +test wasm_instructions/wasm32/vfunop/f64x2.nearest ... bench: 5128208 ns/iter (+/- 410540) +test wasm_instructions/wasm32/vfunop/f64x2.nearest/confirmation ... bench: 11013950 ns/iter (+/- 517195) +test wasm_instructions/wasm64/vfunop/f64x2.nearest ... bench: 5216725 ns/iter (+/- 23964) +test wasm_instructions/wasm64/vfunop/f64x2.nearest/confirmation ... bench: 11115682 ns/iter (+/- 81879) +test wasm_instructions/wasm32/vfunop/f32x4.sqrt ... bench: 12014961 ns/iter (+/- 19979) +test wasm_instructions/wasm32/vfunop/f32x4.sqrt/confirmation ... bench: 23964703 ns/iter (+/- 1267202) +test wasm_instructions/wasm64/vfunop/f32x4.sqrt ... bench: 12040992 ns/iter (+/- 91290) +test wasm_instructions/wasm64/vfunop/f32x4.sqrt/confirmation ... bench: 23736476 ns/iter (+/- 515845) +test wasm_instructions/wasm32/vfunop/f64x2.sqrt ... bench: 28867230 ns/iter (+/- 886277) +test wasm_instructions/wasm32/vfunop/f64x2.sqrt/confirmation ... bench: 57513546 ns/iter (+/- 101803) +test wasm_instructions/wasm64/vfunop/f64x2.sqrt ... bench: 28897934 ns/iter (+/- 540846) +test wasm_instructions/wasm64/vfunop/f64x2.sqrt/confirmation ... bench: 57636393 ns/iter (+/- 49276) +test wasm_instructions/wasm32/vitestop/i8x16.all_true ... bench: 3977630 ns/iter (+/- 223835) +test wasm_instructions/wasm32/vitestop/i8x16.all_true/confirmation ... bench: 7820756 ns/iter (+/- 29736) +test wasm_instructions/wasm64/vitestop/i8x16.all_true ... bench: 4011086 ns/iter (+/- 341134) +test wasm_instructions/wasm64/vitestop/i8x16.all_true/confirmation ... bench: 7743501 ns/iter (+/- 675602) +test wasm_instructions/wasm32/vitestop/i16x8.all_true ... bench: 4033186 ns/iter (+/- 515189) +test wasm_instructions/wasm32/vitestop/i16x8.all_true/confirmation ... bench: 7742077 ns/iter (+/- 530874) +test wasm_instructions/wasm64/vitestop/i16x8.all_true ... bench: 4031794 ns/iter (+/- 282396) +test wasm_instructions/wasm64/vitestop/i16x8.all_true/confirmation ... bench: 8027935 ns/iter (+/- 413708) +test wasm_instructions/wasm32/vitestop/i32x4.all_true ... bench: 3970095 ns/iter (+/- 428098) +test wasm_instructions/wasm32/vitestop/i32x4.all_true/confirmation ... bench: 7826891 ns/iter (+/- 362988) +test wasm_instructions/wasm64/vitestop/i32x4.all_true ... bench: 4076944 ns/iter (+/- 168090) +test wasm_instructions/wasm64/vitestop/i32x4.all_true/confirmation ... bench: 7809513 ns/iter (+/- 387960) +test wasm_instructions/wasm32/vitestop/i64x2.all_true ... bench: 4128160 ns/iter (+/- 335310) +test wasm_instructions/wasm32/vitestop/i64x2.all_true/confirmation ... bench: 8025241 ns/iter (+/- 126875) +test wasm_instructions/wasm64/vitestop/i64x2.all_true ... bench: 4136873 ns/iter (+/- 245098) +test wasm_instructions/wasm64/vitestop/i64x2.all_true/confirmation ... bench: 7971289 ns/iter (+/- 396586) +test wasm_instructions/wasm32/vbitmask/i8x16.bitmask ... bench: 2914787 ns/iter (+/- 24028) +test wasm_instructions/wasm32/vbitmask/i8x16.bitmask/confirmation ... bench: 5624805 ns/iter (+/- 11063) +test wasm_instructions/wasm64/vbitmask/i8x16.bitmask ... bench: 2933208 ns/iter (+/- 264401) +test wasm_instructions/wasm64/vbitmask/i8x16.bitmask/confirmation ... bench: 5623740 ns/iter (+/- 406704) +test wasm_instructions/wasm32/vbitmask/i16x8.bitmask ... bench: 3210806 ns/iter (+/- 33465) +test wasm_instructions/wasm32/vbitmask/i16x8.bitmask/confirmation ... bench: 6109033 ns/iter (+/- 256722) +test wasm_instructions/wasm64/vbitmask/i16x8.bitmask ... bench: 3149428 ns/iter (+/- 228610) +test wasm_instructions/wasm64/vbitmask/i16x8.bitmask/confirmation ... bench: 6095325 ns/iter (+/- 792887) +test wasm_instructions/wasm32/vbitmask/i32x4.bitmask ... bench: 2932011 ns/iter (+/- 18836) +test wasm_instructions/wasm32/vbitmask/i32x4.bitmask/confirmation ... bench: 5612012 ns/iter (+/- 567463) +test wasm_instructions/wasm64/vbitmask/i32x4.bitmask ... bench: 2974430 ns/iter (+/- 142153) +test wasm_instructions/wasm64/vbitmask/i32x4.bitmask/confirmation ... bench: 5606552 ns/iter (+/- 349206) +test wasm_instructions/wasm32/vbitmask/i64x2.bitmask ... bench: 2921853 ns/iter (+/- 143509) +test wasm_instructions/wasm32/vbitmask/i64x2.bitmask/confirmation ... bench: 5625840 ns/iter (+/- 315270) +test wasm_instructions/wasm64/vbitmask/i64x2.bitmask ... bench: 2889076 ns/iter (+/- 30706) +test wasm_instructions/wasm64/vbitmask/i64x2.bitmask/confirmation ... bench: 5626262 ns/iter (+/- 259832) +test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_s ... bench: 2421626 ns/iter (+/- 147504) +test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_s/confirmation ... bench: 4675339 ns/iter (+/- 119108) +test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_s ... bench: 2425185 ns/iter (+/- 75213) +test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_s/confirmation ... bench: 4534786 ns/iter (+/- 610945) +test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_u ... bench: 2376071 ns/iter (+/- 42359) +test wasm_instructions/wasm32/vnarrow/i8x16.narrow_i16x8_u/confirmation ... bench: 4566726 ns/iter (+/- 675133) +test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_u ... bench: 2448056 ns/iter (+/- 34557) +test wasm_instructions/wasm64/vnarrow/i8x16.narrow_i16x8_u/confirmation ... bench: 4559426 ns/iter (+/- 246154) +test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_s ... bench: 2390351 ns/iter (+/- 168906) +test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_s/confirmation ... bench: 4541125 ns/iter (+/- 512926) +test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_s ... bench: 2431523 ns/iter (+/- 51857) +test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_s/confirmation ... bench: 4581939 ns/iter (+/- 31594) +test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_u ... bench: 2406989 ns/iter (+/- 12518) +test wasm_instructions/wasm32/vnarrow/i16x8.narrow_i32x4_u/confirmation ... bench: 4605310 ns/iter (+/- 131897) +test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_u ... bench: 2401432 ns/iter (+/- 153373) +test wasm_instructions/wasm64/vnarrow/i16x8.narrow_i32x4_u/confirmation ... bench: 4568531 ns/iter (+/- 215495) +test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_s ... bench: 2354552 ns/iter (+/- 149804) +test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_s/confirmation ... bench: 4575799 ns/iter (+/- 496221) +test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_s ... bench: 2395348 ns/iter (+/- 17071) +test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_s/confirmation ... bench: 4682866 ns/iter (+/- 821281) +test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_u ... bench: 2413858 ns/iter (+/- 19929) +test wasm_instructions/wasm32/vextend/i16x8.extend_low_i8x16_u/confirmation ... bench: 4641783 ns/iter (+/- 61524) +test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_u ... bench: 2397728 ns/iter (+/- 27974) +test wasm_instructions/wasm64/vextend/i16x8.extend_low_i8x16_u/confirmation ... bench: 4619025 ns/iter (+/- 408301) +test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_s ... bench: 2389000 ns/iter (+/- 222109) +test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_s/confirmation ... bench: 4575757 ns/iter (+/- 16356) +test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_s ... bench: 2403406 ns/iter (+/- 328639) +test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_s/confirmation ... bench: 4533316 ns/iter (+/- 430775) +test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_u ... bench: 2415113 ns/iter (+/- 24181) +test wasm_instructions/wasm32/vextend/i32x4.extend_low_i16x8_u/confirmation ... bench: 4665394 ns/iter (+/- 59110) +test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_u ... bench: 2388178 ns/iter (+/- 27739) +test wasm_instructions/wasm64/vextend/i32x4.extend_low_i16x8_u/confirmation ... bench: 4625525 ns/iter (+/- 36361) +test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_s ... bench: 2365886 ns/iter (+/- 85484) +test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_s/confirmation ... bench: 4539879 ns/iter (+/- 628576) +test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_s ... bench: 2451934 ns/iter (+/- 152390) +test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_s/confirmation ... bench: 4555168 ns/iter (+/- 723903) +test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_u ... bench: 2414798 ns/iter (+/- 27676) +test wasm_instructions/wasm32/vextend/i64x2.extend_low_i32x4_u/confirmation ... bench: 4609822 ns/iter (+/- 33982) +test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_u ... bench: 2434785 ns/iter (+/- 18574) +test wasm_instructions/wasm64/vextend/i64x2.extend_low_i32x4_u/confirmation ... bench: 4603817 ns/iter (+/- 45617) +test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_s ... bench: 3542808 ns/iter (+/- 48708) +test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_s/confirmation ... bench: 6730216 ns/iter (+/- 272989) +test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_s ... bench: 3487080 ns/iter (+/- 282992) +test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_s/confirmation ... bench: 6779395 ns/iter (+/- 391326) +test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_u ... bench: 2641062 ns/iter (+/- 110625) +test wasm_instructions/wasm32/vextend/i16x8.extend_high_i8x16_u/confirmation ... bench: 5639405 ns/iter (+/- 24555) +test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_u ... bench: 2655400 ns/iter (+/- 161676) +test wasm_instructions/wasm64/vextend/i16x8.extend_high_i8x16_u/confirmation ... bench: 5644726 ns/iter (+/- 114544) +test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_s ... bench: 3504884 ns/iter (+/- 54527) +test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_s/confirmation ... bench: 6692833 ns/iter (+/- 773167) +test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_s ... bench: 3475049 ns/iter (+/- 427543) +test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_s/confirmation ... bench: 6790115 ns/iter (+/- 362178) +test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_u ... bench: 2658943 ns/iter (+/- 275403) +test wasm_instructions/wasm32/vextend/i32x4.extend_high_i16x8_u/confirmation ... bench: 5626237 ns/iter (+/- 520988) +test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_u ... bench: 2619536 ns/iter (+/- 15668) +test wasm_instructions/wasm64/vextend/i32x4.extend_high_i16x8_u/confirmation ... bench: 5653975 ns/iter (+/- 303137) +test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_s ... bench: 3461636 ns/iter (+/- 253247) +test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_s/confirmation ... bench: 6720916 ns/iter (+/- 36730) +test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_s ... bench: 3530131 ns/iter (+/- 295272) +test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_s/confirmation ... bench: 6710067 ns/iter (+/- 656319) +test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_u ... bench: 2638287 ns/iter (+/- 109946) +test wasm_instructions/wasm32/vextend/i64x2.extend_high_i32x4_u/confirmation ... bench: 5737225 ns/iter (+/- 64670) +test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_u ... bench: 2656896 ns/iter (+/- 201646) +test wasm_instructions/wasm64/vextend/i64x2.extend_high_i32x4_u/confirmation ... bench: 5648132 ns/iter (+/- 26360) +test wasm_instructions/wasm32/vishiftop/i16x8.shl ... bench: 4891363 ns/iter (+/- 317806) +test wasm_instructions/wasm32/vishiftop/i16x8.shl/confirmation ... bench: 8914183 ns/iter (+/- 72983) +test wasm_instructions/wasm64/vishiftop/i16x8.shl ... bench: 4791879 ns/iter (+/- 44937) +test wasm_instructions/wasm64/vishiftop/i16x8.shl/confirmation ... bench: 9031470 ns/iter (+/- 53840) +test wasm_instructions/wasm32/vishiftop/i16x8.shr_s ... bench: 5029651 ns/iter (+/- 388493) +test wasm_instructions/wasm32/vishiftop/i16x8.shr_s/confirmation ... bench: 9036500 ns/iter (+/- 57792) +test wasm_instructions/wasm64/vishiftop/i16x8.shr_s ... bench: 4861907 ns/iter (+/- 35153) +test wasm_instructions/wasm64/vishiftop/i16x8.shr_s/confirmation ... bench: 9133919 ns/iter (+/- 813549) +test wasm_instructions/wasm32/vishiftop/i16x8.shr_u ... bench: 4825594 ns/iter (+/- 309618) +test wasm_instructions/wasm32/vishiftop/i16x8.shr_u/confirmation ... bench: 9001874 ns/iter (+/- 34804) +test wasm_instructions/wasm64/vishiftop/i16x8.shr_u ... bench: 4630585 ns/iter (+/- 201837) +test wasm_instructions/wasm64/vishiftop/i16x8.shr_u/confirmation ... bench: 8999315 ns/iter (+/- 1132641) +test wasm_instructions/wasm32/vishiftop/i32x4.shl ... bench: 4728197 ns/iter (+/- 102682) +test wasm_instructions/wasm32/vishiftop/i32x4.shl/confirmation ... bench: 8996740 ns/iter (+/- 97345) +test wasm_instructions/wasm64/vishiftop/i32x4.shl ... bench: 4871410 ns/iter (+/- 301042) +test wasm_instructions/wasm64/vishiftop/i32x4.shl/confirmation ... bench: 8979624 ns/iter (+/- 50299) +test wasm_instructions/wasm32/vishiftop/i32x4.shr_s ... bench: 4960105 ns/iter (+/- 34339) +test wasm_instructions/wasm32/vishiftop/i32x4.shr_s/confirmation ... bench: 8984125 ns/iter (+/- 1389893) +test wasm_instructions/wasm64/vishiftop/i32x4.shr_s ... bench: 4794729 ns/iter (+/- 298491) +test wasm_instructions/wasm64/vishiftop/i32x4.shr_s/confirmation ... bench: 8958454 ns/iter (+/- 134031) +test wasm_instructions/wasm32/vishiftop/i32x4.shr_u ... bench: 4796091 ns/iter (+/- 239096) +test wasm_instructions/wasm32/vishiftop/i32x4.shr_u/confirmation ... bench: 9051436 ns/iter (+/- 944701) +test wasm_instructions/wasm64/vishiftop/i32x4.shr_u ... bench: 4697132 ns/iter (+/- 414881) +test wasm_instructions/wasm64/vishiftop/i32x4.shr_u/confirmation ... bench: 9018626 ns/iter (+/- 56770) +test wasm_instructions/wasm32/vishiftop/i64x2.shl ... bench: 4863307 ns/iter (+/- 131059) +test wasm_instructions/wasm32/vishiftop/i64x2.shl/confirmation ... bench: 8974449 ns/iter (+/- 697927) +test wasm_instructions/wasm64/vishiftop/i64x2.shl ... bench: 4705162 ns/iter (+/- 370588) +test wasm_instructions/wasm64/vishiftop/i64x2.shl/confirmation ... bench: 9020066 ns/iter (+/- 1255585) +test wasm_instructions/wasm32/vishiftop/i64x2.shr_u ... bench: 4728950 ns/iter (+/- 67625) +test wasm_instructions/wasm32/vishiftop/i64x2.shr_u/confirmation ... bench: 8977600 ns/iter (+/- 641222) +test wasm_instructions/wasm64/vishiftop/i64x2.shr_u ... bench: 4843102 ns/iter (+/- 67092) +test wasm_instructions/wasm64/vishiftop/i64x2.shr_u/confirmation ... bench: 9016325 ns/iter (+/- 70089) +test wasm_instructions/wasm32/vishiftop/i8x16.shl ... bench: 6732127 ns/iter (+/- 135547) +test wasm_instructions/wasm32/vishiftop/i8x16.shl/confirmation ... bench: 13838183 ns/iter (+/- 375660) +test wasm_instructions/wasm64/vishiftop/i8x16.shl ... bench: 6821877 ns/iter (+/- 44904) +test wasm_instructions/wasm64/vishiftop/i8x16.shl/confirmation ... bench: 13904159 ns/iter (+/- 380579) +test wasm_instructions/wasm32/vishiftop/i8x16.shr_s ... bench: 7647200 ns/iter (+/- 388955) +test wasm_instructions/wasm32/vishiftop/i8x16.shr_s/confirmation ... bench: 15519485 ns/iter (+/- 589930) +test wasm_instructions/wasm64/vishiftop/i8x16.shr_s ... bench: 7561625 ns/iter (+/- 417673) +test wasm_instructions/wasm64/vishiftop/i8x16.shr_s/confirmation ... bench: 15557937 ns/iter (+/- 1460404) +test wasm_instructions/wasm32/vishiftop/i8x16.shr_u ... bench: 5981458 ns/iter (+/- 538649) +test wasm_instructions/wasm32/vishiftop/i8x16.shr_u/confirmation ... bench: 11600772 ns/iter (+/- 44642) +test wasm_instructions/wasm64/vishiftop/i8x16.shr_u ... bench: 5899943 ns/iter (+/- 57197) +test wasm_instructions/wasm64/vishiftop/i8x16.shr_u/confirmation ... bench: 11338701 ns/iter (+/- 1103892) +test wasm_instructions/wasm32/vishiftop/i64x2.shr_s ... bench: 8667852 ns/iter (+/- 171311) +test wasm_instructions/wasm32/vishiftop/i64x2.shr_s/confirmation ... bench: 17446893 ns/iter (+/- 102976) +test wasm_instructions/wasm64/vishiftop/i64x2.shr_s ... bench: 8684588 ns/iter (+/- 80878) +test wasm_instructions/wasm64/vishiftop/i64x2.shr_s/confirmation ... bench: 17353171 ns/iter (+/- 534645) +test wasm_instructions/wasm32/vibinop/i8x16.add ... bench: 2414652 ns/iter (+/- 131565) +test wasm_instructions/wasm32/vibinop/i8x16.add/confirmation ... bench: 4567034 ns/iter (+/- 24523) +test wasm_instructions/wasm64/vibinop/i8x16.add ... bench: 2447248 ns/iter (+/- 47787) +test wasm_instructions/wasm64/vibinop/i8x16.add/confirmation ... bench: 4624265 ns/iter (+/- 21844) +test wasm_instructions/wasm32/vibinop/i8x16.sub ... bench: 2374578 ns/iter (+/- 175095) +test wasm_instructions/wasm32/vibinop/i8x16.sub/confirmation ... bench: 4568743 ns/iter (+/- 18577) +test wasm_instructions/wasm64/vibinop/i8x16.sub ... bench: 2389592 ns/iter (+/- 114201) +test wasm_instructions/wasm64/vibinop/i8x16.sub/confirmation ... bench: 4577809 ns/iter (+/- 67401) +test wasm_instructions/wasm32/vibinop/i16x8.add ... bench: 2430294 ns/iter (+/- 261494) +test wasm_instructions/wasm32/vibinop/i16x8.add/confirmation ... bench: 4561056 ns/iter (+/- 67056) +test wasm_instructions/wasm64/vibinop/i16x8.add ... bench: 2369008 ns/iter (+/- 33084) +test wasm_instructions/wasm64/vibinop/i16x8.add/confirmation ... bench: 4572339 ns/iter (+/- 16773) +test wasm_instructions/wasm32/vibinop/i16x8.sub ... bench: 2370905 ns/iter (+/- 141215) +test wasm_instructions/wasm32/vibinop/i16x8.sub/confirmation ... bench: 4552841 ns/iter (+/- 334617) +test wasm_instructions/wasm64/vibinop/i16x8.sub ... bench: 2430883 ns/iter (+/- 26912) +test wasm_instructions/wasm64/vibinop/i16x8.sub/confirmation ... bench: 4585897 ns/iter (+/- 27051) +test wasm_instructions/wasm32/vibinop/i32x4.add ... bench: 2372142 ns/iter (+/- 32165) +test wasm_instructions/wasm32/vibinop/i32x4.add/confirmation ... bench: 4571099 ns/iter (+/- 280116) +test wasm_instructions/wasm64/vibinop/i32x4.add ... bench: 2428487 ns/iter (+/- 151769) +test wasm_instructions/wasm64/vibinop/i32x4.add/confirmation ... bench: 4683189 ns/iter (+/- 44521) +test wasm_instructions/wasm32/vibinop/i32x4.sub ... bench: 2427708 ns/iter (+/- 159794) +test wasm_instructions/wasm32/vibinop/i32x4.sub/confirmation ... bench: 4648623 ns/iter (+/- 43821) +test wasm_instructions/wasm64/vibinop/i32x4.sub ... bench: 2443963 ns/iter (+/- 33892) +test wasm_instructions/wasm64/vibinop/i32x4.sub/confirmation ... bench: 4579438 ns/iter (+/- 353732) +test wasm_instructions/wasm32/vibinop/i64x2.add ... bench: 2433374 ns/iter (+/- 37783) +test wasm_instructions/wasm32/vibinop/i64x2.add/confirmation ... bench: 4575311 ns/iter (+/- 34020) +test wasm_instructions/wasm64/vibinop/i64x2.add ... bench: 2385241 ns/iter (+/- 68067) +test wasm_instructions/wasm64/vibinop/i64x2.add/confirmation ... bench: 4557374 ns/iter (+/- 69325) +test wasm_instructions/wasm32/vibinop/i64x2.sub ... bench: 2427505 ns/iter (+/- 23737) +test wasm_instructions/wasm32/vibinop/i64x2.sub/confirmation ... bench: 4573544 ns/iter (+/- 319419) +test wasm_instructions/wasm64/vibinop/i64x2.sub ... bench: 2363562 ns/iter (+/- 34594) +test wasm_instructions/wasm64/vibinop/i64x2.sub/confirmation ... bench: 4558014 ns/iter (+/- 381610) +test wasm_instructions/wasm32/viminmaxop/i8x16.min_s ... bench: 2449515 ns/iter (+/- 21119) +test wasm_instructions/wasm32/viminmaxop/i8x16.min_s/confirmation ... bench: 4561171 ns/iter (+/- 229031) +test wasm_instructions/wasm64/viminmaxop/i8x16.min_s ... bench: 2437081 ns/iter (+/- 153052) +test wasm_instructions/wasm64/viminmaxop/i8x16.min_s/confirmation ... bench: 4678784 ns/iter (+/- 37225) +test wasm_instructions/wasm32/viminmaxop/i8x16.min_u ... bench: 2394154 ns/iter (+/- 17817) +test wasm_instructions/wasm32/viminmaxop/i8x16.min_u/confirmation ... bench: 4554621 ns/iter (+/- 507768) +test wasm_instructions/wasm64/viminmaxop/i8x16.min_u ... bench: 2432106 ns/iter (+/- 36668) +test wasm_instructions/wasm64/viminmaxop/i8x16.min_u/confirmation ... bench: 4576734 ns/iter (+/- 294356) +test wasm_instructions/wasm32/viminmaxop/i8x16.max_s ... bench: 2401872 ns/iter (+/- 112916) +test wasm_instructions/wasm32/viminmaxop/i8x16.max_s/confirmation ... bench: 4586591 ns/iter (+/- 35983) +test wasm_instructions/wasm64/viminmaxop/i8x16.max_s ... bench: 2447483 ns/iter (+/- 25323) +test wasm_instructions/wasm64/viminmaxop/i8x16.max_s/confirmation ... bench: 4600770 ns/iter (+/- 396503) +test wasm_instructions/wasm32/viminmaxop/i8x16.max_u ... bench: 2385250 ns/iter (+/- 139653) +test wasm_instructions/wasm32/viminmaxop/i8x16.max_u/confirmation ... bench: 4589827 ns/iter (+/- 25269) +test wasm_instructions/wasm64/viminmaxop/i8x16.max_u ... bench: 2412273 ns/iter (+/- 217899) +test wasm_instructions/wasm64/viminmaxop/i8x16.max_u/confirmation ... bench: 4574716 ns/iter (+/- 10594) +test wasm_instructions/wasm32/viminmaxop/i16x8.min_s ... bench: 2383574 ns/iter (+/- 123864) +test wasm_instructions/wasm32/viminmaxop/i16x8.min_s/confirmation ... bench: 4571501 ns/iter (+/- 272412) +test wasm_instructions/wasm64/viminmaxop/i16x8.min_s ... bench: 2421883 ns/iter (+/- 66386) +test wasm_instructions/wasm64/viminmaxop/i16x8.min_s/confirmation ... bench: 4571043 ns/iter (+/- 612001) +test wasm_instructions/wasm32/viminmaxop/i16x8.min_u ... bench: 2378910 ns/iter (+/- 173135) +test wasm_instructions/wasm32/viminmaxop/i16x8.min_u/confirmation ... bench: 4588789 ns/iter (+/- 27098) +test wasm_instructions/wasm64/viminmaxop/i16x8.min_u ... bench: 2383906 ns/iter (+/- 195491) +test wasm_instructions/wasm64/viminmaxop/i16x8.min_u/confirmation ... bench: 4547863 ns/iter (+/- 371766) +test wasm_instructions/wasm32/viminmaxop/i16x8.max_s ... bench: 2401395 ns/iter (+/- 113112) +test wasm_instructions/wasm32/viminmaxop/i16x8.max_s/confirmation ... bench: 4598837 ns/iter (+/- 12146) +test wasm_instructions/wasm64/viminmaxop/i16x8.max_s ... bench: 2445655 ns/iter (+/- 32478) +test wasm_instructions/wasm64/viminmaxop/i16x8.max_s/confirmation ... bench: 4579354 ns/iter (+/- 17202) +test wasm_instructions/wasm32/viminmaxop/i16x8.max_u ... bench: 2342504 ns/iter (+/- 220088) +test wasm_instructions/wasm32/viminmaxop/i16x8.max_u/confirmation ... bench: 4596620 ns/iter (+/- 57274) +test wasm_instructions/wasm64/viminmaxop/i16x8.max_u ... bench: 2397347 ns/iter (+/- 192123) +test wasm_instructions/wasm64/viminmaxop/i16x8.max_u/confirmation ... bench: 4558388 ns/iter (+/- 373549) +test wasm_instructions/wasm32/viminmaxop/i32x4.min_s ... bench: 2401003 ns/iter (+/- 233514) +test wasm_instructions/wasm32/viminmaxop/i32x4.min_s/confirmation ... bench: 4693141 ns/iter (+/- 71794) +test wasm_instructions/wasm64/viminmaxop/i32x4.min_s ... bench: 2384949 ns/iter (+/- 8798) +test wasm_instructions/wasm64/viminmaxop/i32x4.min_s/confirmation ... bench: 4578442 ns/iter (+/- 611919) +test wasm_instructions/wasm32/viminmaxop/i32x4.min_u ... bench: 2392686 ns/iter (+/- 264553) +test wasm_instructions/wasm32/viminmaxop/i32x4.min_u/confirmation ... bench: 4661650 ns/iter (+/- 75508) +test wasm_instructions/wasm64/viminmaxop/i32x4.min_u ... bench: 2387273 ns/iter (+/- 244281) +test wasm_instructions/wasm64/viminmaxop/i32x4.min_u/confirmation ... bench: 4682787 ns/iter (+/- 51111) +test wasm_instructions/wasm32/viminmaxop/i32x4.max_s ... bench: 2407787 ns/iter (+/- 40786) +test wasm_instructions/wasm32/viminmaxop/i32x4.max_s/confirmation ... bench: 4582362 ns/iter (+/- 12419) +test wasm_instructions/wasm64/viminmaxop/i32x4.max_s ... bench: 2415176 ns/iter (+/- 268645) +test wasm_instructions/wasm64/viminmaxop/i32x4.max_s/confirmation ... bench: 4677964 ns/iter (+/- 43450) +test wasm_instructions/wasm32/viminmaxop/i32x4.max_u ... bench: 2376526 ns/iter (+/- 188939) +test wasm_instructions/wasm32/viminmaxop/i32x4.max_u/confirmation ... bench: 4594754 ns/iter (+/- 30754) +test wasm_instructions/wasm64/viminmaxop/i32x4.max_u ... bench: 2427197 ns/iter (+/- 13451) +test wasm_instructions/wasm64/viminmaxop/i32x4.max_u/confirmation ... bench: 4579591 ns/iter (+/- 21091) +test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_s ... bench: 2409943 ns/iter (+/- 37813) +test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_s/confirmation ... bench: 4653774 ns/iter (+/- 289630) +test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_s ... bench: 2431815 ns/iter (+/- 280729) +test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_s/confirmation ... bench: 4570893 ns/iter (+/- 610922) +test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_u ... bench: 2439988 ns/iter (+/- 16406) +test wasm_instructions/wasm32/visatbinop/i8x16.add_sat_u/confirmation ... bench: 4565023 ns/iter (+/- 491383) +test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_u ... bench: 2419492 ns/iter (+/- 89984) +test wasm_instructions/wasm64/visatbinop/i8x16.add_sat_u/confirmation ... bench: 4603365 ns/iter (+/- 198068) +test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_s ... bench: 2387959 ns/iter (+/- 255871) +test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_s/confirmation ... bench: 4560156 ns/iter (+/- 374216) +test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_s ... bench: 2379043 ns/iter (+/- 208413) +test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_s/confirmation ... bench: 4556113 ns/iter (+/- 263052) +test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_u ... bench: 2397094 ns/iter (+/- 185431) +test wasm_instructions/wasm32/visatbinop/i8x16.sub_sat_u/confirmation ... bench: 4576269 ns/iter (+/- 316269) +test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_u ... bench: 2429463 ns/iter (+/- 185568) +test wasm_instructions/wasm64/visatbinop/i8x16.sub_sat_u/confirmation ... bench: 4573002 ns/iter (+/- 310384) +test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_s ... bench: 2385966 ns/iter (+/- 266794) +test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_s/confirmation ... bench: 4598242 ns/iter (+/- 25061) +test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_s ... bench: 2403878 ns/iter (+/- 209993) +test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_s/confirmation ... bench: 4577777 ns/iter (+/- 491799) +test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_u ... bench: 2418938 ns/iter (+/- 119337) +test wasm_instructions/wasm32/visatbinop/i16x8.add_sat_u/confirmation ... bench: 4527845 ns/iter (+/- 402512) +test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_u ... bench: 2419902 ns/iter (+/- 339933) +test wasm_instructions/wasm64/visatbinop/i16x8.add_sat_u/confirmation ... bench: 4567836 ns/iter (+/- 456599) +test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_s ... bench: 2365621 ns/iter (+/- 93466) +test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_s/confirmation ... bench: 4571374 ns/iter (+/- 47400) +test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_s ... bench: 2398754 ns/iter (+/- 120775) +test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_s/confirmation ... bench: 4624050 ns/iter (+/- 354835) +test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_u ... bench: 2410502 ns/iter (+/- 132885) +test wasm_instructions/wasm32/visatbinop/i16x8.sub_sat_u/confirmation ... bench: 4551086 ns/iter (+/- 432979) +test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_u ... bench: 2388345 ns/iter (+/- 20723) +test wasm_instructions/wasm64/visatbinop/i16x8.sub_sat_u/confirmation ... bench: 4558521 ns/iter (+/- 632412) +test wasm_instructions/wasm32/vimul/i16x8.mul ... bench: 2353243 ns/iter (+/- 71193) +test wasm_instructions/wasm32/vimul/i16x8.mul/confirmation ... bench: 4577511 ns/iter (+/- 121952) +test wasm_instructions/wasm64/vimul/i16x8.mul ... bench: 2417208 ns/iter (+/- 123591) +test wasm_instructions/wasm64/vimul/i16x8.mul/confirmation ... bench: 4533451 ns/iter (+/- 468394) +test wasm_instructions/wasm32/vimul/i32x4.mul ... bench: 4549341 ns/iter (+/- 355225) +test wasm_instructions/wasm32/vimul/i32x4.mul/confirmation ... bench: 8825576 ns/iter (+/- 332935) +test wasm_instructions/wasm64/vimul/i32x4.mul ... bench: 4592546 ns/iter (+/- 35055) +test wasm_instructions/wasm64/vimul/i32x4.mul/confirmation ... bench: 8834843 ns/iter (+/- 329889) +test wasm_instructions/wasm32/vimul/i64x2.mul ... bench: 8831916 ns/iter (+/- 20223) +test wasm_instructions/wasm32/vimul/i64x2.mul/confirmation ... bench: 17519483 ns/iter (+/- 125375) +test wasm_instructions/wasm64/vimul/i64x2.mul ... bench: 8954148 ns/iter (+/- 715740) +test wasm_instructions/wasm64/vimul/i64x2.mul/confirmation ... bench: 17411917 ns/iter (+/- 712199) +test wasm_instructions/wasm32/vavgr/i8x16.avgr_u ... bench: 2385452 ns/iter (+/- 109839) +test wasm_instructions/wasm32/vavgr/i8x16.avgr_u/confirmation ... bench: 4564576 ns/iter (+/- 384848) +test wasm_instructions/wasm64/vavgr/i8x16.avgr_u ... bench: 2426156 ns/iter (+/- 206176) +test wasm_instructions/wasm64/vavgr/i8x16.avgr_u/confirmation ... bench: 4587589 ns/iter (+/- 28669) +test wasm_instructions/wasm32/vavgr/i16x8.avgr_u ... bench: 2361122 ns/iter (+/- 167432) +test wasm_instructions/wasm32/vavgr/i16x8.avgr_u/confirmation ... bench: 4523192 ns/iter (+/- 459422) +test wasm_instructions/wasm64/vavgr/i16x8.avgr_u ... bench: 2437385 ns/iter (+/- 38027) +test wasm_instructions/wasm64/vavgr/i16x8.avgr_u/confirmation ... bench: 4575039 ns/iter (+/- 249133) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_s ... bench: 3526102 ns/iter (+/- 309995) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_s/confirmation ... bench: 6836397 ns/iter (+/- 39654) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_s ... bench: 3478057 ns/iter (+/- 169965) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_s/confirmation ... bench: 6814866 ns/iter (+/- 17829) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_s ... bench: 3512645 ns/iter (+/- 22097) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_s/confirmation ... bench: 6813859 ns/iter (+/- 53211) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_s ... bench: 3542977 ns/iter (+/- 26888) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_s/confirmation ... bench: 6775115 ns/iter (+/- 69093) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_s ... bench: 3480108 ns/iter (+/- 243234) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_s/confirmation ... bench: 6730449 ns/iter (+/- 271599) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_s ... bench: 3515141 ns/iter (+/- 276473) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_s/confirmation ... bench: 6756720 ns/iter (+/- 66941) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_u ... bench: 3570828 ns/iter (+/- 63806) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_low_i32x4_u/confirmation ... bench: 6722491 ns/iter (+/- 139709) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_u ... bench: 3524380 ns/iter (+/- 232235) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_low_i32x4_u/confirmation ... bench: 6749282 ns/iter (+/- 811119) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_u ... bench: 3491892 ns/iter (+/- 101382) +test wasm_instructions/wasm32/vextmul/i64x2.extmul_high_i32x4_u/confirmation ... bench: 6689039 ns/iter (+/- 746462) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_u ... bench: 3580732 ns/iter (+/- 41169) +test wasm_instructions/wasm64/vextmul/i64x2.extmul_high_i32x4_u/confirmation ... bench: 6719234 ns/iter (+/- 339251) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_s ... bench: 5646983 ns/iter (+/- 771720) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_s/confirmation ... bench: 11029745 ns/iter (+/- 57825) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_s ... bench: 5660100 ns/iter (+/- 27972) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_s/confirmation ... bench: 10995088 ns/iter (+/- 484159) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_u ... bench: 3464313 ns/iter (+/- 399085) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_low_i8x16_u/confirmation ... bench: 6747000 ns/iter (+/- 471850) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_u ... bench: 3506771 ns/iter (+/- 290697) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_low_i8x16_u/confirmation ... bench: 6741922 ns/iter (+/- 469104) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_u ... bench: 4570401 ns/iter (+/- 285791) +test wasm_instructions/wasm32/vextmul/i16x8.extmul_high_i8x16_u/confirmation ... bench: 8830760 ns/iter (+/- 31467) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_u ... bench: 4544331 ns/iter (+/- 378686) +test wasm_instructions/wasm64/vextmul/i16x8.extmul_high_i8x16_u/confirmation ... bench: 9069720 ns/iter (+/- 25715) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_s ... bench: 4548049 ns/iter (+/- 30659) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_s/confirmation ... bench: 8822131 ns/iter (+/- 75348) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_s ... bench: 4587979 ns/iter (+/- 372639) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_s/confirmation ... bench: 8967559 ns/iter (+/- 718436) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_s ... bench: 4540465 ns/iter (+/- 436460) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_s/confirmation ... bench: 8831631 ns/iter (+/- 178953) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_s ... bench: 4576066 ns/iter (+/- 25097) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_s/confirmation ... bench: 8821040 ns/iter (+/- 581962) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_u ... bench: 4543639 ns/iter (+/- 285413) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_low_i16x8_u/confirmation ... bench: 8804000 ns/iter (+/- 150242) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_u ... bench: 4575618 ns/iter (+/- 155729) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_low_i16x8_u/confirmation ... bench: 8953383 ns/iter (+/- 31000) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_u ... bench: 4541488 ns/iter (+/- 630102) +test wasm_instructions/wasm32/vextmul/i32x4.extmul_high_i16x8_u/confirmation ... bench: 8808146 ns/iter (+/- 499873) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_u ... bench: 4676541 ns/iter (+/- 596143) +test wasm_instructions/wasm64/vextmul/i32x4.extmul_high_i16x8_u/confirmation ... bench: 8845501 ns/iter (+/- 559163) +test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_s ... bench: 3370683 ns/iter (+/- 259586) +test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_s/confirmation ... bench: 6911276 ns/iter (+/- 630879) +test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_s ... bench: 3356877 ns/iter (+/- 178209) +test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_s/confirmation ... bench: 7318938 ns/iter (+/- 27088) +test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_u ... bench: 4563791 ns/iter (+/- 282236) +test wasm_instructions/wasm32/vextadd/i16x8.extadd_pairwise_i8x16_u/confirmation ... bench: 8814393 ns/iter (+/- 566747) +test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_u ... bench: 4564123 ns/iter (+/- 341797) +test wasm_instructions/wasm64/vextadd/i16x8.extadd_pairwise_i8x16_u/confirmation ... bench: 8911043 ns/iter (+/- 540093) +test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_s ... bench: 2728427 ns/iter (+/- 164368) +test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_s/confirmation ... bench: 5670446 ns/iter (+/- 426061) +test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_s ... bench: 2675124 ns/iter (+/- 173917) +test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_s/confirmation ... bench: 5517317 ns/iter (+/- 208561) +test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_u ... bench: 6715967 ns/iter (+/- 527697) +test wasm_instructions/wasm32/vextadd/i32x4.extadd_pairwise_i16x8_u/confirmation ... bench: 15279444 ns/iter (+/- 47457) +test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_u ... bench: 6908381 ns/iter (+/- 54343) +test wasm_instructions/wasm64/vextadd/i32x4.extadd_pairwise_i16x8_u/confirmation ... bench: 16612184 ns/iter (+/- 510536) +test wasm_instructions/wasm32/vfbinop/f32x4.add ... bench: 5192302 ns/iter (+/- 31255) +test wasm_instructions/wasm32/vfbinop/f32x4.add/confirmation ... bench: 10066954 ns/iter (+/- 183455) +test wasm_instructions/wasm64/vfbinop/f32x4.add ... bench: 4994085 ns/iter (+/- 16960) +test wasm_instructions/wasm64/vfbinop/f32x4.add/confirmation ... bench: 10177771 ns/iter (+/- 896034) +test wasm_instructions/wasm32/vfbinop/f32x4.sub ... bench: 5083017 ns/iter (+/- 223907) +test wasm_instructions/wasm32/vfbinop/f32x4.sub/confirmation ... bench: 9833954 ns/iter (+/- 85460) +test wasm_instructions/wasm64/vfbinop/f32x4.sub ... bench: 4956743 ns/iter (+/- 449724) +test wasm_instructions/wasm64/vfbinop/f32x4.sub/confirmation ... bench: 10811810 ns/iter (+/- 837487) +test wasm_instructions/wasm32/vfbinop/f32x4.mul ... bench: 4998369 ns/iter (+/- 20035) +test wasm_instructions/wasm32/vfbinop/f32x4.mul/confirmation ... bench: 10021983 ns/iter (+/- 866068) +test wasm_instructions/wasm64/vfbinop/f32x4.mul ... bench: 4974505 ns/iter (+/- 328364) +test wasm_instructions/wasm64/vfbinop/f32x4.mul/confirmation ... bench: 10417201 ns/iter (+/- 53632) +test wasm_instructions/wasm32/vfbinop/f64x2.add ... bench: 5018501 ns/iter (+/- 263502) +test wasm_instructions/wasm32/vfbinop/f64x2.add/confirmation ... bench: 10228587 ns/iter (+/- 815295) +test wasm_instructions/wasm64/vfbinop/f64x2.add ... bench: 5009196 ns/iter (+/- 400448) +test wasm_instructions/wasm64/vfbinop/f64x2.add/confirmation ... bench: 10595571 ns/iter (+/- 892180) +test wasm_instructions/wasm32/vfbinop/f64x2.sub ... bench: 4998511 ns/iter (+/- 311301) +test wasm_instructions/wasm32/vfbinop/f64x2.sub/confirmation ... bench: 10203066 ns/iter (+/- 619661) +test wasm_instructions/wasm64/vfbinop/f64x2.sub ... bench: 4993788 ns/iter (+/- 410972) +test wasm_instructions/wasm64/vfbinop/f64x2.sub/confirmation ... bench: 10412761 ns/iter (+/- 423385) +test wasm_instructions/wasm32/vfbinop/f64x2.mul ... bench: 4996168 ns/iter (+/- 471451) +test wasm_instructions/wasm32/vfbinop/f64x2.mul/confirmation ... bench: 11248540 ns/iter (+/- 54130) +test wasm_instructions/wasm64/vfbinop/f64x2.mul ... bench: 5051974 ns/iter (+/- 234019) +test wasm_instructions/wasm64/vfbinop/f64x2.mul/confirmation ... bench: 10837095 ns/iter (+/- 44202) +test wasm_instructions/wasm32/vfbinop/f32x4.div ... bench: 20633055 ns/iter (+/- 852270) +test wasm_instructions/wasm32/vfbinop/f32x4.div/confirmation ... bench: 41143670 ns/iter (+/- 973488) +test wasm_instructions/wasm64/vfbinop/f32x4.div ... bench: 20589086 ns/iter (+/- 423391) +test wasm_instructions/wasm64/vfbinop/f32x4.div/confirmation ... bench: 40996808 ns/iter (+/- 657524) +test wasm_instructions/wasm32/vfbinop/f64x2.div ... bench: 22756412 ns/iter (+/- 777994) +test wasm_instructions/wasm32/vfbinop/f64x2.div/confirmation ... bench: 45202387 ns/iter (+/- 103186) +test wasm_instructions/wasm64/vfbinop/f64x2.div ... bench: 22768597 ns/iter (+/- 221299) +test wasm_instructions/wasm64/vfbinop/f64x2.div/confirmation ... bench: 45511420 ns/iter (+/- 273177) +test wasm_instructions/wasm32/vfbinop/f32x4.min ... bench: 8555315 ns/iter (+/- 61332) +test wasm_instructions/wasm32/vfbinop/f32x4.min/confirmation ... bench: 18830294 ns/iter (+/- 729840) +test wasm_instructions/wasm64/vfbinop/f32x4.min ... bench: 8419152 ns/iter (+/- 111444) +test wasm_instructions/wasm64/vfbinop/f32x4.min/confirmation ... bench: 17264775 ns/iter (+/- 1028905) +test wasm_instructions/wasm32/vfbinop/f32x4.max ... bench: 9630569 ns/iter (+/- 885038) +test wasm_instructions/wasm32/vfbinop/f32x4.max/confirmation ... bench: 19871972 ns/iter (+/- 1274406) +test wasm_instructions/wasm64/vfbinop/f32x4.max ... bench: 9560357 ns/iter (+/- 51608) +test wasm_instructions/wasm64/vfbinop/f32x4.max/confirmation ... bench: 20352583 ns/iter (+/- 824281) +test wasm_instructions/wasm32/vfbinop/f64x2.min ... bench: 8404067 ns/iter (+/- 227483) +test wasm_instructions/wasm32/vfbinop/f64x2.min/confirmation ... bench: 18333147 ns/iter (+/- 826863) +test wasm_instructions/wasm64/vfbinop/f64x2.min ... bench: 8307590 ns/iter (+/- 633432) +test wasm_instructions/wasm64/vfbinop/f64x2.min/confirmation ... bench: 17915397 ns/iter (+/- 110820) +test wasm_instructions/wasm32/vfbinop/f64x2.max ... bench: 9341367 ns/iter (+/- 41157) +test wasm_instructions/wasm32/vfbinop/f64x2.max/confirmation ... bench: 18892466 ns/iter (+/- 954277) +test wasm_instructions/wasm64/vfbinop/f64x2.max ... bench: 9672375 ns/iter (+/- 730326) +test wasm_instructions/wasm64/vfbinop/f64x2.max/confirmation ... bench: 19700097 ns/iter (+/- 25932) +test wasm_instructions/wasm32/vfbinop/f32x4.pmin ... bench: 2374075 ns/iter (+/- 147337) +test wasm_instructions/wasm32/vfbinop/f32x4.pmin/confirmation ... bench: 4578548 ns/iter (+/- 29796) +test wasm_instructions/wasm64/vfbinop/f32x4.pmin ... bench: 2366926 ns/iter (+/- 204980) +test wasm_instructions/wasm64/vfbinop/f32x4.pmin/confirmation ... bench: 4579099 ns/iter (+/- 542489) +test wasm_instructions/wasm32/vfbinop/f32x4.pmax ... bench: 2408826 ns/iter (+/- 124933) +test wasm_instructions/wasm32/vfbinop/f32x4.pmax/confirmation ... bench: 4593729 ns/iter (+/- 47728) +test wasm_instructions/wasm64/vfbinop/f32x4.pmax ... bench: 2390845 ns/iter (+/- 144778) +test wasm_instructions/wasm64/vfbinop/f32x4.pmax/confirmation ... bench: 4554293 ns/iter (+/- 408659) +test wasm_instructions/wasm32/vfbinop/f64x2.pmin ... bench: 2355199 ns/iter (+/- 80944) +test wasm_instructions/wasm32/vfbinop/f64x2.pmin/confirmation ... bench: 4584961 ns/iter (+/- 347142) +test wasm_instructions/wasm64/vfbinop/f64x2.pmin ... bench: 2441525 ns/iter (+/- 325509) +test wasm_instructions/wasm64/vfbinop/f64x2.pmin/confirmation ... bench: 4581097 ns/iter (+/- 28655) +test wasm_instructions/wasm32/vfbinop/f64x2.pmax ... bench: 2450350 ns/iter (+/- 25428) +test wasm_instructions/wasm32/vfbinop/f64x2.pmax/confirmation ... bench: 4589627 ns/iter (+/- 35294) +test wasm_instructions/wasm64/vfbinop/f64x2.pmax ... bench: 2418035 ns/iter (+/- 72506) +test wasm_instructions/wasm64/vfbinop/f64x2.pmax/confirmation ... bench: 4595709 ns/iter (+/- 450100) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_s ... bench: 5616347 ns/iter (+/- 290704) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_s/confirmation ... bench: 11382547 ns/iter (+/- 276945) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_s ... bench: 5629772 ns/iter (+/- 281306) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_s/confirmation ... bench: 11095625 ns/iter (+/- 39791) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_s_zero ... bench: 4637115 ns/iter (+/- 539747) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_s_zero/confirmation ... bench: 10374831 ns/iter (+/- 1231603) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_s_zero ... bench: 4695216 ns/iter (+/- 57115) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_s_zero/confirmation ... bench: 9953391 ns/iter (+/- 204180) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_u ... bench: 9861633 ns/iter (+/- 920070) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f32x4_u/confirmation ... bench: 19458831 ns/iter (+/- 806380) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_u ... bench: 9885974 ns/iter (+/- 26561) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f32x4_u/confirmation ... bench: 19590844 ns/iter (+/- 637505) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_u_zero ... bench: 6788175 ns/iter (+/- 189679) +test wasm_instructions/wasm32/vtrunc/i32x4.trunc_sat_f64x2_u_zero/confirmation ... bench: 15213168 ns/iter (+/- 541446) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_u_zero ... bench: 6786270 ns/iter (+/- 31569) +test wasm_instructions/wasm64/vtrunc/i32x4.trunc_sat_f64x2_u_zero/confirmation ... bench: 14383724 ns/iter (+/- 1229049) +test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_s ... bench: 2389435 ns/iter (+/- 61298) +test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_s/confirmation ... bench: 4597389 ns/iter (+/- 325904) +test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_s ... bench: 2392206 ns/iter (+/- 22739) +test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_s/confirmation ... bench: 4559440 ns/iter (+/- 32046) +test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_s ... bench: 2410488 ns/iter (+/- 418091) +test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_s/confirmation ... bench: 4537483 ns/iter (+/- 393080) +test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_s ... bench: 2383582 ns/iter (+/- 22140) +test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_s/confirmation ... bench: 4558671 ns/iter (+/- 298191) +test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_u ... bench: 10636776 ns/iter (+/- 44924) +test wasm_instructions/wasm32/vconvert/f32x4.convert_i32x4_u/confirmation ... bench: 21171926 ns/iter (+/- 27730) +test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_u ... bench: 10582934 ns/iter (+/- 23122) +test wasm_instructions/wasm64/vconvert/f32x4.convert_i32x4_u/confirmation ... bench: 21625726 ns/iter (+/- 79534) +test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_u ... bench: 4315530 ns/iter (+/- 199211) +test wasm_instructions/wasm32/vconvert/f64x2.convert_low_i32x4_u/confirmation ... bench: 10308308 ns/iter (+/- 467116) +test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_u ... bench: 4530369 ns/iter (+/- 22899) +test wasm_instructions/wasm64/vconvert/f64x2.convert_low_i32x4_u/confirmation ... bench: 10236532 ns/iter (+/- 24148) +test wasm_instructions/wasm32/vdemote/f32x4.demote_f64x2_zero ... bench: 5223871 ns/iter (+/- 511679) +test wasm_instructions/wasm32/vdemote/f32x4.demote_f64x2_zero/confirmation ... bench: 10434848 ns/iter (+/- 21545) +test wasm_instructions/wasm64/vdemote/f32x4.demote_f64x2_zero ... bench: 5116031 ns/iter (+/- 395960) +test wasm_instructions/wasm64/vdemote/f32x4.demote_f64x2_zero/confirmation ... bench: 10962999 ns/iter (+/- 1361847) +test wasm_instructions/wasm32/vpromote/f64x2.promote_low_f32x4 ... bench: 5192977 ns/iter (+/- 91995) +test wasm_instructions/wasm32/vpromote/f64x2.promote_low_f32x4/confirmation ... bench: 10500662 ns/iter (+/- 603525) +test wasm_instructions/wasm64/vpromote/f64x2.promote_low_f32x4 ... bench: 5158496 ns/iter (+/- 257061) +test wasm_instructions/wasm64/vpromote/f64x2.promote_low_f32x4/confirmation ... bench: 10671516 ns/iter (+/- 52728) +test wasm_instructions/wasm32/vvar/local.get ... bench: 2390886 ns/iter (+/- 16882) +test wasm_instructions/wasm32/vvar/local.get/confirmation ... bench: 4541045 ns/iter (+/- 341767) +test wasm_instructions/wasm64/vvar/local.get ... bench: 2351662 ns/iter (+/- 14675) +test wasm_instructions/wasm64/vvar/local.get/confirmation ... bench: 4569346 ns/iter (+/- 320087) +test wasm_instructions/wasm32/vvar/global.get ... bench: 17344576 ns/iter (+/- 1029416) +test wasm_instructions/wasm32/vvar/global.get/confirmation ... bench: 34366053 ns/iter (+/- 911668) +test wasm_instructions/wasm64/vvar/global.get ... bench: 17357515 ns/iter (+/- 916876) +test wasm_instructions/wasm64/vvar/global.get/confirmation ... bench: 34351846 ns/iter (+/- 611014) +test wasm_instructions/wasm32/vvar/local.set ... bench: 2374371 ns/iter (+/- 115509) +test wasm_instructions/wasm32/vvar/local.set/confirmation ... bench: 4540407 ns/iter (+/- 184581) +test wasm_instructions/wasm64/vvar/local.set ... bench: 2436805 ns/iter (+/- 129400) +test wasm_instructions/wasm64/vvar/local.set/confirmation ... bench: 4545955 ns/iter (+/- 512535) +test wasm_instructions/wasm32/vvar/global.set ... bench: 2381413 ns/iter (+/- 18799) +test wasm_instructions/wasm32/vvar/global.set/confirmation ... bench: 4574018 ns/iter (+/- 372460) +test wasm_instructions/wasm64/vvar/global.set ... bench: 2384801 ns/iter (+/- 18679) +test wasm_instructions/wasm64/vvar/global.set/confirmation ... bench: 4587013 ns/iter (+/- 16992) +test wasm_instructions/wasm32/vvar/local.tee ... bench: 2423193 ns/iter (+/- 245953) +test wasm_instructions/wasm32/vvar/local.tee/confirmation ... bench: 4567136 ns/iter (+/- 505872) +test wasm_instructions/wasm64/vvar/local.tee ... bench: 2392868 ns/iter (+/- 11550) +test wasm_instructions/wasm64/vvar/local.tee/confirmation ... bench: 4580608 ns/iter (+/- 32870) +test wasm_instructions/wasm32/vmem/v128.load ... bench: 3612103 ns/iter (+/- 402359) +test wasm_instructions/wasm32/vmem/v128.load/confirmation ... bench: 6941132 ns/iter (+/- 17461) +test wasm_instructions/wasm64/vmem/v128.load ... bench: 5353826 ns/iter (+/- 352392) +test wasm_instructions/wasm64/vmem/v128.load/confirmation ... bench: 10754938 ns/iter (+/- 885116) +test wasm_instructions/wasm32/vmem/v128.load_unaligned ... bench: 3621915 ns/iter (+/- 265384) +test wasm_instructions/wasm32/vmem/v128.load_unaligned/confirmation ... bench: 6918820 ns/iter (+/- 54743) +test wasm_instructions/wasm64/vmem/v128.load_unaligned ... bench: 5402944 ns/iter (+/- 474330) +test wasm_instructions/wasm64/vmem/v128.load_unaligned/confirmation ... bench: 10365900 ns/iter (+/- 68345) +test wasm_instructions/wasm32/vmem/v128.store ... bench: 3168200 ns/iter (+/- 23174) +test wasm_instructions/wasm32/vmem/v128.store/confirmation ... bench: 5979940 ns/iter (+/- 437904) +test wasm_instructions/wasm64/vmem/v128.store ... bench: 4129036 ns/iter (+/- 291012) +test wasm_instructions/wasm64/vmem/v128.store/confirmation ... bench: 8038391 ns/iter (+/- 356252) +test wasm_instructions/wasm32/vmem/v128.store_unaligned ... bench: 3112420 ns/iter (+/- 341722) +test wasm_instructions/wasm32/vmem/v128.store_unaligned/confirmation ... bench: 5983783 ns/iter (+/- 369330) +test wasm_instructions/wasm64/vmem/v128.store_unaligned ... bench: 4152287 ns/iter (+/- 312172) +test wasm_instructions/wasm64/vmem/v128.store_unaligned/confirmation ... bench: 7998454 ns/iter (+/- 291393) +test wasm_instructions/wasm32/vmem/v128.load8x8_s ... bench: 3617594 ns/iter (+/- 332859) +test wasm_instructions/wasm32/vmem/v128.load8x8_s/confirmation ... bench: 7024098 ns/iter (+/- 371542) +test wasm_instructions/wasm64/vmem/v128.load8x8_s ... bench: 5440358 ns/iter (+/- 79308) +test wasm_instructions/wasm64/vmem/v128.load8x8_s/confirmation ... bench: 10577905 ns/iter (+/- 98973) +test wasm_instructions/wasm32/vmem/v128.load8x8_u ... bench: 3689017 ns/iter (+/- 261644) +test wasm_instructions/wasm32/vmem/v128.load8x8_u/confirmation ... bench: 7132403 ns/iter (+/- 376804) +test wasm_instructions/wasm64/vmem/v128.load8x8_u ... bench: 5418753 ns/iter (+/- 328896) +test wasm_instructions/wasm64/vmem/v128.load8x8_u/confirmation ... bench: 10558125 ns/iter (+/- 547669) +test wasm_instructions/wasm32/vmem/v128.load16x4_s ... bench: 3621412 ns/iter (+/- 74792) +test wasm_instructions/wasm32/vmem/v128.load16x4_s/confirmation ... bench: 7009155 ns/iter (+/- 331392) +test wasm_instructions/wasm64/vmem/v128.load16x4_s ... bench: 5402740 ns/iter (+/- 686921) +test wasm_instructions/wasm64/vmem/v128.load16x4_s/confirmation ... bench: 10623171 ns/iter (+/- 876028) +test wasm_instructions/wasm32/vmem/v128.load16x4_u ... bench: 3634739 ns/iter (+/- 370501) +test wasm_instructions/wasm32/vmem/v128.load16x4_u/confirmation ... bench: 7152031 ns/iter (+/- 31984) +test wasm_instructions/wasm64/vmem/v128.load16x4_u ... bench: 5448616 ns/iter (+/- 373179) +test wasm_instructions/wasm64/vmem/v128.load16x4_u/confirmation ... bench: 10512163 ns/iter (+/- 236622) +test wasm_instructions/wasm32/vmem/v128.load32x2_s ... bench: 3710224 ns/iter (+/- 22584) +test wasm_instructions/wasm32/vmem/v128.load32x2_s/confirmation ... bench: 7104372 ns/iter (+/- 32367) +test wasm_instructions/wasm64/vmem/v128.load32x2_s ... bench: 5429310 ns/iter (+/- 525688) +test wasm_instructions/wasm64/vmem/v128.load32x2_s/confirmation ... bench: 11053870 ns/iter (+/- 55220) +test wasm_instructions/wasm32/vmem/v128.load32x2_u ... bench: 3685163 ns/iter (+/- 513355) +test wasm_instructions/wasm32/vmem/v128.load32x2_u/confirmation ... bench: 7161424 ns/iter (+/- 190707) +test wasm_instructions/wasm64/vmem/v128.load32x2_u ... bench: 5399633 ns/iter (+/- 448578) +test wasm_instructions/wasm64/vmem/v128.load32x2_u/confirmation ... bench: 10739258 ns/iter (+/- 85141) +test wasm_instructions/wasm32/vmem/v128.load32_zero ... bench: 3595566 ns/iter (+/- 25950) +test wasm_instructions/wasm32/vmem/v128.load32_zero/confirmation ... bench: 6913161 ns/iter (+/- 24951) +test wasm_instructions/wasm64/vmem/v128.load32_zero ... bench: 5348928 ns/iter (+/- 397996) +test wasm_instructions/wasm64/vmem/v128.load32_zero/confirmation ... bench: 10771109 ns/iter (+/- 389649) +test wasm_instructions/wasm32/vmem/v128.load64_zero ... bench: 3552710 ns/iter (+/- 194159) +test wasm_instructions/wasm32/vmem/v128.load64_zero/confirmation ... bench: 6902150 ns/iter (+/- 484663) +test wasm_instructions/wasm64/vmem/v128.load64_zero ... bench: 5374839 ns/iter (+/- 392188) +test wasm_instructions/wasm64/vmem/v128.load64_zero/confirmation ... bench: 10515193 ns/iter (+/- 67174) +test wasm_instructions/wasm32/vmem/v128.load8_splat ... bench: 3716058 ns/iter (+/- 311929) +test wasm_instructions/wasm32/vmem/v128.load8_splat/confirmation ... bench: 7078530 ns/iter (+/- 303815) +test wasm_instructions/wasm64/vmem/v128.load8_splat ... bench: 5426250 ns/iter (+/- 472143) +test wasm_instructions/wasm64/vmem/v128.load8_splat/confirmation ... bench: 10570129 ns/iter (+/- 923441) +test wasm_instructions/wasm32/vmem/v128.load16_splat ... bench: 3639992 ns/iter (+/- 161890) +test wasm_instructions/wasm32/vmem/v128.load16_splat/confirmation ... bench: 7130989 ns/iter (+/- 34331) +test wasm_instructions/wasm64/vmem/v128.load16_splat ... bench: 5425028 ns/iter (+/- 111556) +test wasm_instructions/wasm64/vmem/v128.load16_splat/confirmation ... bench: 10648882 ns/iter (+/- 389200) +test wasm_instructions/wasm32/vmem/v128.load32_splat ... bench: 3691775 ns/iter (+/- 22896) +test wasm_instructions/wasm32/vmem/v128.load32_splat/confirmation ... bench: 7001238 ns/iter (+/- 451034) +test wasm_instructions/wasm64/vmem/v128.load32_splat ... bench: 5397752 ns/iter (+/- 619932) +test wasm_instructions/wasm64/vmem/v128.load32_splat/confirmation ... bench: 10512963 ns/iter (+/- 471780) +test wasm_instructions/wasm32/vmem/v128.load64_splat ... bench: 3614107 ns/iter (+/- 156464) +test wasm_instructions/wasm32/vmem/v128.load64_splat/confirmation ... bench: 7005060 ns/iter (+/- 53015) +test wasm_instructions/wasm64/vmem/v128.load64_splat ... bench: 5441658 ns/iter (+/- 24586) +test wasm_instructions/wasm64/vmem/v128.load64_splat/confirmation ... bench: 10417255 ns/iter (+/- 540652) +test wasm_instructions/wasm32/vmem/v128.load8_lane ... bench: 3781470 ns/iter (+/- 249276) +test wasm_instructions/wasm32/vmem/v128.load8_lane/confirmation ... bench: 7381451 ns/iter (+/- 471112) +test wasm_instructions/wasm64/vmem/v128.load8_lane ... bench: 5547788 ns/iter (+/- 527935) +test wasm_instructions/wasm64/vmem/v128.load8_lane/confirmation ... bench: 10850701 ns/iter (+/- 841215) +test wasm_instructions/wasm32/vmem/v128.load16_lane ... bench: 3696438 ns/iter (+/- 486653) +test wasm_instructions/wasm32/vmem/v128.load16_lane/confirmation ... bench: 7269351 ns/iter (+/- 442680) +test wasm_instructions/wasm64/vmem/v128.load16_lane ... bench: 5487621 ns/iter (+/- 127751) +test wasm_instructions/wasm64/vmem/v128.load16_lane/confirmation ... bench: 10626657 ns/iter (+/- 30335) +test wasm_instructions/wasm32/vmem/v128.load32_lane ... bench: 3887156 ns/iter (+/- 43700) +test wasm_instructions/wasm32/vmem/v128.load32_lane/confirmation ... bench: 7596605 ns/iter (+/- 87475) +test wasm_instructions/wasm64/vmem/v128.load32_lane ... bench: 5536685 ns/iter (+/- 453732) +test wasm_instructions/wasm64/vmem/v128.load32_lane/confirmation ... bench: 11076707 ns/iter (+/- 302151) +test wasm_instructions/wasm32/vmem/v128.load64_lane ... bench: 3789539 ns/iter (+/- 153415) +test wasm_instructions/wasm32/vmem/v128.load64_lane/confirmation ... bench: 7299036 ns/iter (+/- 15461) +test wasm_instructions/wasm64/vmem/v128.load64_lane ... bench: 5550350 ns/iter (+/- 430282) +test wasm_instructions/wasm64/vmem/v128.load64_lane/confirmation ... bench: 10983383 ns/iter (+/- 1208541) +test wasm_instructions/wasm32/vmem/v128.store8_lane ... bench: 3060037 ns/iter (+/- 85698) +test wasm_instructions/wasm32/vmem/v128.store8_lane/confirmation ... bench: 5863180 ns/iter (+/- 854892) +test wasm_instructions/wasm64/vmem/v128.store8_lane ... bench: 4329396 ns/iter (+/- 215497) +test wasm_instructions/wasm64/vmem/v128.store8_lane/confirmation ... bench: 8430182 ns/iter (+/- 572031) +test wasm_instructions/wasm32/vmem/v128.store16_lane ... bench: 3027997 ns/iter (+/- 187397) +test wasm_instructions/wasm32/vmem/v128.store16_lane/confirmation ... bench: 5961808 ns/iter (+/- 40426) +test wasm_instructions/wasm64/vmem/v128.store16_lane ... bench: 4377374 ns/iter (+/- 58220) +test wasm_instructions/wasm64/vmem/v128.store16_lane/confirmation ... bench: 8424787 ns/iter (+/- 54376) +test wasm_instructions/wasm32/vmem/v128.store32_lane ... bench: 3064976 ns/iter (+/- 241376) +test wasm_instructions/wasm32/vmem/v128.store32_lane/confirmation ... bench: 5941972 ns/iter (+/- 287197) +test wasm_instructions/wasm64/vmem/v128.store32_lane ... bench: 4367650 ns/iter (+/- 564129) +test wasm_instructions/wasm64/vmem/v128.store32_lane/confirmation ... bench: 8539875 ns/iter (+/- 22684) +test wasm_instructions/wasm32/vmem/v128.store64_lane ... bench: 3087488 ns/iter (+/- 197852) +test wasm_instructions/wasm32/vmem/v128.store64_lane/confirmation ... bench: 5911514 ns/iter (+/- 518287) +test wasm_instructions/wasm64/vmem/v128.store64_lane ... bench: 4369366 ns/iter (+/- 199964) +test wasm_instructions/wasm64/vmem/v128.store64_lane/confirmation ... bench: 8480283 ns/iter (+/- 115955) diff --git a/rs/execution_environment/benches/run-all-benchmarks.sh b/rs/execution_environment/benches/run-all-benchmarks.sh index 3b53f9e027e..3e72b0c219d 100755 --- a/rs/execution_environment/benches/run-all-benchmarks.sh +++ b/rs/execution_environment/benches/run-all-benchmarks.sh @@ -28,15 +28,12 @@ run() { # Counter file tracks the number of benchmark executions so far. counter_file="${min_file%.*}.counter" - counter=$(cat "${counter_file}" 2>/dev/null || echo "-1") - # Quickly execute the benchmarks initially to identify any broken ones. - [ "${counter}" -eq "-1" ] && quick="yes" || quick="no" - [ -f "${min_file}" ] || counter="-1" + counter=$(cat "${counter_file}" 2>/dev/null || echo "0") + [ -f "${min_file}" ] || counter="0" # Execute benchmark if needed. if [ "${counter}" -lt "${i}" ]; then echo "==> Running ${name} benchmarks ($((counter + 1)) of ${REPEAT})" >&2 - QUICK="${quick}" BENCH="${bench}" MIN_FILE="${min_file}" FILTER="${filter}" \ - "${RUN_BENCHMARK}" + BENCH="${bench}" MIN_FILE="${min_file}" FILTER="${filter}" "${RUN_BENCHMARK}" echo "$((counter + 1))" >"${counter_file}" fi # Summarize results if the benchmark was executed or if it's the final iteration. @@ -46,7 +43,7 @@ run() { fi } -for i in $(seq 0 "${REPEAT}"); do +for i in $(seq 1 "${REPEAT}"); do run "${i}" "Embedders Compilation" \ "//rs/embedders:compilation_bench" "EMBEDDERS_COMPILATION.min" run "${i}" "Embedders Heap" \ diff --git a/rs/execution_environment/benches/run-benchmark.sh b/rs/execution_environment/benches/run-benchmark.sh index c258eba58fc..fbbbb8f22eb 100755 --- a/rs/execution_environment/benches/run-benchmark.sh +++ b/rs/execution_environment/benches/run-benchmark.sh @@ -8,9 +8,6 @@ set -ue DEPENDENCIES="awk bash bazel rg sed tail tee" which ${DEPENDENCIES} >/dev/null || (echo "Error checking dependencies: ${DEPENDENCIES}" >&2 && exit 1) -QUICK="${QUICK:-no}" -[ "${QUICK}" = "no" ] || BENCH_ARGS="--quick --output-format=bencher" - printf " %-12s := %s\n" \ "BENCH" "${BENCH:?Usage: BENCH='//rs/embedders:heap_bench' ${0}}" \ "BENCH_ARGS" "${BENCH_ARGS:=--warm-up-time=1 --measurement-time=1 --output-format=bencher}" \ @@ -24,7 +21,7 @@ TMP_FILE="${TMP_FILE:-${MIN_FILE%.*}.tmp}" bash -c "set -o pipefail; \ bazel run '${BENCH}' -- ${FILTER} ${BENCH_ARGS} \ 2>&1 | tee '${LOG_FILE}' | rg '^(test .* )?bench:' --line-buffered \ - | sed -uEe 's/^test (.+) ... bench: +/> bench: \1 /' -Ee 's/^bench: +/> quick: /'" \ + | sed -uEe 's/^test (.+) ... bench: +/> bench: \1 /'" \ || ( echo "Error running the benchmark:" tail -10 "${LOG_FILE}" | sed 's/^/! /' @@ -35,7 +32,7 @@ bash -c "set -o pipefail; \ if ! [ -s "${MIN_FILE}" ]; then echo " Storing results in ${MIN_FILE}" >&2 cat "${LOG_FILE}" | rg "^test .* bench:" >"${MIN_FILE}" \ - || echo " No results found in ${LOG_FILE} (quick run?)" >&2 + || echo " No results found in ${LOG_FILE}" >&2 else echo " Merging ${LOG_FILE} into ${MIN_FILE}" >&2 rm -f "${TMP_FILE}" @@ -56,6 +53,6 @@ else echo "${min_bench}" >>"${TMP_FILE}" done echo " Updating results in ${MIN_FILE}" >&2 - mv -f "${TMP_FILE}" "${MIN_FILE}" 2>/dev/null || echo " No results to update (quick run?)" >&2 + mv -f "${TMP_FILE}" "${MIN_FILE}" 2>/dev/null || echo " No results to update" >&2 fi rm -f "${LOG_FILE}" diff --git a/rs/execution_environment/benches/summarize-results.sh b/rs/execution_environment/benches/summarize-results.sh index a9cdf2f2aa7..8e94a73e1dc 100755 --- a/rs/execution_environment/benches/summarize-results.sh +++ b/rs/execution_environment/benches/summarize-results.sh @@ -65,10 +65,10 @@ esac # Produce top regressed/improved details. if [ "${total_diff}" != "0" ]; then cat "${TMP_FILE}" | sort -rn | rg '^[1-9]' | head -5 | while read diff name; do - echo "+ ${name} time regressed by ${diff}%" + echo " + ${name} time regressed by ${diff}%" done cat "${TMP_FILE}" | sort -n | rg '^-' | head -5 | while read diff name; do - echo "- ${name} time improved by ${diff}%" + echo " - ${name} time improved by ${diff}%" done fi # rm -f "${TMP_FILE}" From 4e29e46f04366166692a0b0f8c2b085b755ff130 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:15:22 +0100 Subject: [PATCH 36/98] chore(PocketIC): remove deprecated endpoint execute_ingress_message (#3361) This PR removes the deprecated endpoint `/instances//update/execute_ingress_message`: PocketIC libraries should use the two endpoints `/instances//update/submit_ingress_message` and `/instances//update/await_ingress_message` to submit and then await an ingress message instead. E.g., the Rust does already so [here](https://github.com/dfinity/ic/blob/bfa465036eb19fdc41020ca3109bff8502e959b6/packages/pocket-ic/src/nonblocking.rs#L1514-L1532). --- rs/pocket_ic_server/CHANGELOG.md | 5 ++ rs/pocket_ic_server/src/pocket_ic.rs | 65 --------------------- rs/pocket_ic_server/src/state_api/routes.rs | 32 +--------- 3 files changed, 8 insertions(+), 94 deletions(-) diff --git a/rs/pocket_ic_server/CHANGELOG.md b/rs/pocket_ic_server/CHANGELOG.md index ab99557c7a6..c814a0a9a4f 100644 --- a/rs/pocket_ic_server/CHANGELOG.md +++ b/rs/pocket_ic_server/CHANGELOG.md @@ -20,6 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Canisters created via `provisional_create_canister_with_cycles` with the management canister ID as the effective canister ID are created on an arbitrary subnet. +### Removed +- The endpoint `/instances//update/execute_ingress_message`: + use the two endpoints `/instances//update/submit_ingress_message` and `/instances//update/await_ingress_message` + to submit and then await an ingress message instead. + ## 7.0.0 - 2024-11-13 diff --git a/rs/pocket_ic_server/src/pocket_ic.rs b/rs/pocket_ic_server/src/pocket_ic.rs index f0f98d27ff5..220099396b0 100644 --- a/rs/pocket_ic_server/src/pocket_ic.rs +++ b/rs/pocket_ic_server/src/pocket_ic.rs @@ -1645,71 +1645,6 @@ impl Operation for AwaitIngressMessage { } } -#[derive(Clone, Debug)] -pub struct ExecuteIngressMessage(pub CanisterCall); - -impl Operation for ExecuteIngressMessage { - fn compute(&self, pic: &mut PocketIc) -> OpOut { - let canister_call = self.0.clone(); - let subnet = route_call(pic, canister_call); - match subnet { - Ok(subnet) => { - match subnet.submit_ingress_as( - self.0.sender, - self.0.canister_id, - self.0.method.clone(), - self.0.payload.clone(), - ) { - Err(SubmitIngressError::HttpError(e)) => { - eprintln!("Failed to submit ingress message: {}", e); - OpOut::Error(PocketIcError::BadIngressMessage(e)) - } - Err(SubmitIngressError::UserError(e)) => { - eprintln!("Failed to submit ingress message: {:?}", e); - Err::(e).into() - } - Ok(msg_id) => { - // Now, we execute on all subnets until we have the result - let max_rounds = 100; - for _i in 0..max_rounds { - for subnet_ in pic.subnets.get_all() { - subnet_.state_machine.execute_round(); - } - match subnet.ingress_status(&msg_id) { - IngressStatus::Known { - state: IngressState::Completed(result), - .. - } => return Ok(result).into(), - IngressStatus::Known { - state: IngressState::Failed(error), - .. - } => { - return Err::< - ic_state_machine_tests::WasmResult, - ic_state_machine_tests::UserError, - >(error) - .into() - } - _ => {} - } - } - OpOut::Error(PocketIcError::BadIngressMessage(format!( - "Failed to answer to ingress {} after {} rounds.", - msg_id, max_rounds - ))) - } - } - } - Err(e) => OpOut::Error(PocketIcError::BadIngressMessage(e)), - } - } - - fn id(&self) -> OpId { - let call_id = self.0.id(); - OpId(format!("canister_update_{}", call_id.0)) - } -} - #[derive(Clone, Debug)] pub struct IngressMessageStatus { pub message_id: MessageId, diff --git a/rs/pocket_ic_server/src/state_api/routes.rs b/rs/pocket_ic_server/src/state_api/routes.rs index add5a1e0d39..327a5ae7621 100644 --- a/rs/pocket_ic_server/src/state_api/routes.rs +++ b/rs/pocket_ic_server/src/state_api/routes.rs @@ -8,9 +8,9 @@ use super::state::{ApiState, OpOut, PocketIcError, StateLabel, UpdateReply}; use crate::pocket_ic::{ AddCycles, AwaitIngressMessage, CallRequest, CallRequestVersion, CanisterReadStateRequest, - DashboardRequest, ExecuteIngressMessage, GetCanisterHttp, GetControllers, GetCyclesBalance, - GetStableMemory, GetSubnet, GetTime, GetTopology, IngressMessageStatus, MockCanisterHttp, - PubKey, Query, QueryRequest, SetStableMemory, SetTime, StatusRequest, SubmitIngressMessage, + DashboardRequest, GetCanisterHttp, GetControllers, GetCyclesBalance, GetStableMemory, + GetSubnet, GetTime, GetTopology, IngressMessageStatus, MockCanisterHttp, PubKey, Query, + QueryRequest, SetStableMemory, SetTime, StatusRequest, SubmitIngressMessage, SubnetReadStateRequest, Tick, }; use crate::{async_trait, pocket_ic::PocketIc, BlobStore, InstanceId, OpId, Operation}; @@ -98,10 +98,6 @@ where "/await_ingress_message", post(handler_await_ingress_message), ) - .directory_route( - "/execute_ingress_message", - post(handler_execute_ingress_message), - ) .directory_route("/set_time", post(handler_set_time)) .directory_route("/add_cycles", post(handler_add_cycles)) .directory_route("/set_stable_memory", post(handler_set_stable_memory)) @@ -1019,28 +1015,6 @@ pub async fn handler_await_ingress_message( } } -pub async fn handler_execute_ingress_message( - State(AppState { api_state, .. }): State, - Path(instance_id): Path, - headers: HeaderMap, - extract::Json(raw_canister_call): extract::Json, -) -> (StatusCode, Json>) { - let timeout = timeout_or_default(headers); - match crate::pocket_ic::CanisterCall::try_from(raw_canister_call) { - Ok(canister_call) => { - let ingress_op = ExecuteIngressMessage(canister_call); - let (code, response) = run_operation(api_state, instance_id, timeout, ingress_op).await; - (code, Json(response)) - } - Err(e) => ( - StatusCode::BAD_REQUEST, - Json(ApiResponse::Error { - message: format!("{:?}", e), - }), - ), - } -} - pub async fn handler_ingress_status( State(AppState { api_state, .. }): State, Path(instance_id): Path, From 806d143ea64dec8c7187507ac3c283fe8ae9819b Mon Sep 17 00:00:00 2001 From: Nikolay Komarevskiy <90605504+nikolay-komarevskiy@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:10:23 +0100 Subject: [PATCH 37/98] chore(boundary): extend `rate-limit` canister `system-test` (#3296) - Verify that adding a `rate-limit` canister self blocking rule has no impact on the API boundary nodes, i.e. `ic-boundary` can still fetch rate-limit rules from the canister - Add additional step of canister upgrade via proposal (mimics the mainnet behavior) - Fixed assertions of checking canister being unreachable/reachable (after applying/removing rate-limit rules). - When canister is being effectively rate-limited, one expects `429` status code in response. However, agent does some [retries](https://github.com/dfinity/agent-rs/blob/a651dbbe69e61d4e8508c144cd60cfa3118eeb3a/ic-agent/src/agent/mod.rs#L1971) on 429 responses. To avoid any retries in the agent and get expected `429` faster, we implement a custom `HttpServiceNoRetry` for the agent middleware. - Removed unnecessary `update` call timeout --------- Co-authored-by: IDX GitLab Automation --- Cargo.lock | 2 + rs/tests/boundary_nodes/BUILD.bazel | 2 + rs/tests/boundary_nodes/Cargo.toml | 2 + .../rate_limit_canister_test.rs | 372 ++++++++++++------ 4 files changed, 263 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6de323b83c6..3133d68aad4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13694,7 +13694,9 @@ name = "ic_boundary_node_system_tests" version = "0.9.0" dependencies = [ "anyhow", + "async-trait", "candid", + "canister-test", "certificate_orchestrator_interface", "ic-agent", "ic-base-types", diff --git a/rs/tests/boundary_nodes/BUILD.bazel b/rs/tests/boundary_nodes/BUILD.bazel index 9d9b4a7982c..6916aa14f96 100644 --- a/rs/tests/boundary_nodes/BUILD.bazel +++ b/rs/tests/boundary_nodes/BUILD.bazel @@ -127,6 +127,7 @@ system_test_nns( env = { "RATE_LIMIT_CANISTER_WASM_PATH": "$(rootpath //rs/boundary_node/rate_limits:rate_limit_canister)", }, + proc_macro_deps = ["@crate_index//:async-trait"], tags = [ "k8s", ], @@ -140,6 +141,7 @@ system_test_nns( "//rs/nns/constants", "//rs/nns/test_utils", "//rs/registry/subnet_type", + "//rs/rust_canisters/canister_test", "//rs/tests/boundary_nodes/utils", "//rs/tests/driver:ic-system-test-driver", "//rs/types/base_types", diff --git a/rs/tests/boundary_nodes/Cargo.toml b/rs/tests/boundary_nodes/Cargo.toml index da97cc1a076..354485874b3 100644 --- a/rs/tests/boundary_nodes/Cargo.toml +++ b/rs/tests/boundary_nodes/Cargo.toml @@ -8,7 +8,9 @@ documentation.workspace = true [dependencies] anyhow = { workspace = true } +async-trait = { workspace = true } candid = { workspace = true } +canister-test = { path = "../../rust_canisters/canister_test" } certificate_orchestrator_interface = { path = "../../boundary_node/certificate_issuance/certificate_orchestrator_interface" } ic-agent = { workspace = true } ic-base-types = { path = "../../types/base_types" } diff --git a/rs/tests/boundary_nodes/rate_limit_canister_test.rs b/rs/tests/boundary_nodes/rate_limit_canister_test.rs index 5aba85a8aea..a59efa82fd8 100644 --- a/rs/tests/boundary_nodes/rate_limit_canister_test.rs +++ b/rs/tests/boundary_nodes/rate_limit_canister_test.rs @@ -4,42 +4,55 @@ Title:: Rate-limit canister integration with API boundary nodes Goal:: Ensure rate-limit rules can be added to the canister and are properly enforced by API Boundary Nodes. Runbook: -1. Set up an Internet Computer (IC) with a system-subnet and an API boundary node. -2. Install the rate-limit canister at a specified mainnet ID. -3. Install the counter canister, which is used for testing enforced rate-limits. -4. Create an `ic-agent` instance associated with an API boundary node. -5. Verify that initially the agent can successfully interact with the counter canister by sending e.g. an update call. -6. Add a rate-limit rule to the rate-limit canister, which completely blocks requests to the counter canister. -// TODO: BOUN-1330 - investigate the reason of flakiness in Step 7, temporarily disable steps below. -7. Verify that the agent can no longer send requests to the counter canister after API boundary node enforces the new rule. -8. Add a rate-limit rule, which unblocks requests to the counter canister. -9. Verify that the agent can send requests to the counter canister again, ensuring that updated rate-limit rules are enforced correctly by API boundary nodes. +1. Set up an Internet Computer (IC) with a system-subnet and an API boundary node. +2. Install the rate-limit canister at a specified mainnet ID, without specifying an authorized_principal in the payload argument. +3. Install the counter canister, which is used for testing enforced rate-limits. +4. Create an `ic-agent` instance associated with an API boundary node. +5. Verify that initially the agent can successfully interact with the counter canister by sending e.g. an update call. +6. Try to add two rate-limit rules to the rate-limit canister, which completely block requests to two canisters: counter and rate-limit (self blocking). +7. Assert canister call fails (rejected), as authorized_principal is unset for the rate-limit canister. +8. Upgrade rate-limit canister code via proposal, specifying authorized_principal in the payload. +9. Retry step 6 and assert it succeeds. +10. Verify that the agent can no longer send requests to the counter canister after API boundary node enforces the new rule. +11. Add a rate-limit rule, which explicitly unblocks requests to the counter canister. + Setting this rule should still be possible despite the rate-limit canister being blocked itself (as there is an explicit allow-rule in the ic-boundary). +12. Verify that the agent can send requests to the counter canister again, ensuring that updated rate-limit rules are enforced correctly by API boundary nodes. end::catalog[] */ -use anyhow::Result; +use anyhow::{bail, Result}; +use async_trait::async_trait; use candid::{Decode, Encode, Principal}; +use canister_test::{Canister, Wasm}; use ic_base_types::PrincipalId; use ic_boundary_nodes_system_test_utils::{ constants::COUNTER_CANISTER_WAT, helpers::install_canisters, }; -use ic_nns_test_utils::itest_helpers::install_rust_canister_from_path; +use ic_nns_constants::{GOVERNANCE_CANISTER_ID, ROOT_CANISTER_ID}; +use ic_nns_test_utils::{ + common::modify_wasm_bytes, governance::upgrade_nns_canister_by_proposal, + itest_helpers::install_rust_canister_from_path, +}; use k256::elliptic_curve::SecretKey; use rand::{rngs::OsRng, SeedableRng}; use rand_chacha::ChaChaRng; use slog::info; -use std::{env, net::SocketAddr}; +use std::{env, net::SocketAddr, sync::Arc, time::Duration}; use tokio::runtime::Runtime; use ic_agent::{ - agent::http_transport::reqwest_transport::reqwest::Client, identity::Secp256k1Identity, Agent, - Identity, + agent::{ + http_transport::reqwest_transport::reqwest::{Client, Request, Response}, + HttpService, + }, + identity::Secp256k1Identity, + Agent, AgentError, Identity, }; use ic_registry_subnet_type::SubnetType; use ic_system_test_driver::{ driver::test_env_api::NnsInstallationBuilder, driver::{ - group::{SystemTestGroup, SystemTestSubGroup}, + group::SystemTestGroup, ic::InternetComputer, test_env::TestEnv, test_env_api::{ @@ -47,7 +60,7 @@ use ic_system_test_driver::{ IcNodeContainer, }, }, - systest, + retry_with_msg_async, systest, util::runtime_from_url, }; use rate_limits_api::{ @@ -100,7 +113,7 @@ async fn test_async(env: TestEnv) { info!( &logger, - "Step 2. Install the rate-limit canister at a specified mainnet ID {rate_limit_id}" + "Step 2. Install the rate-limit canister at a specified mainnet ID {rate_limit_id} (do not set any authorized_principal)" ); let mut rate_limit_canister = nns @@ -108,29 +121,38 @@ async fn test_async(env: TestEnv) { .await .unwrap(); + let path_to_wasm = get_dependency_path( + env::var("RATE_LIMIT_CANISTER_WASM_PATH").expect("RATE_LIMIT_CANISTER_WASM_PATH not set"), + ); + + let wasm: Wasm = Wasm::from_file(path_to_wasm.clone()); + let args = Encode!(&InitArg { registry_polling_period_secs: 5, - authorized_principal: Some(full_access_principal), + authorized_principal: None, }) .unwrap(); - info!(&logger, "Installing rate-limit canister wasm ..."); + info!( + &logger, + "Installing rate-limit canister wasm (with unset authorized_principal)..." + ); - install_rust_canister_from_path( - &mut rate_limit_canister, - get_dependency_path( - env::var("RATE_LIMIT_CANISTER_WASM_PATH") - .expect("RATE_LIMIT_CANISTER_WASM_PATH not set"), - ), - Some(args), - ) - .await; + install_rust_canister_from_path(&mut rate_limit_canister, path_to_wasm, Some(args)).await; info!( &logger, "Rate-limit canister with id={rate_limit_id} installed successfully" ); + let root = Canister::new(&nns, ROOT_CANISTER_ID); + + // set the root principal as the controller of the canister + rate_limit_canister + .set_controller(ROOT_CANISTER_ID.into()) + .await + .unwrap(); + info!(&logger, "Step 3. Installing counter canister ..."); let counter_canister_id = install_canisters( @@ -156,8 +178,8 @@ async fn test_async(env: TestEnv) { .expect("Could not create HTTP client."); let agent = Agent::builder() .with_url(format!("https://{api_bn_domain}")) - .with_http_client(client) .with_identity(full_access_identity) + .with_arc_http_middleware(Arc::new(HttpServiceNoRetry { client })) // do not use inbuilt retry logic for 429 responses .build() .unwrap(); agent.fetch_root_key().await.unwrap(); @@ -177,101 +199,202 @@ async fn test_async(env: TestEnv) { info!( &logger, - "Step 6. Add a rate-limit rule that blocks requests to counter canister" + "Step 6. Try to add two rate-limit rules that block requests to counter and rate-limit canisters" ); - set_rate_limit_rule( + let result = set_rate_limit_rules( &api_bn_agent, rate_limit_id, - RateLimitRule { - canister_id: Some(counter_canister_id), - limit: Action::Block, - ..Default::default() - }, + vec![ + InputRule { + incident_id: "b97730ac-4879-47f2-9fea-daf20b8d4b64".to_string(), + rule_raw: RateLimitRule { + canister_id: Some(counter_canister_id), + limit: Action::Block, + ..Default::default() + } + .to_bytes_json() + .unwrap(), + description: "Block requests to counter canister".to_string(), + }, + InputRule { + incident_id: "34bb6dee-9646-4543-ba62-af546ea5565b".to_string(), + rule_raw: RateLimitRule { + canister_id: Some(rate_limit_id), + limit: Action::Block, + ..Default::default() + } + .to_bytes_json() + .unwrap(), + description: "Block requests to rate-limit canister".to_string(), + }, + ], + ) + .await; + + info!( + &logger, + "Step 7. Assert canister call fails (rejected), as authorized_principal is unset for the rate-limit canister", + ); + + assert!(result.unwrap_err().contains("reject")); + + info!( + &logger, + "Step 8. Upgrade rate-limit canister code via proposal, specifying authorized_principal in the payload", + ); + + let args = Encode!(&InitArg { + registry_polling_period_secs: 5, + authorized_principal: Some(full_access_principal), + }) + .unwrap(); + + // apply a no-impact WASM modification and reinstall the canister + let new_wasm = modify_wasm_bytes(wasm.bytes().as_slice(), 42); + + upgrade_nns_canister_by_proposal( + &rate_limit_canister, + &Canister::new(&nns, GOVERNANCE_CANISTER_ID), + &root, + true, + Wasm::from_bytes(new_wasm), + Some(args), ) .await; - // TODO: BOUN-1330 - investigate the reason of flakiness in Step 7, temporarily disable steps below. - - // info!( - // &logger, - // "Step 7. Verify that the api_bn_agent can no longer send requests to the counter canister" - // ); - - // retry_with_msg_async!( - // "check_counter_canister_becomes_unreachable".to_string(), - // &logger, - // Duration::from_secs(180), - // Duration::from_secs(5), - // || async { - // match timeout( - // Duration::from_secs(2), - // api_bn_agent.update(&counter_canister_id, "write").call(), - // ) - // .await - // { - // Ok(_) => bail!("counter canister is still reachable, retrying"), - // Err(_) => Ok(()), - // } - // } - // ) - // .await - // .expect("failed to check that canister becomes unreachable"); - - // info!( - // &logger, - // "Step 8. Add a rate-limit rule, which unblocks requests to the counter canister" - // ); - - // set_rate_limit_rule( - // &api_bn_agent, - // rate_limit_id, - // RateLimitRule { - // canister_id: Some(counter_canister_id), - // limit: Action::Limit(300, Duration::from_secs(60)), - // ..Default::default() - // }, - // ) - // .await; - - // info!( - // &logger, - // "Step 9. Verify that agent can send requests to the counter canister again" - // ); - - // retry_with_msg_async!( - // "check_counter_canister_becomes_reachable".to_string(), - // &logger, - // Duration::from_secs(180), - // Duration::from_secs(5), - // || async { - // match timeout( - // Duration::from_secs(2), - // api_bn_agent.update(&counter_canister_id, "write").call(), - // ) - // .await - // { - // Ok(_) => Ok(()), - // Err(_) => bail!("counter canister is still unreachable, retrying"), - // } - // } - // ) - // .await - // .expect("failed to check that canister becomes reachable"); + info!( + &logger, + "Step 9. Assert adding two rate-limit rules to the rate-limit canister now succeeds" + ); + + set_rate_limit_rules( + &api_bn_agent, + rate_limit_id, + vec![ + InputRule { + incident_id: "b97730ac-4879-47f2-9fea-daf20b8d4b64".to_string(), + rule_raw: RateLimitRule { + canister_id: Some(counter_canister_id), + limit: Action::Block, + ..Default::default() + } + .to_bytes_json() + .unwrap(), + description: "Block requests to counter canister".to_string(), + }, + InputRule { + incident_id: "34bb6dee-9646-4543-ba62-af546ea5565b".to_string(), + rule_raw: RateLimitRule { + canister_id: Some(rate_limit_id), + limit: Action::Block, + ..Default::default() + } + .to_bytes_json() + .unwrap(), + description: "Block requests to rate-limit canister".to_string(), + }, + ], + ) + .await + .unwrap(); + + info!( + &logger, + "Step 10. Verify that the api_bn_agent can no longer send requests to the counter canister" + ); + + retry_with_msg_async!( + "check_counter_canister_becomes_unreachable".to_string(), + &logger, + Duration::from_secs(180), + Duration::from_secs(5), + || async { + match api_bn_agent + .update(&counter_canister_id, "write") + .call() + .await + { + Ok(_) => { + bail!("counter canister is still reachable, retrying"); + } + Err(error) => { + // We should observe Too Many Requests 429 http error + if let AgentError::HttpError(ref payload) = error { + if payload.status == 429 { + return Ok(()); + } + } + bail!("update call failed with unexpected error: {error:?}"); + } + } + } + ) + .await + .expect("failed to check that canister becomes unreachable"); + + info!( + &logger, + "Step 11. Add a rate-limit rule, which unblocks requests to the counter canister" + ); + + set_rate_limit_rules( + &api_bn_agent, + rate_limit_id, + vec![InputRule { + incident_id: "e6a27788-01a5-444a-9035-ab3af3ad84f3".to_string(), + rule_raw: RateLimitRule { + canister_id: Some(counter_canister_id), + limit: Action::Limit(300, Duration::from_secs(60)), + ..Default::default() + } + .to_bytes_json() + .unwrap(), + description: "Unblock requests to the counter canister".to_string(), + }], + ) + .await + .unwrap(); + + info!( + &logger, + "Step 12. Verify that agent can send requests to the counter canister again" + ); + + retry_with_msg_async!( + "check_counter_canister_becomes_reachable".to_string(), + &logger, + Duration::from_secs(180), + Duration::from_secs(5), + || async { + match api_bn_agent + .update(&counter_canister_id, "write") + .call() + .await + { + Ok(response) => { + info!(&logger, "update call succeeded with response: {response:?}"); + Ok(()) + } + Err(error) => { + info!(&logger, "update call failed with error: {error:?}"); + bail!("counter canister is still unreachable, retrying"); + } + } + } + ) + .await + .expect("failed to check that canister becomes reachable"); } -async fn set_rate_limit_rule( +async fn set_rate_limit_rules( agent: &Agent, rate_limit_canister_id: Principal, - rule: RateLimitRule, -) { + rules: Vec, +) -> Result<(), String> { let args = Encode!(&InputConfig { schema_version: 1, - rules: vec![InputRule { - incident_id: "b97730ac-4879-47f2-9fea-daf20b8d4b64".to_string(), - rule_raw: rule.to_bytes_json().unwrap(), - description: "Setting a rate-limit rule for testing".to_string(), - },], + rules, }) .unwrap(); @@ -280,9 +403,11 @@ async fn set_rate_limit_rule( .with_arg(args) .call_and_wait() .await - .unwrap(); + .map_err(|err| err.to_string())?; - let _ = Decode!(&result, AddConfigResponse).expect("failed to add new rate-limit config"); + Decode!(&result, AddConfigResponse) + .expect("failed to deserialize response") + .map_err(|err| format!("{err:?}")) } fn test(env: TestEnv) { @@ -293,7 +418,24 @@ fn test(env: TestEnv) { fn main() -> Result<()> { SystemTestGroup::new() .with_setup(setup) - .add_parallel(SystemTestSubGroup::new().add_test(systest!(test))) + .add_test(systest!(test)) .execute_from_args()?; Ok(()) } + +// The default HttpService in ic-agent retries on 429 errors, but we expect these and don't want retries. +#[derive(Debug)] +struct HttpServiceNoRetry { + client: Client, +} + +#[async_trait] +impl HttpService for HttpServiceNoRetry { + async fn call<'a>( + &'a self, + req: &'a (dyn Fn() -> Result + Send + Sync), + _max_tcp_retries: usize, + ) -> Result { + Ok(self.client.call(req, _max_tcp_retries).await?) + } +} From 2136abeadec6604cfd2b16c46974d4a07270acdf Mon Sep 17 00:00:00 2001 From: Nikolay Komarevskiy <90605504+nikolay-komarevskiy@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:23:25 +0100 Subject: [PATCH 38/98] chore(boundary): bump `ic-gateway` to `v0.1.63` (#3378) Co-authored-by: IDX GitLab Automation --- ic-os/boundary-guestos/context/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ic-os/boundary-guestos/context/Dockerfile b/ic-os/boundary-guestos/context/Dockerfile index 3292d751cc5..0177f381a6d 100644 --- a/ic-os/boundary-guestos/context/Dockerfile +++ b/ic-os/boundary-guestos/context/Dockerfile @@ -25,8 +25,8 @@ WORKDIR /tmp # Download and verify ic-gateway RUN \ - curl -L -O https://github.com/dfinity/ic-gateway/releases/download/v0.1.62/ic-gateway_0.1.62_amd64.deb && \ - echo "91aa1a2de67ac8147b3d45642ddc5bb28934b1611e7f2aa31ce01c98507c5c71 ic-gateway_0.1.62_amd64.deb" | sha256sum -c + curl -L -O https://github.com/dfinity/ic-gateway/releases/download/v0.1.63/ic-gateway_0.1.63_amd64.deb && \ + echo "f33d2bd14b7dcc9964a62e522fdf3fa6ab9360bd7bd9a87e83a8a515dd36e18b ic-gateway_0.1.63_amd64.deb" | sha256sum -c # # Second build stage: @@ -56,9 +56,9 @@ FROM image-${BUILD_TYPE} USER root:root -COPY --from=download /tmp/ic-gateway_0.1.62_amd64.deb /tmp/ic-gateway_0.1.62_amd64.deb -RUN dpkg -i --force-confold /tmp/ic-gateway_0.1.62_amd64.deb && \ - rm /tmp/ic-gateway_0.1.62_amd64.deb +COPY --from=download /tmp/ic-gateway_0.1.63_amd64.deb /tmp/ic-gateway_0.1.63_amd64.deb +RUN dpkg -i --force-confold /tmp/ic-gateway_0.1.63_amd64.deb && \ + rm /tmp/ic-gateway_0.1.63_amd64.deb RUN mkdir -p /boot/config \ /boot/efi \ From 60596066decf1b438406b918f32e1b3281fcd9c6 Mon Sep 17 00:00:00 2001 From: jasonz-dfinity <133917836+jasonz-dfinity@users.noreply.github.com> Date: Thu, 9 Jan 2025 07:09:58 -0800 Subject: [PATCH 39/98] =?UTF-8?q?test(nns):=20Revert=20"test(nns):=20Suppo?= =?UTF-8?q?rt=20caching=20of=20the=20golden=20NNS=20state=20when=20runni?= =?UTF-8?q?=E2=80=A6=20(#3356)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the state machine tests modifies the state in place, running tests this way more than one time (which is the whole point of caching it) might yield surprising results. Therefore the `USE_CACHED_STATE_DIR` should be removed. --- rs/nns/test_utils/golden_nns_state/src/lib.rs | 75 ++++--------------- 1 file changed, 13 insertions(+), 62 deletions(-) diff --git a/rs/nns/test_utils/golden_nns_state/src/lib.rs b/rs/nns/test_utils/golden_nns_state/src/lib.rs index 0e1a466306c..90aa86ce529 100644 --- a/rs/nns/test_utils/golden_nns_state/src/lib.rs +++ b/rs/nns/test_utils/golden_nns_state/src/lib.rs @@ -1,18 +1,12 @@ use ic_base_types::{CanisterId, PrincipalId, SubnetId}; use ic_config::{execution_environment::Config, subnet_config::SubnetConfig}; use ic_registry_subnet_type::SubnetType; -use ic_state_machine_tests::{ - StateMachine, StateMachineBuilder, StateMachineConfig, StateMachineStateDir, -}; +use ic_state_machine_tests::{StateMachine, StateMachineBuilder, StateMachineConfig}; use ic_config::flag_status::FlagStatus; use ic_registry_routing_table::{CanisterIdRange, RoutingTable, CANISTER_IDS_PER_SUBNET}; use std::ops::RangeInclusive; -use std::{ - path::{Path, PathBuf}, - process::Command, - str::FromStr, -}; +use std::{path::Path, process::Command, str::FromStr}; use tempfile::TempDir; // TODO: Add support for PocketIc. @@ -104,7 +98,8 @@ fn new_state_machine_with_golden_state_or_panic(setup_config: SetupConfig) -> St hypervisor_config.unwrap_or_default(), ))); - let state_dir = maybe_download_golden_nns_state_or_panic(scp_location, archive_state_dir_name); + let state_dir = + download_and_untar_golden_nns_state_or_panic(scp_location, archive_state_dir_name); let state_machine_builder = state_machine_builder .with_state_machine_state_dir(Box::new(state_dir)) // Patch StateMachine. This is a bit of a hack that we need because we @@ -119,67 +114,23 @@ fn new_state_machine_with_golden_state_or_panic(setup_config: SetupConfig) -> St state_machine } -/// A directory for storing the golden state which can be either a temporary directory or a cached -/// directory which can be used across multiple tests. -enum StateDir { - // A temporary directory that will be deleted after the test is done. - Temp(TempDir), - // A directory that will be cached and reused across tests. - Cache(PathBuf), -} - -impl StateMachineStateDir for StateDir { - fn path(&self) -> PathBuf { - match self { - Self::Temp(temp_dir) => temp_dir.path().to_path_buf(), - Self::Cache(path) => path.clone(), - } - } -} - -fn maybe_download_golden_nns_state_or_panic( - scp_location: ScpLocation, - archive_state_dir_name: &str, -) -> StateDir { - let maybe_use_cached_state_dir = std::env::var_os("USE_CACHED_STATE_DIR"); - - match maybe_use_cached_state_dir { - Some(cached_state_dir) => { - let destination = PathBuf::from(cached_state_dir).join(archive_state_dir_name); - if !destination.exists() { - std::fs::create_dir(&destination) - .unwrap_or_else(|_| panic!("Failed to create directory {destination:?}")); - download_and_untar_golden_nns_state_or_panic( - scp_location, - archive_state_dir_name, - &destination, - ); - } - StateDir::Cache(destination) - } - None => { - let state_dir = bazel_test_compatible_temp_dir_or_panic(); - download_and_untar_golden_nns_state_or_panic( - scp_location, - archive_state_dir_name, - state_dir.path(), - ); - StateDir::Temp(state_dir) - } - } -} - fn download_and_untar_golden_nns_state_or_panic( scp_location: ScpLocation, archive_state_dir_name: &str, - destination: &Path, -) { +) -> TempDir { let download_destination = bazel_test_compatible_temp_dir_or_panic(); let download_destination = download_destination .path() .join(format!("{}.tar.zst", archive_state_dir_name)); download_golden_nns_state_or_panic(scp_location, &download_destination); - untar_state_archive_or_panic(&download_destination, destination, archive_state_dir_name); + + let state_dir = bazel_test_compatible_temp_dir_or_panic(); + untar_state_archive_or_panic( + &download_destination, + state_dir.path(), + archive_state_dir_name, + ); + state_dir } // Privates From 68e52f27bb067914fb58e92db2d3332d3a66e484 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:13:32 +0100 Subject: [PATCH 40/98] feat(governance): Enable periodic confirmation. (#3371) This is done by flipping a couple of flags. This is the last step in the release of "periodic confirmation". There is still some post-launch follow up work. All the usual consequences of this being a flag flip apply. In particular, if we need to roll back, it will be fairly easy and low risk. This causes a performance regression for metrics. [A ticket][regression] has been opened to follow up on that. For now, this has been deemed acceptable, because metrics are calculated in the background, and is performed infrequently. [regression]: https://dfinity.atlassian.net/browse/NNS1-3535 # References This is part of the "periodic confirmation" feature that was recently approved in proposal [132411][prop]. [prop]: https://dashboard.internetcomputer.org/proposal/132411 Closes [NNS1-3444]. [NNS1-3444]: https://dfinity.atlassian.net/browse/NNS1-3444 --- .../governance/canbench/canbench_results.yml | 8 ++--- rs/nns/governance/src/lib.rs | 4 +-- rs/nns/governance/unreleased_changelog.md | 32 +++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/rs/nns/governance/canbench/canbench_results.yml b/rs/nns/governance/canbench/canbench_results.yml index 7d8efc965bc..98282e4d781 100644 --- a/rs/nns/governance/canbench/canbench_results.yml +++ b/rs/nns/governance/canbench/canbench_results.yml @@ -55,7 +55,7 @@ benches: scopes: {} compute_ballots_for_new_proposal_with_stable_neurons: total: - instructions: 2019526 + instructions: 2197226 heap_increase: 0 stable_memory_increase: 0 scopes: {} @@ -85,7 +85,7 @@ benches: scopes: {} list_neurons_heap: total: - instructions: 4345595 + instructions: 4700995 heap_increase: 9 stable_memory_increase: 0 scopes: {} @@ -133,13 +133,13 @@ benches: scopes: {} neuron_metrics_calculation_heap: total: - instructions: 954474 + instructions: 1457674 heap_increase: 0 stable_memory_increase: 0 scopes: {} neuron_metrics_calculation_stable: total: - instructions: 2479136 + instructions: 2982336 heap_increase: 0 stable_memory_increase: 0 scopes: {} diff --git a/rs/nns/governance/src/lib.rs b/rs/nns/governance/src/lib.rs index c85919f1875..13b1890016b 100644 --- a/rs/nns/governance/src/lib.rs +++ b/rs/nns/governance/src/lib.rs @@ -196,9 +196,9 @@ pub const DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS: u64 = 1725148800; // amount of time. thread_local! { - static IS_VOTING_POWER_ADJUSTMENT_ENABLED: Cell = const { Cell::new(cfg!(feature = "test")) }; + static IS_VOTING_POWER_ADJUSTMENT_ENABLED: Cell = const { Cell::new(true) }; - static IS_PRUNE_FOLLOWING_ENABLED: Cell = const { Cell::new(cfg!(feature = "test")) }; + static IS_PRUNE_FOLLOWING_ENABLED: Cell = const { Cell::new(true) }; // TODO(NNS1-3247): To release the feature, set this to true. Do not simply // delete. That way, if we need to recall the feature, we can do that via a diff --git a/rs/nns/governance/unreleased_changelog.md b/rs/nns/governance/unreleased_changelog.md index 992f06a9226..5751df51cb8 100644 --- a/rs/nns/governance/unreleased_changelog.md +++ b/rs/nns/governance/unreleased_changelog.md @@ -34,6 +34,38 @@ links to keepachangelog.com as its source of inspiration. ## Added +### Periodic Confirmation + +Enabled voting power adjustment and follow pruning. + +#### Prior Work + +This section describes related changes in previous releases. + +We already started recording how long it's been since neurons have confirmed +their following (aka refreshed voting power). Neurons were also given the +ability to confirm their following. Those who have never confirmed are +considered as having refreshed on Sep 1, 2024. + +This feature was proposed and approved in motion [proposal 132411]. + +[proposal 132411]: https://dashboard.internetcomputer.org/proposal/132411 + +#### New Behavior(s) (In This Release) + +With this enablement, not refreshing for more than 6 months will start to affect +the neuron. More precisely, + +1. If a neuron has not refreshed in 6 months, then votes have less influence on + the outcome of proposals. + +2. If a neuron has not refreshed in 7 months, + + a. It stops following other neurons (except on the NeuronManagement topic; + those followees are retained). + + b. Its influence on proposals goes to 0. + ## Changed ## Deprecated From 6704c14386f703ebbb46b6345bfe7dd14180f87e Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" <189003650+pr-automation-bot-public[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 10:17:39 -0600 Subject: [PATCH 41/98] chore: Update Base Image Refs [2025-01-09-0807] (#3374) Updating base container image references. Run URL: https://github.com/dfinity/ic/actions/runs/12685817695 Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> --- ic-os/boundary-guestos/context/docker-base.prod | 2 +- ic-os/guestos/context/docker-base.dev | 2 +- ic-os/guestos/context/docker-base.prod | 2 +- ic-os/hostos/context/docker-base.dev | 2 +- ic-os/hostos/context/docker-base.prod | 2 +- ic-os/setupos/context/docker-base.dev | 2 +- ic-os/setupos/context/docker-base.prod | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ic-os/boundary-guestos/context/docker-base.prod b/ic-os/boundary-guestos/context/docker-base.prod index b7015b232fc..8abee27e8f2 100644 --- a/ic-os/boundary-guestos/context/docker-base.prod +++ b/ic-os/boundary-guestos/context/docker-base.prod @@ -1 +1 @@ -ghcr.io/dfinity/boundaryos-base@sha256:ef882d02bc505767eb687a447d2a516a49951c4bd2f5244e0834cc763d5fe9e9 +ghcr.io/dfinity/boundaryos-base@sha256:f771e5cbb6bc8c42983a331d52f1377b220006c8ced778bf17853359b7a8425d diff --git a/ic-os/guestos/context/docker-base.dev b/ic-os/guestos/context/docker-base.dev index dfe5c047f91..fbe705c58e0 100644 --- a/ic-os/guestos/context/docker-base.dev +++ b/ic-os/guestos/context/docker-base.dev @@ -1 +1 @@ -ghcr.io/dfinity/guestos-base-dev@sha256:af84d8211c4b5e258036e40db3c0a22aff13bd4812793fe9792faea21053a24d +ghcr.io/dfinity/guestos-base-dev@sha256:8f9c6e9ee671ee35b7c78f8d2d6f02de515d88b2623ab3068ed6ccafbdf85367 diff --git a/ic-os/guestos/context/docker-base.prod b/ic-os/guestos/context/docker-base.prod index fdb2f130916..796248cb4e3 100644 --- a/ic-os/guestos/context/docker-base.prod +++ b/ic-os/guestos/context/docker-base.prod @@ -1 +1 @@ -ghcr.io/dfinity/guestos-base@sha256:0fabffa89d47510c79714842d4b5f15945095f4c76102bd6ec5dc8d62ba36ed3 +ghcr.io/dfinity/guestos-base@sha256:cacd67837eb7be7c2be6e3d7e3199ac8c32a738e0aa1205c7a3d938bee804882 diff --git a/ic-os/hostos/context/docker-base.dev b/ic-os/hostos/context/docker-base.dev index f3efc47634d..d67538ae2a8 100644 --- a/ic-os/hostos/context/docker-base.dev +++ b/ic-os/hostos/context/docker-base.dev @@ -1 +1 @@ -ghcr.io/dfinity/hostos-base-dev@sha256:fcc23e7050ad3411effc1981a25ef33a667745f4211318297b000bc1616da3a2 +ghcr.io/dfinity/hostos-base-dev@sha256:4c99f3bdeb4ab0dae3ef9b29b85392e0586cadc5b2c17d775a7d71e4eb5638ee diff --git a/ic-os/hostos/context/docker-base.prod b/ic-os/hostos/context/docker-base.prod index cbe9fb5337b..f0b91faaaaa 100644 --- a/ic-os/hostos/context/docker-base.prod +++ b/ic-os/hostos/context/docker-base.prod @@ -1 +1 @@ -ghcr.io/dfinity/hostos-base@sha256:12ff5dce3ab883c608b10cf28ff0229cc49d933314b073d67714d086522d8c5f +ghcr.io/dfinity/hostos-base@sha256:a4d22768b111eff3ef5e875f83dc55eea9f6b853deb6753bfcd1071271b2303d diff --git a/ic-os/setupos/context/docker-base.dev b/ic-os/setupos/context/docker-base.dev index a5867e433cd..dcf1b5f7dfb 100644 --- a/ic-os/setupos/context/docker-base.dev +++ b/ic-os/setupos/context/docker-base.dev @@ -1 +1 @@ -ghcr.io/dfinity/setupos-base-dev@sha256:2c93a5e0fe7b9356f480956530d2d4a7402713be52991be3d8beb208eabfd4cb +ghcr.io/dfinity/setupos-base-dev@sha256:7d5ac4b029c62424b2563f35ec98cd7d2c3f4dc3e4b620872576c0f64973a338 diff --git a/ic-os/setupos/context/docker-base.prod b/ic-os/setupos/context/docker-base.prod index b3935e5ee7c..75515f4802d 100644 --- a/ic-os/setupos/context/docker-base.prod +++ b/ic-os/setupos/context/docker-base.prod @@ -1 +1 @@ -ghcr.io/dfinity/setupos-base@sha256:02a3ab89253bcc4461d6c9a9a11a030371158174d1c74a5c80a751b55f6e0710 +ghcr.io/dfinity/setupos-base@sha256:533a3ef6c894b3256e57253ac93597ad43b0a4595b621206bb82d79ba04448e1 From 760e1f764b56f4f655a09789c245da487eccc5cb Mon Sep 17 00:00:00 2001 From: Alin Sinpalean <58422065+alin-at-dfinity@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:22:18 +0100 Subject: [PATCH 42/98] feat: Implement `MutableIntMap` (#3303) `MutableIntMap` is an internally mutable variant of `IntMap`. The underlying tree is still a persistent data structure, so cloning is constant time and different copies of the same `MutableIntMap` can be modified independently. And the performance is similar, since it's based on the same internals. It is intended as a drop-in replacement for `BTreeMap` (hence the internal mutability as opposed to the purely functional interface of `IntMap`). For that reason, it also implements `remove()`, `split_off()` and `extend()`; as well as a couple of syntactic sugar methods (e.g. `keys()` and `values()`). And it provides support for any integer-like keys (that can be efficiently mapped to `u64` or `u128`). The main performance difference between `IntMap` and `MutableIntMap` comes from (i) having `insert()` return the previous value; and (ii) keeping track of / recalculating the size of the map, so that `len()` completes in constant time. --------- Co-authored-by: Stefan Schneider <31004026+schneiderstefan@users.noreply.github.com> --- rs/replicated_state/BUILD.bazel | 2 +- rs/replicated_state/benches/bench_intmap.rs | 211 +++- rs/replicated_state/src/page_map.rs | 36 +- rs/replicated_state/src/page_map/int_map.rs | 945 +++++++++++++++--- .../src/page_map/int_map/test.rs | 489 ++++++++- .../src/page_map/page_allocator.rs | 2 +- .../src/page_map/page_allocator/mmap.rs | 6 +- rs/replicated_state/src/page_map/storage.rs | 2 +- .../src/page_map/storage/tests.rs | 2 +- 9 files changed, 1456 insertions(+), 239 deletions(-) diff --git a/rs/replicated_state/BUILD.bazel b/rs/replicated_state/BUILD.bazel index 7a20362c223..fe5acc9a3ce 100644 --- a/rs/replicated_state/BUILD.bazel +++ b/rs/replicated_state/BUILD.bazel @@ -120,7 +120,7 @@ rust_bench( name = "replicated_state_intmap_bench", testonly = True, srcs = [ - "benches/bench_allocator.rs", + "benches/bench_intmap.rs", ], deps = [":replicated_state"] + BIN_DEPENDENCIES, ) diff --git a/rs/replicated_state/benches/bench_intmap.rs b/rs/replicated_state/benches/bench_intmap.rs index 9c15511bbb5..a425a8030ad 100644 --- a/rs/replicated_state/benches/bench_intmap.rs +++ b/rs/replicated_state/benches/bench_intmap.rs @@ -1,7 +1,7 @@ use criterion::{black_box, BatchSize, BenchmarkId, Criterion}; use criterion_time::ProcessTime; -use ic_replicated_state::page_map::int_map::IntMap; +use ic_replicated_state::page_map::int_map::{AsInt, IntMap, MutableIntMap}; use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; @@ -11,57 +11,208 @@ fn value(k: u64) -> Value { Arc::new(k.to_be_bytes().to_vec()) } +const BENCH_SIZES: &[u64] = &[10, 100, 1000]; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct Key128(i32, usize); + +impl AsInt for Key128 { + type Repr = u128; + + #[inline] + fn as_int(&self) -> u128 { + (self.0 as u128) << 64 | self.1 as u128 + } +} + +fn key128(i: u64) -> Key128 { + Key128(i as i32 / 4, i as usize % 4) +} + fn bench_intmap(c: &mut Criterion) { let mut group = c.benchmark_group("Insert"); - for n in [10u64, 100, 1000].iter().cloned() { + for &n in BENCH_SIZES.iter() { group.bench_function(BenchmarkId::new("patricia", n), |b| { b.iter(|| { - let m: IntMap<_> = (0..n).map(|x| (x, value(x))).collect(); + let m: IntMap = (0..n).map(|x| (x * 13 % n, value(x))).collect(); + black_box(m); + }) + }); + group.bench_function(BenchmarkId::new("mpatricia", n), |b| { + b.iter(|| { + let m: MutableIntMap = (0..n).map(|x| (x * 13 % n, value(x))).collect(); + black_box(m); + }) + }); + group.bench_function(BenchmarkId::new("mpatricia_128", n), |b| { + b.iter(|| { + let m: MutableIntMap = + (0..n).map(|x| (key128(x * 13 % n), value(x))).collect(); black_box(m); }) }); group.bench_function(BenchmarkId::new("cow_btree", n), |b| { b.iter(|| { - let m: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); + let m: Arc> = + Arc::new((0..n).map(|x| (x * 13 % n, value(x))).collect()); + black_box(m); + }) + }); + group.bench_function(BenchmarkId::new("cow_btree_128", n), |b| { + b.iter(|| { + let m: Arc> = + Arc::new((0..n).map(|x| (key128(x * 13 % n), value(x))).collect()); black_box(m); }) }); group.bench_function(BenchmarkId::new("cow_hash", n), |b| { b.iter(|| { - let m: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); + let m: Arc> = + Arc::new((0..n).map(|x| (x * 13 % n, value(x))).collect()); + black_box(m); + }) + }); + group.bench_function(BenchmarkId::new("cow_hash_128", n), |b| { + b.iter(|| { + let m: Arc> = + Arc::new((0..n).map(|x| (key128(x * 13 % n), value(x))).collect()); black_box(m); }) }); } group.finish(); - let mut group = c.benchmark_group("Lookup"); - for n in [10u64, 100, 1000].iter().cloned() { - let patricia_map: IntMap = (0..n).map(|x| (x, value(x))).collect(); + let mut group = c.benchmark_group("Remove"); + for &n in BENCH_SIZES.iter() { + let patricia_map: IntMap = (0..n).map(|x| (x, value(x))).collect(); + let mpatricia_map: MutableIntMap = (0..n).map(|x| (x, value(x))).collect(); let btree_map: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); let hash_map: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); + + group.bench_function(BenchmarkId::new("patricia", n), |b| { + b.iter_batched( + || patricia_map.clone(), + |mut map| { + for i in 0..n { + map = map.remove(&(i * 13 % n)).0; + map = map.remove(&(i * 13 % n + n)).0; + } + black_box(map); + }, + BatchSize::SmallInput, + ); + }); + group.bench_function(BenchmarkId::new("mpatricia", n), |b| { + b.iter_batched( + || mpatricia_map.clone(), + |mut map| { + for i in 0..n { + map.remove(&(i * 13 % n)); + map.remove(&(i * 13 % n + n)); + } + black_box(map); + }, + BatchSize::SmallInput, + ); + }); + group.bench_function(BenchmarkId::new("cow_btree", n), |b| { + b.iter_batched( + || Arc::clone(&btree_map), + |mut map| { + let map = Arc::make_mut(&mut map); + for i in 0..n { + map.remove(&(i * 13 % n)); + map.remove(&(i * 13 % n + n)); + } + black_box(map); + }, + BatchSize::SmallInput, + ); + }); + group.bench_function(BenchmarkId::new("cow_hash", n), |b| { + b.iter_batched( + || Arc::clone(&hash_map), + |mut map| { + let map = Arc::make_mut(&mut map); + for i in 0..n { + map.remove(&(i * 13 % n)); + map.remove(&(i * 13 % n + n)); + } + black_box(map); + }, + BatchSize::SmallInput, + ); + }); + } + group.finish(); + + let mut group = c.benchmark_group("Lookup"); + for &n in BENCH_SIZES.iter() { + const N: u64 = 5; + let kv = |x| (N * x, value(x)); + let kv128 = |x| (key128(N * x), value(x)); + + let patricia_map: IntMap = (0..n).map(kv).collect(); + let mpatricia_map: MutableIntMap = (0..n).map(kv).collect(); + let patricia_128_map: MutableIntMap = (0..n).map(kv128).collect(); + let btree_map: Arc> = Arc::new((0..n).map(kv).collect()); + let btree_128_map: Arc> = Arc::new((0..n).map(kv128).collect()); + let hash_map: Arc> = Arc::new((0..n).map(kv).collect()); + let hash_128_map: Arc> = Arc::new((0..n).map(kv128).collect()); group.bench_function(BenchmarkId::new("patricia", n), |b| { b.iter(|| { for i in 0..n { - black_box(patricia_map.get(i)); - black_box(patricia_map.get(i + n)); + black_box(patricia_map.get(&(i * N))); + black_box(patricia_map.get(&(i * N + 3))); + } + }); + }); + group.bench_function(BenchmarkId::new("mpatricia", n), |b| { + b.iter(|| { + for i in 0..n { + black_box(mpatricia_map.get(&(i * N))); + black_box(mpatricia_map.get(&(i * N + 3))); + } + }); + }); + group.bench_function(BenchmarkId::new("mpatricia_128", n), |b| { + b.iter(|| { + for i in 0..n { + black_box(patricia_128_map.get(&key128(i * N))); + black_box(patricia_128_map.get(&key128(i * N + 3))); } }); }); group.bench_function(BenchmarkId::new("cow_btree", n), |b| { b.iter(|| { for i in 0..n { - black_box(btree_map.get(&i)); - black_box(btree_map.get(&(i + n))); + black_box(btree_map.get(&(i * N))); + black_box(btree_map.get(&(i * N + 3))); + } + }); + }); + group.bench_function(BenchmarkId::new("cow_btree_128", n), |b| { + b.iter(|| { + for i in 0..n { + black_box(btree_128_map.get(&key128(i * N))); + black_box(btree_128_map.get(&key128(i * N + 3))); } }); }); group.bench_function(BenchmarkId::new("cow_hash", n), |b| { b.iter(|| { for i in 0..n { - black_box(hash_map.get(&i)); - black_box(hash_map.get(&(i + n))); + black_box(hash_map.get(&(i * N))); + black_box(hash_map.get(&(i * N + 3))); + } + }); + }); + group.bench_function(BenchmarkId::new("cow_hash_128", n), |b| { + b.iter(|| { + for i in 0..n { + black_box(hash_128_map.get(&key128(i * N))); + black_box(hash_128_map.get(&key128(i * N + 3))); } }); }); @@ -69,9 +220,13 @@ fn bench_intmap(c: &mut Criterion) { group.finish(); let mut group = c.benchmark_group("Union"); - for n in [10u64, 100, 1000].iter().cloned() { - let patricia_lmap: IntMap = (0..n).map(|x| (x, value(x))).collect(); - let patricia_rmap: IntMap = (n / 2..n + n / 2).map(|x| (x, value(x))).collect(); + for &n in BENCH_SIZES.iter() { + let patricia_lmap: IntMap = (0..n).map(|x| (x, value(x))).collect(); + let patricia_rmap: IntMap = (n / 2..n + n / 2).map(|x| (x, value(x))).collect(); + + let mpatricia_lmap: MutableIntMap = (0..n).map(|x| (x, value(x))).collect(); + let mpatricia_rmap: MutableIntMap = + (n / 2..n + n / 2).map(|x| (x, value(x))).collect(); let btree_lmap: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); @@ -91,6 +246,16 @@ fn bench_intmap(c: &mut Criterion) { BatchSize::SmallInput, ); }); + group.bench_function(BenchmarkId::new("mpatricia", n), |b| { + b.iter_batched( + || (mpatricia_lmap.clone(), mpatricia_rmap.clone()), + |(mut l, r)| { + l.union(r); + black_box(l); + }, + BatchSize::SmallInput, + ); + }); group.bench_function(BenchmarkId::new("cow_btree", n), |b| { b.iter_batched( || (Arc::clone(&btree_lmap), Arc::clone(&btree_rmap)), @@ -121,8 +286,9 @@ fn bench_intmap(c: &mut Criterion) { group.finish(); let mut group = c.benchmark_group("Iter"); - for n in [10u64, 100, 1000].iter().cloned() { - let patricia_map: IntMap = (0..n).map(|x| (x, value(x))).collect(); + for &n in BENCH_SIZES.iter() { + let patricia_map: IntMap = (0..n).map(|x| (x, value(x))).collect(); + let mpatricia_map: MutableIntMap = (0..n).map(|x| (x, value(x))).collect(); let btree_map: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); let hash_map: Arc> = Arc::new((0..n).map(|x| (x, value(x))).collect()); @@ -134,6 +300,13 @@ fn bench_intmap(c: &mut Criterion) { } }); }); + group.bench_function(BenchmarkId::new("mpatricia", n), |b| { + b.iter(|| { + for e in mpatricia_map.iter() { + black_box(e); + } + }); + }); group.bench_function(BenchmarkId::new("cow_btree", n), |b| { b.iter(|| { for e in btree_map.iter() { diff --git a/rs/replicated_state/src/page_map.rs b/rs/replicated_state/src/page_map.rs index 46fce36445b..ee6a474152b 100644 --- a/rs/replicated_state/src/page_map.rs +++ b/rs/replicated_state/src/page_map.rs @@ -167,7 +167,7 @@ impl<'a> WriteBuffer<'a> { /// operation. This allows us to simplify canister state management: we can /// simply have a copy of the whole PageMap in every canister snapshot. #[derive(Clone, Debug, Default)] -pub(crate) struct PageDelta(IntMap); +pub(crate) struct PageDelta(IntMap); impl PageDelta { /// Gets content of the page at the specified index. @@ -176,21 +176,19 @@ impl PageDelta { /// allocating pages in this `PageDelta`. It serves as a witness that /// the contents of the page is still valid. fn get_page(&self, page_index: PageIndex) -> Option<&PageBytes> { - self.0.get(page_index.get()).map(|p| p.contents()) + self.0.get(&page_index).map(|p| p.contents()) } /// Returns a reference to the page at the specified index. fn get_page_ref(&self, page_index: PageIndex) -> Option<&Page> { - self.0.get(page_index.get()) + self.0.get(&page_index) } /// Returns (lower, upper), where: /// - lower is the largest index/page smaller or equal to the given page index. /// - upper is the smallest index/page larger or equal to the given page index. fn bounds(&self, page_index: PageIndex) -> Bounds { - let (lower, upper) = self.0.bounds(page_index.get()); - let map_index = |(k, v)| (PageIndex::new(k), v); - (lower.map(map_index), upper.map(map_index)) + self.0.bounds(&page_index) } /// Modifies this delta in-place by applying all the entries in `rhs` to it. @@ -199,8 +197,8 @@ impl PageDelta { } /// Enumerates all the pages in this delta. - fn iter(&self) -> impl Iterator { - self.0.iter().map(|(idx, page)| (PageIndex::new(idx), page)) + fn iter(&self) -> impl Iterator { + self.0.iter() } /// Returns true if the page delta contains no pages. @@ -210,8 +208,8 @@ impl PageDelta { /// Returns the largest page index in the page delta. /// If the page delta is empty, then it returns `None`. - fn max_page_index(&self) -> Option { - self.0.max_key().map(PageIndex::from) + fn max_page_index(&self) -> Option<&PageIndex> { + self.0.max_key() } /// Returns the number of pages in the page delta. @@ -225,7 +223,7 @@ where I: IntoIterator, { fn from(delta: I) -> Self { - Self(delta.into_iter().map(|(i, p)| (i.get(), p)).collect()) + Self(delta.into_iter().collect()) } } @@ -562,7 +560,7 @@ impl PageMap { self.page_allocator.serialize_page_delta( pages .iter() - .map(|index| (*index, self.page_delta.get_page_ref(*index).unwrap())), + .map(|index| (index, self.page_delta.get_page_ref(*index).unwrap())), ) } @@ -652,7 +650,7 @@ impl PageMap { } /// Returns the iterator over delta pages in this `PageMap` - pub fn delta_pages_iter(&self) -> impl Iterator + '_ { + pub fn delta_pages_iter(&self) -> impl Iterator + '_ { self.page_delta .iter() .map(|(index, page)| (index, page.contents())) @@ -699,7 +697,7 @@ impl PageMap { if result_range.end < max_range.end { let (_, upper_bound) = page_delta.bounds(result_range.end); match upper_bound { - Some((key, page)) if key < max_range.end => { + Some((&key, page)) if key < max_range.end => { if include { let end = PageIndex::new(key.get() + 1); instructions.push((key..end, MemoryMapOrData::Data(page.contents()))); @@ -729,7 +727,7 @@ impl PageMap { let (lower_bound, _) = page_delta.bounds(PageIndex::new(result_range.start.get() - 1)); match lower_bound { - Some((key, page)) if key >= max_range.start => { + Some((&key, page)) if key >= max_range.start => { let end = PageIndex::new(key.get() + 1); if include { instructions.push((key..end, MemoryMapOrData::Data(page.contents()))); @@ -849,7 +847,7 @@ impl PageMap { } pub fn get_page_delta_indices(&self) -> Vec { - self.page_delta.iter().map(|(index, _)| index).collect() + self.page_delta.iter().map(|(index, _)| *index).collect() } /// Whether there are any page deltas @@ -937,10 +935,10 @@ impl PageMap { let mut last_applied_index: Option = None; let num_host_pages = self.num_host_pages() as u64; for (index, _) in page_delta.iter() { - debug_assert!(self.page_delta.0.get(index.get()).is_some()); - assert!(index < num_host_pages.into()); + debug_assert!(self.page_delta.0.get(index).is_some()); + assert!(*index < num_host_pages.into()); - if last_applied_index.is_some() && last_applied_index.unwrap() >= index { + if last_applied_index.is_some() && last_applied_index.unwrap() >= *index { continue; } diff --git a/rs/replicated_state/src/page_map/int_map.rs b/rs/replicated_state/src/page_map/int_map.rs index dfee6bc72d5..1dcecde9410 100644 --- a/rs/replicated_state/src/page_map/int_map.rs +++ b/rs/replicated_state/src/page_map/int_map.rs @@ -3,72 +3,115 @@ #[cfg(test)] mod test; -use std::{cmp::Ordering, sync::Arc}; +use ic_validate_eq::ValidateEq; +use phantom_newtype::Id; +use std::cmp::Ordering; +use std::fmt::Debug; +use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Sub}; +use std::sync::Arc; /// Big-endian patricia trees. +/// +/// `K` and `V` are the key and value types, respectively, where `K` can be +/// represented as an unsigned integer type (`u64` or `u128`). #[derive(Clone, Debug, Default)] -enum Tree { +enum Tree { /// An empty tree. + /// /// Allowing empty trees simplifies the code a bit. #[default] Empty, + /// A key-value pair. - Leaf(u64, T), + Leaf(K, V), + /// A binary fork. /// /// Invariants: /// /// * Both left and right subtrees aren't empty, i.e., - /// + /// ``` /// left.len() > 0 && right.len() > 0 + /// ``` /// - /// * For each leaf L in left and right, the key bits match the prefix up - /// to but not including the branching bit, i.e., + /// * For each leaf `L` in `left` and `right`, the key bits match the prefix + /// up to but not including the branching bit, i.e., + /// ``` + /// matches_prefix(L.key, prefix, branching_bit) == true + /// ``` /// - /// matches_prefix(L.key, prefix, branching_bit) == true. + /// * For each leaf `L` in the left subtree: + /// ``` + /// L.key & (1 << branching_bit) == 0 + /// ``` /// - /// * For each leaf L in the left subtree: + /// * For each leaf `L` in the right subtree: + /// ``` + /// L.key & (1 << branching_bit) != 0 + /// ``` /// - /// L.key & (1 << branching_bit) == 0. - /// - /// * For each leaf L in the right subtree: - /// - /// L.key & (1 << branching_bit) == 1. - /// - /// * 0 ≤ branching_bit ≤ 63. + /// * ``` + /// 0 ≤ branching_bit < K::Repr::size_bits(). + /// ``` Branch { - prefix: u64, + prefix: K::Repr, branching_bit: u8, - left: Arc>, - right: Arc>, + left: Arc>, + right: Arc>, }, } -/// Creates a branch node having subtrees t0 and t1 as children. +/// Creates a branch node having subtrees `t0` and `t1` as children. /// -/// Precondition: p0 ≠ p1 +/// Precondition: `p0 ≠ p1` #[inline] -fn join(p0: u64, t0: Arc>, p1: u64, t1: Arc>) -> Tree { - let b = branching_bit(p0, p1); +fn join( + p0: K::Repr, + t0: Arc>, + p1: K::Repr, + t1: Arc>, +) -> Tree { + debug_assert_eq!( + p0, + match t0.as_ref() { + Tree::Leaf(k, _) => k.as_int(), + Tree::Branch { prefix, .. } => *prefix, + Tree::Empty => panic!("expected a leaf or branch"), + } + ); + debug_assert_eq!( + p1, + match t1.as_ref() { + Tree::Leaf(k, _) => k.as_int(), + Tree::Branch { prefix, .. } => *prefix, + Tree::Empty => panic!("expected a leaf or branch"), + } + ); + + let branching_bit = branching_bit(p0, p1); + let prefix = mask(p0, branching_bit); - if p0 & (1 << b) == 0 { + // NB: This assumes that `K::Repr` is an unsigned integer type. This is ensured + // by the `IntKey` extending `sealed::UnsignedInt` (which is only implemented + // for unsigned integer types). + if p0 < p1 { Tree::Branch { - prefix: mask(p0, b), - branching_bit: b, + prefix, + branching_bit, left: t0, right: t1, } } else { Tree::Branch { - prefix: mask(p0, b), - branching_bit: b, + prefix, + branching_bit, left: t1, right: t0, } } } -/// Modifies the contents of an Arc, creating a copy if necessary. +/// Modifies the contents of an `Arc`, creating a copy if necessary. #[inline] fn with_arc(mut p: Arc, f: impl FnOnce(T) -> T) -> Arc { let dst = Arc::make_mut(&mut p); @@ -76,7 +119,17 @@ fn with_arc(mut p: Arc, f: impl FnOnce(T) -> T) -> Arc p } -/// Extracts a value from an Arc, cloning its content if necessary. +/// Calls the given function on the mutable contents of an `Arc`, creating a +/// copy if necessary. +#[inline] +fn with_arc2(mut p: Arc, f: impl FnOnce(T) -> (T, V)) -> (Arc, V) { + let dst = Arc::make_mut(&mut p); + let v; + (*dst, v) = f(std::mem::take(dst)); + (p, v) +} + +/// Extracts a value from an `Arc`, cloning its content if necessary. #[inline] fn take_arc(p: Arc) -> T { match Arc::try_unwrap(p) { @@ -86,20 +139,140 @@ fn take_arc(p: Arc) -> T { } /// The return type of the `bounds()` method. +/// /// See the comments of the public `bounds()` method. -pub(crate) type Bounds<'a, K, V> = (Option<(K, &'a V)>, Option<(K, &'a V)>); +pub(crate) type Bounds<'a, K, V> = (Option<(&'a K, &'a V)>, Option<(&'a K, &'a V)>); + +mod int_key { + /// Limit the types that can be used as `IntKey` to unsigned integer types. + /// + /// Warning! Do not implement this trait for other types. + pub(super) trait UnsignedInt {} + + impl UnsignedInt for u64 {} + impl UnsignedInt for u128 {} +} + +/// An integer key type for `IntMap` (implemented for `u64` and `u128`). +#[allow(private_bounds)] +pub trait IntKey: + Sized + + Eq + + Ord + + Copy + + Sub + + BitAnd + + BitOr + + BitXor + + Not + + Shl + + Debug + + int_key::UnsignedInt +{ + /// The type's zero value. + fn zero() -> Self; + + /// The type's unit value. + fn one() -> Self; + + /// The type's maximum value. + fn max_value() -> Self; + + /// The type's size in bits. + #[inline] + fn size_bits() -> u8 { + size_of::() as u8 * 8 + } + + /// Returns the number of leading zeros in the binary representation of `self`. + fn leading_zeros(self) -> u32; +} + +impl IntKey for u64 { + #[inline] + fn zero() -> Self { + 0 + } + + #[inline] + fn one() -> Self { + 1 + } + + #[inline] + fn max_value() -> Self { + Self::MAX + } + + #[inline] + fn leading_zeros(self) -> u32 { + self.leading_zeros() + } +} -impl Tree { - fn get(&self, key: u64) -> Option<&T> { +impl IntKey for u128 { + #[inline] + fn zero() -> Self { + 0 + } + + #[inline] + fn one() -> Self { + 1 + } + + #[inline] + fn max_value() -> Self { + Self::MAX + } + + #[inline] + fn leading_zeros(self) -> u32 { + self.leading_zeros() + } +} + +/// Conversion from actual key type (`K`) to `IntKey`. +/// +/// The compiler doesn't like us using `From` / `Into` for this, so we define +/// our own trait instead. +pub trait AsInt: Copy + Ord { + type Repr: IntKey; + + fn as_int(&self) -> Self::Repr; +} + +impl AsInt for u64 { + type Repr = u64; + + #[inline] + fn as_int(&self) -> u64 { + *self + } +} + +impl AsInt for Id { + type Repr = u64; + + #[inline] + fn as_int(&self) -> u64 { + self.get() + } +} + +impl Tree { + fn get(&self, key: K::Repr) -> Option<&V> { match self { Tree::Empty => None, + Tree::Leaf(k, v) => { - if key == *k { + if key == k.as_int() { Some(v) } else { None } } + Tree::Branch { prefix, branching_bit, @@ -108,7 +281,7 @@ impl Tree { } => { if !matches_prefix(key, *prefix, *branching_bit) { None - } else if key & (1 << branching_bit) == 0 { + } else if key & (K::Repr::one() << *branching_bit) == K::Repr::zero() { (*left).get(key) } else { (*right).get(key) @@ -118,55 +291,62 @@ impl Tree { } /// See the comments of the public `bounds()` method. - fn bounds(&self, key: u64) -> Bounds { + fn bounds(&self, key: &K) -> Bounds { match self { Tree::Empty => (None, None), + Tree::Leaf(k, v) => match key.cmp(k) { - Ordering::Less => (None, Some((*k, v))), - Ordering::Equal => (Some((key, v)), Some((key, v))), - Ordering::Greater => (Some((*k, v)), None), + Ordering::Less => (None, Some((k, v))), + Ordering::Equal => (Some((k, v)), Some((k, v))), + Ordering::Greater => (Some((k, v)), None), }, + Tree::Branch { prefix, branching_bit, left, right, - } => match mask(key, *branching_bit).cmp(prefix) { - Ordering::Less => (None, (*left).min()), - Ordering::Greater => ((*right).max(), None), - Ordering::Equal => { - if key & (1 << branching_bit) == 0 { - let (start, end) = (*left).bounds(key); - if end.is_none() { - (start, (*right).min()) - } else { - (start, end) - } - } else { - let (start, end) = (*right).bounds(key); - if start.is_none() { - ((*left).max(), end) + } => { + let key_int = key.as_int(); + match mask(key_int, *branching_bit).cmp(prefix) { + Ordering::Less => (None, (*left).min()), + Ordering::Greater => ((*right).max(), None), + Ordering::Equal => { + if key_int & (K::Repr::one() << *branching_bit) == K::Repr::zero() { + let (start, end) = (*left).bounds(key); + if end.is_none() { + (start, (*right).min()) + } else { + (start, end) + } } else { - (start, end) + let (start, end) = (*right).bounds(key); + if start.is_none() { + ((*left).max(), end) + } else { + (start, end) + } } } } - }, + } } } - // Returns the smallest key/value pair in the given tree. - // If the tree is empty, then it returns `None`. - fn min(&self) -> Option<(u64, &T)> { + /// Returns the smallest key/value pair in this tree. + /// If the tree is empty, then it returns `None`. + fn min(&self) -> Option<(&K, &V)> { let mut node = self; loop { match node { Tree::Empty => { return None; } + Tree::Leaf(k, v) => { - return Some((*k, v)); + return Some((k, v)); } + Tree::Branch { prefix: _, branching_bit: _, @@ -179,18 +359,20 @@ impl Tree { } } - // Returns the largest key/value pair in the given tree. - // If the tree is empty, then it returns `None`. - fn max(&self) -> Option<(u64, &T)> { + /// Returns the largest key/value pair in this tree. + /// If the tree is empty, then it returns `None`. + fn max(&self) -> Option<(&K, &V)> { let mut node = self; loop { match node { Tree::Empty => { return None; } + Tree::Leaf(k, v) => { - return Some((*k, v)); + return Some((k, v)); } + Tree::Branch { prefix: _, branching_bit: _, @@ -203,72 +385,141 @@ impl Tree { } } - fn insert(self, key: u64, value: T) -> Self { + fn insert(self, key: K, value: V) -> (Self, Option) { match self { - Tree::Empty => Tree::Leaf(key, value), + Tree::Empty => (Tree::Leaf(key, value), None), + Tree::Leaf(k, v) => { if k == key { - Tree::Leaf(k, value) + (Tree::Leaf(k, value), Some(v)) } else { - join( - key, - Arc::new(Tree::Leaf(key, value)), - k, - Arc::new(Tree::Leaf(k, v)), + ( + join( + key.as_int(), + Arc::new(Tree::Leaf(key, value)), + k.as_int(), + Arc::new(Tree::Leaf(k, v)), + ), + None, ) } } + Tree::Branch { prefix, branching_bit, left, right, } => { - if matches_prefix(key, prefix, branching_bit) { - if key & (1 << branching_bit) == 0 { - Tree::Branch { - prefix, - branching_bit, - left: with_arc(left, |l| l.insert(key, value)), - right, - } + let key_int = key.as_int(); + if matches_prefix(key_int, prefix, branching_bit) { + if key_int & (K::Repr::one() << branching_bit) == K::Repr::zero() { + let (left, res) = with_arc2(left, |l| l.insert(key, value)); + ( + Tree::Branch { + prefix, + branching_bit, + left, + right, + }, + res, + ) } else { - Tree::Branch { - prefix, - branching_bit, - left, - right: with_arc(right, |r| r.insert(key, value)), - } + let (right, res) = with_arc2(right, |r| r.insert(key, value)); + ( + Tree::Branch { + prefix, + branching_bit, + left, + right, + }, + res, + ) } } else { - join( - key, - Arc::new(Tree::Leaf(key, value)), - prefix, - Arc::new(Tree::Branch { + ( + join( + key_int, + Arc::new(Tree::Leaf(key, value)), prefix, - branching_bit, - left, - right, - }), + Arc::new(Tree::Branch { + prefix, + branching_bit, + left, + right, + }), + ), + None, ) } } } } + fn remove(self, key: &K) -> (Self, Option) { + match self { + Tree::Empty => (Tree::Empty, None), + + Tree::Leaf(k, v) if &k == key => (Tree::Empty, Some(v)), + + Tree::Leaf(..) => (self, None), + + Tree::Branch { + prefix, + branching_bit, + left, + right, + } if matches_prefix(key.as_int(), prefix, branching_bit) => { + if key.as_int() & (K::Repr::one() << branching_bit) == K::Repr::zero() { + let (left, res) = take_arc(left).remove(key); + match left { + Tree::Empty => (take_arc(right), res), + _ => ( + Tree::Branch { + prefix, + branching_bit, + left: Arc::new(left), + right, + }, + res, + ), + } + } else { + let (right, res) = take_arc(right).remove(key); + match right { + Tree::Empty => (take_arc(left), res), + _ => ( + Tree::Branch { + prefix, + branching_bit, + left, + right: Arc::new(right), + }, + res, + ), + } + } + } + + Tree::Branch { .. } => (self, None), + } + } + fn union(self, other: Self) -> Self { match (self, other) { (Tree::Empty, t) | (t, Tree::Empty) => t, - (Tree::Leaf(k, v), t) => t.insert(k, v), + + (Tree::Leaf(k, v), t) => t.insert(k, v).0, + (t, Tree::Leaf(k, v)) => { - if t.get(k).is_some() { + if t.get(k.as_int()).is_some() { // In case of collision, retain the value in `self`. t } else { - t.insert(k, v) + t.insert(k, v).0 } } + ( Tree::Branch { prefix: p0, @@ -292,14 +543,14 @@ impl Tree { right: with_arc(right0, move |r| r.union(take_arc(right1))), } } else if b0 > b1 && matches_prefix(p1, p0, b0) { + // Pattern p1 contains p0 as a sub-pattern. let t = Tree::Branch { prefix: p1, branching_bit: b1, left: left1, right: right1, }; - // Pattern p1 contains p0 as a sub-pattern. - if p1 & (1 << b0) == 0 { + if p1 & (K::Repr::one() << b0) == K::Repr::zero() { Tree::Branch { prefix: p0, branching_bit: b0, @@ -322,7 +573,7 @@ impl Tree { left: left0, right: right0, }; - if p0 & (1 << b1) == 0 { + if p0 & (K::Repr::one() << b1) == K::Repr::zero() { Tree::Branch { prefix: p1, branching_bit: b1, @@ -356,23 +607,93 @@ impl Tree { } } + /// Splits the tree in two just before the given key. + pub fn split(self, key: &K) -> (Self, Self) { + match self { + Tree::Empty => (Tree::Empty, Tree::Empty), + + Tree::Leaf(k, _) if k.as_int() < key.as_int() => (self, Tree::Empty), + + Tree::Leaf(..) => (Tree::Empty, self), + + Tree::Branch { + prefix, + branching_bit, + left, + right, + } if matches_prefix(key.as_int(), prefix, branching_bit) => { + if key.as_int() & (K::Repr::one() << branching_bit) == K::Repr::zero() { + let (ll, lr) = take_arc(left).split(key); + (ll, lr.union(take_arc(right))) + } else { + let (rl, rr) = take_arc(right).split(key); + (take_arc(left).union(rl), rr) + } + } + + Tree::Branch { prefix, .. } => { + if prefix < key.as_int() { + (self, Tree::Empty) + } else { + (Tree::Empty, self) + } + } + } + } + fn len(&self) -> usize { match self { Tree::Empty => 0, + Tree::Leaf(_, _) => 1, + Tree::Branch { left, right, .. } => left.len() + right.len(), } } } -/// Purely functional persistent sorted map with an integer key. +impl ValidateEq for Tree +where + K: AsInt + PartialEq + std::fmt::Debug, + V: ValidateEq + Clone, +{ + fn validate_eq(&self, rhs: &Self) -> Result<(), String> { + let mut left_iter = IntMapIter::new(self); + let mut right_iter = IntMapIter::new(rhs); + + loop { + match (left_iter.next(), right_iter.next()) { + (None, None) => return Ok(()), + + (Some((lk, lv)), Some((rk, rv))) => { + if lk != rk { + return Err(format!("Key divergence: {:#?} != {:#?}", lk, rk)); + } + if let Err(err) = lv.validate_eq(rv) { + return Err(format!("Value divergence @{:#?}: {}", lk, err)); + } + } + + _ => { + return Err(format!( + "Length divergence: {} != {}", + self.len(), + rhs.len() + )) + } + } + } + } +} + +/// Purely functional persistent sorted map with an integer-like key. /// -/// Persistence means that the map can be cheaply (in O(1)) cloned, and each +/// Persistence means that the map can be cheaply cloned (in `O(1)`), and each /// version can be modified independently. /// /// This data structure provides blazingly fast lookups (often comparable to or -/// surpassing a HashMap), while inserts are relatively expensive (2-10x slower -/// than a HashMap, depending on the size of the value and the map). +/// surpassing a `HashMap`) with relatively expensive inserts (2-10x slower than +/// a `HashMap`, depending on the size of the value and the map). /// /// The implementation is based on big-endian patricia trees. /// @@ -380,54 +701,74 @@ impl Tree { /// September 1998, pages 77-86, /// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.5452 #[derive(Clone, Debug)] -pub struct IntMap(Tree); +pub struct IntMap(Tree); -impl Default for IntMap { +impl Default for IntMap { fn default() -> Self { Self(Tree::Empty) } } -impl IntMap { +impl IntMap { /// Creates a new empty map. pub fn new() -> Self { Self::default() } - /// Looks up a value by integer key. + /// Looks up a value by key. /// - /// Complexity: O(min(N, 64)) - pub fn get(&self, key: u64) -> Option<&T> { - self.0.get(key) - } - - // Returns `(lower, upper)` inclusive bounds for the given key such that: - // - `lower` is the largest key/value pair in the tree that is smaller or equal to the - // given key. If such a key doesn't exist then, `lower = None`. - // - `upper` is the smallest key/value pair in the tree that is larger or equal to the - // given key. If such a key doesn't exist then, `upper = None`. - // - // In all cases the following post-conditions hold: - // - lower.0 <= key <= upper.0, - // - for all i in [lower.0 + 1..upper.0 - 1]: self.get(i) == None, - // - lower == Some((k, v)) implies self.get(k) == v, - // - upper == Some((k, v)) implies self.get(k) == v, - // - // Complexity: O(min(N, 64)) - pub fn bounds(&self, key: u64) -> Bounds { + /// Complexity: `O(min(N, |key|))`. + pub fn get(&self, key: &K) -> Option<&V> { + self.0.get(key.as_int()) + } + + /// Returns `true` if the map contains the specified key. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn contains_key(&self, key: &K) -> bool { + self.0.get(key.as_int()).is_some() + } + + /// Returns `(lower, upper)` inclusive bounds for the given key such that: + /// - `lower` is the largest key/value pair in the tree that is smaller than + /// or equal to the given key. If such a key doesn't exist, then + /// `lower = None`. + /// - `upper` is the smallest key/value pair in the tree that is larger than + /// or equal to the given key. If such a key doesn't exist, then + /// `upper = None`. + /// + /// In all cases the following post-conditions hold: + /// - `lower.0 <= key <= upper.0`, + /// - `for all i in [lower.0 + 1..upper.0 - 1]: self.get(i) == None`, + /// - `lower == Some((k, v))` implies `self.get(k) == v`, + /// - `upper == Some((k, v))` implies `self.get(k) == v`, + /// + /// Complexity: `O(min(N, |key|))`. + pub fn bounds(&self, key: &K) -> Bounds { self.0.bounds(key) } - /// Inserts a new entry into this map. + /// Inserts a new entry into this map. Returns the mutated map and the previous + /// value for the key, if any. /// - /// Complexity: O(min(N, 64)) - pub fn insert(self, key: u64, value: T) -> Self { - Self(self.0.insert(key, value)) + /// Complexity: `O(min(N, |key|))`. + pub fn insert(self, key: K, value: V) -> (Self, Option) { + let (tree, res) = self.0.insert(key, value); + (Self(tree), res) + } + + /// Removes the entry with the given key from this map. Returns the mutated map + /// and the removed value, if any. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn remove(self, key: &K) -> (Self, Option) { + let (tree, res) = self.0.remove(key); + (Self(tree), res) } /// Unions two maps, preferring entries from self in case of a collision. /// - /// Complexity: O(N + M) + /// Complexity: `O(N + M)` pub fn union(self, other: Self) -> Self { Self(self.0.union(other.0)) } @@ -435,95 +776,379 @@ impl IntMap { /// Returns an iterator over key-value pairs. /// The keys are guaranteed to be sorted. /// - /// A full traversal requires O(N) operations. - pub fn iter(&self) -> IntMapIter<'_, T> { + /// A full traversal requires `O(N)` operations. + pub fn iter(&self) -> IntMapIter<'_, K, V> { IntMapIter::new(&self.0) } + /// Returns an iterator over the keys. + /// The keys are guaranteed to be sorted. + /// + /// A full traversal requires `O(N)` operations. + pub fn keys(&self) -> impl Iterator { + IntMapIter::new(&self.0).map(|(k, _v)| k) + } + /// Returns the number of entries in this map. /// - /// Complexity: O(N) + /// Complexity: `O(N)` pub fn len(&self) -> usize { self.0.len() } /// Returns true if this map is empty. /// - /// Complexity: O(1) + /// Complexity: `O(1)` pub fn is_empty(&self) -> bool { matches!(self.0, Tree::Empty) } - /// Returns the largest key in the given tree. + /// Returns the largest key in this map. /// If the tree is empty, then it returns `None`. - pub fn max_key(&self) -> Option { + /// + /// Complexity: `O(min(N, |key|))`. + pub fn max_key(&self) -> Option<&K> { self.0.max().map(|(k, _v)| k) } } -impl std::iter::FromIterator<(u64, T)> for IntMap { - fn from_iter(iter: I) -> Self +impl std::iter::FromIterator<(K, V)> for IntMap { + fn from_iter(iter: Iter) -> Self + where + Iter: IntoIterator, + { + let mut m = Self::new(); + for (k, v) in iter { + m = m.insert(k, v).0; + } + m + } +} + +impl PartialEq for IntMap { + fn eq(&self, other: &Self) -> bool { + self.iter().eq(other.iter()) + } +} +impl Eq for IntMap {} + +impl ValidateEq for IntMap +where + K: AsInt + PartialEq + std::fmt::Debug, + V: ValidateEq + Clone, +{ + fn validate_eq(&self, rhs: &Self) -> Result<(), String> { + self.0.validate_eq(&rhs.0) + } +} + +/// An internally mutable variant of `IntMap`. +/// +/// The underlying tree is still a persistent data structure, so different +/// copies of the same `MutableIntMap` can be modified independently. And the +/// performance is similar, since it's based on the same internals. +#[derive(Clone, Debug)] +pub struct MutableIntMap { + tree: Tree, + len: usize, +} + +impl Default for MutableIntMap { + fn default() -> Self { + Self { + tree: Tree::Empty, + len: 0, + } + } +} + +impl MutableIntMap { + /// Creates a new empty map. + pub fn new() -> Self { + Self::default() + } + + /// Looks up a value by integer key. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn get(&self, key: &K) -> Option<&V> { + self.tree.get(key.as_int()) + } + + /// Returns `true` if the map contains a value for the specified key. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn contains_key(&self, key: &K) -> bool { + self.tree.get(key.as_int()).is_some() + } + + /// Returns `(lower, upper)` inclusive bounds for the given key such that: + /// - `lower` is the largest key/value pair in the tree that is smaller than + /// or equal to the given key. If such a key doesn't exist, then + /// `lower = None`. + /// - `upper` is the smallest key/value pair in the tree that is larger than + /// or equal to the given key. If such a key doesn't exist, then + /// `upper = None`. + /// + /// In all cases the following post-conditions hold: + /// - `lower.0 <= key <= upper.0`, + /// - `for all i in [lower.0 + 1..upper.0 - 1]: self.get(i) == None`, + /// - `lower == Some((k, v))` implies `self.get(k) == v`, + /// - `upper == Some((k, v))` implies `self.get(k) == v`, + /// + /// Complexity: `O(min(N, |key|))`. + pub fn bounds(&self, key: &K) -> Bounds { + self.tree.bounds(key) + } + + /// Inserts a new entry into this map. Returns the previous value for the key, + /// if any. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn insert(&mut self, key: K, value: V) -> Option { + let tree = std::mem::take(&mut self.tree); + let res; + (self.tree, res) = tree.insert(key, value); + + if res.is_none() { + self.len += 1; + } + debug_assert_eq!(self.tree.len(), self.len); + + res + } + + /// Removes and returns the entry with the given key, if any, from this map. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn remove(&mut self, key: &K) -> Option { + let tree = std::mem::take(&mut self.tree); + let res; + (self.tree, res) = tree.remove(key); + + if res.is_some() { + self.len -= 1; + } + debug_assert_eq!(self.tree.len(), self.len); + + res + } + + /// Unions two maps, preferring entries from `self`` in case of a collision. + /// + /// Complexity: `O(N + M)` + pub fn union(&mut self, other: Self) { + let tree = std::mem::take(&mut self.tree); + self.tree = tree.union(other.tree); + // TODO(MR-645): Have `Tree::union()` also return the new length. + self.len = self.tree.len(); + } + + /// Splits the collection into two at the given key. Returns everything after + /// the given key, including the key. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn split_off(&mut self, key: &K) -> Self { + let tree = std::mem::take(&mut self.tree); + let right; + (self.tree, right) = tree.split(key); + + let old_len = self.len; + // TODO(MR-645): Have `Tree::split()` also return the new lengths. + self.len = self.tree.len(); + + Self { + tree: right, + len: old_len - self.len, + } + } + + /// Returns an iterator over key-value pairs. + /// The keys are guaranteed to be sorted. + /// + /// A full traversal requires O(N) operations. + pub fn iter(&self) -> IntMapIter<'_, K, V> { + IntMapIter::new(&self.tree) + } + + /// Returns an iterator over the keys. + /// The keys are guaranteed to be sorted. + /// + /// A full traversal requires O(N) operations. + pub fn keys(&self) -> impl Iterator { + IntMapIter::new(&self.tree).map(|(k, _v)| k) + } + + /// Returns an iterator over the values, in order by key. + /// + /// A full traversal requires O(N) operations. + pub fn values(&self) -> impl Iterator { + IntMapIter::new(&self.tree).map(|(_k, v)| v) + } + + /// Returns the number of entries in this map. + /// + /// Complexity: `O(1)` + pub fn len(&self) -> usize { + self.len + } + + /// Returns true if this map is empty. + /// + /// Complexity: `O(1)` + pub fn is_empty(&self) -> bool { + matches!(self.tree, Tree::Empty) + } + + /// Returns the smallest key in this map. + /// If the tree is empty, then it returns `None`. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn min_key(&self) -> Option<&K> { + self.tree.min().map(|(k, _v)| k) + } + + /// Returns the largest key in this map. + /// If the tree is empty, then it returns `None`. + /// + /// Complexity: `O(min(N, |key|))`. + pub fn max_key(&self) -> Option<&K> { + self.tree.max().map(|(k, _v)| k) + } +} + +impl std::iter::FromIterator<(K, V)> for MutableIntMap { + fn from_iter(iter: Iter) -> Self where - I: IntoIterator, + Iter: IntoIterator, { let mut m = Self::new(); for (k, v) in iter { - m = m.insert(k, v); + m.insert(k, v); } m } } -/// Iterates over an IntMap, visiting keys in sorted order. -pub struct IntMapIter<'a, T>( +impl PartialEq for MutableIntMap { + fn eq(&self, other: &Self) -> bool { + self.iter().eq(other.iter()) + } +} +impl Eq for MutableIntMap {} + +impl ValidateEq for MutableIntMap +where + K: AsInt + PartialEq + std::fmt::Debug, + V: ValidateEq + Clone, +{ + fn validate_eq(&self, rhs: &Self) -> Result<(), String> { + if self.len != rhs.len { + return Err(format!("Length divergence: {} != {}", self.len, rhs.len)); + } + self.tree.validate_eq(&rhs.tree) + } +} + +/// Iterates over an `IntMap`, visiting keys in sorted order. +pub struct IntMapIter<'a, K: AsInt, V>( /// The stack of subtrees we haven't visited yet. - /// Trees in the back should be visited first. - Vec<&'a Tree>, + /// Trees in the back are visited first. + Vec<&'a Tree>, ); -impl<'a, T> IntMapIter<'a, T> { - fn new(root: &'a Tree) -> Self { +impl<'a, K: AsInt, V> IntMapIter<'a, K, V> { + fn new(root: &'a Tree) -> Self { Self(vec![root]) } } -impl<'a, T> std::iter::Iterator for IntMapIter<'a, T> { - type Item = (u64, &'a T); +impl<'a, K: AsInt, V: Clone> std::iter::Iterator for IntMapIter<'a, K, V> { + type Item = (&'a K, &'a V); fn next(&mut self) -> Option { let mut p = self.0.pop()?; - // Find the most-left subtree, pushing all the right nodes onto the + // Find the leftmost subtree, pushing all the right hand side nodes onto the // stack. while let Tree::Branch { left, right, .. } = p { + debug_assert!(left.len() > 0 && right.len() > 0); self.0.push(right); p = left; } match p { Tree::Empty => None, - Tree::Leaf(k, v) => Some((*k, v)), + Tree::Leaf(k, v) => Some((k, v)), Tree::Branch { .. } => unreachable!(), } } } +/// Consuming iterator over an `IntMap`, visiting keys in sorted order. +/// +/// A full traversal requires `O(N)` operations. +pub struct IntMapIntoIter( + /// The stack of subtrees we haven't visited yet. + /// Trees in the back should be visited first. + Vec>, +); + +impl IntMapIntoIter { + fn new(root: Tree) -> Self { + Self(vec![root]) + } +} + +impl std::iter::Iterator for IntMapIntoIter { + type Item = (K, V); + + fn next(&mut self) -> Option { + let mut p = self.0.pop()?; + // Find the leftmost subtree, pushing all the right hand side nodes onto the + // stack. + while let Tree::Branch { left, right, .. } = p { + debug_assert!(left.len() > 0 && right.len() > 0); + self.0.push(take_arc(right)); + p = take_arc(left); + } + match p { + Tree::Empty => None, + Tree::Leaf(k, v) => Some((k, v)), + Tree::Branch { .. } => unreachable!(), + } + } +} + +impl IntoIterator for MutableIntMap { + type Item = (K, V); + type IntoIter = IntMapIntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntMapIntoIter::new(self.tree) + } +} + /// Finds the most significant bit in which two bit patterns disagree. #[inline] -fn branching_bit(p0: u64, p1: u64) -> u8 { +fn branching_bit(p0: I, p1: I) -> u8 { debug_assert_ne!(p0, p1); - let zs = (p0 ^ p1).leading_zeros(); - (63 - zs) as u8 + let zs = (p0 ^ p1).leading_zeros() as u8; + I::size_bits() - 1 - zs } /// Clears all the key bits at or lower than the branching bit. #[inline] -fn mask(key: u64, branching_bit: u8) -> u64 { - debug_assert!(branching_bit <= 63); - let m = 1 << branching_bit; - key & !(m | (m - 1)) +fn mask(key: I, branching_bit: u8) -> I { + debug_assert!(branching_bit < I::size_bits()); + + // FYI: Using precomputed masks here and when testing the branching bit improves + // `u128` performance by about 20%, but has no effect on `u64` performance. + // Because two `[u128; 128]` arrays are potentially large for the CPU cache (2 + // KiB each), it is probably best to stick with computing the masks on the fly. + key & ((I::max_value() << 1) << branching_bit) } /// Checks if the key matches the branch prefix. #[inline] -fn matches_prefix(key: u64, branch_prefix: u64, branching_bit: u8) -> bool { +fn matches_prefix(key: I, branch_prefix: I, branching_bit: u8) -> bool { mask(key, branching_bit) == branch_prefix } diff --git a/rs/replicated_state/src/page_map/int_map/test.rs b/rs/replicated_state/src/page_map/int_map/test.rs index 4ec31df495f..3c13bb1e12e 100644 --- a/rs/replicated_state/src/page_map/int_map/test.rs +++ b/rs/replicated_state/src/page_map/int_map/test.rs @@ -1,12 +1,14 @@ -use super::IntMap; +use super::*; +use proptest::prelude::*; +use std::collections::BTreeMap; #[test] fn test_int_map_consecutive_inserts() { - let m: IntMap = (0..100u64).map(|x| (x, x + 100)).collect(); + let m: IntMap = (0..100u64).map(|x| (x, x + 100)).collect(); for i in 0..100u64 { assert_eq!( - m.get(i).cloned(), + m.get(&i).cloned(), Some(i + 100), "failed to find inserted values, map: {:?}", m @@ -16,59 +18,57 @@ fn test_int_map_consecutive_inserts() { #[test] fn test_int_map_sparse_inserts() { - let m: IntMap = (0..100u64) + let m: IntMap = (0..100u64) .filter(|x| x % 2 == 0) .map(|x| (x, x + 100)) .collect(); for i in 0..100u64 { if i % 2 == 0 { - assert_eq!(m.get(i).cloned(), Some(i + 100)); + assert_eq!(m.get(&i).cloned(), Some(i + 100)); } else { - assert_eq!(m.get(i).cloned(), None); + assert_eq!(m.get(&i).cloned(), None); } } } #[test] fn test_int_map_union() { - let lmap: IntMap = (1..101u64).map(|x| (x, x)).collect(); - let rmap: IntMap = (50..150u64).map(|x| (x, x + 100)).collect(); + let lmap: IntMap = (1..101u64).map(|x| (x, x)).collect(); + let rmap: IntMap = (50..150u64).map(|x| (x, x + 100)).collect(); let m = rmap.union(lmap); - assert!(m.get(0).is_none()); + assert!(m.get(&0).is_none()); for i in 1..50u64 { - assert_eq!(m.get(i).cloned(), Some(i)); + assert_eq!(m.get(&i).cloned(), Some(i)); } for i in 50..150u64 { - assert_eq!(m.get(i).cloned(), Some(i + 100), "Map: {:?}", m); + assert_eq!(m.get(&i).cloned(), Some(i + 100), "Map: {:?}", m); } - assert!(m.get(150).is_none()); + assert!(m.get(&150).is_none()); } #[test] fn test_iter() { - use std::collections::BTreeMap; - - let int_map: IntMap<_> = (1..100u64).map(|x| (x, x)).collect(); + let int_map: IntMap = (1..100u64).map(|x| (x, x)).collect(); let btree_map: BTreeMap<_, _> = (1..100u64).map(|x| (x, x)).collect(); - assert!(int_map.iter().eq(btree_map.iter().map(|(k, v)| (*k, v)))); + assert!(int_map.iter().eq(btree_map.iter())); } #[test] fn test_int_map_bounds() { - let m: IntMap = (10..=100u64).map(|x| (7 * x, 0)).collect(); + let m: IntMap = (10..=100u64).map(|x| (7 * x, 0)).collect(); for i in 0..800 { - let (start, end) = m.bounds(i); + let (start, end) = m.bounds(&i); if (70..=700).contains(&i) { - assert_eq!(start, Some(((i / 7) * 7, &0))); - assert_eq!(end, Some((((i + 6) / 7) * 7, &0))); + assert_eq!(start, Some((&((i / 7) * 7), &0))); + assert_eq!(end, Some((&(((i + 6) / 7) * 7), &0))); } else if i < 70 { assert_eq!(start, None); - assert_eq!(end, Some((70, &0))); + assert_eq!(end, Some((&70, &0))); } else { - assert_eq!(start, Some((700, &0))); + assert_eq!(start, Some((&700, &0))); assert_eq!(end, None) } } @@ -76,23 +76,444 @@ fn test_int_map_bounds() { #[test] fn test_max_key() { - let m = IntMap::::new(); + let m = IntMap::::new(); assert_eq!(m.max_key(), None); - let m = m.insert(100, 101); - assert_eq!(m.max_key(), Some(100)); - let m = m.insert(10, 101); - assert_eq!(m.max_key(), Some(100)); - let m = m.insert(1000, 101); - assert_eq!(m.max_key(), Some(1000)); - let m = m.insert(1000000, 101); - assert_eq!(m.max_key(), Some(1000000)); + let m = m.insert(100, 101).0; + assert_eq!(m.max_key(), Some(&100)); + let m = m.insert(10, 101).0; + assert_eq!(m.max_key(), Some(&100)); + let m = m.insert(1000, 101).0; + assert_eq!(m.max_key(), Some(&1000)); + let m = m.insert(1000000, 101).0; + assert_eq!(m.max_key(), Some(&1000000)); } #[test] fn test_max_key_range() { - let mut m = IntMap::::new(); + let mut m = IntMap::::new(); for i in 0..1000u64 { - m = m.insert(i, i + 100); - assert_eq!(m.max_key(), Some(i)); + m = m.insert(i, i + 100).0; + assert_eq!(m.max_key(), Some(&i)); + } +} + +#[test_strategy::proptest] +fn test_insert(#[strategy(proptest::collection::vec(0u64..20u64, 10))] keys: Vec) { + let mut btree_map = BTreeMap::new(); + let mut int_map = IntMap::new(); + let mut mutable_int_map = MutableIntMap::new(); + for (value, key) in keys.into_iter().enumerate() { + let expected = btree_map.insert(key, value); + + let previous; + (int_map, previous) = int_map.insert(key, value); + prop_assert!(is_well_formed(&int_map.0)); + prop_assert_eq!(expected, previous); + prop_assert_eq!(btree_map.len(), int_map.len()); + prop_assert!(btree_map.iter().eq(int_map.iter())); + + prop_assert!(is_well_formed(&mutable_int_map.tree)); + prop_assert_eq!(expected, mutable_int_map.insert(key, value)); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); + } +} + +/// Creates 3 maps with identical contents, from the given keys. +#[allow(clippy::type_complexity)] +fn make_maps( + keys: Vec, +) -> ( + BTreeMap, + IntMap, + MutableIntMap, +) { + let mut btree_map = BTreeMap::new(); + let mut int_map = IntMap::new(); + let mut mutable_int_map = MutableIntMap::new(); + for (value, key) in keys.into_iter().enumerate() { + btree_map.insert(key, value); + int_map = int_map.insert(key, value).0; + mutable_int_map.insert(key, value); + } + assert!(is_well_formed(&int_map.0)); + assert!(is_well_formed(&mutable_int_map.tree)); + (btree_map, int_map, mutable_int_map) +} + +#[test_strategy::proptest] +fn test_lookup( + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec, + #[strategy(proptest::collection::vec(0u64..20u64, 10))] lookups: Vec, +) { + let (btree_map, int_map, mutable_int_map) = make_maps(keys); + + for key in lookups { + prop_assert_eq!(btree_map.get(&key), int_map.get(&key)); + prop_assert_eq!(btree_map.get(&key), mutable_int_map.get(&key)); + + prop_assert_eq!(btree_map.contains_key(&key), int_map.contains_key(&key)); + prop_assert_eq!( + btree_map.contains_key(&key), + mutable_int_map.contains_key(&key) + ); + } +} + +#[test_strategy::proptest] +fn test_bounds( + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec, + #[strategy(proptest::collection::vec(0u64..20u64, 10))] lookups: Vec, +) { + let (btree_map, int_map, mutable_int_map) = make_maps(keys); + + for key in lookups { + let (lower, upper) = int_map.bounds(&key); + prop_assert_eq!((lower, upper), mutable_int_map.bounds(&key)); + + if lower == upper { + if let Some((k, v)) = lower { + // Exact match. + prop_assert_eq!(k, &key); + prop_assert_eq!(btree_map.get(&key), Some(v)); + } else { + // Empty map. + prop_assert!(int_map.is_empty()); + } + continue; + } + + prop_assert_eq!(btree_map.range(..key).next_back(), lower); + prop_assert_eq!(btree_map.range(key..).next(), upper); + } + + prop_assert_eq!( + btree_map.last_key_value().map(|(k, _)| k), + int_map.max_key() + ); + prop_assert_eq!( + btree_map.first_key_value().map(|(k, _)| k), + mutable_int_map.min_key() + ); + prop_assert_eq!( + btree_map.last_key_value().map(|(k, _)| k), + mutable_int_map.max_key() + ); +} + +#[test_strategy::proptest] +fn test_remove( + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] inserts: Vec, + #[strategy(proptest::collection::vec(0u64..20u64, 10))] removes: Vec, +) { + let (mut btree_map, mut int_map, mut mutable_int_map) = make_maps(inserts); + + for key in removes { + let expected = btree_map.remove(&key); + + let removed; + (int_map, removed) = int_map.remove(&key); + prop_assert!(is_well_formed(&int_map.0)); + prop_assert_eq!(expected, removed); + prop_assert_eq!(btree_map.len(), int_map.len()); + prop_assert!(btree_map.iter().eq(int_map.iter())); + + prop_assert!(is_well_formed(&mutable_int_map.tree)); + prop_assert_eq!(expected, mutable_int_map.remove(&key)); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); + } +} + +#[test_strategy::proptest] +fn test_union( + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] first: Vec, + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] second: Vec, +) { + let (mut first_btree_map, first_int_map, mut mutable_int_map) = make_maps(first); + let (mut btree_map, second_int_map, second_mutable_int_map) = make_maps(second); + + btree_map.append(&mut first_btree_map); + let int_map = first_int_map.union(second_int_map); + mutable_int_map.union(second_mutable_int_map); + + prop_assert!(is_well_formed(&int_map.0)); + prop_assert_eq!(btree_map.len(), int_map.len()); + prop_assert!(btree_map.iter().eq(int_map.iter())); + + prop_assert!(is_well_formed(&mutable_int_map.tree)); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); +} + +#[test_strategy::proptest] +fn test_split_off( + #[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec, + #[strategy(0u64..20u64)] split_key: u64, +) { + let (mut btree_map, _, mut mutable_int_map) = make_maps(keys); + + let btree_right = btree_map.split_off(&split_key); + let mutable_int_right = mutable_int_map.split_off(&split_key); + + prop_assert!(is_well_formed(&mutable_int_map.tree)); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); + + prop_assert!(is_well_formed(&mutable_int_right.tree)); + prop_assert_eq!(btree_right.len(), mutable_int_right.len()); + prop_assert!(btree_right.iter().eq(mutable_int_right.iter())); +} + +#[test_strategy::proptest] +fn test_len(#[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec) { + let (btree_map, int_map, mutable_int_map) = make_maps(keys); + + prop_assert_eq!(btree_map.len(), int_map.len()); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + + prop_assert_eq!(btree_map.is_empty(), int_map.is_empty()); + prop_assert_eq!(btree_map.is_empty(), mutable_int_map.is_empty()); +} + +#[test_strategy::proptest] +fn test_iterators(#[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec) { + let (btree_map, int_map, mutable_int_map) = make_maps(keys); + + prop_assert!(btree_map.iter().eq(int_map.iter())); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); + + prop_assert!(btree_map.keys().eq(int_map.keys())); + prop_assert!(btree_map.keys().eq(mutable_int_map.keys())); + + prop_assert!(btree_map.values().eq(mutable_int_map.values())); + + prop_assert!(btree_map.into_iter().eq(mutable_int_map.into_iter())); +} + +#[test_strategy::proptest] +fn test_from_iter(#[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec) { + let (btree_map, _, mutable_int_map) = make_maps(keys); + + let int_map = btree_map.clone().into_iter().collect::>(); + prop_assert!(is_well_formed(&int_map.0)); + prop_assert_eq!(btree_map.len(), int_map.len()); + prop_assert!(btree_map.iter().eq(int_map.iter())); + + let mutable_int_map = mutable_int_map.into_iter().collect::>(); + prop_assert!(is_well_formed(&mutable_int_map.tree)); + prop_assert_eq!(btree_map.len(), mutable_int_map.len()); + prop_assert!(btree_map.iter().eq(mutable_int_map.iter())); +} + +#[test_strategy::proptest] +fn test_eq(#[strategy(proptest::collection::vec(0u64..20u64, 0..10))] keys: Vec) { + use ic_validate_eq::ValidateEq; + use std::fmt::Debug; + + #[derive(Clone, Debug, PartialEq)] + struct Foo(usize); + impl ValidateEq for Foo { + fn validate_eq(&self, rhs: &Self) -> Result<(), String> { + if self.0 != rhs.0 { + return Err(format!("lhs = {:#?}, rhs = {:#?}", self, rhs)); + } + Ok(()) + } + } + + fn assert_eq(lhs: &M, rhs: &M) -> Result<(), TestCaseError> + where + M: Debug + PartialEq + ValidateEq, + { + prop_assert_eq!(lhs, rhs); + prop_assert_eq!(Ok(()), lhs.validate_eq(rhs)); + Ok(()) + } + fn assert_ne(lhs: &M, rhs: &M) -> Result<(), TestCaseError> + where + M: Debug + PartialEq + ValidateEq, + { + prop_assert_ne!(lhs, rhs); + prop_assert_ne!(Ok(()), lhs.validate_eq(rhs)); + Ok(()) + } + + let mut int_map = IntMap::new(); + let mut mutable_int_map = MutableIntMap::new(); + for (value, key) in keys.into_iter().enumerate() { + int_map = int_map.insert(key, Foo(value)).0; + mutable_int_map.insert(key, Foo(value)); + } + + let initial_int_map = int_map.clone(); + let initial_mutable_int_map = mutable_int_map.clone(); + assert_eq(&initial_int_map, &int_map)?; + assert_eq(&initial_mutable_int_map, &mutable_int_map)?; + + // No longer equal after an insert. + let int_map = int_map.insert(99, Foo(13)).0; + prop_assert!(mutable_int_map.insert(99, Foo(13)).is_none()); + assert_ne(&initial_int_map, &int_map)?; + assert_ne(&initial_mutable_int_map, &mutable_int_map)?; + + // Need a non-empty map to test equality after remove. + if !initial_int_map.is_empty() { + let key = initial_int_map.max_key().unwrap(); + + // No longer equal after a remove. + let int_map = initial_int_map.clone().remove(key).0; + let mut mutable_int_map = initial_mutable_int_map.clone(); + prop_assert!(mutable_int_map.remove(key).is_some()); + assert_ne(&initial_int_map, &int_map)?; + assert_ne(&initial_mutable_int_map, &mutable_int_map)?; + } +} + +#[test_strategy::proptest] +fn test_u64_values( + #[strategy(proptest::collection::vec(any::(), 0..10))] keys: Vec, + #[strategy(proptest::collection::vec(any::(), 10))] lookups: Vec, +) { + let (btree_map, int_map, mutable_int_map) = make_maps(keys); + + for key in lookups { + prop_assert_eq!(btree_map.get(&key), int_map.get(&key)); + prop_assert_eq!(btree_map.get(&key), mutable_int_map.get(&key)); + } +} + +#[test_strategy::proptest] +fn test_u128_values( + #[strategy(proptest::collection::vec(any::(), 0..10))] keys: Vec, + #[strategy(proptest::collection::vec(any::(), 10))] lookups: Vec, +) { + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + struct Key128(u64, u64); + impl Key128 { + fn new(value: u128) -> Self { + Key128((value >> 64) as u64, value as u64) + } + } + impl AsInt for Key128 { + type Repr = u128; + + #[inline] + fn as_int(&self) -> u128 { + (self.0 as u128) << 64 | self.1 as u128 + } + } + + let mut btree_map = BTreeMap::new(); + let mut int_map = IntMap::new(); + let mut mutable_int_map = MutableIntMap::new(); + for (value, key) in keys.into_iter().enumerate() { + let key = Key128::new(key); + btree_map.insert(key, value); + int_map = int_map.insert(key, value).0; + mutable_int_map.insert(key, value); + } + prop_assert!(is_well_formed(&int_map.0)); + prop_assert!(is_well_formed(&mutable_int_map.tree)); + + for key in lookups { + let key = Key128::new(key); + prop_assert_eq!(btree_map.get(&key), int_map.get(&key)); + prop_assert_eq!(btree_map.get(&key), mutable_int_map.get(&key)); + } +} + +#[test] +fn test_validate_eq() { + use ic_validate_eq::ValidateEq; + + #[derive(Clone, Debug, PartialEq)] + struct MyU64(u64); + impl ValidateEq for MyU64 { + fn validate_eq(&self, rhs: &Self) -> Result<(), String> { + if self.0 != rhs.0 { + return Err(format!("{} != {}", self.0, rhs.0)); + } + Ok(()) + } + } + + fn do_validate_eq(lhs: &[(u64, u64)], rhs: &[(u64, u64)]) -> Result<(), String> { + let left: IntMap = lhs.iter().map(|(k, v)| (*k, MyU64(*v))).collect(); + let right: IntMap = rhs.iter().map(|(k, v)| (*k, MyU64(*v))).collect(); + left.validate_eq(&right) + } + + assert!(do_validate_eq(&[], &[]).is_ok()); + assert!(do_validate_eq(&[(1, 2)], &[(1, 2)]).is_ok()); + assert!(do_validate_eq(&[(1, 2), (7, 8)], &[(1, 2), (7, 8)]).is_ok()); + + assert_eq!( + Err("Length divergence: 0 != 1".to_string()), + do_validate_eq(&[], &[(1, 2)]) + ); + assert_eq!( + Err("Length divergence: 2 != 1".to_string()), + do_validate_eq(&[(1, 2), (7, 8)], &[(1, 2)]) + ); + assert_eq!( + Err("Key divergence: 7 != 8".to_string()), + do_validate_eq(&[(1, 2), (7, 8)], &[(1, 2), (8, 8)]) + ); + assert_eq!( + Err("Value divergence @7: 8 != 7".to_string()), + do_validate_eq(&[(1, 2), (7, 8)], &[(1, 2), (7, 7)]) + ); +} + +/// Returns `true` iff the tree is well formed. +fn is_well_formed(tree: &Tree) -> bool { + match tree { + Tree::Empty => true, + + Tree::Leaf(_, _) => true, + + Tree::Branch { + prefix, + branching_bit, + left, + right, + } => { + let valid_left = match left.as_ref() { + Tree::Leaf(k, _) => { + matches_prefix(k.as_int(), *prefix, *branching_bit) + && k.as_int() & (K::Repr::one() << *branching_bit) == K::Repr::zero() + } + Tree::Branch { + prefix: p, + branching_bit: b, + .. + } => { + b < branching_bit + && matches_prefix(*p, *prefix, *branching_bit) + && *p & (K::Repr::one() << *branching_bit) == K::Repr::zero() + && is_well_formed(left.as_ref()) + } + Tree::Empty => false, + }; + let valid_right = match right.as_ref() { + Tree::Leaf(k, _) => { + matches_prefix(k.as_int(), *prefix, *branching_bit) + && k.as_int() & (K::Repr::one() << *branching_bit) != K::Repr::zero() + } + Tree::Branch { + prefix: p, + branching_bit: b, + .. + } => { + b < branching_bit + && matches_prefix(*p, *prefix, *branching_bit) + && *p & (K::Repr::one() << *branching_bit) != K::Repr::zero() + && is_well_formed(right.as_ref()) + } + Tree::Empty => false, + }; + valid_left && valid_right + } } } diff --git a/rs/replicated_state/src/page_map/page_allocator.rs b/rs/replicated_state/src/page_map/page_allocator.rs index 2792dde4acf..4a8d133be67 100644 --- a/rs/replicated_state/src/page_map/page_allocator.rs +++ b/rs/replicated_state/src/page_map/page_allocator.rs @@ -118,7 +118,7 @@ impl PageAllocator { /// The generic parameters simplify the usage with `PageDelta::iter()`. pub fn serialize_page_delta<'a, I>(&'a self, page_delta: I) -> PageDeltaSerialization where - I: IntoIterator, + I: IntoIterator, { self.0.serialize_page_delta(page_delta) } diff --git a/rs/replicated_state/src/page_map/page_allocator/mmap.rs b/rs/replicated_state/src/page_map/page_allocator/mmap.rs index 35f7bba7693..850c5a95289 100644 --- a/rs/replicated_state/src/page_map/page_allocator/mmap.rs +++ b/rs/replicated_state/src/page_map/page_allocator/mmap.rs @@ -262,11 +262,11 @@ impl PageAllocatorInner { // See the comments of the corresponding method in `PageAllocator`. pub fn serialize_page_delta<'a, I>(&'a self, page_delta: I) -> PageDeltaSerialization where - I: IntoIterator, + I: IntoIterator, { let pages: Vec<_> = page_delta .into_iter() - .map(|(page_index, page)| MmapPageSerialization { + .map(|(&page_index, page)| MmapPageSerialization { page_index, file_offset: page.0.offset, validation: page.0.validation, @@ -629,7 +629,7 @@ impl MmapBasedPageAllocatorCore { MmapAdvise::MADV_HUGEPAGE, ) }.unwrap_or_else(|err| { - // We don't need to panic, madvise failing is not a problem, + // We don't need to panic, madvise failing is not a problem, // it will only mean that we are not using huge pages. println!( "MmapPageAllocator failed to madvise {} bytes at address {:?} for memory file #{}: {}", diff --git a/rs/replicated_state/src/page_map/storage.rs b/rs/replicated_state/src/page_map/storage.rs index eb1774f7c79..85b6266d8c3 100644 --- a/rs/replicated_state/src/page_map/storage.rs +++ b/rs/replicated_state/src/page_map/storage.rs @@ -473,7 +473,7 @@ impl OverlayFile { for (index, data) in delta.iter() { let shard = index.get() / lsmt_config.shard_num_pages; page_data[shard as usize].push(data.contents()); - page_indices[shard as usize].push(index); + page_indices[shard as usize].push(*index); } for shard in 0..num_shards { diff --git a/rs/replicated_state/src/page_map/storage/tests.rs b/rs/replicated_state/src/page_map/storage/tests.rs index e92f73d1221..3dfa9aec111 100644 --- a/rs/replicated_state/src/page_map/storage/tests.rs +++ b/rs/replicated_state/src/page_map/storage/tests.rs @@ -562,7 +562,7 @@ fn write_overlays_and_verify_with_tempdir( page_map.update( combined_delta .iter() - .map(|(i, p)| (i, p.contents())) + .map(|(i, p)| (*i, p.contents())) .collect::>() .as_slice(), ); From 5c6dc53561b470e7dbf6772fde4a6e7b5a1fdda7 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Thu, 9 Jan 2025 19:20:55 +0100 Subject: [PATCH 43/98] feat(governance-tools): Script that adds entry for new release to CHANGELOG after a proposal was successfully executed. (#3367) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # References [👈 Previous PR][prev] [prev]: https://github.com/dfinity/ic/pull/3332 --- rs/nns/governance/CHANGELOG.md | 8 +- rs/nns/governance/unreleased_changelog.md | 5 +- .../nns-tools/add-release-to-changelog.sh | 149 ++++++++++++++++++ 3 files changed, 154 insertions(+), 8 deletions(-) create mode 100755 testnet/tools/nns-tools/add-release-to-changelog.sh diff --git a/rs/nns/governance/CHANGELOG.md b/rs/nns/governance/CHANGELOG.md index f749025ba6b..026ed3c923c 100644 --- a/rs/nns/governance/CHANGELOG.md +++ b/rs/nns/governance/CHANGELOG.md @@ -8,11 +8,7 @@ unreleased_changelog.md file. In general though, the entries you see here were moved from there. -# TEMPLATE: Proposal $ID +INSERT NEW RELEASES HERE -http://dashboard.internetcomputer.org/proposal/$ID -## Added - -* Flying feature was added to widgets. This feature was discussed and/or - proposed at $FORUM_THREAD_URL and $MOTION_PROPOSAL_URL. +END diff --git a/rs/nns/governance/unreleased_changelog.md b/rs/nns/governance/unreleased_changelog.md index 5751df51cb8..90de181cefb 100644 --- a/rs/nns/governance/unreleased_changelog.md +++ b/rs/nns/governance/unreleased_changelog.md @@ -15,14 +15,15 @@ because this new function has no user-visible behavior change yet. Wait until it is active (e.g. the feature flag is flipped to "enable") before adding an entry to this file. -TODO: Automate moving content from unreleased_changelog.md to CHANGELOG.md. - # How to Write a Good Entry The intended audience here is people who vote (with their neurons) in NNS, not necessarily engineers who develop this canister. +If there is a motion proposal and/or forum thread where a feature (or bug fix) +was proposed, link to it. + # The Origin of This Process diff --git a/testnet/tools/nns-tools/add-release-to-changelog.sh b/testnet/tools/nns-tools/add-release-to-changelog.sh new file mode 100755 index 00000000000..ce10ccbbfef --- /dev/null +++ b/testnet/tools/nns-tools/add-release-to-changelog.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +NNS_TOOLS_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +source "$NNS_TOOLS_DIR/lib/include.sh" + +help() { + print_green " +Usage: $0 + PROPOSAL_ID: The ID of a recently executed Governance backend canister upgrade proposal. + + Moves the pending new changelog entry from unreleased_changelog.md to CHANGELOG.md. + + The commit that the proposal is baded on MUST be currently check out. + Otherwise, this script will do nothing, and terminate with a nonzero exit + status. + +" >&2 + exit 1 +} + +PROPOSAL_ID="${1}" + +cd "$(repo_root)" +PWD="$(pwd)" + +# Fetch the proposal. +print_purple "Fetching proposal ${PROPOSAL_ID}..." >&2 +PROPOSAL_INFO=$( + __dfx --quiet \ + canister call \ + --ic \ + --candid rs/nns/governance/canister/governance.did \ + $(nns_canister_id governance) \ + get_proposal_info "(${PROPOSAL_ID})" \ + | idl2json +) +# Unwrap. +LEN=$(echo "${PROPOSAL_INFO}" | jq '. | length') +if [[ "${LEN}" -ne 1 ]]; then + print_red "Unexpected result from the get_proposal_info method:" >&2 + print_red "Should have one element, but has ${LEN}" >&2 + exit 1 +fi +PROPOSAL_INFO=$(echo "${PROPOSAL_INFO}" | jq '.[0]') + +# Assert was executed. +EXECUTED_TIMESTAMP_SECONDS=$(echo "${PROPOSAL_INFO}" | jq '.executed_timestamp_seconds | tonumber') +if [[ "${EXECUTED_TIMESTAMP_SECONDS}" -eq 0 ]]; then + print_red "Proposal ${PROPOSAL_ID} exists, but was not successfully executed." >&2 + exit 1 +fi +SECONDS_AGO=$(($(date +%s) - "${EXECUTED_TIMESTAMP_SECONDS}")) +EXECUTED_ON=$( + date --utc \ + --date=@"${EXECUTED_TIMESTAMP_SECONDS}" \ + --iso-8601 +) +print_purple "Proposal ${PROPOSAL_ID} was executed ${SECONDS_AGO} seconds ago." >&2 + +# Extract which canister was upgraded, and to what commit. +TITLE=$(echo "${PROPOSAL_INFO}" | jq -r '.proposal[0].summary' | head -n 1) +CANISTER_NAME=$( + echo "${TITLE}" \ + | sed 's/# Upgrade the //' | sed 's/ Canister to Commit .*//' \ + | tr '[:upper:]' '[:lower:]' +) +DESTINATION_COMMIT_ID=$(echo "${TITLE}" | sed 's/# Upgrade the .* Canister to Commit //') + +# Fail if the proposal's commit is not checked out. +if [[ $(git rev-parse HEAD) != $DESTINATION_COMMIT_ID* ]]; then + echo >&2 + print_red "You currently have $(git rev-parse HEAD)" >&2 + print_red "checked out, but this command only supports being run when" >&2 + print_red "the proposal's commit (${DESTINATION_COMMIT_ID}) is checked out." >&2 + exit 1 +fi + +# cd to the canister's primary code path. +CANISTER_CODE_PATH=$( + get_nns_canister_code_location "${CANISTER_NAME}" \ + | sed "s^${PWD}^.^g" \ + | cut -d' ' -f1 +) +cd "${CANISTER_CODE_PATH}" + +# Assert that there is a CHANGELOG.md file. +if [[ ! -e CHANGELOG.md ]]; then + echo >&2 + print_red "${CANISTER_NAME} has no CHANGELOG.md file." >&2 + exit 1 +fi +# TODO: Also verify that unreleased_changelog.md exists. +# TODO: Verify that there are no uncommited changes in this dir, the canister's primary code path. + +# Construct new entry for CHANGELOG.md +# +# Python is used to filter out empty sections. +# Python is used because I cannot figure out how to do that using mac sed. +NEW_FEATURES_AND_FIXES=$( + sed '1,/^# Next Upgrade Proposal$/d' \ + unreleased_changelog.md \ + | python3 -c 'import sys, re; s = sys.stdin.read(); print(re.sub(r"## [\w ]+\n+(?=##|\Z)", "", s).strip())' +) +if [[ -z "${NEW_FEATURES_AND_FIXES}" ]]; then + echo >&2 + print_red "The ${CANISTER_NAME} canister has no information in its unreleased_changelog.md." >&2 + exit 1 +fi +NEW_ENTRY="# ${EXECUTED_ON}: Proposal ${PROPOSAL_ID} + +http://dashboard.internetcomputer.org/proposals/${PROPOSAL_ID} + +${NEW_FEATURES_AND_FIXES} +" + +CHANGELOG_INTRODUCTION=$(sed -n '/^INSERT NEW RELEASES HERE$/q;p' CHANGELOG.md) +CHANGELOG_EARLIER_RELEASES=$(sed '1,/^INSERT NEW RELEASES HERE$/d' CHANGELOG.md) + +# Insert new entry into CHANGELOG.md. +echo -n "${CHANGELOG_INTRODUCTION} + + +INSERT NEW RELEASES HERE + + +${NEW_ENTRY}${CHANGELOG_EARLIER_RELEASES} +" \ + >CHANGELOG.md + +UNRELEASED_CHANGELOG_INTRODUCTION=$(sed -n '/^# Next Upgrade Proposal$/q;p' unreleased_changelog.md) +echo -n "${UNRELEASED_CHANGELOG_INTRODUCTION} + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security +""" \ + >unreleased_changelog.md From c2b0c10d3ec329246583762e68a7e5aa33fec267 Mon Sep 17 00:00:00 2001 From: stiegerc Date: Thu, 9 Jan 2025 22:20:25 +0100 Subject: [PATCH 44/98] fix: Repartition input schedules in canister migration in state machine tests (#3381) --- rs/state_machine_tests/src/lib.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index 6578db7c5c7..87eb8cf6e70 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -2569,8 +2569,7 @@ impl StateMachine { /// After you import the canister, you can execute methods on it and upgrade it. /// The original directory is not modified. /// - /// The function is currently not used in code, but it is useful for local - /// testing and debugging. Do not remove it. + /// This function is useful for local testing and debugging. Do not remove it. /// /// # Panics /// @@ -2580,6 +2579,8 @@ impl StateMachine { canister_directory: P, canister_id: CanisterId, ) { + use ic_replicated_state::testing::SystemStateTesting; + let canister_directory = canister_directory.as_ref(); assert!( canister_directory.is_dir(), @@ -2632,7 +2633,7 @@ impl StateMachine { } } - let canister_state = ic_state_manager::checkpoint::load_canister_state( + let mut canister_state = ic_state_manager::checkpoint::load_canister_state( &tip_canister_layout, &canister_id, ic_types::Height::new(0), @@ -2649,7 +2650,14 @@ impl StateMachine { .0; let (h, mut state) = self.state_manager.take_tip(); + + // Repartition input schedules; Required step for migrating canisters. + canister_state + .system_state + .split_input_schedules(&canister_id, &state.canister_states); + state.put_canister_state(canister_state); + self.state_manager.commit_and_certify( state, h.increment(), From 19e3c685aeba2f55936ce25bdd32ea66365d916d Mon Sep 17 00:00:00 2001 From: Andrew Battat <113942931+andrewbattat@users.noreply.github.com> Date: Thu, 9 Jan 2025 20:24:09 -0600 Subject: [PATCH 45/98] feat(node): Add log-config service to GuestOS (#3389) Add the log-config service to GuestOS This service was previously just on HostOS and would log config.ini and deployment.json. Now the service is on HostOS and GuestOS and logs the config object. --- ic-os/components/guestos.bzl | 4 +++- ic-os/components/hostos.bzl | 6 +++--- .../misc/log-config/log-config-guestos.service | 14 ++++++++++++++ .../log-config/log-config-hostos.service} | 4 +++- .../log-config/log-config.sh | 6 ++---- ic-os/guestos/defs.bzl | 2 +- rs/ic_os/config/src/main.rs | 2 +- 7 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 ic-os/components/misc/log-config/log-config-guestos.service rename ic-os/components/{hostos-scripts/log-config/log-config.service => misc/log-config/log-config-hostos.service} (58%) rename ic-os/components/{hostos-scripts => misc}/log-config/log-config.sh (82%) diff --git a/ic-os/components/guestos.bzl b/ic-os/components/guestos.bzl index a97124f7c3b..5efa43fad2a 100644 --- a/ic-os/components/guestos.bzl +++ b/ic-os/components/guestos.bzl @@ -63,6 +63,8 @@ component_files = { Label("misc/guestos/sysctl.d/privileged-ports.conf"): "/etc/sysctl.d/privileged-ports.conf", Label("misc/guestos/sysfs.d/hugepage.conf"): "/etc/sysfs.d/hugepage.conf", Label("misc/guestos/hsm/pcscd"): "/etc/default/pcscd", + Label("misc/log-config/log-config-guestos.service"): "/etc/systemd/system/log-config.service", + Label("misc/log-config/log-config.sh"): "/opt/ic/bin/log-config.sh", # monitoring Label("monitoring/filebeat/setup-filebeat-permissions.sh"): "/opt/ic/bin/setup-filebeat-permissions.sh", @@ -162,6 +164,6 @@ component_files = { # fstrim Label("fstrim/sync_fstrim.sh"): "/opt/ic/bin/sync_fstrim.sh", - # TODO(NODE-1519): delete update-config.service after switch to new icos config + # TODO(NODE-1518): delete update-config.service after switch to new icos config Label("misc/update-config/update-guestos-config.service"): "/etc/systemd/system/update-config.service", } diff --git a/ic-os/components/hostos.bzl b/ic-os/components/hostos.bzl index 3566742c219..b41fe465e17 100644 --- a/ic-os/components/hostos.bzl +++ b/ic-os/components/hostos.bzl @@ -29,8 +29,6 @@ component_files = { Label("hostos-scripts/verbose-logging/verbose-logging.sh"): "/opt/ic/bin/verbose-logging.sh", Label("hostos-scripts/verbose-logging/verbose-logging.service"): "/etc/systemd/system/verbose-logging.service", Label("hostos-scripts/verbose-logging/logrotate.d/verbose-logging"): "/etc/logrotate.d/verbose-logging", - Label("hostos-scripts/log-config/log-config.service"): "/etc/systemd/system/log-config.service", - Label("hostos-scripts/log-config/log-config.sh"): "/opt/ic/bin/log-config.sh", # early-boot Label("early-boot/relabel-machine-id/relabel-machine-id.sh"): "/opt/ic/bin/relabel-machine-id.sh", @@ -73,6 +71,8 @@ component_files = { Label("monitoring/metrics-proxy/metrics-proxy.service"): "/etc/systemd/system/metrics-proxy.service", Label("monitoring/journald.conf"): "/etc/systemd/journald.conf", Label("monitoring/logrotate/override.conf"): "/etc/systemd/system/logrotate.service.d/override.conf", + Label("misc/log-config/log-config-hostos.service"): "/etc/systemd/system/log-config.service", + Label("misc/log-config/log-config.sh"): "/opt/ic/bin/log-config.sh", # networking Label("networking/generate-network-config/hostos/generate-network-config.service"): "/etc/systemd/system/generate-network-config.service", @@ -98,6 +98,6 @@ component_files = { Label("upgrade/systemd-generators/systemd-gpt-auto-generator"): "/etc/systemd/system-generators/systemd-gpt-auto-generator", Label("upgrade/install-upgrade.sh"): "/opt/ic/bin/install-upgrade.sh", - # TODO(NODE-1519): delete update-config.service after switch to new icos config + # TODO(NODE-1518): delete update-config.service after switch to new icos config Label("misc/update-config/update-hostos-config.service"): "/etc/systemd/system/update-config.service", } diff --git a/ic-os/components/misc/log-config/log-config-guestos.service b/ic-os/components/misc/log-config/log-config-guestos.service new file mode 100644 index 00000000000..705bdfb511c --- /dev/null +++ b/ic-os/components/misc/log-config/log-config-guestos.service @@ -0,0 +1,14 @@ +[Unit] +Description=Log config partition +After=bootstrap-ic-node.service +Requires=bootstrap-ic-node.service +After=update-config.service +Wants=update-config.service + +[Service] +Type=oneshot +ExecStart=/opt/ic/bin/log-config.sh +RemainAfterExit=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/ic-os/components/hostos-scripts/log-config/log-config.service b/ic-os/components/misc/log-config/log-config-hostos.service similarity index 58% rename from ic-os/components/hostos-scripts/log-config/log-config.service rename to ic-os/components/misc/log-config/log-config-hostos.service index b5e319f5a6f..90bb67bbe41 100644 --- a/ic-os/components/hostos-scripts/log-config/log-config.service +++ b/ic-os/components/misc/log-config/log-config-hostos.service @@ -1,5 +1,7 @@ [Unit] -Description=Log HostOS config partition +Description=Log config partition +After=update-config.service +Wants=update-config.service [Service] Type=oneshot diff --git a/ic-os/components/hostos-scripts/log-config/log-config.sh b/ic-os/components/misc/log-config/log-config.sh similarity index 82% rename from ic-os/components/hostos-scripts/log-config/log-config.sh rename to ic-os/components/misc/log-config/log-config.sh index 5f8399c90b4..afb4655e306 100644 --- a/ic-os/components/hostos-scripts/log-config/log-config.sh +++ b/ic-os/components/misc/log-config/log-config.sh @@ -1,8 +1,7 @@ #!/bin/bash CONFIG_DIR="/boot/config" -CONFIG="/boot/config/config.ini" -DEPLOYMENT="/boot/config/deployment.json" +CONFIG="/boot/config/config.json" log_directory_structure() { local dir=$1 @@ -28,7 +27,6 @@ log_file_contents() { fi } -echo "Logging HostOS config partition" +echo "Logging config partition" log_directory_structure "$CONFIG_DIR" log_file_contents "$CONFIG" -log_file_contents "$DEPLOYMENT" diff --git a/ic-os/guestos/defs.bzl b/ic-os/guestos/defs.bzl index 745165a3132..aa2c7e36260 100644 --- a/ic-os/guestos/defs.bzl +++ b/ic-os/guestos/defs.bzl @@ -55,7 +55,7 @@ def image_deps(mode, malicious = False): # additional libraries to install "//rs/ic_os/release:nss_icos": "/usr/lib/x86_64-linux-gnu/libnss_icos.so.2:0644", # Allows referring to the guest IPv6 by name guestos from host, and host as hostos from guest. - # TODO(NODE-1519): delete config tool from guestos after switch to new icos config + # TODO(NODE-1518): delete config tool from guestos after switch to new icos config "//rs/ic_os/release:config": "/opt/ic/bin/config:0755", }, diff --git a/rs/ic_os/config/src/main.rs b/rs/ic_os/config/src/main.rs index 3b614e82172..06dde31b2b0 100644 --- a/rs/ic_os/config/src/main.rs +++ b/rs/ic_os/config/src/main.rs @@ -367,7 +367,7 @@ pub fn main() -> Result<()> { generate_testnet_config(args, clap_args.guestos_config_json_path) } - // TODO(NODE-1519): delete UpdateGuestosConfig and UpdateHostosConfig after moved to new config format + // TODO(NODE-1518): delete UpdateGuestosConfig and UpdateHostosConfig after moved to new config format // Regenerate config.json on *every boot* in case the config structure changes between // when we roll out the update-config service and when we roll out the 'config integration' Some(Commands::UpdateGuestosConfig) => update_guestos_config(), From 8df1883e69c7e3b543f8d15a8d7ee96a750036f6 Mon Sep 17 00:00:00 2001 From: Igor Novgorodov Date: Fri, 10 Jan 2025 10:23:47 +0100 Subject: [PATCH 46/98] feat(BOUN-1333, BOUN-1334): ratelimit: add scaling, change allow rule, change shedding latencies (#3379) * Adds optional autoscaling of rules to the ratelimiter (CLI arg `--rate-limit-generic-autoscale`). If enabled it will divide the limit by the number of API BNs in the registry and recalculate whenever the number changes (when the new snapshot is published) * Remove implicit allow rule for the ratelimit canister, instead just bypass the ratelimiting for the requests that originate from localhost. This allows to create ratelimit rules for the canister itself * Change HTTP code from `429` to `403` when rejecting requests by the rule that has `limit: block` * Bump load shedding latencies in `ic-gateway` to fix the false positives that we're getting occasionally --------- Co-authored-by: IDX GitLab Automation --- .../opt/ic/bin/setup-ic-gateway.sh | 2 +- .../ic_boundary/src/check/test.rs | 1 + rs/boundary_node/ic_boundary/src/cli.rs | 7 + rs/boundary_node/ic_boundary/src/core.rs | 42 +- .../ic_boundary/src/rate_limiting/fetcher.rs | 29 +- .../ic_boundary/src/rate_limiting/generic.rs | 762 +++++++++++++----- rs/boundary_node/ic_boundary/src/routes.rs | 8 +- rs/boundary_node/ic_boundary/src/snapshot.rs | 49 ++ .../rate_limit_canister_test.rs | 12 +- 9 files changed, 681 insertions(+), 231 deletions(-) diff --git a/ic-os/components/boundary-guestos/opt/ic/bin/setup-ic-gateway.sh b/ic-os/components/boundary-guestos/opt/ic/bin/setup-ic-gateway.sh index a89ca3edd54..135b4657973 100755 --- a/ic-os/components/boundary-guestos/opt/ic/bin/setup-ic-gateway.sh +++ b/ic-os/components/boundary-guestos/opt/ic/bin/setup-ic-gateway.sh @@ -150,7 +150,7 @@ SHED_SYSTEM_CPU="0.95" SHED_SYSTEM_MEMORY="0.95" SHED_SHARDED_EWMA="0.6" SHED_SHARDED_PASSTHROUGH="20000" -SHED_SHARDED_LATENCY="query:1s,call:1s,sync_call:13s,read_state:1s,read_state_subnet:1s,status:100ms,health:100ms,registrations:5s,http:5s" +SHED_SHARDED_LATENCY="query:2s,call:2s,sync_call:13s,read_state:2s,read_state_subnet:2s,status:100ms,health:100ms,registrations:5s,http:5s" EOF if [ ! -z "${DENYLIST_URL:-}" ]; then diff --git a/rs/boundary_node/ic_boundary/src/check/test.rs b/rs/boundary_node/ic_boundary/src/check/test.rs index e65b17284fa..2bec3d0fe5d 100644 --- a/rs/boundary_node/ic_boundary/src/check/test.rs +++ b/rs/boundary_node/ic_boundary/src/check/test.rs @@ -83,6 +83,7 @@ pub fn generate_custom_registry_snapshot( nns_public_key: vec![], subnets, nodes: nodes_hash, + api_bns: vec![], } } diff --git a/rs/boundary_node/ic_boundary/src/cli.rs b/rs/boundary_node/ic_boundary/src/cli.rs index f006f47f185..8ca8c993d02 100644 --- a/rs/boundary_node/ic_boundary/src/cli.rs +++ b/rs/boundary_node/ic_boundary/src/cli.rs @@ -288,6 +288,13 @@ pub struct RateLimiting { /// Maximum number of shards that we store (per rule) #[clap(env, long, default_value = "30000")] pub rate_limit_generic_max_shards: u64, + + /// Whether to use the number of API BNs from the registry to scale the rate limit rules. + /// E.g. if a ratelimit action is set to "500/1h" and the number of API BNs is 5 then the + /// rule would be adjusted to "100/1h" so that the total ratelimit of all API BNs would be "500/1h". + /// Important: if after the divison the numerator would be less than 1 then it would be rounded to 1. + #[clap(env, long)] + pub rate_limit_generic_autoscale: bool, } #[derive(Args)] diff --git a/rs/boundary_node/ic_boundary/src/core.rs b/rs/boundary_node/ic_boundary/src/core.rs index c52a8fc70c6..3f88273f4a9 100644 --- a/rs/boundary_node/ic_boundary/src/core.rs +++ b/rs/boundary_node/ic_boundary/src/core.rs @@ -50,6 +50,7 @@ use ic_types::{crypto::threshold_sig::ThresholdSigPublicKey, messages::MessageId use nix::unistd::{getpgid, setpgid, Pid}; use prometheus::Registry; use rand::rngs::OsRng; +use tokio::sync::watch; use tokio_util::sync::CancellationToken; use tower::{limit::ConcurrencyLimitLayer, util::MapResponseLayer, ServiceBuilder}; use tower_http::{compression::CompressionLayer, request_id::MakeRequestUuid, ServiceBuilderExt}; @@ -200,6 +201,9 @@ pub async fn main(cli: Cli) -> Result<(), Error> { // Setup registry-related stuff let persister = Persister::new(Arc::clone(&routing_table)); + // Snapshot update notification channels + let (channel_snapshot_send, channel_snapshot_recv) = tokio::sync::watch::channel(None); + // Registry Client let (registry_client, registry_replicator, nns_pub_key) = if let Some(v) = &cli.registry.registry_local_store_path { @@ -221,6 +225,8 @@ pub async fn main(cli: Cli) -> Result<(), Error> { WithMetricsPersist(persister, MetricParamsPersist::new(&metrics_registry)), http_client_check, &metrics_registry, + channel_snapshot_send, + channel_snapshot_recv.clone(), &mut runners, )?; @@ -285,28 +291,25 @@ pub async fn main(cli: Cli) -> Result<(), Error> { let generic_limiter_opts = generic::Options { tti: cli.rate_limiting.rate_limit_generic_tti, max_shards: cli.rate_limiting.rate_limit_generic_max_shards, + poll_interval: cli.rate_limiting.rate_limit_generic_poll_interval, + autoscale: cli.rate_limiting.rate_limit_generic_autoscale, }; let generic_limiter = if let Some(v) = &cli.rate_limiting.rate_limit_generic_file { Some(Arc::new(generic::GenericLimiter::new_from_file( v.clone(), generic_limiter_opts, + channel_snapshot_recv, + ))) + } else if let Some(v) = cli.rate_limiting.rate_limit_generic_canister_id { + Some(Arc::new(generic::GenericLimiter::new_from_canister( + v, + agent.clone().unwrap(), + generic_limiter_opts, + cli.misc.crypto_config.is_some(), + channel_snapshot_recv, ))) } else { - cli.rate_limiting.rate_limit_generic_canister_id.map(|x| { - Arc::new(if cli.misc.crypto_config.is_some() { - generic::GenericLimiter::new_from_canister_update( - x, - agent.clone().unwrap(), - generic_limiter_opts, - ) - } else { - generic::GenericLimiter::new_from_canister_query( - x, - agent.clone().unwrap(), - generic_limiter_opts, - ) - }) - }) + None }; // HTTP Logs Anonymization @@ -438,11 +441,7 @@ pub async fn main(cli: Cli) -> Result<(), Error> { runners.push(Box::new(metrics_runner)); if let Some(v) = generic_limiter { - let runner = Box::new(WithThrottle( - v, - ThrottleParams::new(cli.rate_limiting.rate_limit_generic_poll_interval), - )); - runners.push(runner); + runners.push(Box::new(v)); } // HTTP Logs Anonymization @@ -608,10 +607,11 @@ fn setup_registry( persister: WithMetricsPersist, http_client_check: Arc, metrics_registry: &Registry, + channel_snapshot_send: watch::Sender>>, + channel_snapshot_recv: watch::Receiver>>, runners: &mut Vec>, ) -> Result<(Option, Option), Error> { // Snapshots - let (channel_snapshot_send, channel_snapshot_recv) = tokio::sync::watch::channel(None); let snapshot_runner = WithMetricsSnapshot( { let mut snapshotter = Snapshotter::new( diff --git a/rs/boundary_node/ic_boundary/src/rate_limiting/fetcher.rs b/rs/boundary_node/ic_boundary/src/rate_limiting/fetcher.rs index 983c95569d4..32635d8bf9d 100644 --- a/rs/boundary_node/ic_boundary/src/rate_limiting/fetcher.rs +++ b/rs/boundary_node/ic_boundary/src/rate_limiting/fetcher.rs @@ -86,7 +86,7 @@ impl FetchesConfig for CanisterConfigFetcherUpdate { } } -pub struct CanisterFetcher(pub Arc, pub CanisterId); +pub struct CanisterFetcher(pub Arc); #[async_trait] impl FetchesRules for CanisterFetcher { @@ -115,14 +115,7 @@ impl FetchesRules for CanisterFetcher { )); } - // Create an explicit allow rule that excludes the ratelimit canister - // from being affected by any of the following rules. - let mut allowlist = vec![RateLimitRule { - canister_id: Some(self.1.get().0), - ..Default::default() - }]; - - let mut rules = response + let rules = response .config .rules .into_iter() @@ -142,14 +135,13 @@ impl FetchesRules for CanisterFetcher { }) .collect::, _>>()?; - allowlist.append(&mut rules); - Ok(allowlist) + Ok(rules) } } #[cfg(test)] mod test { - use std::{str::FromStr, time::Duration}; + use std::time::Duration; use candid::Encode; use indoc::indoc; @@ -256,28 +248,21 @@ mod test { #[tokio::test] async fn test_canister_fetcher() { - let canister_id = CanisterId::from_str("pawub-syaaa-aaaam-qb7zq-cai").unwrap(); - // Check bad schema - let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherBadSchema), canister_id); + let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherBadSchema)); assert!(canister_fetcher.fetch_rules().await.is_err()); // Check missing rule - let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherNoneRule), canister_id); + let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherNoneRule)); assert!(canister_fetcher.fetch_rules().await.is_err()); // Check correct rules parsing - let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherOk), canister_id); + let canister_fetcher = CanisterFetcher(Arc::new(FakeConfigFetcherOk)); let rules = canister_fetcher.fetch_rules().await.unwrap(); assert_eq!( rules, vec![ - // Make sure there's an explicit allow rule - RateLimitRule { - canister_id: Some(canister_id.get().0), - ..Default::default() - }, RateLimitRule { canister_id: Some(principal!("aaaaa-aa")), subnet_id: Some(principal!( diff --git a/rs/boundary_node/ic_boundary/src/rate_limiting/generic.rs b/rs/boundary_node/ic_boundary/src/rate_limiting/generic.rs index e988dde00ff..81ee83f615d 100644 --- a/rs/boundary_node/ic_boundary/src/rate_limiting/generic.rs +++ b/rs/boundary_node/ic_boundary/src/rate_limiting/generic.rs @@ -1,4 +1,12 @@ -use std::{net::IpAddr, path::PathBuf, sync::Arc, time::Duration}; +use std::{ + net::IpAddr, + path::PathBuf, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, + }, + time::Duration, +}; use anyhow::{Context as _, Error}; use arc_swap::ArcSwap; @@ -17,6 +25,8 @@ use ic_types::CanisterId; use ipnet::IpNet; use rate_limits_api::v1::{Action, IpPrefixes, RateLimitRule, RequestType as RequestTypeRule}; use ratelimit::Ratelimiter; +#[allow(clippy::disallowed_types)] +use tokio::sync::{watch, Mutex}; use tracing::warn; use super::{ @@ -31,6 +41,7 @@ use crate::{ core::Run, persist::RouteSubnet, routes::{ErrorCause, RateLimitCause, RequestContext, RequestType}, + snapshot::RegistrySnapshot, }; // Converts between different request types @@ -46,6 +57,13 @@ fn convert_request_type(rt: RequestType) -> RequestTypeRule { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Decision { + Pass, + Block, + Limit, +} + pub struct Context<'a> { subnet_id: Principal, canister_id: Option, @@ -74,7 +92,7 @@ impl PartialEq for Bucket { impl Eq for Bucket {} impl Bucket { - fn is_allowed(&self, ctx: &Context) -> Option { + fn evaluate(&self, ctx: &Context) -> Option { if let Some(v) = self.rule.subnet_id { if ctx.subnet_id != v { return None; @@ -112,13 +130,13 @@ impl Bucket { } if self.rule.limit == Action::Pass { - return Some(true); + return Some(Decision::Pass); } else if self.rule.limit == Action::Block { - return Some(false); + return Some(Decision::Block); } - if let Some(v) = &self.limiter { - return Some(match v { + if let Some(limiter) = &self.limiter { + let allowed = match limiter { Limiter::Single(v) => v.try_wait().is_ok(), Limiter::Sharded(v, prefix) => { let prefix = match ctx.ip { @@ -130,6 +148,12 @@ impl Bucket { let net = IpNet::new_assert(ctx.ip, prefix); v.acquire(net) } + }; + + return Some(if allowed { + Decision::Pass + } else { + Decision::Limit }); } @@ -138,55 +162,84 @@ impl Bucket { } } +#[derive(Debug, Clone, Eq, PartialEq)] pub struct Options { pub tti: Duration, pub max_shards: u64, + pub poll_interval: Duration, + pub autoscale: bool, } pub struct GenericLimiter { fetcher: Arc, buckets: ArcSwap>, + active_rules: ArcSwap>, + scale: AtomicU32, + #[allow(clippy::disallowed_types)] + channel_snapshot: Mutex>>>, opts: Options, } impl GenericLimiter { - pub fn new_from_file(path: PathBuf, opts: Options) -> Self { + pub fn new_from_file( + path: PathBuf, + opts: Options, + channel_snapshot: watch::Receiver>>, + ) -> Self { let fetcher = Arc::new(FileFetcher(path)); - Self::new_with_fetcher(fetcher, opts) + Self::new_with_fetcher(fetcher, opts, channel_snapshot) } - pub fn new_from_canister_query(canister_id: CanisterId, agent: Agent, opts: Options) -> Self { - let config_fetcher = CanisterConfigFetcherQuery(agent, canister_id); - Self::new_with_config_fetcher(Arc::new(config_fetcher), canister_id, opts) - } - - pub fn new_from_canister_update(canister_id: CanisterId, agent: Agent, opts: Options) -> Self { - let config_fetcher = CanisterConfigFetcherUpdate(agent, canister_id); - Self::new_with_config_fetcher(Arc::new(config_fetcher), canister_id, opts) - } - - fn new_with_config_fetcher( - config_fetcher: Arc, + pub fn new_from_canister( canister_id: CanisterId, + agent: Agent, opts: Options, + use_update_call: bool, + channel_snapshot: watch::Receiver>>, ) -> Self { - let fetcher = Arc::new(CanisterFetcher(config_fetcher, canister_id)); - Self::new_with_fetcher(fetcher, opts) + let config_fetcher: Arc = if use_update_call { + Arc::new(CanisterConfigFetcherUpdate(agent, canister_id)) + } else { + Arc::new(CanisterConfigFetcherQuery(agent, canister_id)) + }; + + let fetcher = Arc::new(CanisterFetcher(config_fetcher)); + Self::new_with_fetcher(fetcher, opts, channel_snapshot) } - fn new_with_fetcher(fetcher: Arc, opts: Options) -> Self { + fn new_with_fetcher( + fetcher: Arc, + opts: Options, + channel_snapshot: watch::Receiver>>, + ) -> Self { Self { fetcher, buckets: ArcSwap::new(Arc::new(vec![])), + active_rules: ArcSwap::new(Arc::new(vec![])), opts, + scale: AtomicU32::new(1), + #[allow(clippy::disallowed_types)] + channel_snapshot: Mutex::new(channel_snapshot), } } - fn process_rules(&self, rules: Vec, old: &Arc>) -> Vec { + fn process_rules( + &self, + rules: Vec, + old: &Arc>, + scale: u32, + ) -> Vec { rules .into_iter() .enumerate() - .map(|(idx, rule)| { + .map(|(idx, mut rule)| { + // Scale the rule limit accordingly + if let Action::Limit(n, d) = rule.limit { + // Make sure the limit doesn't go below 1 + let limit = (n / scale).max(1); + rule.limit = Action::Limit(limit, d); + } + // Check if the same rule exists in the same position. // If yes, then copy over the old limiter to avoid resetting it. if let Some(v) = old.get(idx) { @@ -219,12 +272,15 @@ impl GenericLimiter { .collect() } - fn apply_rules(&self, rules: Vec) -> bool { + fn apply_rules(&self, rules: Vec, scale: u32) -> bool { let old = self.buckets.load_full(); - let new = Arc::new(self.process_rules(rules, &old)); + let new = Arc::new(self.process_rules(rules, &old, scale)); if old != new { - warn!("GenericLimiter: ruleset updated: {} rules", new.len()); + warn!( + "GenericLimiter: ruleset updated: {} rules (scale {scale})", + new.len() + ); for b in new.as_ref() { warn!("GenericLimiter: {}", b.rule); @@ -244,29 +300,66 @@ impl GenericLimiter { .await .context("unable to fetch rules")?; - self.apply_rules(rules); + self.apply_rules(rules.clone(), self.scale.load(Ordering::SeqCst)); + + // Store the new copy of the rules as a golden copy for future recalculation + self.active_rules.store(Arc::new(rules)); + Ok(()) } - fn acquire_token(&self, ctx: Context) -> bool { + fn evaluate(&self, ctx: Context) -> Decision { + // Always allow access from localhost. + // This makes sure that ic-boundary & colocated services will always be able to query anything. + if ctx.ip.is_loopback() { + return Decision::Pass; + } + for b in self.buckets.load_full().as_ref() { - if let Some(v) = b.is_allowed(&ctx) { + if let Some(v) = b.evaluate(&ctx) { return v; } } // No rules / no match -> pass - true + Decision::Pass } } #[async_trait] impl Run for Arc { async fn run(&mut self) -> Result<(), Error> { - if let Err(e) = self.refresh().await { - warn!("GenericLimiter: unable to refresh: {e:#}"); + let mut interval = tokio::time::interval(self.opts.poll_interval); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + + let mut channel = self.channel_snapshot.lock().await; + + loop { + tokio::select! { + biased; + + Ok(()) = channel.changed(), if self.opts.autoscale => { + let snapshot = channel.borrow_and_update().clone(); + + if let Some(v) = snapshot { + // Store the count of API BNs as a scale and make sure it's >= 1 + let scale = v.api_bns.len().max(1) as u32; + self.scale.store(scale, Ordering::SeqCst); + + warn!("GenericLimiter: got a new registry snapshot, recalculating with scale {scale}"); + + // Recalculate the rules based on the potentially new scale + self.apply_rules(self.active_rules.load().as_ref().clone(), scale); + } + } + + _ = interval.tick() => { + if let Err(e) = self.refresh().await { + warn!("GenericLimiter: unable to refresh: {e:#}"); + } + } + } } - Ok(()) } } @@ -287,27 +380,60 @@ pub async fn middleware( ip: conn_info.remote_addr.ip(), }; - if !state.acquire_token(ctx) { - return Err(ErrorCause::RateLimited(RateLimitCause::Generic)); + match state.evaluate(ctx) { + Decision::Pass => Ok(next.run(request).await), + Decision::Block => Err(ErrorCause::Forbidden), + Decision::Limit => Err(ErrorCause::RateLimited(RateLimitCause::Generic)), } - - Ok(next.run(request).await) } #[cfg(test)] mod test { - use crate::principal; - use super::*; use indoc::indoc; use std::str::FromStr; - #[test] - fn test_ratelimit() { - let rules = indoc! {" - - canister_id: pawub-syaaa-aaaam-qb7zq-cai - limit: pass + use crate::{ + principal, + snapshot::{generate_stub_snapshot, ApiBoundaryNode}, + }; + + struct BrokenFetcher; + #[async_trait] + impl FetchesRules for BrokenFetcher { + async fn fetch_rules(&self) -> Result, Error> { + Err(anyhow::anyhow!("boo")) + } + } + + struct TestFetcher(Vec); + + #[async_trait] + impl FetchesRules for TestFetcher { + async fn fetch_rules(&self) -> Result, Error> { + Ok(self.0.clone()) + } + } + + #[tokio::test] + async fn test_ratelimit() { + let ip1 = IpAddr::from_str("10.0.0.1").unwrap(); + let ip2 = IpAddr::from_str("192.168.0.1").unwrap(); + let ip_local4 = IpAddr::from_str("127.0.0.1").unwrap(); + let ip_local6 = IpAddr::from_str("::1").unwrap(); + + let id0 = principal!("pawub-syaaa-aaaam-qb7zq-cai"); + let id1 = principal!("aaaaa-aa"); + let id2 = principal!("5s2ji-faaaa-aaaaa-qaaaq-cai"); + let id3 = principal!("qoctq-giaaa-aaaaa-aaaea-cai"); + + let subnet_id = + principal!("3hhby-wmtmw-umt4t-7ieyg-bbiig-xiylg-sblrt-voxgt-bqckd-a75bf-rqe"); + let subnet_id2 = + principal!("6pbhf-qzpdk-kuqbr-pklfa-5ehhf-jfjps-zsj6q-57nrl-kzhpd-mu7hc-vae"); + + let rules = indoc! {" - canister_id: pawub-syaaa-aaaam-qb7zq-cai limit: block @@ -340,201 +466,475 @@ mod test { - canister_id: qoctq-giaaa-aaaaa-aaaea-cai limit: 20/1h "}; + let rules: Vec = serde_yaml::from_str(rules).unwrap(); let opts = Options { tti: Duration::from_secs(10), max_shards: 10000, + poll_interval: Duration::from_secs(30), + autoscale: true, }; - let limiter = GenericLimiter::new_from_file("/tmp/foo".into(), opts); - limiter.apply_rules(rules); - let ip1 = IpAddr::from_str("10.0.0.1").unwrap(); - let ip2 = IpAddr::from_str("192.168.0.1").unwrap(); - - let id1 = principal!("aaaaa-aa"); - let id2 = principal!("5s2ji-faaaa-aaaaa-qaaaq-cai"); - let id3 = principal!("qoctq-giaaa-aaaaa-aaaea-cai"); - let id4 = principal!("pawub-syaaa-aaaam-qb7zq-cai"); + // Check that fetching works + let fetcher = TestFetcher(rules.clone()); + let (_, rx) = watch::channel(None); + let limiter = Arc::new(GenericLimiter::new_with_fetcher( + Arc::new(fetcher), + opts.clone(), + rx, + )); + assert!(limiter.refresh().await.is_ok()); + assert_eq!(limiter.active_rules.load().len(), 7); + + // Check id1 limiting with any method + // 10 pass + for _ in 0..10 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + } - let subnet_id = - principal!("3hhby-wmtmw-umt4t-7ieyg-bbiig-xiylg-sblrt-voxgt-bqckd-a75bf-rqe"); - let subnet_id2 = - principal!("6pbhf-qzpdk-kuqbr-pklfa-5ehhf-jfjps-zsj6q-57nrl-kzhpd-mu7hc-vae"); + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); + } - // Check that pass action for this canister always allows + // Check different rules + let (tx, rx) = watch::channel(None); + let limiter = Arc::new(GenericLimiter::new_with_fetcher( + Arc::new(BrokenFetcher), + opts, + rx, + )); + + let mut runner = limiter.clone(); + tokio::spawn(async move { + let _ = runner.run().await; + }); + + limiter.apply_rules(rules.clone(), 1); + + let mut snapshot = generate_stub_snapshot(vec![]); + snapshot.api_bns = vec![ + ApiBoundaryNode { + id: principal!("3hhby-wmtmw-umt4t-7ieyg-bbiig-xiylg-sblrt-voxgt-bqckd-a75bf-rqe"), + addr: ip1, + port: 31337, + }, + ApiBoundaryNode { + id: principal!("3hhby-wmtmw-umt4t-7ieyg-bbiig-xiylg-sblrt-voxgt-bqckd-a75bf-rqe"), + addr: ip2, + port: 31337, + }, + ]; + + // Check that blocked canister always works from localhost even if there's a block rule present for _ in 0..100 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id4), - method: None, - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id0), + method: None, + request_type: RequestType::Query, + ip: ip_local4, + }), + Decision::Pass + ); + } + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id0), + method: None, + request_type: RequestType::Query, + ip: ip_local6, + }), + Decision::Pass + ); } - // Check id1 blocking with any method + // Check id1 limiting with any method // 10 pass for _ in 0..10 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id1), - method: Some("foo"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); } // then all blocked for _ in 0..100 { - assert!(!limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id1), - method: Some("bar"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); } - // Check id2 blocking with two methods + // Check id2 limiting with two methods // 20 pass // Another subnet_id which shouldn't have any difference for _ in 0..20 { - assert!(limiter.acquire_token(Context { - subnet_id: subnet_id2, - canister_id: Some(id2), - method: Some("foo"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id: subnet_id2, + canister_id: Some(id2), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); } - // Then all blocked + // Then all limit for _ in 0..100 { - assert!(!limiter.acquire_token(Context { - subnet_id: subnet_id2, - canister_id: Some(id2), - method: Some("bar"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id: subnet_id2, + canister_id: Some(id2), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); } - // Other methods should not block ever + // Other methods should not limit ever for _ in 0..100 { - assert!(limiter.acquire_token(Context { - subnet_id: subnet_id2, - canister_id: Some(id2), - method: Some("lol"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id: subnet_id2, + canister_id: Some(id2), + method: Some("lol"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); } for _ in 0..100 { - assert!(limiter.acquire_token(Context { - subnet_id: subnet_id2, - canister_id: Some(id2), - method: Some("rofl"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id: subnet_id2, + canister_id: Some(id2), + method: Some("rofl"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); } // This method should be blocked always for _ in 0..100 { - assert!(!limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id2), - method: Some("baz"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id2), + method: Some("baz"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Block + ); } - // Check id3 blocking with any method and request type call + // Check id3 limiting with any method and request type call // 10 pass for _ in 0..10 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: Some("rofl"), - request_type: RequestType::Call, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: Some("rofl"), + request_type: RequestType::Call, + ip: ip1, + }), + Decision::Pass + ); } - // then all blocked + // then all limited for _ in 0..100 { - assert!(!limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: Some("bar"), - request_type: RequestType::Call, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: Some("bar"), + request_type: RequestType::Call, + ip: ip1, + }), + Decision::Limit + ); } - // Then check id3 blocking with any method and request type query + // Then check id3 limiting with any method and request type query // 20 pass for _ in 0..20 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: Some("baz"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: Some("baz"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); } - // then all blocked + // then all limited for _ in 0..100 { - assert!(!limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: Some("zob"), - request_type: RequestType::Query, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: Some("zob"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); } // Check per-ip-subnet blocking // IP1 // 10 pass for _ in 0..10 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: None, - request_type: RequestType::ReadState, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: None, + request_type: RequestType::ReadState, + ip: ip1, + }), + Decision::Pass + ); } - // Then all blocked + // Then all limited for _ in 0..10 { - assert!(!limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: None, - request_type: RequestType::ReadState, - ip: ip1, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: None, + request_type: RequestType::ReadState, + ip: ip1, + }), + Decision::Limit + ); } // IP2 // 10 pass for _ in 0..10 { - assert!(limiter.acquire_token(Context { - subnet_id, - canister_id: Some(id3), - method: None, - request_type: RequestType::ReadState, - ip: ip2, - })); + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: None, + request_type: RequestType::ReadState, + ip: ip2, + }), + Decision::Pass + ); } - // Then all blocked + // Then all limited for _ in 0..10 { - assert!(!limiter.acquire_token(Context { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id3), + method: None, + request_type: RequestType::ReadState, + ip: ip2, + }), + Decision::Limit + ); + } + + // Check that scaling works, the rules should fire 2x earlier now + limiter.apply_rules(rules.clone(), 2); + + // 5 pass (instead of configured 10) + for _ in 0..5 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + } + + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); + } + + // Make sure that resetting scale back to 1 works + limiter.apply_rules(rules.clone(), 1); + + // 10 pass + for _ in 0..10 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + } + + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); + } + + // Check that limit after scaling doesn't go under 1 + limiter.apply_rules(rules.clone(), 100); + + // 1 pass (instead of configured 10) + assert_eq!( + limiter.evaluate(Context { subnet_id, - canister_id: Some(id3), - method: None, - request_type: RequestType::ReadState, - ip: ip2, - })); + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); + } + + // Check that autoscaling works by sending a snapshot + limiter.active_rules.store(Arc::new(rules.clone())); + tx.send(Some(Arc::new(snapshot.clone()))).unwrap(); + tokio::time::sleep(Duration::from_millis(100)).await; + + // 5 pass (instead of configured 10) + for _ in 0..5 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + } + + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); + } + + // Check that autoscaling resets to 1 if there are no API BNs + snapshot.api_bns = vec![]; + tx.send(Some(Arc::new(snapshot))).unwrap(); + tokio::time::sleep(Duration::from_millis(100)).await; + + // 10 pass + for _ in 0..10 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("foo"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Pass + ); + } + + // then all blocked + for _ in 0..100 { + assert_eq!( + limiter.evaluate(Context { + subnet_id, + canister_id: Some(id1), + method: Some("bar"), + request_type: RequestType::Query, + ip: ip1, + }), + Decision::Limit + ); } } } diff --git a/rs/boundary_node/ic_boundary/src/routes.rs b/rs/boundary_node/ic_boundary/src/routes.rs index 026e93f5eb5..b063157c1b6 100644 --- a/rs/boundary_node/ic_boundary/src/routes.rs +++ b/rs/boundary_node/ic_boundary/src/routes.rs @@ -73,8 +73,7 @@ pub enum RateLimitCause { Generic, } -// Categorized possible causes for request processing failures -// Not using Error as inner type since it's not cloneable +/// Categorized possible causes for request processing failures #[derive(Clone, Debug, Display)] #[strum(serialize_all = "snake_case")] pub enum ErrorCause { @@ -84,6 +83,7 @@ pub enum ErrorCause { UnableToParseCBOR(String), UnableToParseHTTPArg(String), LoadShed, + Forbidden, MalformedRequest(String), NoRoutingTable, SubnetNotFound, @@ -143,6 +143,7 @@ impl ErrorCause { Self::ReplicaTLSErrorOther(_) => ErrorClientFacing::ReplicaError, Self::ReplicaTLSErrorCert(_) => ErrorClientFacing::ReplicaError, Self::ReplicaErrorOther(_) => ErrorClientFacing::ReplicaError, + Self::Forbidden => ErrorClientFacing::Forbidden, Self::RateLimited(_) => ErrorClientFacing::RateLimited, } } @@ -169,6 +170,7 @@ pub enum ErrorClientFacing { #[strum(serialize = "internal_server_error")] Other, PayloadTooLarge(usize), + Forbidden, RateLimited, ReplicaError, ServiceUnavailable, @@ -187,6 +189,7 @@ impl ErrorClientFacing { Self::NoHealthyNodes => StatusCode::SERVICE_UNAVAILABLE, Self::Other => StatusCode::INTERNAL_SERVER_ERROR, Self::PayloadTooLarge(_) => StatusCode::PAYLOAD_TOO_LARGE, + Self::Forbidden => StatusCode::FORBIDDEN, Self::RateLimited => StatusCode::TOO_MANY_REQUESTS, Self::ReplicaError => StatusCode::SERVICE_UNAVAILABLE, Self::ServiceUnavailable => StatusCode::SERVICE_UNAVAILABLE, @@ -205,6 +208,7 @@ impl ErrorClientFacing { Self::NoHealthyNodes => "There are currently no healthy replica nodes available to handle the request. This may be due to an ongoing upgrade of the replica software in the subnet. Please try again later.".to_string(), Self::Other => "Internal Server Error".to_string(), Self::PayloadTooLarge(x) => format!("Payload is too large: maximum body size is {x} bytes."), + Self::Forbidden => "Request is forbidden according to currently active policy, it might work later.".to_string(), Self::RateLimited => "Rate limit exceeded. Please slow down requests and try again later.".to_string(), Self::ReplicaError => "An unexpected error occurred while communicating with the upstream replica node. Please try again later.".to_string(), Self::ServiceUnavailable => "The API boundary node is temporarily unable to process the request. Please try again later.".to_string(), diff --git a/rs/boundary_node/ic_boundary/src/snapshot.rs b/rs/boundary_node/ic_boundary/src/snapshot.rs index 7866c4a0e78..2de9a70131d 100644 --- a/rs/boundary_node/ic_boundary/src/snapshot.rs +++ b/rs/boundary_node/ic_boundary/src/snapshot.rs @@ -13,6 +13,7 @@ use async_trait::async_trait; use candid::Principal; use ic_registry_client::client::RegistryClient; use ic_registry_client_helpers::{ + api_boundary_node::ApiBoundaryNodeRegistry, crypto::CryptoRegistry, node::NodeRegistry, routing_table::RoutingTableRegistry, @@ -86,6 +87,14 @@ impl Node { } } +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub struct ApiBoundaryNode { + pub id: Principal, + pub addr: IpAddr, + pub port: u16, +} + #[derive(Clone, Debug)] pub struct CanisterRange { pub start: Principal, @@ -138,6 +147,7 @@ pub struct RegistrySnapshot { pub nns_public_key: Vec, pub subnets: Vec, pub nodes: HashMap>, + pub api_bns: Vec, } pub struct Snapshotter { @@ -192,6 +202,38 @@ impl Snapshotter { self.persister = Some(persister); } + fn get_api_boundary_nodes( + &self, + version: RegistryVersion, + ) -> Result, Error> { + let node_ids = self + .registry_client + .get_api_boundary_node_ids(version) + .context("unable to get API BN node ids")?; + + let nodes = node_ids + .into_iter() + .map(|x| -> Result<_, Error> { + let node = self + .registry_client + .get_node_record(x, version) + .context("unable to get node record")? + .context("node not available")?; + + let http_endpoint = node.http.context("http endpoint not available")?; + + Ok(ApiBoundaryNode { + id: x.get().0, + addr: IpAddr::from_str(http_endpoint.ip_addr.as_str()) + .context("unable to parse IP address")?, + port: http_endpoint.port as u16, + }) + }) + .collect::, _>>()?; + + Ok(nodes) + } + // Creates a snapshot of the registry for given version fn get_snapshot(&self, version: RegistryVersion) -> Result { // Get routing table with canister ranges @@ -243,6 +285,11 @@ impl Snapshotter { .context("failed to get subnet ids")? // Result .context("subnet ids not available")?; // Option + // Fetch a list of API BNs + let api_bns = self + .get_api_boundary_nodes(version) + .context("unable to get API BNs")?; + let subnets = subnet_ids .into_iter() .map(|subnet_id| { @@ -337,6 +384,7 @@ impl Snapshotter { nns_public_key: nns_key_with_prefix, subnets, nodes: nodes_map, + api_bns, }) } } @@ -463,6 +511,7 @@ pub fn generate_stub_snapshot(subnets: Vec) -> RegistrySnapshot { nns_public_key: vec![], subnets, nodes, + api_bns: vec![], } } diff --git a/rs/tests/boundary_nodes/rate_limit_canister_test.rs b/rs/tests/boundary_nodes/rate_limit_canister_test.rs index a59efa82fd8..af557884146 100644 --- a/rs/tests/boundary_nodes/rate_limit_canister_test.rs +++ b/rs/tests/boundary_nodes/rate_limit_canister_test.rs @@ -178,7 +178,7 @@ async fn test_async(env: TestEnv) { .expect("Could not create HTTP client."); let agent = Agent::builder() .with_url(format!("https://{api_bn_domain}")) - .with_identity(full_access_identity) + .with_identity(full_access_identity.clone()) .with_arc_http_middleware(Arc::new(HttpServiceNoRetry { client })) // do not use inbuilt retry logic for 429 responses .build() .unwrap(); @@ -319,9 +319,9 @@ async fn test_async(env: TestEnv) { bail!("counter canister is still reachable, retrying"); } Err(error) => { - // We should observe Too Many Requests 429 http error + // We should observe 403 http error, as all requests are blocked if let AgentError::HttpError(ref payload) = error { - if payload.status == 429 { + if payload.status == 403 { return Ok(()); } } @@ -338,8 +338,12 @@ async fn test_async(env: TestEnv) { "Step 11. Add a rate-limit rule, which unblocks requests to the counter canister" ); + // api_bn_agent can't communicate with canister after blocking, hence we use nns_agent + let mut nns_agent = nns_node.build_default_agent_async().await; + nns_agent.set_identity(full_access_identity); + set_rate_limit_rules( - &api_bn_agent, + &nns_agent, rate_limit_id, vec![InputRule { incident_id: "e6a27788-01a5-444a-9035-ab3af3ad84f3".to_string(), From c68c2eb07db0762d46ecd18840cfd242d2805ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Fri, 10 Jan 2025 11:29:02 +0100 Subject: [PATCH 47/98] test(ICRC_Ledger): FI-1625: Adapt golden state test to V4 migration (#3397) Adapt the ICRC golden state test to handle the case where some canisters have already been upgraded to the V4 version, and further no migration is expected to happen if they are upgraded to the same version again. --- .../icrc1/tests/golden_state_upgrade_downgrade.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs b/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs index bfa0c0d13f3..948773fba0a 100644 --- a/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs +++ b/rs/ledger_suite/icrc1/tests/golden_state_upgrade_downgrade.rs @@ -73,8 +73,8 @@ lazy_static! { Wasm::from_bytes(archive_wasm()), None, ); - pub static ref ALLOWANCES_MIGRATED_LEDGER_MODULE_HASH: Vec = - hex::decode("25071c2c55ad4571293e00d8e277f442aec7aed88109743ac52df3125209ff45").unwrap(); + pub static ref BALANCES_MIGRATED_LEDGER_MODULE_HASH: Vec = + hex::decode("3b03d1bb1145edbcd11101ab2788517bc0f427c3bd7b342b9e3e7f42e29d5822").unwrap(); } #[cfg(feature = "u256-tokens")] @@ -97,8 +97,8 @@ lazy_static! { Wasm::from_bytes(archive_wasm()), None, ); - pub static ref ALLOWANCES_MIGRATED_LEDGER_MODULE_HASH: Vec = - hex::decode("9637743e1215a4db376a62ee807a0986faf20833be2b332df09b3d5dbdd7339e").unwrap(); + pub static ref BALANCES_MIGRATED_LEDGER_MODULE_HASH: Vec = + hex::decode("8b2e3e596a147780b0e99ce36d0b8f1f3ba41a98b819b42980a7c08c309b44c1").unwrap(); } pub struct Wasms { @@ -188,7 +188,7 @@ impl LedgerSuiteConfig { let deployed_module_hash = canister_status .module_hash() .expect("should have ledger canister module hash"); - if deployed_module_hash.as_slice() == ALLOWANCES_MIGRATED_LEDGER_MODULE_HASH.as_slice() { + if deployed_module_hash.as_slice() == BALANCES_MIGRATED_LEDGER_MODULE_HASH.as_slice() { ExpectMigration::No } else { ExpectMigration::Yes From 6da5c715e250abd3e024ba96258bfbb7cbd6d537 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Fri, 10 Jan 2025 05:54:58 -0600 Subject: [PATCH 48/98] refactor: move `serve_journal` into upgrade_journal.rs (#3393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What `serve_journal` is moved into `upgrade_journal.rs` within SNS Governance. Previously it was located in `ic-nervous-system-common` ## Why 1. `serve_journal` was only used by SNS Governance, so it didn't really need to be in ic-nervous-system-common. I think it was there because that's also where `serve_logs` was. If there was another reason, please let me know. 2. `serve_journal` a somewhat dangerous function because it is generic. It takes anything that implements Serialize. I think this was done because no function in `ic-nervous-system-common` can take `UpgradeJournal` because that would require depending on `ic-sns-governance` which would introduce a circular dependency. But the function being generic is dangerous. We really only want to serve the journal with this function, not any other type. This would normally not be a problem, because what else are you going to pass to `serve_journal` besides the journal? But now we have two types named journal: the one in `ic-sns-governance` and `ic-sns-governance-api`. And you really want to serialize the `ic-sns-governance-api` one, because that's the one that has the manual `Serialize` implementation on it that leads to the journal having a user-friendly output. By moving the function into `ic-sns-governance`, we're able to make it not-generic, and depend on only one type. Then there's no chance that it will be called incorrect. For convenience, I made the function take a `ic-sns-governance` `UpgradeJournal` and do the conversion to the `ic-sns-governance-api` `UpgradeJournal` itself. This simplifies its usage at the call site In the next PR, I'm moving some things around, and this change is very useful to make sure we're passing right thing to serve_journal. [Next PR →](https://github.com/dfinity/ic/pull/3391) --- Cargo.lock | 1 + rs/nervous_system/common/src/lib.rs | 15 ---------- rs/sns/governance/BUILD.bazel | 1 + rs/sns/governance/Cargo.toml | 1 + rs/sns/governance/canister/canister.rs | 36 +++++++++++------------- rs/sns/governance/canister/tests.rs | 14 +++++---- rs/sns/governance/src/upgrade_journal.rs | 14 +++++++++ 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3133d68aad4..224642148bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11861,6 +11861,7 @@ dependencies = [ "rust_decimal_macros", "serde", "serde_bytes", + "serde_json", "strum", "strum_macros", "tempfile", diff --git a/rs/nervous_system/common/src/lib.rs b/rs/nervous_system/common/src/lib.rs index 04dc8386068..59900b4db52 100644 --- a/rs/nervous_system/common/src/lib.rs +++ b/rs/nervous_system/common/src/lib.rs @@ -722,21 +722,6 @@ pub fn serve_metrics( } } -pub fn serve_journal(journal: &Journal) -> HttpResponse -where - Journal: serde::Serialize, -{ - match serde_json::to_string(journal) { - Err(err) => { - HttpResponseBuilder::server_error(format!("Failed to encode journal: {}", err)).build() - } - Ok(body) => HttpResponseBuilder::ok() - .header("Content-Type", "application/json") - .with_body_and_content_length(body) - .build(), - } -} - /// Returns the total amount of memory (heap, stable memory, etc) that the calling canister has allocated. #[cfg(target_arch = "wasm32")] pub fn total_memory_size_bytes() -> usize { diff --git a/rs/sns/governance/BUILD.bazel b/rs/sns/governance/BUILD.bazel index 7cdf3aa0716..763d4df9757 100644 --- a/rs/sns/governance/BUILD.bazel +++ b/rs/sns/governance/BUILD.bazel @@ -62,6 +62,7 @@ DEPENDENCIES = [ "@crate_index//:rust_decimal", "@crate_index//:serde", "@crate_index//:serde_bytes", + "@crate_index//:serde_json", "@crate_index//:strum", ] diff --git a/rs/sns/governance/Cargo.toml b/rs/sns/governance/Cargo.toml index 8c76978b518..6d00f0868f6 100644 --- a/rs/sns/governance/Cargo.toml +++ b/rs/sns/governance/Cargo.toml @@ -79,6 +79,7 @@ rust_decimal = "1.36.0" rust_decimal_macros = "1.36.0" serde = { workspace = true } serde_bytes = { workspace = true } +serde_json = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true } canbench-rs = { version = "0.1.7", optional = true } diff --git a/rs/sns/governance/canister/canister.rs b/rs/sns/governance/canister/canister.rs index 6b7755c17f0..2c5e83ebaf4 100644 --- a/rs/sns/governance/canister/canister.rs +++ b/rs/sns/governance/canister/canister.rs @@ -11,7 +11,7 @@ use ic_nervous_system_clients::{ }; use ic_nervous_system_common::{ dfn_core_stable_mem_utils::{BufferedStableMemReader, BufferedStableMemWriter}, - serve_journal, serve_logs, serve_logs_v2, serve_metrics, + serve_logs, serve_logs_v2, serve_metrics, }; use ic_nervous_system_proto::pb::v1::{ GetTimersRequest, GetTimersResponse, ResetTimersRequest, ResetTimersResponse, Timers, @@ -25,6 +25,20 @@ use ic_sns_governance::{ logs::{ERROR, INFO}, pb::v1 as sns_gov_pb, types::{Environment, HeapGrowthPotential}, + upgrade_journal::serve_journal, +}; +use ic_sns_governance_api::pb::v1::{ + get_running_sns_version_response::UpgradeInProgress, governance::Version, + ClaimSwapNeuronsRequest, ClaimSwapNeuronsResponse, FailStuckUpgradeInProgressRequest, + FailStuckUpgradeInProgressResponse, GetMaturityModulationRequest, + GetMaturityModulationResponse, GetMetadataRequest, GetMetadataResponse, GetMode, + GetModeResponse, GetNeuron, GetNeuronResponse, GetProposal, GetProposalResponse, + GetRunningSnsVersionRequest, GetRunningSnsVersionResponse, + GetSnsInitializationParametersRequest, GetSnsInitializationParametersResponse, + GetUpgradeJournalRequest, GetUpgradeJournalResponse, Governance as GovernanceProto, + ListNervousSystemFunctionsResponse, ListNeurons, ListNeuronsResponse, ListProposals, + ListProposalsResponse, ManageNeuron, ManageNeuronResponse, NervousSystemParameters, + RewardEvent, SetMode, SetModeResponse, }; #[cfg(feature = "test")] use ic_sns_governance_api::pb::v1::{ @@ -32,22 +46,6 @@ use ic_sns_governance_api::pb::v1::{ AdvanceTargetVersionResponse, GovernanceError, MintTokensRequest, MintTokensResponse, Neuron, RefreshCachedUpgradeStepsRequest, RefreshCachedUpgradeStepsResponse, }; -use ic_sns_governance_api::pb::{ - v1 as api, - v1::{ - get_running_sns_version_response::UpgradeInProgress, governance::Version, - ClaimSwapNeuronsRequest, ClaimSwapNeuronsResponse, FailStuckUpgradeInProgressRequest, - FailStuckUpgradeInProgressResponse, GetMaturityModulationRequest, - GetMaturityModulationResponse, GetMetadataRequest, GetMetadataResponse, GetMode, - GetModeResponse, GetNeuron, GetNeuronResponse, GetProposal, GetProposalResponse, - GetRunningSnsVersionRequest, GetRunningSnsVersionResponse, - GetSnsInitializationParametersRequest, GetSnsInitializationParametersResponse, - GetUpgradeJournalRequest, GetUpgradeJournalResponse, Governance as GovernanceProto, - ListNervousSystemFunctionsResponse, ListNeurons, ListNeuronsResponse, ListProposals, - ListProposalsResponse, ManageNeuron, ManageNeuronResponse, NervousSystemParameters, - RewardEvent, SetMode, SetModeResponse, - }, -}; use prost::Message; use rand::{RngCore, SeedableRng}; use rand_chacha::ChaCha20Rng; @@ -646,9 +644,7 @@ pub fn http_request(request: HttpRequest) -> HttpResponse { .clone() .expect("The upgrade journal is not initialized for this SNS."); - let journal = api::UpgradeJournal::from(journal); - - serve_journal(&journal.entries) + serve_journal(&journal) } "/metrics" => serve_metrics(encode_metrics), "/logs" => serve_logs_v2(request, &INFO, &ERROR), diff --git a/rs/sns/governance/canister/tests.rs b/rs/sns/governance/canister/tests.rs index d0ed0b1ee29..f5c7e7a90c2 100644 --- a/rs/sns/governance/canister/tests.rs +++ b/rs/sns/governance/canister/tests.rs @@ -1,11 +1,7 @@ use super::*; use assert_matches::assert_matches; use candid_parser::utils::{service_equal, CandidSource}; -use ic_sns_governance_api::pb::v1::{ - governance::{Version, Versions}, - upgrade_journal_entry::{Event, UpgradeStepsRefreshed}, - DisburseMaturityInProgress, Neuron, UpgradeJournal, UpgradeJournalEntry, -}; +use ic_sns_governance_api::pb::v1::{DisburseMaturityInProgress, Neuron}; use maplit::btreemap; use pretty_assertions::assert_eq; use std::collections::HashSet; @@ -115,6 +111,12 @@ fn test_populate_finalize_disbursement_timestamp_seconds() { #[test] fn test_upgrade_journal() { + use ic_sns_governance::pb::v1::{ + governance::{Version, Versions}, + upgrade_journal_entry::{Event, UpgradeStepsRefreshed}, + UpgradeJournal, UpgradeJournalEntry, + }; + let journal = UpgradeJournal { entries: vec![UpgradeJournalEntry { timestamp_seconds: Some(1000), @@ -135,7 +137,7 @@ fn test_upgrade_journal() { // Currently, the `/journal` Http endpoint serves the entries directly, rather than the whole // journal object. - let http_response = serve_journal(&journal.entries); + let http_response = serve_journal(&journal); let expected_headers: HashSet<(_, _)> = HashSet::from_iter([ ("Content-Type".to_string(), "application/json".to_string()), ("Content-Length".to_string(), "277".to_string()), diff --git a/rs/sns/governance/src/upgrade_journal.rs b/rs/sns/governance/src/upgrade_journal.rs index 1ca20da4916..623955d2a5b 100644 --- a/rs/sns/governance/src/upgrade_journal.rs +++ b/rs/sns/governance/src/upgrade_journal.rs @@ -238,3 +238,17 @@ impl upgrade_journal_entry::Event { } } } + +pub fn serve_journal(journal: &UpgradeJournal) -> ic_canisters_http_types::HttpResponse { + use ic_canisters_http_types::HttpResponseBuilder; + let journal = ic_sns_governance_api::pb::v1::UpgradeJournal::from(journal.clone()); + match serde_json::to_string(&journal.entries) { + Err(err) => { + HttpResponseBuilder::server_error(format!("Failed to encode journal: {}", err)).build() + } + Ok(body) => HttpResponseBuilder::ok() + .header("Content-Type", "application/json") + .with_body_and_content_length(body) + .build(), + } +} From df2145592dd82c731b46896c8134145f6d303099 Mon Sep 17 00:00:00 2001 From: kpop-dfinity <125868903+kpop-dfinity@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:11:17 +0100 Subject: [PATCH 49/98] test(consensus): move the `IngressPayload` serialization/deserialization unit test from `test_utilities/types/` to `rs/types/types` (#3384) It makes little sense to me to have unit tests for `IngressPayload` in a test utilities crate Note: to avoid cyclic dependency I'm not using `SignedIngressBuilder` to construct a `SignedIngress` --- Cargo.lock | 1 - rs/test_utilities/types/BUILD.bazel | 1 - rs/test_utilities/types/Cargo.toml | 1 - .../types/src/batch/ingress_payload.rs | 74 --------------- rs/types/types/src/batch/ingress.rs | 95 ++++++++++++++++--- 5 files changed, 82 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 224642148bf..6adacd63a50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13061,7 +13061,6 @@ dependencies = [ name = "ic-test-utilities-types" version = "0.9.0" dependencies = [ - "assert_matches", "bincode", "ic-canister-client-sender", "ic-crypto-ed25519", diff --git a/rs/test_utilities/types/BUILD.bazel b/rs/test_utilities/types/BUILD.bazel index 7a9748adc93..f5d2a16e788 100644 --- a/rs/test_utilities/types/BUILD.bazel +++ b/rs/test_utilities/types/BUILD.bazel @@ -25,7 +25,6 @@ rust_test( crate = ":types", deps = [ # Keep sorted. - "@crate_index//:assert_matches", "@crate_index//:bincode", "@crate_index//:serde_cbor", ], diff --git a/rs/test_utilities/types/Cargo.toml b/rs/test_utilities/types/Cargo.toml index 300abf61004..bbac97ba3da 100644 --- a/rs/test_utilities/types/Cargo.toml +++ b/rs/test_utilities/types/Cargo.toml @@ -14,6 +14,5 @@ ic-types-test-utils = { path = "../../types/types_test_utils" } rand = { workspace = true } [dev-dependencies] -assert_matches = { workspace = true } bincode = { workspace = true } serde_cbor = { workspace = true } diff --git a/rs/test_utilities/types/src/batch/ingress_payload.rs b/rs/test_utilities/types/src/batch/ingress_payload.rs index f858ae6542e..bef65d6638a 100644 --- a/rs/test_utilities/types/src/batch/ingress_payload.rs +++ b/rs/test_utilities/types/src/batch/ingress_payload.rs @@ -36,77 +36,3 @@ impl IngressPayloadBuilder { self.ingress_payload.into() } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::messages::SignedIngressBuilder; - use assert_matches::assert_matches; - use ic_types::{batch::IngressPayloadError, time::expiry_time_from_now}; - use std::convert::TryFrom; - use std::time::Duration; - - #[test] - fn test_ingress_payload_deserialization() { - // serialization/deserialization of empty payload. - let payload = IngressPayload::default(); - let bytes = bincode::serialize(&payload).unwrap(); - assert_eq!( - bincode::deserialize::(&bytes).unwrap(), - payload - ); - let time = expiry_time_from_now(); - - // Some test messages. - let m1 = SignedIngressBuilder::new() - .method_name("m1".to_string()) - .expiry_time(time + Duration::from_secs(1)) - .build(); - let m1_id = m1.id(); - let m2 = SignedIngressBuilder::new() - .method_name("m2".to_string()) - .expiry_time(time + Duration::from_secs(2)) - .build(); - let m3 = SignedIngressBuilder::new() - .method_name("m3".to_string()) - .expiry_time(time + Duration::from_secs(3)) - .build(); - - let msgs = vec![m1, m2, m3]; - let payload = IngressPayload::from(msgs.clone()); - // Serialization/deserialization works. - let mut bytes = bincode::serialize(&payload).unwrap(); - assert_eq!( - bincode::deserialize::(&bytes).unwrap(), - payload - ); - // Individual lookup works. - assert_matches!(payload.get(0).unwrap(), (_, msg) if msg == msgs[0]); - assert_matches!(payload.get(1).unwrap(), (_, msg) if msg == msgs[1]); - assert_matches!(payload.get(2).unwrap(), (_, msg) if msg == msgs[2]); - // Test IndexOutOfBound. - assert_matches!(payload.get(3), Err(IngressPayloadError::IndexOutOfBound(3))); - // Converting back to messages should match original - assert_eq!(msgs, >::try_from(payload).unwrap()); - - // A sub-sequence search function - fn find(array: &[u8], subseq: &[u8]) -> Option { - (0..array.len() - subseq.len() + 1).find(|&i| array[i..i + subseq.len()] == subseq[..]) - } - - // Mutate some byte, deserialization works, but casting back to messages fail. - let pos = find(&bytes, m1_id.as_bytes()).unwrap(); - // `+= 1` may overflow in debug mode. - bytes[pos] ^= 1; - let payload = bincode::deserialize::(&bytes); - assert!(payload.is_ok()); - let payload = payload.unwrap(); - // get(0) should return error. - assert_matches!( - payload.get(0), - Err(IngressPayloadError::MismatchedMessageIdAtIndex(0)) - ); - // Conversion should also fail. - assert!(>::try_from(payload).is_err()); - } -} diff --git a/rs/types/types/src/batch/ingress.rs b/rs/types/types/src/batch/ingress.rs index 3bfcdafadaf..467136fe982 100644 --- a/rs/types/types/src/batch/ingress.rs +++ b/rs/types/types/src/batch/ingress.rs @@ -204,41 +204,45 @@ mod tests { }, time::expiry_time_from_now, }; + use assert_matches::assert_matches; + use std::convert::TryFrom; - /// Build a Vec. Convert to IngressPayload and then back to - /// Vec. Ensure that the two vectors are identical. - #[test] - fn into_ingress_payload_and_back() { - let ingress_expiry = expiry_time_from_now(); - let content = HttpCallContent::Call { + fn fake_http_call_content(method_name: &str) -> HttpCallContent { + HttpCallContent::Call { update: HttpCanisterUpdate { canister_id: Blob(vec![42; 8]), - method_name: "some_method".to_string(), + method_name: method_name.to_string(), arg: Blob(b"".to_vec()), sender: Blob(vec![0x05]), nonce: Some(Blob(vec![1, 2, 3, 4])), - ingress_expiry: ingress_expiry.as_nanos_since_unix_epoch(), + ingress_expiry: expiry_time_from_now().as_nanos_since_unix_epoch(), }, - }; + } + } + + /// Build a Vec. Convert to IngressPayload and then back to + /// Vec. Ensure that the two vectors are identical. + #[test] + fn into_ingress_payload_and_back() { let update_messages = vec![ HttpRequestEnvelope:: { - content: content.clone(), + content: fake_http_call_content("1"), sender_pubkey: Some(Blob(vec![2; 32])), sender_sig: Some(Blob(vec![1; 32])), sender_delegation: None, }, HttpRequestEnvelope:: { - content: content.clone(), + content: fake_http_call_content("2"), sender_pubkey: None, sender_sig: None, sender_delegation: None, }, HttpRequestEnvelope:: { - content, + content: fake_http_call_content("3"), sender_pubkey: Some(Blob(vec![2; 32])), sender_sig: Some(Blob(vec![1; 32])), sender_delegation: Some(vec![SignedDelegation::new( - Delegation::new(vec![1, 2], ingress_expiry), + Delegation::new(vec![1, 2], expiry_time_from_now()), vec![3, 4], )]), }, @@ -251,4 +255,69 @@ mod tests { let signed_ingresses1 = Vec::::try_from(ingress_payload).unwrap(); assert_eq!(signed_ingresses, signed_ingresses1); } + + #[test] + fn test_ingress_payload_deserialization() { + // serialization/deserialization of empty payload. + let payload = IngressPayload::default(); + let bytes = bincode::serialize(&payload).unwrap(); + assert_eq!( + bincode::deserialize::(&bytes).unwrap(), + payload + ); + + let fake_ingress_message = |method_name| { + let message = HttpRequestEnvelope:: { + content: fake_http_call_content(method_name), + sender_pubkey: None, + sender_sig: None, + sender_delegation: None, + }; + + SignedIngress::try_from(message).unwrap() + }; + + // Some test messages. + let m1 = fake_ingress_message("m1"); + let m1_id = m1.id(); + let m2 = fake_ingress_message("m2"); + let m3 = fake_ingress_message("m3"); + + let msgs = vec![m1, m2, m3]; + let payload = IngressPayload::from(msgs.clone()); + // Serialization/deserialization works. + let mut bytes = bincode::serialize(&payload).unwrap(); + assert_eq!( + bincode::deserialize::(&bytes).unwrap(), + payload + ); + // Individual lookup works. + assert_matches!(payload.get(0).unwrap(), (_, msg) if msg == msgs[0]); + assert_matches!(payload.get(1).unwrap(), (_, msg) if msg == msgs[1]); + assert_matches!(payload.get(2).unwrap(), (_, msg) if msg == msgs[2]); + // Test IndexOutOfBound. + assert_matches!(payload.get(3), Err(IngressPayloadError::IndexOutOfBound(3))); + // Converting back to messages should match original + assert_eq!(msgs, >::try_from(payload).unwrap()); + + // A sub-sequence search function + fn find(array: &[u8], subseq: &[u8]) -> Option { + (0..array.len() - subseq.len() + 1).find(|&i| array[i..i + subseq.len()] == subseq[..]) + } + + // Mutate some byte, deserialization works, but casting back to messages fail. + let pos = find(&bytes, m1_id.as_bytes()).unwrap(); + // `+= 1` may overflow in debug mode. + bytes[pos] ^= 1; + let payload = bincode::deserialize::(&bytes); + assert!(payload.is_ok()); + let payload = payload.unwrap(); + // get(0) should return error. + assert_matches!( + payload.get(0), + Err(IngressPayloadError::MismatchedMessageIdAtIndex(0)) + ); + // Conversion should also fail. + assert!(>::try_from(payload).is_err()); + } } From 69981dc7111b8ea8d0103754dc9bd15ae2775c5d Mon Sep 17 00:00:00 2001 From: Alin Sinpalean <58422065+alin-at-dfinity@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:09:26 +0100 Subject: [PATCH 50/98] perf: Use `MutableIntMap` in `SystemState` (#3304) Use `MutableIntMap` instead of `BTreeMap` for all maps and priority queues under `SystemState` with integer-like keys, making them virtually free to clone (something we do a lot during execution and certification) at the cost of up to 2x slower lookup and iteration, up to 3x slower insert and up to 5x slower remove. Also add a `MutableIntMap` tracking the count of callbacks per call context, to avoid `CallContextManager::outstanding_calls` iterating over the full list of callbacks every time. --- .../src/canister_state/queues.rs | 41 ++-- .../src/canister_state/queues/message_pool.rs | 91 +++++-- .../queues/message_pool/tests.rs | 15 +- .../system_state/call_context_manager.rs | 222 +++++++++++------- rs/replicated_state/src/page_map/int_map.rs | 2 - 5 files changed, 247 insertions(+), 124 deletions(-) diff --git a/rs/replicated_state/src/canister_state/queues.rs b/rs/replicated_state/src/canister_state/queues.rs index 5d0b8db172c..17ea0b26eac 100644 --- a/rs/replicated_state/src/canister_state/queues.rs +++ b/rs/replicated_state/src/canister_state/queues.rs @@ -10,6 +10,7 @@ use self::message_pool::{ Context, InboundReference, Kind, MessagePool, OutboundReference, SomeReference, }; use self::queue::{CanisterQueue, IngressQueue, InputQueue, OutputQueue}; +use crate::page_map::int_map::MutableIntMap; use crate::replicated_state::MR_SYNTHETIC_REJECT_MESSAGE_MAX_LEN; use crate::{CanisterState, CheckpointLoadingMetrics, InputQueueType, InputSource, StateError}; use ic_base_types::PrincipalId; @@ -164,7 +165,7 @@ pub struct CanisterQueues { /// /// Used for response deduplication (whether due to a locally generated reject /// response to a best-effort call; or due to a malicious / buggy subnet). - callbacks_with_enqueued_response: BTreeSet, + callbacks_with_enqueued_response: MutableIntMap, } /// Circular iterator that consumes output queue messages: loops over output @@ -364,13 +365,13 @@ struct MessageStoreImpl { /// `CanisterInput::DeadlineExpired` by `peek_input()` / `pop_input()` (and /// "inflated" by `SystemState` into `SysUnknown` reject responses based on the /// callback). - expired_callbacks: BTreeMap, + expired_callbacks: MutableIntMap, /// Compact reject responses (`CallbackIds`) replacing best-effort responses /// that were shed. These are returned as `CanisterInput::ResponseDropped` by /// `peek_input()` / `pop_input()` (and "inflated" by `SystemState` into /// `SysUnknown` reject responses based on the callback). - shed_responses: BTreeMap, + shed_responses: MutableIntMap, } impl MessageStoreImpl { @@ -554,7 +555,7 @@ trait InboundMessageStore: MessageStore { fn callbacks_with_enqueued_response( &self, canister_queues: &BTreeMap, Arc)>, - ) -> Result, String>; + ) -> Result, String>; } impl InboundMessageStore for MessageStoreImpl { @@ -567,8 +568,8 @@ impl InboundMessageStore for MessageStoreImpl { fn callbacks_with_enqueued_response( &self, canister_queues: &BTreeMap, Arc)>, - ) -> Result, String> { - let mut callbacks = BTreeSet::new(); + ) -> Result, String> { + let mut callbacks = MutableIntMap::new(); canister_queues .values() .flat_map(|(input_queue, _)| input_queue.iter()) @@ -603,7 +604,7 @@ impl InboundMessageStore for MessageStoreImpl { } }; - if callbacks.insert(callback_id) { + if callbacks.insert(callback_id, ()).is_none() { Ok(()) } else { Err(format!( @@ -758,9 +759,10 @@ impl CanisterQueues { match self.canister_queues.get_mut(&sender) { Some((queue, _)) if queue.check_has_reserved_response_slot().is_ok() => { // Check against duplicate responses. - if !self + if self .callbacks_with_enqueued_response - .insert(response.originator_reply_callback) + .insert(response.originator_reply_callback, ()) + .is_some() { debug_assert_eq!(Ok(()), self.test_invariants()); if response.deadline == NO_DEADLINE { @@ -796,7 +798,8 @@ impl CanisterQueues { // aleady checked for a matching callback). Silently drop it. debug_assert!(self .callbacks_with_enqueued_response - .contains(&response.originator_reply_callback)); + .get(&response.originator_reply_callback) + .is_some()); return Ok(false); } } @@ -853,7 +856,11 @@ impl CanisterQueues { }; // Check against duplicate responses. - if !self.callbacks_with_enqueued_response.insert(callback_id) { + if self + .callbacks_with_enqueued_response + .insert(callback_id, ()) + .is_some() + { // There is already a response enqueued for the callback. return Ok(false); } @@ -920,7 +927,10 @@ impl CanisterQueues { if let Some(msg_) = &msg { if let Some(callback_id) = msg_.response_callback_id() { - assert!(self.callbacks_with_enqueued_response.remove(&callback_id)); + assert!(self + .callbacks_with_enqueued_response + .remove(&callback_id) + .is_some()); } debug_assert_eq!(Ok(()), self.test_invariants()); debug_assert_eq!(Ok(()), self.schedules_ok(&|_| InputQueueType::RemoteSubnet)); @@ -1559,7 +1569,8 @@ impl CanisterQueues { // request that was still in an output queue. assert!(self .callbacks_with_enqueued_response - .insert(response.originator_reply_callback)); + .insert(response.originator_reply_callback, ()) + .is_none()); let reference = self.store.insert_inbound(response.into()); Arc::make_mut(input_queue).push_response(reference); @@ -1742,7 +1753,7 @@ fn input_queue_type_fn<'a>( impl From<&CanisterQueues> for pb_queues::CanisterQueues { fn from(item: &CanisterQueues) -> Self { fn callback_references_to_proto( - callback_references: &BTreeMap, + callback_references: &MutableIntMap, ) -> Vec { callback_references .iter() @@ -1791,7 +1802,7 @@ impl TryFrom<(pb_queues::CanisterQueues, &dyn CheckpointLoadingMetrics)> for Can fn callback_references_try_from_proto( callback_references: Vec, - ) -> Result, ProxyDecodeError> + ) -> Result, ProxyDecodeError> { callback_references .into_iter() diff --git a/rs/replicated_state/src/canister_state/queues/message_pool.rs b/rs/replicated_state/src/canister_state/queues/message_pool.rs index f0507ccbf55..592d1bd8059 100644 --- a/rs/replicated_state/src/canister_state/queues/message_pool.rs +++ b/rs/replicated_state/src/canister_state/queues/message_pool.rs @@ -1,4 +1,5 @@ use super::CanisterInput; +use crate::page_map::int_map::{AsInt, MutableIntMap}; use ic_protobuf::proxy::{try_from_option_field, ProxyDecodeError}; use ic_protobuf::state::queues::v1 as pb_queues; use ic_types::messages::{ @@ -8,7 +9,7 @@ use ic_types::time::CoarseTime; use ic_types::{CountBytes, Time}; use ic_validate_eq::ValidateEq; use ic_validate_eq_derive::ValidateEq; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::marker::PhantomData; use std::ops::{AddAssign, SubAssign}; use std::sync::Arc; @@ -131,6 +132,33 @@ impl Id { } } +impl AsInt for Id { + type Repr = u64; + + #[inline] + fn as_int(&self) -> u64 { + self.0 + } +} + +impl AsInt for (CoarseTime, Id) { + type Repr = u128; + + #[inline] + fn as_int(&self) -> u128 { + (self.0.as_secs_since_unix_epoch() as u128) << 64 | self.1 .0 as u128 + } +} + +impl AsInt for (usize, Id) { + type Repr = u128; + + #[inline] + fn as_int(&self) -> u128 { + (self.0 as u128) << 64 | self.1 .0 as u128 + } +} + /// A typed reference -- inbound (`CanisterInput`) or outbound /// (`RequestOrResponse`) -- to a message in the `MessagePool`. #[derive(Debug)] @@ -214,6 +242,15 @@ impl From> for Id { } } +impl AsInt for Reference { + type Repr = u64; + + #[inline] + fn as_int(&self) -> u64 { + self.0 + } +} + /// A reference to an inbound message (returned as a `CanisterInput`). pub(super) type InboundReference = Reference; @@ -327,7 +364,7 @@ impl TryFrom for CallbackReferenc pub(super) struct MessagePool { /// Pool contents. #[validate_eq(CompareWithValidateEq)] - messages: BTreeMap, + messages: MutableIntMap, /// Records the (implicit) deadlines of all the outbound guaranteed response /// requests (only). @@ -337,7 +374,7 @@ pub(super) struct MessagePool { /// `outbound_guaranteed_request_deadlines.keys().collect() == messages.keys().filter(|id| (id.context(), id.class(), id.kind()) == (Context::Outbound, Class::GuaranteedResponse, Kind::Request)).collect()` /// * The deadline matches the one recorded in `deadline_queue`: /// `outbound_guaranteed_request_deadlines.iter().all(|(id, deadline)| deadline_queue.contains(&(deadline, id)))` - outbound_guaranteed_request_deadlines: BTreeMap, + outbound_guaranteed_request_deadlines: MutableIntMap, /// Running message stats for the pool. message_stats: MessageStats, @@ -348,13 +385,13 @@ pub(super) struct MessagePool { /// by deadline. /// /// Message IDs break ties, ensuring deterministic ordering. - deadline_queue: BTreeSet<(CoarseTime, Id)>, + deadline_queue: MutableIntMap<(CoarseTime, Id), ()>, /// Load shedding priority queue. Holds all best-effort messages, ordered by /// size. /// /// Message IDs break ties, ensuring deterministic ordering. - size_queue: BTreeSet<(usize, Id)>, + size_queue: MutableIntMap<(usize, Id), ()>, /// A monotonically increasing counter used to generate unique message IDs. message_id_generator: u64, @@ -470,7 +507,7 @@ impl MessagePool { // all best-effort messages except responses in input queues; plus guaranteed // response requests in output queues if actual_deadline != NO_DEADLINE { - self.deadline_queue.insert((actual_deadline, id)); + self.deadline_queue.insert((actual_deadline, id), ()); // Record in the outbound guaranteed response deadline map, iff it's an outbound // guaranteed response request. @@ -483,7 +520,7 @@ impl MessagePool { // Record in load shedding queue iff it's a best-effort message. if class == Class::BestEffort { - self.size_queue.insert((size_bytes, id)); + self.size_queue.insert((size_bytes, id), ()); } reference @@ -552,7 +589,7 @@ impl MessagePool { .outbound_guaranteed_request_deadlines .remove(&id) .unwrap(); - let removed = self.deadline_queue.remove(&(deadline, id)); + let removed = self.deadline_queue.remove(&(deadline, id)).is_some(); debug_assert!(removed); } @@ -564,7 +601,7 @@ impl MessagePool { // All other best-effort messages do expire. (_, BestEffort, _) => { - let removed = self.deadline_queue.remove(&(msg.deadline(), id)); + let removed = self.deadline_queue.remove(&(msg.deadline(), id)).is_some(); debug_assert!(removed); } } @@ -573,7 +610,7 @@ impl MessagePool { /// Removes the given message from the load shedding queue. fn remove_from_size_queue(&mut self, id: Id, msg: &RequestOrResponse) { if id.class() == Class::BestEffort { - let removed = self.size_queue.remove(&(msg.count_bytes(), id)); + let removed = self.size_queue.remove(&(msg.count_bytes(), id)).is_some(); debug_assert!(removed); } } @@ -582,7 +619,7 @@ impl MessagePool { /// /// Time complexity: `O(log(self.len()))`. pub(super) fn has_expired_deadlines(&self, now: Time) -> bool { - if let Some((deadline, _)) = self.deadline_queue.first() { + if let Some((deadline, _)) = self.deadline_queue.min_key() { let now = CoarseTime::floor(now); if *deadline < now { return true; @@ -602,7 +639,7 @@ impl MessagePool { } let now = CoarseTime::floor(now); - if self.deadline_queue.first().unwrap().0 >= now { + if self.deadline_queue.min_key().unwrap().0 >= now { // No expired messages, bail out. return Vec::new(); } @@ -614,7 +651,7 @@ impl MessagePool { // Take and return all expired messages. let expired = temp .into_iter() - .map(|(_, id)| { + .map(|((_, id), _)| { let msg = self.take_impl(id).unwrap(); if id.is_outbound_guaranteed_request() { self.outbound_guaranteed_request_deadlines.remove(&id); @@ -633,7 +670,8 @@ impl MessagePool { /// /// Time complexity: `O(log(self.len()))`. pub(super) fn shed_largest_message(&mut self) -> Option<(SomeReference, RequestOrResponse)> { - if let Some((_, id)) = self.size_queue.pop_last() { + if let Some(&(size_bytes, id)) = self.size_queue.max_key() { + self.size_queue.remove(&(size_bytes, id)).unwrap(); debug_assert_eq!(Class::BestEffort, id.class()); let msg = self.take_impl(id).unwrap(); @@ -661,7 +699,7 @@ impl MessagePool { /// `debug_assert!()` checks. /// /// Time complexity: `O(n)`. - fn calculate_message_stats(messages: &BTreeMap) -> MessageStats { + fn calculate_message_stats(messages: &MutableIntMap) -> MessageStats { let mut stats = MessageStats::default(); for (id, msg) in messages.iter() { stats += MessageStats::stats_delta(msg, id.context()); @@ -754,11 +792,14 @@ impl MessagePool { /// Time complexity: `O(n * log(n))`. #[allow(clippy::type_complexity)] fn calculate_priority_queues( - messages: &BTreeMap, - outbound_guaranteed_request_deadlines: &BTreeMap, - ) -> (BTreeSet<(CoarseTime, Id)>, BTreeSet<(usize, Id)>) { - let mut expected_deadline_queue = BTreeSet::new(); - let mut expected_size_queue = BTreeSet::new(); + messages: &MutableIntMap, + outbound_guaranteed_request_deadlines: &MutableIntMap, + ) -> ( + MutableIntMap<(CoarseTime, Id), ()>, + MutableIntMap<(usize, Id), ()>, + ) { + let mut expected_deadline_queue = MutableIntMap::new(); + let mut expected_size_queue = MutableIntMap::new(); messages.iter().for_each(|(id, msg)| { use Class::*; use Context::*; @@ -767,7 +808,7 @@ impl MessagePool { // Outbound guaranteed response requests have (separately recorded) deadlines. (Outbound, GuaranteedResponse, Request) => { let deadline = outbound_guaranteed_request_deadlines.get(id).unwrap(); - expected_deadline_queue.insert((*deadline, *id)); + expected_deadline_queue.insert((*deadline, *id), ()); } // All other guaranteed response messages neither expire nor can be shed. @@ -776,13 +817,13 @@ impl MessagePool { // Inbound best-effort responses don't have expiration deadlines, but can be // shed. (Inbound, BestEffort, Response) => { - expected_size_queue.insert((msg.count_bytes(), *id)); + expected_size_queue.insert((msg.count_bytes(), *id), ()); } // All other best-effort messages are enqueued in both priority queues. (_, BestEffort, _) => { - expected_deadline_queue.insert((msg.deadline(), *id)); - expected_size_queue.insert((msg.count_bytes(), *id)); + expected_deadline_queue.insert((msg.deadline(), *id), ()); + expected_size_queue.insert((msg.count_bytes(), *id), ()); } } }); @@ -821,7 +862,7 @@ impl TryFrom for MessagePool { fn try_from(item: pb_queues::MessagePool) -> Result { let message_count = item.messages.len(); - let messages: BTreeMap<_, _> = item + let messages: MutableIntMap<_, _> = item .messages .into_iter() .map(|entry| { diff --git a/rs/replicated_state/src/canister_state/queues/message_pool/tests.rs b/rs/replicated_state/src/canister_state/queues/message_pool/tests.rs index 3f2ab229095..48e850920f3 100644 --- a/rs/replicated_state/src/canister_state/queues/message_pool/tests.rs +++ b/rs/replicated_state/src/canister_state/queues/message_pool/tests.rs @@ -70,6 +70,9 @@ fn test_insert() { (time(50 + REQUEST_LIFETIME.as_secs() as u32), id5) }, pool.deadline_queue + .iter() + .map(|((t, id), _)| (*t, *id)) + .collect() ); // All best-effort messages should be in the load shedding queue. @@ -102,7 +105,7 @@ fn test_insert_outbound_request_deadline_rounding() { pool.insert_outbound_request(request(NO_DEADLINE).into(), current_time); - assert_eq!(expected_deadline, pool.deadline_queue.first().unwrap().0); + assert_eq!(expected_deadline, pool.deadline_queue.min_key().unwrap().0); } #[test] @@ -233,6 +236,9 @@ fn test_expiration() { (time(40 + REQUEST_LIFETIME.as_secs() as u32), id4) }, pool.deadline_queue + .iter() + .map(|((t, id), _)| (*t, *id)) + .collect() ); // There are expiring messages. assert!(pool.has_expired_deadlines(t_max)); @@ -1028,9 +1034,12 @@ fn time(seconds_since_unix_epoch: u32) -> CoarseTime { CoarseTime::from_secs_since_unix_epoch(seconds_since_unix_epoch) } -fn assert_exact_messages_in_queue(messages: BTreeSet, queue: &BTreeSet<(T, Id)>) { +fn assert_exact_messages_in_queue(messages: BTreeSet, queue: &MutableIntMap<(T, Id), ()>) +where + (T, Id): AsInt, +{ assert_eq!(messages.len(), queue.len()); - assert_eq!(messages, queue.iter().map(|(_, id)| *id).collect()) + assert_eq!(messages, queue.iter().map(|((_, id), ())| *id).collect()) } /// Generates an `InboundReference` for a request of the given class. diff --git a/rs/replicated_state/src/canister_state/system_state/call_context_manager.rs b/rs/replicated_state/src/canister_state/system_state/call_context_manager.rs index eb79a67cf09..3982278d4bf 100644 --- a/rs/replicated_state/src/canister_state/system_state/call_context_manager.rs +++ b/rs/replicated_state/src/canister_state/system_state/call_context_manager.rs @@ -1,6 +1,7 @@ #[cfg(test)] mod tests; +use crate::page_map::int_map::{AsInt, MutableIntMap}; use ic_interfaces::execution_environment::HypervisorError; use ic_management_canister_types::IC_00; use ic_protobuf::proxy::{try_from_option_field, ProxyDecodeError}; @@ -18,12 +19,14 @@ use ic_types::{ PrincipalId, Time, UserId, }; use serde::{Deserialize, Serialize}; -use std::collections::btree_map::Entry; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::convert::{From, TryFrom, TryInto}; use std::sync::Arc; use std::time::Duration; +#[cfg(test)] +use std::collections::BTreeMap; + /// Contains all context information related to an incoming call. #[derive(Clone, Eq, PartialEq, Debug)] pub struct CallContext { @@ -277,8 +280,8 @@ impl CallContextManagerStats { /// /// Time complexity: `O(n)`. pub(crate) fn calculate_stats( - call_contexts: &BTreeMap, - callbacks: &BTreeMap>, + call_contexts: &MutableIntMap, + callbacks: &MutableIntMap>, ) -> CallContextManagerStats { let unresponded_canister_update_call_contexts = call_contexts .values() @@ -320,11 +323,13 @@ impl CallContextManagerStats { /// (since this response was just delivered). /// /// Time complexity: `O(n)`. - #[allow(dead_code)] + #[cfg(test)] pub(crate) fn calculate_unresponded_callbacks_per_respondent( - callbacks: &BTreeMap>, + callbacks: &MutableIntMap>, aborted_or_paused_response: Option<&Response>, ) -> BTreeMap { + use std::collections::btree_map::Entry; + let mut callback_counts = callbacks.values().fold( BTreeMap::::new(), |mut counts, callback| { @@ -365,9 +370,9 @@ impl CallContextManagerStats { /// plus one for a paused or aborted canister request execution, if any. /// /// Time complexity: `O(n)`. - #[allow(dead_code)] + #[cfg(test)] pub(crate) fn calculate_unresponded_call_contexts_per_originator( - call_contexts: &BTreeMap, + call_contexts: &MutableIntMap, aborted_or_paused_request: Option<&Request>, ) -> BTreeMap { let mut unresponded_canister_update_call_contexts = call_contexts @@ -418,11 +423,14 @@ pub struct CallContextManager { next_callback_id: u64, /// Call contexts (including deleted ones) that still have open callbacks. - call_contexts: BTreeMap, + call_contexts: MutableIntMap, + + /// Counts of open callbacks per call context. + outstanding_callbacks: MutableIntMap, /// Callbacks still awaiting response, plus the callback of the currently /// paused or aborted DTS response execution, if any. - callbacks: BTreeMap>, + callbacks: MutableIntMap>, /// Callback deadline priority queue. Holds all not-yet-expired best-effort /// callbacks, ordered by deadline. `CallbackIds` break ties, ensuring @@ -430,7 +438,7 @@ pub struct CallContextManager { /// /// When a `CallbackId` is returned by `expired_callbacks()`, it is removed from /// the queue. This ensures that each callback is expired at most once. - unexpired_callbacks: BTreeSet<(CoarseTime, CallbackId)>, + unexpired_callbacks: MutableIntMap<(CoarseTime, CallbackId), ()>, /// Guaranteed response and overall callback and call context stats. stats: CallContextManagerStats, @@ -575,7 +583,7 @@ impl CallContextManager { /// Returns the currently open `CallContexts` maintained by this /// `CallContextManager`. - pub fn call_contexts(&self) -> &BTreeMap { + pub fn call_contexts(&self) -> &MutableIntMap { &self.call_contexts } @@ -594,18 +602,21 @@ impl CallContextManager { call_context_id: CallContextId, cycles: Cycles, ) -> Result<&CallContext, &str> { - let call_context = self + let mut call_context = self .call_contexts - .get_mut(&call_context_id) + .remove(&call_context_id) .ok_or("Canister accepted cycles from invalid call context")?; - call_context - .withdraw_cycles(cycles) - .map_err(|_| "Canister accepted more cycles than available from call context")?; - Ok(call_context) + let res = call_context.withdraw_cycles(cycles); + self.call_contexts.insert(call_context_id, call_context); + + match res { + Ok(()) => Ok(self.call_contexts.get(&call_context_id).unwrap()), + Err(()) => Err("Canister accepted more cycles than available from call context"), + } } /// Returns the `Callback`s maintained by this `CallContextManager`. - pub fn callbacks(&self) -> &BTreeMap> { + pub fn callbacks(&self) -> &MutableIntMap> { &self.callbacks } @@ -642,9 +653,9 @@ impl CallContextManager { OutstandingCalls::No }; - let context = self + let mut context = self .call_contexts - .get_mut(&call_context_id) + .remove(&call_context_id) .unwrap_or_else(|| panic!("no call context with ID={}", call_context_id)); // Update call context `instructions_executed += instructions_used` context.instructions_executed = context @@ -663,65 +674,56 @@ impl CallContextManager { let (action, call_context) = match (result, responded, outstanding_calls) { (Ok(None), Responded::No, OutstandingCalls::Yes) | (Err(_), Responded::No, OutstandingCalls::Yes) => { + self.call_contexts.insert(call_context_id, context); (CallContextAction::NotYetResponded, None) } (Ok(None), Responded::Yes, OutstandingCalls::Yes) | (Err(_), Responded::Yes, OutstandingCalls::Yes) => { + self.call_contexts.insert(call_context_id, context); (CallContextAction::AlreadyResponded, None) } (Ok(None), Responded::Yes, OutstandingCalls::No) - | (Err(_), Responded::Yes, OutstandingCalls::No) => ( - CallContextAction::AlreadyResponded, - self.call_contexts.remove(&call_context_id), - ), + | (Err(_), Responded::Yes, OutstandingCalls::No) => { + (CallContextAction::AlreadyResponded, Some(context)) + } (Ok(None), Responded::No, OutstandingCalls::No) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; - ( - CallContextAction::NoResponse { refund }, - self.call_contexts.remove(&call_context_id), - ) + (CallContextAction::NoResponse { refund }, Some(context)) } (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::No) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; - ( - CallContextAction::Reply { payload, refund }, - self.call_contexts.remove(&call_context_id), - ) + (CallContextAction::Reply { payload, refund }, Some(context)) } (Ok(Some(WasmResult::Reply(payload))), Responded::No, OutstandingCalls::Yes) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; context.mark_responded(); + self.call_contexts.insert(call_context_id, context); (CallContextAction::Reply { payload, refund }, None) } (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::No) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; - ( - CallContextAction::Reject { payload, refund }, - self.call_contexts.remove(&call_context_id), - ) + (CallContextAction::Reject { payload, refund }, Some(context)) } (Ok(Some(WasmResult::Reject(payload))), Responded::No, OutstandingCalls::Yes) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; context.mark_responded(); + self.call_contexts.insert(call_context_id, context); (CallContextAction::Reject { payload, refund }, None) } (Err(error), Responded::No, OutstandingCalls::No) => { self.stats.on_call_context_response(&context.call_origin); let refund = context.available_cycles; - ( - CallContextAction::Fail { error, refund }, - self.call_contexts.remove(&call_context_id), - ) + (CallContextAction::Fail { error, refund }, Some(context)) } // The following can never happen since we handle at the SystemApi level if a canister @@ -748,18 +750,17 @@ impl CallContextManager { // TODO: Remove, this is only used in tests. #[cfg(test)] fn mark_responded(&mut self, call_context_id: CallContextId) -> Result<(), String> { - let call_context = self + let mut call_context = self .call_contexts - .get_mut(&call_context_id) + .remove(&call_context_id) .ok_or(format!("Call context not found: {}", call_context_id))?; - if call_context.responded { - return Ok(()); - } - - call_context.mark_responded(); + if !call_context.responded { + call_context.mark_responded(); - self.stats - .on_call_context_response(&call_context.call_origin); + self.stats + .on_call_context_response(&call_context.call_origin); + } + self.call_contexts.insert(call_context_id, call_context); debug_assert!(self.stats_ok()); Ok(()) @@ -773,10 +774,21 @@ impl CallContextManager { self.stats.on_register_callback(&callback); if callback.deadline != NO_DEADLINE { self.unexpired_callbacks - .insert((callback.deadline, callback_id)); + .insert((callback.deadline, callback_id), ()); } + self.outstanding_callbacks.insert( + callback.call_context_id, + self.outstanding_callbacks + .get(&callback.call_context_id) + .unwrap_or(&0) + + 1, + ); self.callbacks.insert(callback_id, Arc::new(callback)); + debug_assert_eq!( + calculate_outstanding_callbacks(&self.callbacks), + self.outstanding_callbacks + ); debug_assert!(self.stats_ok()); callback_id @@ -786,11 +798,27 @@ impl CallContextManager { /// the callback and return it. pub(super) fn unregister_callback(&mut self, callback_id: CallbackId) -> Option> { self.callbacks.remove(&callback_id).inspect(|callback| { + let outstanding_callbacks = *self + .outstanding_callbacks + .get(&callback.call_context_id) + .unwrap_or(&0); + if outstanding_callbacks <= 1 { + self.outstanding_callbacks.remove(&callback.call_context_id); + } else { + self.outstanding_callbacks + .insert(callback.call_context_id, outstanding_callbacks - 1); + } + self.stats.on_unregister_callback(callback); if callback.deadline != NO_DEADLINE { self.unexpired_callbacks .remove(&(callback.deadline, callback_id)); } + + debug_assert_eq!( + calculate_outstanding_callbacks(&self.callbacks), + self.outstanding_callbacks + ); debug_assert!(self.stats_ok()); }) } @@ -799,7 +827,7 @@ impl CallContextManager { /// whose deadlines are `< now`. pub(super) fn has_expired_callbacks(&self, now: CoarseTime) -> bool { self.unexpired_callbacks - .first() + .min_key() .map(|(deadline, _)| *deadline < now) .unwrap_or(false) } @@ -819,7 +847,7 @@ impl CallContextManager { expired_callbacks .into_iter() - .map(|(_, callback_id)| callback_id) + .map(|((_, callback_id), ())| callback_id) } /// Returns the call origin, which is either the message ID of the ingress @@ -839,14 +867,11 @@ impl CallContextManager { } /// Returns the number of outstanding calls for a given call context. - // - // TODO: This could be made more efficient by tracking the callback count per - // call context in a map. pub fn outstanding_calls(&self, call_context_id: CallContextId) -> usize { - self.callbacks - .iter() - .filter(|(_, callback)| callback.call_context_id == call_context_id) - .count() + *self + .outstanding_callbacks + .get(&call_context_id) + .unwrap_or(&0) } /// Expose the `next_callback_id` field so that the canister sandbox can @@ -954,7 +979,9 @@ impl CallContextManager { // subset of all best-effort callbacks. let all_callback_deadlines = calculate_callback_deadlines(&self.callbacks); debug_assert!( - all_callback_deadlines.is_superset(&self.unexpired_callbacks), + self.unexpired_callbacks + .iter() + .all(|(key, ())| all_callback_deadlines.contains(key)), "unexpired_callbacks: {:?}, all_callback_deadlines: {:?}", self.unexpired_callbacks, all_callback_deadlines @@ -972,21 +999,26 @@ impl CallContextManager { ) -> Vec { let mut reject_responses = Vec::new(); - for call_context in self.call_contexts.values_mut() { - if !call_context.has_responded() { - // Generate a reject response. - if let Some(response) = reject(call_context) { - reject_responses.push(response) - } + let call_contexts = std::mem::take(&mut self.call_contexts); + self.call_contexts = call_contexts + .into_iter() + .map(|(id, mut call_context)| { + if !call_context.has_responded() { + // Generate a reject response. + if let Some(response) = reject(&call_context) { + reject_responses.push(response) + } - call_context.mark_responded(); - self.stats - .on_call_context_response(&call_context.call_origin); - } + call_context.mark_responded(); + self.stats + .on_call_context_response(&call_context.call_origin); + } - // Mark the call context as deleted. - call_context.mark_deleted(); - } + // Mark the call context as deleted. + call_context.mark_deleted(); + (id, call_context) + }) + .collect(); debug_assert!(self.stats_ok()); reject_responses @@ -1041,7 +1073,7 @@ impl From<&CallContextManager> for pb::CallContextManager { unexpired_callbacks: item .unexpired_callbacks .iter() - .map(|(_, id)| id.get()) + .map(|((_, id), ())| id.get()) .collect(), } } @@ -1050,8 +1082,8 @@ impl From<&CallContextManager> for pb::CallContextManager { impl TryFrom for CallContextManager { type Error = ProxyDecodeError; fn try_from(value: pb::CallContextManager) -> Result { - let mut call_contexts = BTreeMap::::new(); - let mut callbacks = BTreeMap::>::new(); + let mut call_contexts = MutableIntMap::::new(); + let mut callbacks = MutableIntMap::>::new(); for pb::CallContextEntry { call_context_id, call_context, @@ -1075,6 +1107,7 @@ impl TryFrom for CallContextManager { )?), ); } + let outstanding_callbacks = calculate_outstanding_callbacks(&callbacks); let unexpired_callbacks = value .unexpired_callbacks .into_iter() @@ -1086,7 +1119,7 @@ impl TryFrom for CallContextManager { callback_id )) })?; - Ok((callback.deadline, callback_id)) + Ok(((callback.deadline, callback_id), ())) }) .collect::>()?; let stats = CallContextManagerStats::calculate_stats(&call_contexts, &callbacks); @@ -1095,6 +1128,7 @@ impl TryFrom for CallContextManager { next_call_context_id: value.next_call_context_id, next_callback_id: value.next_callback_id, call_contexts, + outstanding_callbacks, callbacks, unexpired_callbacks, stats, @@ -1109,7 +1143,7 @@ impl TryFrom for CallContextManager { /// /// Time complexity: `O(n)`. fn calculate_callback_deadlines( - callbacks: &BTreeMap>, + callbacks: &MutableIntMap>, ) -> BTreeSet<(CoarseTime, CallbackId)> { callbacks .iter() @@ -1118,6 +1152,36 @@ fn calculate_callback_deadlines( .collect() } +/// Calculates the counts of callbacks per call context. +/// +/// Time complexity: `O(n)`. +fn calculate_outstanding_callbacks( + callbacks: &MutableIntMap>, +) -> MutableIntMap { + callbacks + .iter() + .map(|(_, callback)| callback.call_context_id) + .fold( + MutableIntMap::::new(), + |mut counts, call_context_id| { + counts.insert( + call_context_id, + counts.get(&call_context_id).unwrap_or(&0) + 1, + ); + counts + }, + ) +} + +impl AsInt for (CoarseTime, CallbackId) { + type Repr = u128; + + #[inline] + fn as_int(&self) -> u128 { + (self.0.as_secs_since_unix_epoch() as u128) << 64 | self.1.get() as u128 + } +} + pub mod testing { use super::{CallContext, CallContextManager}; use ic_types::messages::CallContextId; diff --git a/rs/replicated_state/src/page_map/int_map.rs b/rs/replicated_state/src/page_map/int_map.rs index 1dcecde9410..238af11f507 100644 --- a/rs/replicated_state/src/page_map/int_map.rs +++ b/rs/replicated_state/src/page_map/int_map.rs @@ -1071,7 +1071,6 @@ impl<'a, K: AsInt, V: Clone> std::iter::Iterator for IntMapIter<'a, K, V> { // Find the leftmost subtree, pushing all the right hand side nodes onto the // stack. while let Tree::Branch { left, right, .. } = p { - debug_assert!(left.len() > 0 && right.len() > 0); self.0.push(right); p = left; } @@ -1106,7 +1105,6 @@ impl std::iter::Iterator for IntMapIntoIter { // Find the leftmost subtree, pushing all the right hand side nodes onto the // stack. while let Tree::Branch { left, right, .. } = p { - debug_assert!(left.len() > 0 && right.len() > 0); self.0.push(take_arc(right)); p = take_arc(left); } From b5192581ccd35b67fe5a1f795ead9cbcd25956d6 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Fri, 10 Jan 2025 17:26:42 +0100 Subject: [PATCH 51/98] docs(governance): Create changelog files for all of our canisters. (#3388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, moves the description of the process from governance/unreleased_changelog.md to nervous_system/changelog_process.md. Other files point to changelog_process.md. # Future Work In the next PRs in this vein, add support for SNS our tools. In particular, proposal generation, and moving content from unreleased_changelog.md to CHANGELOG.md. # References [👈 Previous PR][prev] [prev]: https://github.com/dfinity/ic/pull/3332 --- rs/nervous_system/changelog_process.md | 59 +++++++++++++++++++ rs/nns/cmc/CHANGELOG.md | 14 +++++ rs/nns/cmc/unreleased_changelog.md | 20 +++++++ rs/nns/governance/CHANGELOG.md | 6 +- rs/nns/governance/unreleased_changelog.md | 32 +--------- rs/nns/gtc/CHANGELOG.md | 14 +++++ rs/nns/gtc/unreleased_changelog.md | 20 +++++++ rs/nns/handlers/lifeline/CHANGELOG.md | 14 +++++ .../handlers/lifeline/unreleased_changelog.md | 20 +++++++ rs/nns/handlers/root/CHANGELOG.md | 14 +++++ rs/nns/handlers/root/unreleased_changelog.md | 20 +++++++ rs/nns/sns-wasm/CHANGELOG.md | 14 +++++ rs/nns/sns-wasm/unreleased_changelog.md | 20 +++++++ rs/registry/CHANGELOG.md | 14 +++++ rs/registry/unreleased_changelog.md | 20 +++++++ rs/sns/governance/CHANGELOG.md | 14 +++++ rs/sns/governance/unreleased_changelog.md | 20 +++++++ rs/sns/root/CHANGELOG.md | 14 +++++ rs/sns/root/unreleased_changelog.md | 20 +++++++ rs/sns/swap/CHANGELOG.md | 14 +++++ rs/sns/swap/unreleased_changelog.md | 20 +++++++ 21 files changed, 371 insertions(+), 32 deletions(-) create mode 100644 rs/nervous_system/changelog_process.md create mode 100644 rs/nns/cmc/CHANGELOG.md create mode 100644 rs/nns/cmc/unreleased_changelog.md create mode 100644 rs/nns/gtc/CHANGELOG.md create mode 100644 rs/nns/gtc/unreleased_changelog.md create mode 100644 rs/nns/handlers/lifeline/CHANGELOG.md create mode 100644 rs/nns/handlers/lifeline/unreleased_changelog.md create mode 100644 rs/nns/handlers/root/CHANGELOG.md create mode 100644 rs/nns/handlers/root/unreleased_changelog.md create mode 100644 rs/nns/sns-wasm/CHANGELOG.md create mode 100644 rs/nns/sns-wasm/unreleased_changelog.md create mode 100644 rs/registry/CHANGELOG.md create mode 100644 rs/registry/unreleased_changelog.md create mode 100644 rs/sns/governance/CHANGELOG.md create mode 100644 rs/sns/governance/unreleased_changelog.md create mode 100644 rs/sns/root/CHANGELOG.md create mode 100644 rs/sns/root/unreleased_changelog.md create mode 100644 rs/sns/swap/CHANGELOG.md create mode 100644 rs/sns/swap/unreleased_changelog.md diff --git a/rs/nervous_system/changelog_process.md b/rs/nervous_system/changelog_process.md new file mode 100644 index 00000000000..e6197217f36 --- /dev/null +++ b/rs/nervous_system/changelog_process.md @@ -0,0 +1,59 @@ +Each canister has a "primary" code directory (e.g. NNS governance's primary code +directory is `rs/nns/governance`). Within that directory, there lives two files: + +1. `unreleased_changelog.md` +2. `CHANGELOG.md` + +The next section describes how these files are maintained. + +# Standard Operating Procedure + +1. When a PR introduces user-visible behavior change in release builds (e.g. the + PR simply consists of `IS_MY_FEATURE_ENABLED = true`), add an entry to the + corresponding `unreleased_changelog.md` file (under the "Next Upgrade + Proposal" heading). This new entry should be added in the **same** PR. There + is a bot that reminds you to do this. + +2. When making an NNS proposal to upgrade this canister (or in the case of SNS, + publish a new WASM), copy entries from `unreleased_changelog.md` to the + proposal's "Features & Fixes" section. This is handled automatically by our + proposal generator scripts. + +3. After the proposal is executed, move the entries from + `unreleased_changelog.md` to its sibling `CHANGELOG.md` file. This can be + done by running + + ```bash + PROPOSAL_ID=??? + + ./testnet/tools/nns-tools/add-release-to-changelog.sh $PROPOSAL_ID + ``` + +If your new code is not active in release builds (because it is behind a feature +flag, or it is simply not called yet), then, do NOT add an entry to +`unreleased_changelog.md`. Instead, wait until your code is actually active in +release builds (e.g. the feature flag is flipped to "enable") before adding an +entry to `unreleased_changelog.md`. + + +# How to Write a Good Entry + +The intended audience of your new entry is people who vote on NNS proposals. In +particular, these people are not necessarily engineers who develop this +canister. In fact, it is best to assume that the reader does not know how to +program at all. (In fact, very many very intelligent people do not know how to +write code!) + +Look at [this example]. Notice how the only Rust code changes in that PR just +sets some `IS_MY_FEATURE_ENABLED` "feature flags" to true. The entry being added +to the `unreleased_changelog.md` file in that same PR describes what the code +behind the flag does, because suddenly, that code is now active in release +builds. + +[this example]: https://github.com/dfinity/ic/pull/3371/files#diff-a0dc71a90ca0ffb3298781894bae5c9dce11c53078ad815c5df1bec4cf0bf625 + + +# The Origin of This Process + +This process is modeled after the process used by nns-dapp. nns-dapp in turn +links to keepachangelog.com as its source of inspiration. diff --git a/rs/nns/cmc/CHANGELOG.md b/rs/nns/cmc/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/nns/cmc/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/nns/cmc/unreleased_changelog.md b/rs/nns/cmc/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/nns/cmc/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/nns/governance/CHANGELOG.md b/rs/nns/governance/CHANGELOG.md index 026ed3c923c..a4306ca17a5 100644 --- a/rs/nns/governance/CHANGELOG.md +++ b/rs/nns/governance/CHANGELOG.md @@ -3,9 +3,9 @@ Proposals before 2025 are NOT listed in here, because this process was introduced later. (We could back fill those later though.) -The process that populates this file is described in the adjacent -unreleased_changelog.md file. In general though, the entries you see here were -moved from there. +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. INSERT NEW RELEASES HERE diff --git a/rs/nns/governance/unreleased_changelog.md b/rs/nns/governance/unreleased_changelog.md index 90de181cefb..aacc80ecf2c 100644 --- a/rs/nns/governance/unreleased_changelog.md +++ b/rs/nns/governance/unreleased_changelog.md @@ -1,34 +1,8 @@ # How This File Is Used -1. When there is a user-visible behavior change to this canister, add an entry - to this file (in the "Next Upgrade Proposal" section) in the same PR. - -2. When making an NNS proposal to upgrade this canister, copy entries to the - proposal's summary. - -3. After the proposal is executed, move the entries from this file to a new - section in the adjacent CHANGELOG.md file. - -If your new code is not active in release builds (because it is behind a feature -flag, or it is simply not called yet), then do NOT add an entry to this file, -because this new function has no user-visible behavior change yet. Wait until it -is active (e.g. the feature flag is flipped to "enable") before adding an entry -to this file. - - -# How to Write a Good Entry - -The intended audience here is people who vote (with their neurons) in NNS, not -necessarily engineers who develop this canister. - -If there is a motion proposal and/or forum thread where a feature (or bug fix) -was proposed, link to it. - - -# The Origin of This Process - -This process is modeled after the process used by nns-dapp. nns-dapp in turn -links to keepachangelog.com as its source of inspiration. +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. # Next Upgrade Proposal diff --git a/rs/nns/gtc/CHANGELOG.md b/rs/nns/gtc/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/nns/gtc/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/nns/gtc/unreleased_changelog.md b/rs/nns/gtc/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/nns/gtc/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/nns/handlers/lifeline/CHANGELOG.md b/rs/nns/handlers/lifeline/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/nns/handlers/lifeline/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/nns/handlers/lifeline/unreleased_changelog.md b/rs/nns/handlers/lifeline/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/nns/handlers/lifeline/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/nns/handlers/root/CHANGELOG.md b/rs/nns/handlers/root/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/nns/handlers/root/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/nns/handlers/root/unreleased_changelog.md b/rs/nns/handlers/root/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/nns/handlers/root/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/nns/sns-wasm/CHANGELOG.md b/rs/nns/sns-wasm/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/nns/sns-wasm/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/nns/sns-wasm/unreleased_changelog.md b/rs/nns/sns-wasm/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/nns/sns-wasm/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/registry/CHANGELOG.md b/rs/registry/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/registry/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/registry/unreleased_changelog.md b/rs/registry/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/registry/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/sns/governance/CHANGELOG.md b/rs/sns/governance/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/sns/governance/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/sns/governance/unreleased_changelog.md b/rs/sns/governance/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/sns/governance/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/sns/root/CHANGELOG.md b/rs/sns/root/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/sns/root/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/sns/root/unreleased_changelog.md b/rs/sns/root/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/sns/root/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security diff --git a/rs/sns/swap/CHANGELOG.md b/rs/sns/swap/CHANGELOG.md new file mode 100644 index 00000000000..a4306ca17a5 --- /dev/null +++ b/rs/sns/swap/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +Proposals before 2025 are NOT listed in here, because this process was +introduced later. (We could back fill those later though.) + +The process that populates this file is described in +`rs/nervous_system/changelog_process.md`. In general though, the entries you see +here were moved from the adjacent `unreleased_changelog.md` file. + + +INSERT NEW RELEASES HERE + + +END diff --git a/rs/sns/swap/unreleased_changelog.md b/rs/sns/swap/unreleased_changelog.md new file mode 100644 index 00000000000..94126a0ff42 --- /dev/null +++ b/rs/sns/swap/unreleased_changelog.md @@ -0,0 +1,20 @@ +# How This File Is Used + +In general, upcoming/unreleased behavior changes are described here. For details +on the process that this file is part of, see +`rs/nervous_system/changelog_process.md`. + + +# Next Upgrade Proposal + +## Added + +## Changed + +## Deprecated + +## Removed + +## Fixed + +## Security From df7d443e6219c462b305152b63ca265171feb6ee Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Fri, 10 Jan 2025 15:26:03 -0600 Subject: [PATCH 52/98] fix: SNS Gov canister should deserialize to proto Governance, not API Governance (#3391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think this was a bug in the code previously. [here](https://github.com/dfinity/ic/blob/4b9b18fcada06a30f9d2286eddcacff6521ace47/rs/sns/governance/canister/canister.rs#L258-L270) is where we serialize Governance: ```rust #[pre_upgrade] fn canister_pre_upgrade() { log!(INFO, "Executing pre upgrade"); let mut writer = BufferedStableMemWriter::new(STABLE_MEM_BUFFER_SIZE); governance() .proto // This gets the `Governance` that's from `ic-sns-governance` .encode(&mut writer) .expect("Error. Couldn't serialize canister pre-upgrade."); writer.flush(); // or `drop(writer)` log!(INFO, "Completed pre upgrade"); } ``` And this is where we were deserializing it: ```rust #[post_upgrade] fn canister_post_upgrade() { log!(INFO, "Executing post upgrade"); let reader = BufferedStableMemReader::new(STABLE_MEM_BUFFER_SIZE); match GovernanceProto::decode(reader) { // this is deserializing to the Governance that's in `ic-sns-governance-api` Err(err) => { // [...] } Ok(mut governance_proto) => { // Post-process GovernanceProto // TODO: Delete this once it's been released. populate_finalize_disbursement_timestamp_seconds(&mut governance_proto); canister_init_(governance_proto); // then in here we pass to canister_init_ Ok(()) } } .expect("Couldn't upgrade canister."); // [...] } ``` `canister_init_`: ```rust #[init] fn canister_init_(init_payload: GovernanceProto) { let init_payload = sns_gov_pb::Governance::from(init_payload); // we convert the `ic-sns-governance-api` Governance to the `ic-sns-governance` Governance // [...] } ``` This seems not quite right to me because we serialize one Governance (`ic-sns-governance`), but deserialize to the other Governance (`ic-sns-governance-api`) and then convert. Why not just deserialize to the `ic-sns-governance` Governance directly? This only works because the `ic-sns-governance-api` types still set `prost` derives, but I don't think we want to be protobuffing the `ic-sns-governance-api` types anyway. (In fact, since we don't want to be protobuffing them, I actually remove their prost implementations in the next PR) --- However, we should still initialize the canister using the API types. Doing this ensures that no proto types are part of our public candid interface. So the `canister_init` method has been restored and annotated with `#[init]`, and takes the API type like `canister_init_` did previously. Now `canister_init_` takes the proto type, so it can be used by `canister_post_upgrade` and by `canister_init` after `canister_init` does the conversion. --- [← Previous PR](https://github.com/dfinity/ic/pull/3393) | [Next PR →](https://github.com/dfinity/ic/pull/3392) --- rs/sns/governance/canister/canister.rs | 14 ++++++++------ rs/sns/governance/canister/tests.rs | 16 +++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/rs/sns/governance/canister/canister.rs b/rs/sns/governance/canister/canister.rs index 2c5e83ebaf4..f29c9e353b0 100644 --- a/rs/sns/governance/canister/canister.rs +++ b/rs/sns/governance/canister/canister.rs @@ -35,7 +35,7 @@ use ic_sns_governance_api::pb::v1::{ GetModeResponse, GetNeuron, GetNeuronResponse, GetProposal, GetProposalResponse, GetRunningSnsVersionRequest, GetRunningSnsVersionResponse, GetSnsInitializationParametersRequest, GetSnsInitializationParametersResponse, - GetUpgradeJournalRequest, GetUpgradeJournalResponse, Governance as GovernanceProto, + GetUpgradeJournalRequest, GetUpgradeJournalResponse, Governance as GovernanceApi, ListNervousSystemFunctionsResponse, ListNeurons, ListNeuronsResponse, ListProposals, ListProposalsResponse, ManageNeuron, ManageNeuronResponse, NervousSystemParameters, RewardEvent, SetMode, SetModeResponse, @@ -208,11 +208,13 @@ fn caller() -> PrincipalId { PrincipalId::from(cdk_caller()) } -/// In contrast to canister_init(), this method does not do deserialization. -/// In addition to canister_init, this method is called by canister_post_upgrade. #[init] -fn canister_init_(init_payload: GovernanceProto) { +fn canister_init(init_payload: GovernanceApi) { let init_payload = sns_gov_pb::Governance::from(init_payload); + canister_init_(init_payload); +} + +fn canister_init_(init_payload: sns_gov_pb::Governance) { let init_payload = ValidGovernanceProto::try_from(init_payload).expect( "Cannot start canister, because the deserialized \ GovernanceProto is invalid in some way", @@ -277,7 +279,7 @@ fn canister_post_upgrade() { let reader = BufferedStableMemReader::new(STABLE_MEM_BUFFER_SIZE); - match GovernanceProto::decode(reader) { + match sns_gov_pb::Governance::decode(reader) { Err(err) => { log!( ERROR, @@ -304,7 +306,7 @@ fn canister_post_upgrade() { log!(INFO, "Completed post upgrade"); } -fn populate_finalize_disbursement_timestamp_seconds(governance_proto: &mut GovernanceProto) { +fn populate_finalize_disbursement_timestamp_seconds(governance_proto: &mut sns_gov_pb::Governance) { for neuron in governance_proto.neurons.values_mut() { for disbursement in neuron.disburse_maturity_in_progress.iter_mut() { disbursement.finalize_disbursement_timestamp_seconds = Some( diff --git a/rs/sns/governance/canister/tests.rs b/rs/sns/governance/canister/tests.rs index f5c7e7a90c2..496348898b1 100644 --- a/rs/sns/governance/canister/tests.rs +++ b/rs/sns/governance/canister/tests.rs @@ -1,7 +1,11 @@ use super::*; use assert_matches::assert_matches; use candid_parser::utils::{service_equal, CandidSource}; -use ic_sns_governance_api::pb::v1::{DisburseMaturityInProgress, Neuron}; +use ic_sns_governance::pb::v1::{ + governance::{Version, Versions}, + upgrade_journal_entry::{Event, UpgradeStepsRefreshed}, + DisburseMaturityInProgress, Neuron, UpgradeJournal, UpgradeJournalEntry, +}; use maplit::btreemap; use pretty_assertions::assert_eq; use std::collections::HashSet; @@ -61,7 +65,7 @@ fn test_set_time_warp() { fn test_populate_finalize_disbursement_timestamp_seconds() { // Step 1: prepare a neuron with 2 in progress disbursement, one with // finalize_disbursement_timestamp_seconds as None, and the other has incorrect timestamp. - let mut governance_proto = GovernanceProto { + let mut governance_proto = sns_gov_pb::Governance { neurons: btreemap! { "1".to_string() => Neuron { disburse_maturity_in_progress: vec![ @@ -86,7 +90,7 @@ fn test_populate_finalize_disbursement_timestamp_seconds() { populate_finalize_disbursement_timestamp_seconds(&mut governance_proto); // Step 3: verifies that both disbursements have the correct finalization timestamps. - let expected_governance_proto = GovernanceProto { + let expected_governance_proto = sns_gov_pb::Governance { neurons: btreemap! { "1".to_string() => Neuron { disburse_maturity_in_progress: vec![ @@ -111,12 +115,6 @@ fn test_populate_finalize_disbursement_timestamp_seconds() { #[test] fn test_upgrade_journal() { - use ic_sns_governance::pb::v1::{ - governance::{Version, Versions}, - upgrade_journal_entry::{Event, UpgradeStepsRefreshed}, - UpgradeJournal, UpgradeJournalEntry, - }; - let journal = UpgradeJournal { entries: vec![UpgradeJournalEntry { timestamp_seconds: Some(1000), From d3354bf1558e487840125b44d3ae19a20bf40dc7 Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Fri, 10 Jan 2025 14:30:58 -0800 Subject: [PATCH 53/98] fix(proposal-tools): Fix code path to be absolute instead of relative (#3406) This fixes a problem where unreleased_changelog.md is not found if running from a different directory. --- testnet/tools/nns-tools/lib/proposals.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testnet/tools/nns-tools/lib/proposals.sh b/testnet/tools/nns-tools/lib/proposals.sh index c89a9930d87..addc68e0026 100644 --- a/testnet/tools/nns-tools/lib/proposals.sh +++ b/testnet/tools/nns-tools/lib/proposals.sh @@ -133,8 +133,8 @@ generate_nns_upgrade_proposal_text() { # our canisters will have such a file, but for now, we are still test # driving this process. FEATURES_AND_FIXES="TODO Hand-craft this section." - PRIMARY_RELATIVE_CODE_LOCATION=$(echo "${RELATIVE_CODE_LOCATION}" | cut -d' ' -f1) - UNRELEASED_CHANGELOG_PATH="${PRIMARY_RELATIVE_CODE_LOCATION}/unreleased_changelog.md" + PRIMARY_CANISTER_CODE_LOCATION=$(echo "${CANISTER_CODE_LOCATION}" | cut -d' ' -f1) + UNRELEASED_CHANGELOG_PATH="${PRIMARY_CANISTER_CODE_LOCATION}/unreleased_changelog.md" if [[ -e "${UNRELEASED_CHANGELOG_PATH}" ]]; then FEATURES_AND_FIXES=$( sed -n '/# Next Upgrade Proposal/,$p' \ From a4224e83a632b00c01fb1604f298244fb70aaf49 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:19:35 +0100 Subject: [PATCH 54/98] feat(governance-tools): Populate "Features & Fixes" section of SNS proposals from unreleased_changelog.md. (#3405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Future Work Add entry to SNS CHANGELOG.md files from unreleased_changelog.md, like how we do with NNS. This just involves making some (small?) changes to the add-release-to-changelog.sh script. # References [👈 Previous PR][prev] [prev]: https://github.com/dfinity/ic/pull/3388 --------- Co-authored-by: Max Summe --- .../nns-tools/add-release-to-changelog.sh | 5 +- testnet/tools/nns-tools/lib/proposals.sh | 50 ++++++++++++++++--- testnet/tools/nns-tools/lib/util.sh | 30 +++++++++++ 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/testnet/tools/nns-tools/add-release-to-changelog.sh b/testnet/tools/nns-tools/add-release-to-changelog.sh index ce10ccbbfef..e3ca0d7d033 100755 --- a/testnet/tools/nns-tools/add-release-to-changelog.sh +++ b/testnet/tools/nns-tools/add-release-to-changelog.sh @@ -94,13 +94,10 @@ fi # TODO: Verify that there are no uncommited changes in this dir, the canister's primary code path. # Construct new entry for CHANGELOG.md -# -# Python is used to filter out empty sections. -# Python is used because I cannot figure out how to do that using mac sed. NEW_FEATURES_AND_FIXES=$( sed '1,/^# Next Upgrade Proposal$/d' \ unreleased_changelog.md \ - | python3 -c 'import sys, re; s = sys.stdin.read(); print(re.sub(r"## [\w ]+\n+(?=##|\Z)", "", s).strip())' + | filter_out_empty_markdown_sections ) if [[ -z "${NEW_FEATURES_AND_FIXES}" ]]; then echo >&2 diff --git a/testnet/tools/nns-tools/lib/proposals.sh b/testnet/tools/nns-tools/lib/proposals.sh index addc68e0026..acce6003a3d 100644 --- a/testnet/tools/nns-tools/lib/proposals.sh +++ b/testnet/tools/nns-tools/lib/proposals.sh @@ -129,9 +129,7 @@ generate_nns_upgrade_proposal_text() { RELATIVE_CODE_LOCATION="$(echo "$CANISTER_CODE_LOCATION" | sed "s/$ESCAPED_IC_REPO/./g")" # If the canister has an unrelease_changelog.md file, use that to populate - # the "Features & Fixes" section of the upgrade proposal. Eventually, all of - # our canisters will have such a file, but for now, we are still test - # driving this process. + # the "Features & Fixes" section of the upgrade proposal. FEATURES_AND_FIXES="TODO Hand-craft this section." PRIMARY_CANISTER_CODE_LOCATION=$(echo "${CANISTER_CODE_LOCATION}" | cut -d' ' -f1) UNRELEASED_CHANGELOG_PATH="${PRIMARY_CANISTER_CODE_LOCATION}/unreleased_changelog.md" @@ -140,8 +138,21 @@ generate_nns_upgrade_proposal_text() { sed -n '/# Next Upgrade Proposal/,$p' \ "${UNRELEASED_CHANGELOG_PATH}" \ | tail -n +3 \ - | sed 's/^## /### /g' + | filter_out_empty_markdown_sections \ + | increment_markdown_heading_levels ) + if [[ -z "${FEATURES_AND_FIXES}" ]]; then + print_yellow "The unreleased_changelog.md has nothing interesting in it." >&2 + print_yellow 'Therefore, Some hand crafting of "Features & Fixes" will be required.' >&2 + FEATURES_AND_FIXES='TODO Hand-craft this section. unreleased_changelog.md was empty. It might be +that this is just a "maintenance" release; i.e. we are not trying to ship +any behavior changes. Instead, we just want the build in production to not +get too old. One reason to run recent builds is so that the next release +does not have a huge amount of changes in it.' + fi + else + print_yellow 'No unreleased_changelog.md file for ${CANISTER_NAME}.' >&2 + print_yellow 'The "Features & Fixes" section will need to be written by hand.' >&2 fi ARGS_HASH="" @@ -270,6 +281,33 @@ generate_sns_bless_wasm_proposal_text() { ESCAPED_IC_REPO=$(printf '%s\n' "$IC_REPO" | sed -e 's/[]\/$*.^[]/\\&/g') RELATIVE_CODE_LOCATION="$(echo "$CANISTER_CODE_LOCATION" | sed "s/$ESCAPED_IC_REPO/./g")" + # If the canister has an unrelease_changelog.md file, use that to populate + # the "Features & Fixes" section of the proposal. + FEATURES_AND_FIXES="TODO Hand-craft this section." + PRIMARY_CANISTER_CODE_LOCATION=$(echo "${CANISTER_CODE_LOCATION}" | cut -d' ' -f1) + UNRELEASED_CHANGELOG_PATH="${PRIMARY_CANISTER_CODE_LOCATION}/unreleased_changelog.md" + if [[ -e "${UNRELEASED_CHANGELOG_PATH}" ]]; then + FEATURES_AND_FIXES=$( + sed -n '/# Next Upgrade Proposal/,$p' \ + "${UNRELEASED_CHANGELOG_PATH}" \ + | tail -n +3 \ + | filter_out_empty_markdown_sections \ + | increment_markdown_heading_levels + ) + if [[ -z "${FEATURES_AND_FIXES}" ]]; then + print_yellow "The unreleased_changelog.md has nothing interesting in it." >&2 + print_yellow 'Therefore, Some hand crafting of "Features & Fixes" will be required.' >&2 + FEATURES_AND_FIXES='TODO Hand-craft this section. unreleased_changelog.md was empty. It might be +that this is just a "maintenance" release; i.e. we are not trying to ship +any behavior changes. Instead, we just want the build in production to not +get too old. One reason to run recent builds is so that the next release +does not have a huge amount of changes in it.' + fi + else + print_yellow 'No unreleased_changelog.md file for ${CANISTER_NAME}.' >&2 + print_yellow 'The "Features & Fixes" section will need to be written by hand.' >&2 + fi + OUTPUT=$( cat <<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Publish SNS $CAPITALIZED_CANISTER_TYPE WASM Built at Commit $SHORT_NEXT_COMMIT @@ -280,9 +318,9 @@ __Source code__: [$NEXT_COMMIT][new-commit] [new-commit]: https://github.com/dfinity/ic/tree/$NEXT_COMMIT -## Summary +## Features & Fixes -TODO add a summary of changes +$FEATURES_AND_FIXES ## New Commits diff --git a/testnet/tools/nns-tools/lib/util.sh b/testnet/tools/nns-tools/lib/util.sh index 190a27d1c4f..fc1d3e8accb 100644 --- a/testnet/tools/nns-tools/lib/util.sh +++ b/testnet/tools/nns-tools/lib/util.sh @@ -134,3 +134,33 @@ confirm() { exit 1 fi } + +#### Markdown + +filter_out_empty_markdown_sections() { + # Python is used, because I'm not sure how to do this with sed. + python3 -c 'import sys, re +s = sys.stdin.read() +print(re.sub( + r"^(#+) [\w ]+\n+(?=\1 |\Z)", + "", # Replace with nothing. + s, # Input. + 0, # Unlimited replacements. + re.MULTILINE, +) +.strip())' +} + +increment_markdown_heading_levels() { + # Python is used, because I'm not sure how to do this with sed. + python3 -c 'import sys, re +s = sys.stdin.read() +print(re.sub( + r"^(#+)", # Grab Markdown heading. + r"\1# ", # Add another # character to increase the level. + s, # Input. + 0, # Unlimited replacements. + re.MULTILINE, +) +.strip())' +} From 8acef9e5114b394d7c49eb5d5fb95021f2257f25 Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:46:31 -0800 Subject: [PATCH 55/98] fix(nns-tools): Fix forum post generator (#3407) --- testnet/tools/nns-tools/lib/proposals.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testnet/tools/nns-tools/lib/proposals.sh b/testnet/tools/nns-tools/lib/proposals.sh index acce6003a3d..18585904ba3 100644 --- a/testnet/tools/nns-tools/lib/proposals.sh +++ b/testnet/tools/nns-tools/lib/proposals.sh @@ -624,12 +624,12 @@ proposal_field_value() { nns_upgrade_proposal_canister_raw_name() { local FILE=$1 - cat "$FILE" | grep "## Proposal to Upgrade the" | cut -d' ' -f6 + cat "$FILE" | grep "# Upgrade the" | cut -d' ' -f4 } sns_wasm_publish_proposal_canister_raw_name() { local FILE=$1 - cat "$FILE" | grep "## Proposal to Publish the SNS" | cut -d' ' -f7 + cat "$FILE" | grep "# Publish SNS" | cut -d' ' -f4 } #### Proposal text validators From cfd1859fd87da4a103966d2a3f0a261bd98ad63c Mon Sep 17 00:00:00 2001 From: Paul Liu Date: Sat, 11 Jan 2025 10:42:21 +0800 Subject: [PATCH 56/98] chore(ckbtc): remove distribute_kyt_fee and reimburse_failed_kyt (#3325) XC-237 Since the ckBTC minter switched to using the checker canister, it no longer needs to distribute kyt fees, or reimburse failed kyt. These calls can be removed from the code, but we do still need to keep them for event and state handling during replay. --- rs/bitcoin/ckbtc/minter/src/guard.rs | 23 ---- rs/bitcoin/ckbtc/minter/src/lib.rs | 129 +-------------------- rs/bitcoin/ckbtc/minter/src/main.rs | 11 -- rs/bitcoin/ckbtc/minter/src/memo.rs | 3 + rs/bitcoin/ckbtc/minter/src/state/audit.rs | 58 +-------- rs/bitcoin/ckbtc/minter/src/tasks.rs | 32 +---- rs/bitcoin/ckbtc/minter/src/tasks/tests.rs | 10 -- 7 files changed, 6 insertions(+), 260 deletions(-) diff --git a/rs/bitcoin/ckbtc/minter/src/guard.rs b/rs/bitcoin/ckbtc/minter/src/guard.rs index 35639580086..954bc2abc1e 100644 --- a/rs/bitcoin/ckbtc/minter/src/guard.rs +++ b/rs/bitcoin/ckbtc/minter/src/guard.rs @@ -89,29 +89,6 @@ impl Drop for TimerLogicGuard { } } -#[must_use] -pub struct DistributeKytFeeGuard(()); - -impl DistributeKytFeeGuard { - pub fn new() -> Option { - mutate_state(|s| { - if s.is_distributing_fee { - return None; - } - s.is_distributing_fee = true; - Some(DistributeKytFeeGuard(())) - }) - } -} - -impl Drop for DistributeKytFeeGuard { - fn drop(&mut self) { - mutate_state(|s| { - s.is_distributing_fee = false; - }); - } -} - pub fn balance_update_guard(p: Principal) -> Result, GuardError> { Guard::new(p) } diff --git a/rs/bitcoin/ckbtc/minter/src/lib.rs b/rs/bitcoin/ckbtc/minter/src/lib.rs index 17606e5bc19..3d156535210 100644 --- a/rs/bitcoin/ckbtc/minter/src/lib.rs +++ b/rs/bitcoin/ckbtc/minter/src/lib.rs @@ -1,9 +1,7 @@ use crate::address::BitcoinAddress; use crate::logs::{P0, P1}; use crate::management::CallError; -use crate::memo::Status; use crate::queries::WithdrawalFee; -use crate::state::ReimbursementReason; use crate::updates::update_balance::UpdateBalanceError; use async_trait::async_trait; use candid::{CandidType, Deserialize, Principal}; @@ -14,8 +12,7 @@ use ic_btc_interface::{ use ic_canister_log::log; use ic_management_canister_types::DerivationPath; use icrc_ledger_types::icrc1::account::Account; -use icrc_ledger_types::icrc1::transfer::{Memo, TransferError}; -use num_traits::ToPrimitive; +use icrc_ledger_types::icrc1::transfer::Memo; use scopeguard::{guard, ScopeGuard}; use serde::Serialize; use serde_bytes::ByteBuf; @@ -464,40 +461,6 @@ fn finalized_txids(candidates: &[state::SubmittedBtcTransaction], new_utxos: &[U .collect() } -async fn reimburse_failed_kyt() { - let try_to_reimburse = state::read_state(|s| s.pending_reimbursements.clone()); - for (burn_block_index, entry) in try_to_reimburse { - let (memo_status, kyt_fee) = match entry.reason { - ReimbursementReason::TaintedDestination { kyt_fee, .. } => (Status::Rejected, kyt_fee), - ReimbursementReason::CallFailed => (Status::CallFailed, 0), - }; - let reimburse_memo = crate::memo::MintMemo::KytFail { - kyt_fee: Some(kyt_fee), - status: Some(memo_status), - associated_burn_index: Some(burn_block_index), - }; - if let Ok(block_index) = crate::updates::update_balance::mint( - entry - .amount - .checked_sub(kyt_fee) - .expect("reimburse underflow"), - entry.account, - crate::memo::encode(&reimburse_memo).into(), - ) - .await - { - state::mutate_state(|s| { - state::audit::reimbursed_failed_deposit( - s, - burn_block_index, - block_index, - &IC_CANISTER_RUNTIME, - ) - }); - } - } -} - async fn finalize_requests() { if state::read_state(|s| s.submitted_transactions.is_empty()) { return; @@ -1119,96 +1082,6 @@ fn distribute(amount: u64, n: u64) -> Vec { shares } -pub async fn distribute_kyt_fees() { - use icrc_ledger_client_cdk::CdkRuntime; - use icrc_ledger_client_cdk::ICRC1Client; - use icrc_ledger_types::icrc1::transfer::TransferArg; - - enum MintError { - TransferError(TransferError), - CallError(i32, String), - } - - impl std::fmt::Debug for MintError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - MintError::TransferError(e) => write!(f, "TransferError({:?})", e), - MintError::CallError(code, msg) => write!(f, "CallError({}, {:?})", code, msg), - } - } - } - - async fn mint(amount: u64, to: candid::Principal, memo: Memo) -> Result { - debug_assert!(memo.0.len() <= CKBTC_LEDGER_MEMO_SIZE as usize); - - let client = ICRC1Client { - runtime: CdkRuntime, - ledger_canister_id: state::read_state(|s| s.ledger_id.get().into()), - }; - client - .transfer(TransferArg { - from_subaccount: None, - to: Account { - owner: to, - subaccount: None, - }, - fee: None, - created_at_time: None, - memo: Some(memo), - amount: candid::Nat::from(amount), - }) - .await - .map_err(|(code, msg)| MintError::CallError(code, msg))? - .map_err(MintError::TransferError) - .map(|n| n.0.to_u64().expect("nat does not fit into u64")) - } - - let fees_to_distribute = state::read_state(|s| s.owed_kyt_amount.clone()); - for (provider, amount) in fees_to_distribute { - let memo = crate::memo::MintMemo::Kyt; - match mint(amount, provider, crate::memo::encode(&memo).into()).await { - Ok(block_index) => { - state::mutate_state(|s| { - if let Err(state::Overdraft(overdraft)) = state::audit::distributed_kyt_fee( - s, - provider, - amount, - block_index, - &IC_CANISTER_RUNTIME, - ) { - // This should never happen because: - // 1. The fee distribution task is guarded (at most one copy is active). - // 2. Fee distribution is the only way to decrease the balance. - log!( - P0, - "BUG[distribute_kyt_fees]: distributed {} to {} but the balance is only {}", - tx::DisplayAmount(amount), - provider, - tx::DisplayAmount(amount - overdraft), - ); - } else { - log!( - P0, - "[distribute_kyt_fees]: minted {} to {}", - tx::DisplayAmount(amount), - provider, - ); - } - }); - } - Err(error) => { - log!( - P0, - "[distribute_kyt_fees]: failed to mint {} to {} with error: {:?}", - tx::DisplayAmount(amount), - provider, - error - ); - } - } - } -} - pub fn timer(runtime: R) { use tasks::{pop_if_ready, run_task}; diff --git a/rs/bitcoin/ckbtc/minter/src/main.rs b/rs/bitcoin/ckbtc/minter/src/main.rs index e12d791e89e..5456da881c9 100644 --- a/rs/bitcoin/ckbtc/minter/src/main.rs +++ b/rs/bitcoin/ckbtc/minter/src/main.rs @@ -50,7 +50,6 @@ fn init(args: MinterArg) { fn setup_tasks() { schedule_now(TaskType::ProcessLogic, &IC_CANISTER_RUNTIME); schedule_now(TaskType::RefreshFeePercentiles, &IC_CANISTER_RUNTIME); - schedule_now(TaskType::DistributeKytFee, &IC_CANISTER_RUNTIME); } #[cfg(feature = "self_check")] @@ -84,16 +83,6 @@ fn check_invariants() -> Result<(), String> { }) } -#[cfg(feature = "self_check")] -#[update] -async fn distribute_kyt_fee() { - let _guard = match ic_ckbtc_minter::guard::DistributeKytFeeGuard::new() { - Some(guard) => guard, - None => return, - }; - ic_ckbtc_minter::distribute_kyt_fees().await; -} - #[cfg(feature = "self_check")] #[update] async fn refresh_fee_percentiles() { diff --git a/rs/bitcoin/ckbtc/minter/src/memo.rs b/rs/bitcoin/ckbtc/minter/src/memo.rs index 7aeed4531d0..554ec72f274 100644 --- a/rs/bitcoin/ckbtc/minter/src/memo.rs +++ b/rs/bitcoin/ckbtc/minter/src/memo.rs @@ -1,3 +1,4 @@ +#![allow(deprecated)] use minicbor::Encoder; use minicbor::{Decode, Encode}; @@ -37,9 +38,11 @@ pub enum MintMemo<'a> { kyt_fee: Option, }, #[n(1)] + #[deprecated] /// The minter minted accumulated check fees to the KYT provider. Kyt, #[n(2)] + #[deprecated] /// The minter failed to check retrieve btc destination address /// or the destination address is tainted. KytFail { diff --git a/rs/bitcoin/ckbtc/minter/src/state/audit.rs b/rs/bitcoin/ckbtc/minter/src/state/audit.rs index 6b7d0aa939b..993f128bf68 100644 --- a/rs/bitcoin/ckbtc/minter/src/state/audit.rs +++ b/rs/bitcoin/ckbtc/minter/src/state/audit.rs @@ -5,9 +5,8 @@ use super::{ RetrieveBtcRequest, SubmittedBtcTransaction, SuspendedReason, }; use crate::state::invariants::CheckInvariantsImpl; -use crate::state::{ReimburseDepositTask, ReimbursedDeposit}; use crate::storage::record_event; -use crate::{CanisterRuntime, ReimbursementReason, Timestamp}; +use crate::{CanisterRuntime, Timestamp}; use candid::Principal; use ic_btc_interface::{Txid, Utxo}; use icrc_ledger_types::icrc1::account::Account; @@ -213,58 +212,3 @@ pub fn distributed_kyt_fee( ); state.distribute_kyt_fee(kyt_provider, amount) } - -pub fn schedule_deposit_reimbursement( - state: &mut CkBtcMinterState, - account: Account, - amount: u64, - reason: ReimbursementReason, - burn_block_index: u64, - runtime: &R, -) { - record_event( - EventType::ScheduleDepositReimbursement { - account, - amount, - reason, - burn_block_index, - }, - runtime, - ); - state.schedule_deposit_reimbursement( - burn_block_index, - ReimburseDepositTask { - account, - amount, - reason, - }, - ); -} - -pub fn reimbursed_failed_deposit( - state: &mut CkBtcMinterState, - burn_block_index: u64, - mint_block_index: u64, - runtime: &R, -) { - record_event( - EventType::ReimbursedFailedDeposit { - burn_block_index, - mint_block_index, - }, - runtime, - ); - let reimbursed_tx = state - .pending_reimbursements - .remove(&burn_block_index) - .expect("bug: reimbursement task should be present"); - state.reimbursed_transactions.insert( - burn_block_index, - ReimbursedDeposit { - account: reimbursed_tx.account, - amount: reimbursed_tx.amount, - reason: reimbursed_tx.reason, - mint_block_index, - }, - ); -} diff --git a/rs/bitcoin/ckbtc/minter/src/tasks.rs b/rs/bitcoin/ckbtc/minter/src/tasks.rs index 4dcfb77c14f..d454c13ab0f 100644 --- a/rs/bitcoin/ckbtc/minter/src/tasks.rs +++ b/rs/bitcoin/ckbtc/minter/src/tasks.rs @@ -1,10 +1,6 @@ #[cfg(test)] mod tests; -use crate::{ - distribute_kyt_fees, estimate_fee_per_vbyte, finalize_requests, reimburse_failed_kyt, - submit_pending_requests, CanisterRuntime, -}; -use ic_btc_interface::Network; +use crate::{estimate_fee_per_vbyte, finalize_requests, submit_pending_requests, CanisterRuntime}; use scopeguard::guard; use std::cell::{Cell, RefCell}; use std::collections::{BTreeMap, BTreeSet}; @@ -19,7 +15,6 @@ thread_local! { pub enum TaskType { ProcessLogic, RefreshFeePercentiles, - DistributeKytFee, } #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] @@ -147,7 +142,6 @@ pub(crate) async fn run_task(task: Task, runtime: R) { submit_pending_requests().await; finalize_requests().await; - reimburse_failed_kyt().await; } TaskType::RefreshFeePercentiles => { const FEE_ESTIMATE_DELAY: Duration = Duration::from_secs(60 * 60); @@ -165,29 +159,5 @@ pub(crate) async fn run_task(task: Task, runtime: R) { }; let _ = estimate_fee_per_vbyte().await; } - TaskType::DistributeKytFee => { - const MAINNET_KYT_FEE_DISTRIBUTION_PERIOD: Duration = Duration::from_secs(24 * 60 * 60); - - let _enqueue_followup_guard = guard((), |_| { - schedule_after( - MAINNET_KYT_FEE_DISTRIBUTION_PERIOD, - TaskType::DistributeKytFee, - &runtime, - ); - }); - let _guard = match crate::guard::DistributeKytFeeGuard::new() { - Some(guard) => guard, - None => return, - }; - - match crate::state::read_state(|s| s.btc_network) { - Network::Mainnet | Network::Testnet => { - distribute_kyt_fees().await; - } - // We use a debug canister build exposing an endpoint - // triggering the fee distribution in tests. - Network::Regtest => {} - } - } } } diff --git a/rs/bitcoin/ckbtc/minter/src/tasks/tests.rs b/rs/bitcoin/ckbtc/minter/src/tasks/tests.rs index 78a8d4beec6..e571855b441 100644 --- a/rs/bitcoin/ckbtc/minter/src/tasks/tests.rs +++ b/rs/bitcoin/ckbtc/minter/src/tasks/tests.rs @@ -48,16 +48,6 @@ async fn should_reschedule_refresh_fees() { .await; } -#[tokio::test] -async fn should_reschedule_distribute_kyt_fee() { - test_reschedule( - TaskType::DistributeKytFee, - || crate::guard::DistributeKytFeeGuard::new().unwrap(), - Duration::from_secs(24 * 60 * 60), - ) - .await; -} - async fn test_reschedule T>( task_type: TaskType, guard: G, From 9dfe291d63f4a7e1ab21ca6922ee46a14cef51e1 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Mon, 13 Jan 2025 08:37:53 +0100 Subject: [PATCH 57/98] fix(PocketIC): run install_backtrace_handler if PocketIC is run as canister sandbox (#3354) This PR runs `install_backtrace_handler` if PocketIC is run as canister sandbox to match the dedicated binary's main function. --- rs/canister_sandbox/BUILD.bazel | 1 - rs/canister_sandbox/bin/canister_sandbox.rs | 2 +- rs/pocket_ic_server/BUILD.bazel | 5 ++++- rs/pocket_ic_server/src/main.rs | 9 +++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/rs/canister_sandbox/BUILD.bazel b/rs/canister_sandbox/BUILD.bazel index 70e77c64477..fe1a2757697 100644 --- a/rs/canister_sandbox/BUILD.bazel +++ b/rs/canister_sandbox/BUILD.bazel @@ -96,7 +96,6 @@ rust_binary( # Keep sorted. ":backend_lib", ":build_script", - "@crate_index//:libc", ], ) diff --git a/rs/canister_sandbox/bin/canister_sandbox.rs b/rs/canister_sandbox/bin/canister_sandbox.rs index 4f76bde94bd..f1a6645a649 100644 --- a/rs/canister_sandbox/bin/canister_sandbox.rs +++ b/rs/canister_sandbox/bin/canister_sandbox.rs @@ -1,4 +1,4 @@ -#[cfg(target_os = "linux")] +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] extern "C" { fn install_backtrace_handler(); } diff --git a/rs/pocket_ic_server/BUILD.bazel b/rs/pocket_ic_server/BUILD.bazel index d0f74e8c21d..112ffb34b72 100644 --- a/rs/pocket_ic_server/BUILD.bazel +++ b/rs/pocket_ic_server/BUILD.bazel @@ -141,7 +141,10 @@ rust_binary( proc_macro_deps = MACRO_DEPENDENCIES, # TODO: restrict the visibility visibility = ["//visibility:public"], - deps = LIB_DEPENDENCIES + [":pocket-ic-server-lib"], + deps = LIB_DEPENDENCIES + [ + ":pocket-ic-server-lib", + "//rs/canister_sandbox:build_script", + ], ) rust_library( diff --git a/rs/pocket_ic_server/src/main.rs b/rs/pocket_ic_server/src/main.rs index 9911af56018..adbc07586c3 100644 --- a/rs/pocket_ic_server/src/main.rs +++ b/rs/pocket_ic_server/src/main.rs @@ -78,6 +78,11 @@ fn current_binary_path() -> Option { std::env::args().next().map(PathBuf::from) } +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +extern "C" { + fn install_backtrace_handler(); +} + fn main() { let current_binary_path = current_binary_path().unwrap(); let current_binary_name = current_binary_path.file_name().unwrap().to_str().unwrap(); @@ -89,6 +94,10 @@ fn main() { // before the arguments are parsed because the parent process does not pass // all the normally required arguments of `pocket-ic-server`. if std::env::args().any(|arg| arg == RUN_AS_CANISTER_SANDBOX_FLAG) { + #[cfg(all(target_os = "linux", target_arch = "x86_64"))] + unsafe { + install_backtrace_handler(); + } canister_sandbox_main(); } else if std::env::args().any(|arg| arg == RUN_AS_SANDBOX_LAUNCHER_FLAG) { sandbox_launcher_main(); From a3dae229b7ff2ab8805b843d6b1a6212b61d33f1 Mon Sep 17 00:00:00 2001 From: Louis Pahlavi Date: Mon, 13 Jan 2025 09:56:53 +0100 Subject: [PATCH 58/98] chore(cketh/ckerc20): proposal to upgrade ledger suite orchestrator and managed canisters (#3402) [(XC-270)](https://dfinity.atlassian.net/browse/XC-270) Proposal to upgrade all ledger suites managed by the ledger suite orchestrator to the latest version. --------- Co-authored-by: gregorydemay <112856886+gregorydemay@users.noreply.github.com> --- .../orchestrator_upgrade_2025_01_10.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 rs/ethereum/cketh/mainnet/orchestrator_upgrade_2025_01_10.md diff --git a/rs/ethereum/cketh/mainnet/orchestrator_upgrade_2025_01_10.md b/rs/ethereum/cketh/mainnet/orchestrator_upgrade_2025_01_10.md new file mode 100644 index 00000000000..421b08c1388 --- /dev/null +++ b/rs/ethereum/cketh/mainnet/orchestrator_upgrade_2025_01_10.md @@ -0,0 +1,97 @@ +# Proposal to upgrade the ledger suite orchestrator canister + +Repository: `https://github.com/dfinity/ic.git` + +Git hash: `c741e349451edf0c9792149ad439bb32a0161371` + +New compressed Wasm hash: `cf9dd8805aa34a385151aa962246c871f36453ab2c38dec4b9d15295570cec26` + +Upgrade args hash: `9dfa9db8b0ddd5f32c0680ff28b98411f1066407aafad00f90d3bd71b9ad9c04` + +Target canister: `vxkom-oyaaa-aaaar-qafda-cai` + +Previous ledger suite orchestrator proposal: https://dashboard.internetcomputer.org/proposal/134357 + +--- + +## Motivation + +Upgrade all ledger suites managed by the orchestrator to the latest +version ([ledger-suite-icrc-2025-01-07](https://github.com/dfinity/ic/releases/tag/ledger-suite-icrc-2025-01-07)) to +continue the migration towards stable memory. + +## Upgrade args + +``` +git fetch +git checkout c741e349451edf0c9792149ad439bb32a0161371 +cd rs/ethereum/ledger-suite-orchestrator +didc encode -d ledger_suite_orchestrator.did -t '(OrchestratorArg)' '(variant { UpgradeArg = record {git_commit_hash = opt "c741e349451edf0c9792149ad439bb32a0161371"; ledger_compressed_wasm_hash = opt "8b2e3e596a147780b0e99ce36d0b8f1f3ba41a98b819b42980a7c08c309b44c1"; index_compressed_wasm_hash = opt "d21d059962144c835c8b291af3033e1f1c835af2350a5cd92b3cf8d687a1a7be"; archive_compressed_wasm_hash = opt "d2170c173f814fafc909737ec82f098714d44aa98ebd4f6dbf4e175160e1200f"}})' | xxd -r -p | sha256sum +``` + +## Release Notes + +### Orchestrator + +``` +git log --format='%C(auto) %h %s' 2190613d3b5bcd9b74c382b22d151580b8ac271a..c741e349451edf0c9792149ad439bb32a0161371 -- rs/ethereum/ledger-suite-orchestrator +c741e34945 feat: ICRC-ledger: FI-1439: Implement V4 for ICRC ledger - migrate balances to stable structures (#2901) +484a58d15c test(cketh): end-to-end test with `foundry` (#3014) +642b305524 feat(cketh/ckerc20): Display upgrades on dashboard (#3009) +2456414f7a fix: Use workspace rust edition instead of specifying it in the Cargo.toml file (#3049) + ``` + +### Ledger Suite + +The commit used `c741e349451edf0c9792149ad439bb32a0161371` corresponds to +the [ICRC Ledger Suite release 2025-01-07](https://github.com/dfinity/ic/releases/tag/ledger-suite-icrc-2025-01-07). + +### Ledger + +``` +git log --format="%C(auto) %h %s" 2190613d3b5bcd9b74c382b22d151580b8ac271a..c741e349451edf0c9792149ad439bb32a0161371 -- rs/ledger_suite/icrc1/ledger +c741e34945 feat: ICRC-ledger: FI-1439: Implement V4 for ICRC ledger - migrate balances to stable structures (#2901) +ddadaafd51 test(ICP_Ledger): FI-1616: Fix ICP ledger upgrade tests (#3213) +dfc3810851 fix(ICRC-Ledger): changed certificate version (#2848) +b006ae9934 feat(ICP-ledger): FI-1438: Implement V3 for ICP ledger - migrate allowances to stable structures (#2818) +``` + +### Index + +``` +git log --format="%C(auto) %h %s" 2190613d3b5bcd9b74c382b22d151580b8ac271a..c741e349451edf0c9792149ad439bb32a0161371 -- rs/ledger_suite/icrc1/index-ng +c741e34945 feat: ICRC-ledger: FI-1439: Implement V4 for ICRC ledger - migrate balances to stable structures (#2901) +575ca531a7 chore(ICRC_Index): FI-1468: Remove old ICRC index canister (#3286) +8d4fcddc6e test(ICRC_Index): FI-1617: Optimize retrieve_blocks_from_ledger_interval tests (#3236) +e369646b76 fix: Use default rust edition instead of specifying it in the BUILD rules (#3047) +``` + +### Archive + +No changes since last version (`2190613d3b5bcd9b74c382b22d151580b8ac271a`). + +``` +git log --format="%C(auto) %h %s" 2190613d3b5bcd9b74c382b22d151580b8ac271a..c741e349451edf0c9792149ad439bb32a0161371 -- rs/ledger_suite/icrc1/archive +``` + +## Wasm Verification + +Verify that the hash of the gzipped WASM matches the proposed hash. + +``` +git fetch +git checkout c741e349451edf0c9792149ad439bb32a0161371 +"./ci/container/build-ic.sh" "--canisters" +sha256sum ./artifacts/canisters/ic-ledger-suite-orchestrator-canister.wasm.gz +``` + +Verify that the hash of the gzipped WASM for the ledger, index and archive match the proposed hash. + +``` +git fetch +git checkout c741e349451edf0c9792149ad439bb32a0161371 +"./ci/container/build-ic.sh" "--canisters" +sha256sum ./artifacts/canisters/ic-icrc1-ledger-u256.wasm.gz +sha256sum ./artifacts/canisters/ic-icrc1-index-ng-u256.wasm.gz +sha256sum ./artifacts/canisters/ic-icrc1-archive-u256.wasm.gz +``` From c8be4fc1b4ca6537ff36c4bd9d2285dfbcd708d6 Mon Sep 17 00:00:00 2001 From: oggy-dfin <89794951+oggy-dfin@users.noreply.github.com> Date: Mon, 13 Jan 2025 10:27:50 +0100 Subject: [PATCH 59/98] feat(IC-1579): TLA instrumentation for `disburse_neuron` (#3337) Adds TLA instrumentation for `disburse_neuron`. Since this calls `transfer_funds` multiple times, we also need some additional functionality to disambiguate the different call sites. The disambiguation requires a small tweak to the existing models (of spawn, split, etc). Moreover the disambiguation functionality (based on the `tla_function` macro) didn't play well with `async_trait`, so we add a special case to handle that. --------- Co-authored-by: IDX GitHub Automation --- Cargo.lock | 1 + rs/nns/governance/src/governance.rs | 23 +- .../governance/src/governance/tla/common.rs | 17 ++ .../src/governance/tla/disburse_neuron.rs | 49 ++++ rs/nns/governance/src/governance/tla/mod.rs | 6 +- rs/nns/governance/tests/fake.rs | 3 +- rs/nns/governance/tests/governance.rs | 4 + rs/nns/governance/tla/Disburse_Neuron.tla | 248 ++++++++++++++++++ .../tla/Disburse_Neuron_Apalache.tla | 70 +++++ rs/nns/governance/tla/Spawn_Neurons.tla | 69 ++--- rs/nns/governance/tla/Split_Neuron.tla | 89 +++---- rs/tla_instrumentation/BUILD.bazel | 5 +- .../tla_instrumentation/Cargo.toml | 1 + .../tests/multiple_calls.rs | 47 ++-- .../src/lib.rs | 130 +++++---- 15 files changed, 611 insertions(+), 151 deletions(-) create mode 100644 rs/nns/governance/src/governance/tla/disburse_neuron.rs create mode 100644 rs/nns/governance/tla/Disburse_Neuron.tla create mode 100644 rs/nns/governance/tla/Disburse_Neuron_Apalache.tla diff --git a/Cargo.lock b/Cargo.lock index 6adacd63a50..909606d2516 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20915,6 +20915,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" name = "tla_instrumentation" version = "0.9.0" dependencies = [ + "async-trait", "candid", "local_key", "sha2 0.10.8", diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index 945cd736477..c05c981f953 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -146,9 +146,9 @@ use crate::storage::with_voting_state_machines_mut; use std::collections::BTreeSet; #[cfg(feature = "tla")] pub use tla::{ - tla_update_method, InstrumentationState, ToTla, CLAIM_NEURON_DESC, MERGE_NEURONS_DESC, - SPAWN_NEURONS_DESC, SPAWN_NEURON_DESC, SPLIT_NEURON_DESC, TLA_INSTRUMENTATION_STATE, - TLA_TRACES_LKEY, TLA_TRACES_MUTEX, + tla_update_method, InstrumentationState, ToTla, CLAIM_NEURON_DESC, DISBURSE_NEURON_DESC, + MERGE_NEURONS_DESC, SPAWN_NEURONS_DESC, SPAWN_NEURON_DESC, SPLIT_NEURON_DESC, + TLA_INSTRUMENTATION_STATE, TLA_TRACES_LKEY, TLA_TRACES_MUTEX, }; // 70 KB (for executing NNS functions that are not canister upgrades) @@ -2655,6 +2655,7 @@ impl Governance { /// - The neuron exists. /// - The caller is the controller of the the neuron. /// - The neuron's state is `Dissolved` at the current timestamp. + #[cfg_attr(feature = "tla", tla_update_method(DISBURSE_NEURON_DESC.clone()))] pub async fn disburse_neuron( &mut self, id: &NeuronId, @@ -2759,6 +2760,13 @@ impl Governance { // an amount less than the transaction fee. if fees_amount_e8s > transaction_fee_e8s { let now = self.env.now(); + tla_log_label!("DisburseNeuron_Fee"); + tla_log_locals! { + fees_amount: fees_amount_e8s, + neuron_id: id.id, + to_account: tla::account_to_tla(to_account), + disburse_amount: disburse_amount_e8s + }; let _result = self .ledger .transfer_funds( @@ -2786,6 +2794,15 @@ impl Governance { // user told us to disburse more than they had in their account (but // the burn still happened). let now = self.env.now(); + + tla_log_label!("DisburseNeuron_Stake"); + tla_log_locals! { + fees_amount: fees_amount_e8s, + neuron_id: id.id, + to_account: tla::account_to_tla(to_account), + disburse_amount: disburse_amount_e8s + }; + let block_height = self .ledger .transfer_funds( diff --git a/rs/nns/governance/src/governance/tla/common.rs b/rs/nns/governance/src/governance/tla/common.rs index f3dcf23e310..31fea3a59f3 100644 --- a/rs/nns/governance/src/governance/tla/common.rs +++ b/rs/nns/governance/src/governance/tla/common.rs @@ -52,3 +52,20 @@ pub fn function_domain_union( } ).collect() } + +pub fn function_range_union( + state_pairs: &[ResolvedStatePair], + field_name: &str, +) -> BTreeSet { + state_pairs.iter().flat_map(|pair| { + match (pair.start.get(field_name), pair.end.get(field_name)) { + (Some(TlaValue::Function(sf)), Some(TlaValue::Function(ef))) => { + sf.values().chain(ef.values()).cloned() + } + _ => { + panic!("Field {} not found in the start or end state, or not a function, when computing the union", field_name) + } + } + } + ).collect() +} diff --git a/rs/nns/governance/src/governance/tla/disburse_neuron.rs b/rs/nns/governance/src/governance/tla/disburse_neuron.rs new file mode 100644 index 00000000000..fdd0f04854a --- /dev/null +++ b/rs/nns/governance/src/governance/tla/disburse_neuron.rs @@ -0,0 +1,49 @@ +use super::{ + account_to_tla, extract_common_constants, function_domain_union, function_range_union, + post_process_trace, +}; +use crate::governance::governance_minting_account; +use lazy_static::lazy_static; +use std::collections::BTreeSet; +use std::iter::once; +use tla_instrumentation::{Label, TlaConstantAssignment, TlaValue, ToTla, Update, VarAssignment}; + +const PID: &str = "Disburse_Neuron"; +lazy_static! { + pub static ref DISBURSE_NEURON_DESC: Update = { + let default_locals = VarAssignment::new() + .add("neuron_id", 0_u64.to_tla_value()) + .add("disburse_amount", 0_u64.to_tla_value()) + .add("to_account", "".to_tla_value()) + .add("fees_amount", 0_u64.to_tla_value()); + Update { + default_start_locals: default_locals.clone(), + default_end_locals: default_locals, + start_label: Label::new("DisburseNeuron1"), + end_label: Label::new("Done"), + process_id: PID.to_string(), + canister_name: "governance".to_string(), + post_process: |trace| { + let mut constants = TlaConstantAssignment { + constants: extract_common_constants(PID, trace).into_iter().collect(), + }; + post_process_trace(trace); + constants.constants.insert( + "Minting_Account_Id".to_string(), + account_to_tla(governance_minting_account()), + ); + let all_accounts = function_range_union(trace, "to_account") + .union(&function_domain_union(trace, "neuron_id_by_account")) + .filter(|account| **account != "".to_tla_value()) + .chain(once(&account_to_tla(governance_minting_account()))) + .cloned() + .collect::>(); + + constants + .constants + .insert("Account_Ids".to_string(), all_accounts.to_tla_value()); + constants + }, + } + }; +} diff --git a/rs/nns/governance/src/governance/tla/mod.rs b/rs/nns/governance/src/governance/tla/mod.rs index 7c2d4b9131d..bf8fa7de13d 100644 --- a/rs/nns/governance/src/governance/tla/mod.rs +++ b/rs/nns/governance/src/governance/tla/mod.rs @@ -10,7 +10,7 @@ pub use tla_instrumentation::{ Destination, GlobalState, InstrumentationState, Label, ResolvedStatePair, TlaConstantAssignment, TlaValue, ToTla, Update, UpdateTrace, VarAssignment, }; -pub use tla_instrumentation_proc_macros::tla_update_method; +pub use tla_instrumentation_proc_macros::{tla_function, tla_update_method}; pub use tla_instrumentation::checker::{check_tla_code_link, PredicateDescription}; @@ -21,16 +21,18 @@ mod common; mod store; pub use common::{account_to_tla, opt_subaccount_to_tla, subaccount_to_tla}; -use common::{function_domain_union, governance_account_id}; +use common::{function_domain_union, function_range_union, governance_account_id}; pub use store::{TLA_INSTRUMENTATION_STATE, TLA_TRACES_LKEY, TLA_TRACES_MUTEX}; mod claim_neuron; +mod disburse_neuron; mod merge_neurons; mod spawn_neuron; mod spawn_neurons; mod split_neuron; pub use claim_neuron::CLAIM_NEURON_DESC; +pub use disburse_neuron::DISBURSE_NEURON_DESC; pub use merge_neurons::MERGE_NEURONS_DESC; pub use spawn_neuron::SPAWN_NEURON_DESC; pub use spawn_neurons::SPAWN_NEURONS_DESC; diff --git a/rs/nns/governance/tests/fake.rs b/rs/nns/governance/tests/fake.rs index 6917631dddf..c9bb3e04c01 100644 --- a/rs/nns/governance/tests/fake.rs +++ b/rs/nns/governance/tests/fake.rs @@ -42,7 +42,7 @@ pub const NODE_PROVIDER_REWARD: u64 = 10_000; #[cfg(feature = "tla")] use ic_nns_governance::governance::tla::{ - self, account_to_tla, Destination, ToTla, TLA_INSTRUMENTATION_STATE, + self, account_to_tla, tla_function, Destination, ToTla, TLA_INSTRUMENTATION_STATE, }; use ic_nns_governance::{tla_log_request, tla_log_response}; @@ -257,6 +257,7 @@ impl FakeDriver { #[async_trait] impl IcpLedger for FakeDriver { + #[cfg_attr(feature = "tla", tla_function(async_trait_fn = true))] async fn transfer_funds( &self, amount_e8s: u64, diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index e77a5f19802..7a11a736248 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -4703,6 +4703,7 @@ fn create_mature_neuron(dissolved: bool) -> (fake::FakeDriver, Governance, Neuro } #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_neuron_lifecycle() { let (driver, mut gov, neuron) = create_mature_neuron(true); @@ -4740,6 +4741,7 @@ fn test_neuron_lifecycle() { } #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_disburse_to_subaccount() { let (driver, mut gov, neuron) = create_mature_neuron(true); @@ -4833,6 +4835,7 @@ fn test_nns1_520() { } #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_disburse_to_main_account() { let (driver, mut gov, neuron) = create_mature_neuron(true); @@ -5430,6 +5433,7 @@ fn test_rate_limiting_neuron_creation() { } #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_cant_disburse_without_paying_fees() { let (driver, mut gov, neuron) = create_mature_neuron(true); diff --git a/rs/nns/governance/tla/Disburse_Neuron.tla b/rs/nns/governance/tla/Disburse_Neuron.tla new file mode 100644 index 00000000000..ed67d7312c2 --- /dev/null +++ b/rs/nns/governance/tla/Disburse_Neuron.tla @@ -0,0 +1,248 @@ +---- MODULE Disburse_Neuron ---- + +EXTENDS TLC, Integers, FiniteSets, Sequences, Variants + +CONSTANTS + Governance_Account_Ids, + Account_Ids, + Neuron_Ids, + Minting_Account_Id + +CONSTANTS + Disburse_Neuron_Process_Ids + +CONSTANTS + \* Minimum stake a neuron can have + MIN_STAKE, + \* The transfer fee charged by the ledger canister + TRANSACTION_FEE + +\* Initial value used for uninitialized accounts +DUMMY_ACCOUNT == "" + +\* @type: (a -> b, Set(a)) => a -> b; +Remove_Arguments(f, S) == [ x \in (DOMAIN f \ S) |-> f[x]] +Max(x, y) == IF x < y THEN y ELSE x + +request(caller, request_args) == [caller |-> caller, method_and_args |-> request_args] +transfer(from, to, amount, fee) == Variant("Transfer", [from |-> from, to |-> to, amount |-> amount, fee |-> fee]) + +o_deduct(disb_amount) == disb_amount + TRANSACTION_FEE + +(* --algorithm Governance_Ledger_Disburse_Neuron { + +variables + + neuron \in [{} -> {}]; + \* Used to decide whether we should refresh or claim a neuron + neuron_id_by_account \in [{} -> {}]; + \* The set of currently locked neurons + locks = {}; + \* The queue of messages sent from the governance canister to the ledger canister + governance_to_ledger = <<>>; + ledger_to_governance = {}; + spawning_neurons = FALSE; + +macro send_request(caller_id, request_args) { + governance_to_ledger := Append(governance_to_ledger, request(caller_id, request_args)) +}; + +macro update_fees(neuron_id, fees_amount) { + if(neuron[neuron_id].cached_stake > fees_amount) { + neuron := [neuron EXCEPT ![neuron_id] = [@ EXCEPT !.cached_stake = @ - fees_amount, !.fees = 0]] + } else { + neuron := [neuron EXCEPT ![neuron_id] = [@ EXCEPT !.cached_stake = 0, !.fees = 0]]; + }; +} + +macro finish() { + locks := locks \ {neuron_id}; + neuron_id := 0; + disburse_amount := 0; + to_account := DUMMY_ACCOUNT; + fees_amount := 0; + goto Done; +} + +process ( Disburse_Neuron \in Disburse_Neuron_Process_Ids ) + variable + \* These model the parameters of the call + neuron_id = 0; + disburse_amount = 0; + to_account = DUMMY_ACCOUNT; + \* The model the internal variables of the procedure. + \* Since +Cal doesn't allow multiple assignments to the same variable in a single block, + \* we also use temporary variables to simulate this and stay closer to the source code + fees_amount = 0; + { + DisburseNeuron1: + either { + \* Simulate calls that just fail early and don't change the state. + \* Not so useful for model checking, but needed to follow the code traces. + goto Done; + } or { + \* This models a few checks at the start of the Rust code. + \* We currently omit the check that the neuron is dissolved, and we plan to add this later. + \* We omit the other checks: who the caller is, whether the neuron is KYC verified, as well + \* as a few well-formedness checks (of the neuron and recipient account) as everything in + \* our model is well-formed. + \* Note that the user can request to disburse an arbitrary amount. This will only fail once + \* we send a message to the ledger. + with(nid \in DOMAIN(neuron) \ locks; amt \in Nat; account \in Account_Ids) { + neuron_id := nid; + disburse_amount := amt; + fees_amount := neuron[neuron_id].fees; + to_account := account; + \* The Rust code has a more elaborate code path to determine the disburse_amount, where the + \* amount argument is left unspecified in the call, and a default value is computed instead. + \* As this default value is in the range between 0 and the neuron's cached_stake, our + \* non-deterministic choice should cover this case. + \* The Rust code throws an error here if the neuron is locked. Instead, we prevent the Disburse_Neuron process from running. + \* This is OK since the Rust code doesn't change the canister's state before obtaining the lock (if it + \* did, the model wouldn't capture this and we could miss behaviors). + locks := locks \union {neuron_id}; + if(fees_amount > TRANSACTION_FEE) { + send_request(self, transfer(neuron[neuron_id].account, Minting_Account_Id, fees_amount, 0)); + } + else { + update_fees(neuron_id, fees_amount); + send_request(self, transfer(neuron[neuron_id].account, to_account, disburse_amount, TRANSACTION_FEE)); + goto DisburseNeuron_Stake_WaitForTransfer; + }; + }; + }; + DisburseNeuron_Fee_WaitForTransfer: + \* Note that we're here only because the fees amount was larger than the + \* transaction fee (otherwise, the goto above would have taken us to DisburseNeuron3) + with(answer \in { resp \in ledger_to_governance: resp.caller = self}) { + ledger_to_governance := ledger_to_governance \ {answer}; + if(answer.response = Variant("Fail", UNIT)) { + finish(); + } else { + update_fees(neuron_id, fees_amount); + send_request(self, transfer(neuron[neuron_id].account, to_account, disburse_amount, TRANSACTION_FEE)); + }; + }; + + DisburseNeuron_Stake_WaitForTransfer: + with(answer \in { resp \in ledger_to_governance: resp.caller = self}) { + ledger_to_governance := ledger_to_governance \ {answer}; + if(answer.response # Variant("Fail", UNIT)) { + neuron := [neuron EXCEPT![neuron_id].cached_stake = + Max(0, @ - (disburse_amount + TRANSACTION_FEE))]; + }; + }; + finish(); + } +} +*) +\* BEGIN TRANSLATION (chksum(pcal) = "49bb5804" /\ chksum(tla) = "fa8fb71a") +VARIABLES pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, spawning_neurons, neuron_id, disburse_amount, + to_account, fees_amount + +vars == << pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, spawning_neurons, neuron_id, disburse_amount, + to_account, fees_amount >> + +ProcSet == (Disburse_Neuron_Process_Ids) + +Init == (* Global variables *) + /\ neuron \in [{} -> {}] + /\ neuron_id_by_account \in [{} -> {}] + /\ locks = {} + /\ governance_to_ledger = <<>> + /\ ledger_to_governance = {} + /\ spawning_neurons = FALSE + (* Process Disburse_Neuron *) + /\ neuron_id = [self \in Disburse_Neuron_Process_Ids |-> 0] + /\ disburse_amount = [self \in Disburse_Neuron_Process_Ids |-> 0] + /\ to_account = [self \in Disburse_Neuron_Process_Ids |-> DUMMY_ACCOUNT] + /\ fees_amount = [self \in Disburse_Neuron_Process_Ids |-> 0] + /\ pc = [self \in ProcSet |-> "DisburseNeuron1"] + +DisburseNeuron1(self) == /\ pc[self] = "DisburseNeuron1" + /\ \/ /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED <> + \/ /\ \E nid \in DOMAIN(neuron) \ locks: + \E amt \in Nat: + \E account \in Account_Ids: + /\ neuron_id' = [neuron_id EXCEPT ![self] = nid] + /\ disburse_amount' = [disburse_amount EXCEPT ![self] = amt] + /\ fees_amount' = [fees_amount EXCEPT ![self] = neuron[neuron_id'[self]].fees] + /\ to_account' = [to_account EXCEPT ![self] = account] + /\ locks' = (locks \union {neuron_id'[self]}) + /\ IF fees_amount'[self] > TRANSACTION_FEE + THEN /\ governance_to_ledger' = Append(governance_to_ledger, request(self, (transfer(neuron[neuron_id'[self]].account, Minting_Account_Id, fees_amount'[self], 0)))) + /\ pc' = [pc EXCEPT ![self] = "DisburseNeuron_Fee_WaitForTransfer"] + /\ UNCHANGED neuron + ELSE /\ IF neuron[neuron_id'[self]].cached_stake > fees_amount'[self] + THEN /\ neuron' = [neuron EXCEPT ![neuron_id'[self]] = [@ EXCEPT !.cached_stake = @ - fees_amount'[self], !.fees = 0]] + ELSE /\ neuron' = [neuron EXCEPT ![neuron_id'[self]] = [@ EXCEPT !.cached_stake = 0, !.fees = 0]] + /\ governance_to_ledger' = Append(governance_to_ledger, request(self, (transfer(neuron'[neuron_id'[self]].account, to_account'[self], disburse_amount'[self], TRANSACTION_FEE)))) + /\ pc' = [pc EXCEPT ![self] = "DisburseNeuron_Stake_WaitForTransfer"] + /\ UNCHANGED << neuron_id_by_account, + ledger_to_governance, + spawning_neurons >> + +DisburseNeuron_Fee_WaitForTransfer(self) == /\ pc[self] = "DisburseNeuron_Fee_WaitForTransfer" + /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self}: + /\ ledger_to_governance' = ledger_to_governance \ {answer} + /\ IF answer.response = Variant("Fail", UNIT) + THEN /\ locks' = locks \ {neuron_id[self]} + /\ neuron_id' = [neuron_id EXCEPT ![self] = 0] + /\ disburse_amount' = [disburse_amount EXCEPT ![self] = 0] + /\ to_account' = [to_account EXCEPT ![self] = DUMMY_ACCOUNT] + /\ fees_amount' = [fees_amount EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << neuron, + governance_to_ledger >> + ELSE /\ IF neuron[neuron_id[self]].cached_stake > fees_amount[self] + THEN /\ neuron' = [neuron EXCEPT ![neuron_id[self]] = [@ EXCEPT !.cached_stake = @ - fees_amount[self], !.fees = 0]] + ELSE /\ neuron' = [neuron EXCEPT ![neuron_id[self]] = [@ EXCEPT !.cached_stake = 0, !.fees = 0]] + /\ governance_to_ledger' = Append(governance_to_ledger, request(self, (transfer(neuron'[neuron_id[self]].account, to_account[self], disburse_amount[self], TRANSACTION_FEE)))) + /\ pc' = [pc EXCEPT ![self] = "DisburseNeuron_Stake_WaitForTransfer"] + /\ UNCHANGED << locks, + neuron_id, + disburse_amount, + to_account, + fees_amount >> + /\ UNCHANGED << neuron_id_by_account, + spawning_neurons >> + +DisburseNeuron_Stake_WaitForTransfer(self) == /\ pc[self] = "DisburseNeuron_Stake_WaitForTransfer" + /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self}: + /\ ledger_to_governance' = ledger_to_governance \ {answer} + /\ IF answer.response # Variant("Fail", UNIT) + THEN /\ neuron' = [neuron EXCEPT![neuron_id[self]].cached_stake = + Max(0, @ - (disburse_amount[self] + TRANSACTION_FEE))] + ELSE /\ TRUE + /\ UNCHANGED neuron + /\ locks' = locks \ {neuron_id[self]} + /\ neuron_id' = [neuron_id EXCEPT ![self] = 0] + /\ disburse_amount' = [disburse_amount EXCEPT ![self] = 0] + /\ to_account' = [to_account EXCEPT ![self] = DUMMY_ACCOUNT] + /\ fees_amount' = [fees_amount EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << neuron_id_by_account, + governance_to_ledger, + spawning_neurons >> + +Disburse_Neuron(self) == DisburseNeuron1(self) + \/ DisburseNeuron_Fee_WaitForTransfer(self) + \/ DisburseNeuron_Stake_WaitForTransfer(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in Disburse_Neuron_Process_Ids: Disburse_Neuron(self)) + \/ Terminating + +Spec == Init /\ [][Next]_vars + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION + +==== diff --git a/rs/nns/governance/tla/Disburse_Neuron_Apalache.tla b/rs/nns/governance/tla/Disburse_Neuron_Apalache.tla new file mode 100644 index 00000000000..d1afcb1e985 --- /dev/null +++ b/rs/nns/governance/tla/Disburse_Neuron_Apalache.tla @@ -0,0 +1,70 @@ +---- MODULE Disburse_Neuron_Apalache ---- + +EXTENDS TLC, Variants + +(* +@typeAlias: proc = Str; +@typeAlias: account = Str; +@typeAlias: neuronId = Int; +@typeAlias: methodCall = Transfer({ from: $account, to: $account, amount: Int, fee: Int}) | AccountBalance({ account: $account }); +@typeAlias: methodResponse = Fail(UNIT) | TransferOk(UNIT) | BalanceQueryOk(Int); +*) +_type_alias_dummy == TRUE + +\* CODE_LINK_INSERT_CONSTANTS + +(* +CONSTANTS + \* @type: Set($account); + Account_Ids, + \* @type: Set($account); + Governance_Account_Ids, + \* @type: Set($neuronId); + Neuron_Ids, + \* @type: $account; + Minting_Account_Id + +CONSTANTS + \* @type: Set($proc); + Disburse_Neuron_Process_Ids + +CONSTANTS + \* Minimum stake a neuron can have + \* @type: Int; + MIN_STAKE, + \* The transfer fee charged by the ledger canister + \* @type: Int; + TRANSACTION_FEE +*) + +VARIABLES + \* @type: $neuronId -> {cached_stake: Int, account: $account, maturity: Int, fees: Int}; + neuron, + \* @type: $account -> $neuronId; + neuron_id_by_account, + \* @type: Set($neuronId); + locks, + \* @type: Seq({caller : $proc, method_and_args: $methodCall }); + governance_to_ledger, + \* @type: Set({caller: $proc, response: $methodResponse }); + ledger_to_governance, + \* @type: $proc -> Str; + pc, + \* Not used by this model, but it's a global variable used by spawn_neurons, so + \* it's the easiest to just add it to all the other models + \* @type: Bool; + spawning_neurons, + \* @type: $proc -> Int; + neuron_id, + \* @type: $proc -> Int; + disburse_amount, + \* @type: $proc -> $account; + to_account, + \* @type: $proc -> Int; + fees_amount + +MOD == INSTANCE Disburse_Neuron + +Next == [MOD!Next]_MOD!vars + +==== diff --git a/rs/nns/governance/tla/Spawn_Neurons.tla b/rs/nns/governance/tla/Spawn_Neurons.tla index 737e398fa5e..3e06d5a8b43 100644 --- a/rs/nns/governance/tla/Spawn_Neurons.tla +++ b/rs/nns/governance/tla/Spawn_Neurons.tla @@ -57,7 +57,7 @@ macro loop_iteration(new_locks) { ]; governance_to_ledger := Append(governance_to_ledger, request(self, transfer(Minting_Account_Id, account, neuron_stake, 0))); - goto WaitForTransfer; + goto SpawnNeurons_Start_WaitForTransfer; }; } @@ -75,7 +75,7 @@ process (Spawn_Neurons \in Spawn_Neurons_Process_Ids) await ready_to_spawn_ids # {}; spawning_neurons := TRUE; loop_iteration(locks); - WaitForTransfer: + SpawnNeurons_Start_WaitForTransfer: with(answer \in { resp \in ledger_to_governance: resp.caller = self }; \* Work around PlusCal not being able to assing to the same variable twice in the same block new_locks = IF answer.response # Variant("Fail", UNIT) @@ -98,7 +98,7 @@ process (Spawn_Neurons \in Spawn_Neurons_Process_Ids) } *) -\* BEGIN TRANSLATION (chksum(pcal) = "21b445f4" /\ chksum(tla) = "5862c78c") +\* BEGIN TRANSLATION (chksum(pcal) = "90f0999" /\ chksum(tla) = "313ea5da") VARIABLES pc, neuron, neuron_id_by_account, locks, governance_to_ledger, ledger_to_governance, spawning_neurons, neuron_id, ready_to_spawn_ids @@ -137,40 +137,41 @@ SpawnNeurons_Start(self) == /\ pc[self] = "SpawnNeurons_Start" ] /\ governance_to_ledger' = Append(governance_to_ledger, request(self, transfer(Minting_Account_Id, account, neuron_stake, 0))) - /\ pc' = [pc EXCEPT ![self] = "WaitForTransfer"] + /\ pc' = [pc EXCEPT ![self] = "SpawnNeurons_Start_WaitForTransfer"] /\ UNCHANGED << neuron_id_by_account, ledger_to_governance >> -WaitForTransfer(self) == /\ pc[self] = "WaitForTransfer" - /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self }: - LET new_locks == IF answer.response # Variant("Fail", UNIT) - THEN locks \ {neuron_id[self]} - ELSE locks IN - /\ ledger_to_governance' = ledger_to_governance \ {answer} - /\ ready_to_spawn_ids' = [ready_to_spawn_ids EXCEPT ![self] = ready_to_spawn_ids[self] \ {neuron_id[self]}] - /\ IF ready_to_spawn_ids'[self] = {} - THEN /\ spawning_neurons' = FALSE - /\ locks' = new_locks - /\ neuron_id' = [neuron_id EXCEPT ![self] = 0] - /\ pc' = [pc EXCEPT ![self] = "SpawnNeurons_Start"] - /\ UNCHANGED << neuron, - governance_to_ledger >> - ELSE /\ \E nid \in ready_to_spawn_ids'[self] \ locks: - LET neuron_stake == (neuron[nid].maturity * (BASIS_POINTS_PER_UNITY + MATURITY_BASIS_POINTS)) \div BASIS_POINTS_PER_UNITY IN - LET account == neuron[nid].account IN - /\ neuron_id' = [neuron_id EXCEPT ![self] = nid] - /\ locks' = (new_locks \union {neuron_id'[self]}) - /\ neuron' = [ neuron EXCEPT - ![neuron_id'[self]].maturity = 0, - ![neuron_id'[self]].cached_stake = neuron_stake - ] - /\ governance_to_ledger' = Append(governance_to_ledger, - request(self, transfer(Minting_Account_Id, account, neuron_stake, 0))) - /\ pc' = [pc EXCEPT ![self] = "WaitForTransfer"] - /\ UNCHANGED spawning_neurons - /\ UNCHANGED neuron_id_by_account - -Spawn_Neurons(self) == SpawnNeurons_Start(self) \/ WaitForTransfer(self) +SpawnNeurons_Start_WaitForTransfer(self) == /\ pc[self] = "SpawnNeurons_Start_WaitForTransfer" + /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self }: + LET new_locks == IF answer.response # Variant("Fail", UNIT) + THEN locks \ {neuron_id[self]} + ELSE locks IN + /\ ledger_to_governance' = ledger_to_governance \ {answer} + /\ ready_to_spawn_ids' = [ready_to_spawn_ids EXCEPT ![self] = ready_to_spawn_ids[self] \ {neuron_id[self]}] + /\ IF ready_to_spawn_ids'[self] = {} + THEN /\ spawning_neurons' = FALSE + /\ locks' = new_locks + /\ neuron_id' = [neuron_id EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "SpawnNeurons_Start"] + /\ UNCHANGED << neuron, + governance_to_ledger >> + ELSE /\ \E nid \in ready_to_spawn_ids'[self] \ locks: + LET neuron_stake == (neuron[nid].maturity * (BASIS_POINTS_PER_UNITY + MATURITY_BASIS_POINTS)) \div BASIS_POINTS_PER_UNITY IN + LET account == neuron[nid].account IN + /\ neuron_id' = [neuron_id EXCEPT ![self] = nid] + /\ locks' = (new_locks \union {neuron_id'[self]}) + /\ neuron' = [ neuron EXCEPT + ![neuron_id'[self]].maturity = 0, + ![neuron_id'[self]].cached_stake = neuron_stake + ] + /\ governance_to_ledger' = Append(governance_to_ledger, + request(self, transfer(Minting_Account_Id, account, neuron_stake, 0))) + /\ pc' = [pc EXCEPT ![self] = "SpawnNeurons_Start_WaitForTransfer"] + /\ UNCHANGED spawning_neurons + /\ UNCHANGED neuron_id_by_account + +Spawn_Neurons(self) == SpawnNeurons_Start(self) + \/ SpawnNeurons_Start_WaitForTransfer(self) (* Allow infinite stuttering to prevent deadlock on termination. *) Terminating == /\ \A self \in ProcSet: pc[self] = "Done" diff --git a/rs/nns/governance/tla/Split_Neuron.tla b/rs/nns/governance/tla/Split_Neuron.tla index fb31c81c630..b9649cea161 100644 --- a/rs/nns/governance/tla/Split_Neuron.tla +++ b/rs/nns/governance/tla/Split_Neuron.tla @@ -4,15 +4,15 @@ EXTENDS TLC, Sequences, Naturals, FiniteSets, Variants CONSTANT FRESH_NEURON_ID(_) -CONSTANTS - Governance_Account_Ids, +CONSTANTS + Governance_Account_Ids, Minting_Account_Id, Neuron_Ids -CONSTANTS +CONSTANTS Split_Neuron_Process_Ids -CONSTANTS +CONSTANTS \* Minimum stake a neuron can have MIN_STAKE, \* The transfer fee charged by the ledger canister @@ -31,8 +31,8 @@ transfer(from, to, amount, fee) == Variant("Transfer", [from |-> from, to |-> to (* --algorithm Governance_Ledger_Split_Neuron { -variables - +variables + neuron \in [{} -> {}]; \* Used to decide whether we should refresh or claim a neuron neuron_id_by_account \in [{} -> {}]; @@ -61,14 +61,14 @@ process ( Split_Neuron \in Split_Neuron_Process_Ids ) { SplitNeuron1: either { - \* Simulate calls that just fail early and don't change the state. + \* Simulate calls that just fail early and don't change the state. \* Not so useful for model checking, but needed to follow the code traces. goto Done; } or { \* Need to make sure there is an element of Split_Neuron_Account_Ids for each \* member of Split_Neuron_Process_Ids - with(nid \in DOMAIN(neuron) \ locks; - amt \in (MIN_STAKE+TRANSACTION_FEE)..neuron[nid].cached_stake; + with(nid \in DOMAIN(neuron) \ locks; + amt \in (MIN_STAKE+TRANSACTION_FEE)..neuron[nid].cached_stake; fresh_account_id \in Governance_Account_Ids \ {neuron[n].account : n \in DOMAIN(neuron)}; ) { sn_parent_neuron_id := nid; @@ -85,15 +85,15 @@ process ( Split_Neuron \in Split_Neuron_Process_Ids ) \* as the locks are taken sequentially there; here, we're sure that these neuron IDs differ, \* so we omit the extra check. locks := locks \union {sn_parent_neuron_id, sn_child_neuron_id}; - neuron := sn_child_neuron_id :> [ cached_stake |-> 0, account |-> sn_child_account_id, fees |-> 0, maturity |-> 0 ] @@ + neuron := sn_child_neuron_id :> [ cached_stake |-> 0, account |-> sn_child_account_id, fees |-> 0, maturity |-> 0 ] @@ [neuron EXCEPT ![sn_parent_neuron_id] = [@ EXCEPT !.cached_stake = @ - sn_amount ] ]; neuron_id_by_account := sn_child_account_id :> sn_child_neuron_id @@ neuron_id_by_account; - governance_to_ledger := Append(governance_to_ledger, + governance_to_ledger := Append(governance_to_ledger, request(self, transfer(neuron[sn_parent_neuron_id].account, neuron[sn_child_neuron_id].account, sn_amount - TRANSACTION_FEE, TRANSACTION_FEE))); }; }; - WaitForTransfer: + SplitNeuron1_WaitForTransfer: with(answer \in { resp \in ledger_to_governance: resp.caller = self}) { ledger_to_governance := ledger_to_governance \ {answer}; if(answer.response = Variant("Fail", UNIT)) { @@ -105,7 +105,7 @@ process ( Split_Neuron \in Split_Neuron_Process_Ids ) with( maturity_to_transfer = (neuron[sn_parent_neuron_id].maturity * sn_amount) \div (neuron[sn_parent_neuron_id].cached_stake + sn_amount) ) { - neuron := [neuron EXCEPT + neuron := [neuron EXCEPT ![sn_child_neuron_id] = [ @ EXCEPT !.cached_stake = sn_amount - TRANSACTION_FEE, !.maturity = maturity_to_transfer ], ![sn_parent_neuron_id] = [ @ EXCEPT !.maturity = @ - maturity_to_transfer ]]; } @@ -115,15 +115,15 @@ process ( Split_Neuron \in Split_Neuron_Process_Ids ) sn_reset_local_vars(); }; -} +} *) -\* BEGIN TRANSLATION (chksum(pcal) = "2f818cef" /\ chksum(tla) = "a6539bfe") -VARIABLES pc, neuron, neuron_id_by_account, locks, governance_to_ledger, - ledger_to_governance, sn_parent_neuron_id, sn_amount, +\* BEGIN TRANSLATION (chksum(pcal) = "15d571de" /\ chksum(tla) = "521933de") +VARIABLES pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, sn_parent_neuron_id, sn_amount, sn_child_neuron_id, sn_child_account_id -vars == << pc, neuron, neuron_id_by_account, locks, governance_to_ledger, - ledger_to_governance, sn_parent_neuron_id, sn_amount, +vars == << pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, sn_parent_neuron_id, sn_amount, sn_child_neuron_id, sn_child_account_id >> ProcSet == (Split_Neuron_Process_Ids) @@ -145,13 +145,13 @@ SplitNeuron1(self) == /\ pc[self] = "SplitNeuron1" /\ \/ /\ pc' = [pc EXCEPT ![self] = "Done"] /\ UNCHANGED <> \/ /\ \E nid \in DOMAIN(neuron) \ locks: - \E amt \in 0..neuron[nid].cached_stake: + \E amt \in (MIN_STAKE+TRANSACTION_FEE)..neuron[nid].cached_stake: \E fresh_account_id \in Governance_Account_Ids \ {neuron[n].account : n \in DOMAIN(neuron)}: /\ sn_parent_neuron_id' = [sn_parent_neuron_id EXCEPT ![self] = nid] /\ sn_amount' = [sn_amount EXCEPT ![self] = amt] /\ sn_child_account_id' = [sn_child_account_id EXCEPT ![self] = fresh_account_id] /\ sn_child_neuron_id' = [sn_child_neuron_id EXCEPT ![self] = FRESH_NEURON_ID(DOMAIN(neuron))] - /\ Assert(sn_child_neuron_id'[self] \notin locks, + /\ Assert(sn_child_neuron_id'[self] \notin locks, "Failure of assertion at line 80, column 13.") /\ (sn_amount'[self] >= MIN_STAKE + TRANSACTION_FEE /\ neuron[sn_parent_neuron_id'[self]].cached_stake - neuron[sn_parent_neuron_id'[self]].fees >= MIN_STAKE + sn_amount'[self]) /\ locks' = (locks \union {sn_parent_neuron_id'[self], sn_child_neuron_id'[self]}) @@ -160,30 +160,31 @@ SplitNeuron1(self) == /\ pc[self] = "SplitNeuron1" /\ neuron_id_by_account' = (sn_child_account_id'[self] :> sn_child_neuron_id'[self] @@ neuron_id_by_account) /\ governance_to_ledger' = Append(governance_to_ledger, request(self, transfer(neuron'[sn_parent_neuron_id'[self]].account, neuron'[sn_child_neuron_id'[self]].account, sn_amount'[self] - TRANSACTION_FEE, TRANSACTION_FEE))) - /\ pc' = [pc EXCEPT ![self] = "WaitForTransfer"] + /\ pc' = [pc EXCEPT ![self] = "SplitNeuron1_WaitForTransfer"] /\ UNCHANGED ledger_to_governance -WaitForTransfer(self) == /\ pc[self] = "WaitForTransfer" - /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self}: - /\ ledger_to_governance' = ledger_to_governance \ {answer} - /\ IF answer.response = Variant("Fail", UNIT) - THEN /\ neuron' = ( LET new_n == Remove_Arguments(neuron, {sn_child_neuron_id[self]}) - IN [new_n EXCEPT ![sn_parent_neuron_id[self]] = [ @ EXCEPT !.cached_stake = @ + sn_amount[self] ] ]) - /\ neuron_id_by_account' = Remove_Arguments(neuron_id_by_account, {sn_child_account_id[self]}) - ELSE /\ LET maturity_to_transfer == (neuron[sn_parent_neuron_id[self]].maturity * sn_amount[self]) \div (neuron[sn_parent_neuron_id[self]].cached_stake + sn_amount[self]) IN - neuron' = [neuron EXCEPT - ![sn_child_neuron_id[self]] = [ @ EXCEPT !.cached_stake = sn_amount[self] - TRANSACTION_FEE, !.maturity = maturity_to_transfer ], - ![sn_parent_neuron_id[self]] = [ @ EXCEPT !.maturity = @ - maturity_to_transfer ]] - /\ UNCHANGED neuron_id_by_account - /\ locks' = locks \ {sn_child_neuron_id[self], sn_parent_neuron_id[self]} - /\ sn_parent_neuron_id' = [sn_parent_neuron_id EXCEPT ![self] = 0] - /\ sn_amount' = [sn_amount EXCEPT ![self] = 0] - /\ sn_child_neuron_id' = [sn_child_neuron_id EXCEPT ![self] = 0] - /\ sn_child_account_id' = [sn_child_account_id EXCEPT ![self] = DUMMY_ACCOUNT] - /\ pc' = [pc EXCEPT ![self] = "Done"] - /\ UNCHANGED governance_to_ledger - -Split_Neuron(self) == SplitNeuron1(self) \/ WaitForTransfer(self) +SplitNeuron1_WaitForTransfer(self) == /\ pc[self] = "SplitNeuron1_WaitForTransfer" + /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self}: + /\ ledger_to_governance' = ledger_to_governance \ {answer} + /\ IF answer.response = Variant("Fail", UNIT) + THEN /\ neuron' = ( LET new_n == Remove_Arguments(neuron, {sn_child_neuron_id[self]}) + IN [new_n EXCEPT ![sn_parent_neuron_id[self]] = [ @ EXCEPT !.cached_stake = @ + sn_amount[self] ] ]) + /\ neuron_id_by_account' = Remove_Arguments(neuron_id_by_account, {sn_child_account_id[self]}) + ELSE /\ LET maturity_to_transfer == (neuron[sn_parent_neuron_id[self]].maturity * sn_amount[self]) \div (neuron[sn_parent_neuron_id[self]].cached_stake + sn_amount[self]) IN + neuron' = [neuron EXCEPT + ![sn_child_neuron_id[self]] = [ @ EXCEPT !.cached_stake = sn_amount[self] - TRANSACTION_FEE, !.maturity = maturity_to_transfer ], + ![sn_parent_neuron_id[self]] = [ @ EXCEPT !.maturity = @ - maturity_to_transfer ]] + /\ UNCHANGED neuron_id_by_account + /\ locks' = locks \ {sn_child_neuron_id[self], sn_parent_neuron_id[self]} + /\ sn_parent_neuron_id' = [sn_parent_neuron_id EXCEPT ![self] = 0] + /\ sn_amount' = [sn_amount EXCEPT ![self] = 0] + /\ sn_child_neuron_id' = [sn_child_neuron_id EXCEPT ![self] = 0] + /\ sn_child_account_id' = [sn_child_account_id EXCEPT ![self] = DUMMY_ACCOUNT] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED governance_to_ledger + +Split_Neuron(self) == SplitNeuron1(self) + \/ SplitNeuron1_WaitForTransfer(self) (* Allow infinite stuttering to prevent deadlock on termination. *) Terminating == /\ \A self \in ProcSet: pc[self] = "Done" @@ -196,7 +197,7 @@ Spec == Init /\ [][Next]_vars Termination == <>(\A self \in ProcSet: pc[self] = "Done") -\* END TRANSLATION +\* END TRANSLATION ==== diff --git a/rs/tla_instrumentation/BUILD.bazel b/rs/tla_instrumentation/BUILD.bazel index 372be6df33f..82649186435 100644 --- a/rs/tla_instrumentation/BUILD.bazel +++ b/rs/tla_instrumentation/BUILD.bazel @@ -73,7 +73,10 @@ rust_test( "TLA_APALACHE_BIN": "$(rootpath @tla_apalache//:bin/apalache-mc)", "TLA_MODULES": "$(locations :tla_models)", }, - proc_macro_deps = [":proc_macros"], + proc_macro_deps = [ + ":proc_macros", + "@crate_index//:async-trait", + ], toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"], deps = [ ":local_key", diff --git a/rs/tla_instrumentation/tla_instrumentation/Cargo.toml b/rs/tla_instrumentation/tla_instrumentation/Cargo.toml index 88fd1e7f227..601256e2254 100644 --- a/rs/tla_instrumentation/tla_instrumentation/Cargo.toml +++ b/rs/tla_instrumentation/tla_instrumentation/Cargo.toml @@ -14,6 +14,7 @@ sha2 = { workspace = true } uuid = { workspace = true } [dev-dependencies] +async-trait = { workspace = true } tokio-test = { workspace = true } local_key = { path = "../local_key" } tla_instrumentation_proc_macros = { path = "../tla_instrumentation_proc_macros" } diff --git a/rs/tla_instrumentation/tla_instrumentation/tests/multiple_calls.rs b/rs/tla_instrumentation/tla_instrumentation/tests/multiple_calls.rs index d97215e7f82..ed2b4fabe5c 100644 --- a/rs/tla_instrumentation/tla_instrumentation/tests/multiple_calls.rs +++ b/rs/tla_instrumentation/tla_instrumentation/tests/multiple_calls.rs @@ -12,6 +12,8 @@ use tla_instrumentation::{ }; use tla_instrumentation_proc_macros::{tla_function, tla_update_method}; +use async_trait::async_trait; + mod common; use common::check_tla_trace; @@ -121,36 +123,47 @@ struct StructCanister { static mut GLOBAL: StructCanister = StructCanister { counter: 0 }; -#[tla_function] -async fn call_maker() { - tla_log_request!( - "WaitForResponse", - Destination::new("othercan"), - "Target_Method", - 2_u64 - ); - tla_log_response!( - Destination::new("othercan"), - TlaValue::Variant { - tag: "Ok".to_string(), - value: Box::new(3_u64.to_tla_value()) - } - ); +struct CallMaker {} + +#[async_trait] +trait CallMakerTrait { + async fn call_maker(&self); +} + +#[async_trait] +impl CallMakerTrait for CallMaker { + #[tla_function(async_trait_fn = true)] + async fn call_maker(&self) { + tla_log_request!( + "WaitForResponse", + Destination::new("othercan"), + "Target_Method", + 2_u64 + ); + tla_log_response!( + Destination::new("othercan"), + TlaValue::Variant { + tag: "Ok".to_string(), + value: Box::new(3_u64.to_tla_value()) + } + ); + } } impl StructCanister { #[tla_update_method(my_f_desc())] pub async fn my_method(&mut self) { self.counter += 1; + let call_maker = CallMaker {}; let mut my_local: u64 = self.counter; tla_log_locals! {my_local: my_local}; tla_log_label!("Phase1"); - call_maker().await; + call_maker.call_maker().await; self.counter += 1; my_local = self.counter; tla_log_locals! {my_local: my_local}; tla_log_label!("Phase2"); - call_maker().await; + call_maker.call_maker().await; self.counter += 1; my_local = self.counter; // Note that this would not be necessary (and would be an error) if diff --git a/rs/tla_instrumentation/tla_instrumentation_proc_macros/src/lib.rs b/rs/tla_instrumentation/tla_instrumentation_proc_macros/src/lib.rs index 0935869facf..a729c93cf47 100644 --- a/rs/tla_instrumentation/tla_instrumentation_proc_macros/src/lib.rs +++ b/rs/tla_instrumentation/tla_instrumentation_proc_macros/src/lib.rs @@ -1,7 +1,7 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use syn::{parse_macro_input, ItemFn}; +use syn::{parse_macro_input, AttributeArgs, ItemFn, Lit, Meta, NestedMeta}; /// Used to annotate top-level methods (which de-facto start an update call) #[proc_macro_attribute] @@ -199,11 +199,18 @@ pub fn tla_update_method(attr: TokenStream, item: TokenStream) -> TokenStream { output.into() } +/// Instructs the TLA instrumentation to "stack" PlusCal labels when entering a function. +/// This is useful when a Rust function makes inter-canister calls and is called from multiple +/// locations in the same update method. In this case, we want the labels in the TLA trace to +/// reflect the different call sites. We do this by "stacking" the labels; for example, if an +/// update method `upd` calls a function `foo` from two different locations, where the first location +/// has the label `A` and the second location has the label `B`, and `foo` adds a label `Call` when +/// it performs the call, then the labels in the TLA trace will be `A_Call` and `B_Call`. #[proc_macro_attribute] -pub fn tla_function(_attr: TokenStream, item: TokenStream) -> TokenStream { +pub fn tla_function(attr: TokenStream, item: TokenStream) -> TokenStream { // Parse the input tokens of the attribute and the function let input_fn = parse_macro_input!(item as ItemFn); - + let args = parse_macro_input!(attr as AttributeArgs); let mut modified_fn = input_fn.clone(); // Deconstruct the function elements @@ -211,61 +218,86 @@ pub fn tla_function(_attr: TokenStream, item: TokenStream) -> TokenStream { attrs, vis, sig, - block: _, + block: body, } = input_fn; let mangled_name = syn::Ident::new(&format!("_tla_impl_{}", sig.ident), sig.ident.span()); modified_fn.sig.ident = mangled_name.clone(); - let has_receiver = sig.inputs.iter().any(|arg| match arg { - syn::FnArg::Receiver(_) => true, - syn::FnArg::Typed(_) => false, - }); - // Creating the modified original function which calls f_impl - let args: Vec<_> = sig - .inputs - .iter() - .filter_map(|arg| match arg { - syn::FnArg::Receiver(_) => None, - syn::FnArg::Typed(pat_type) => Some(&*pat_type.pat), - }) - .collect(); - let asyncness = sig.asyncness; - - let call = match (asyncness.is_some(), has_receiver) { - (true, true) => quote! { self.#mangled_name(#(#args),*).await }, - (true, false) => quote! { #mangled_name(#(#args),*).await }, - (false, true) => quote! { self.#mangled_name(#(#args),*) }, - (false, false) => quote! { #mangled_name(#(#args),*) }, - }; - - let output = quote! { - #modified_fn - - #(#attrs)* #vis #sig { - TLA_INSTRUMENTATION_STATE.try_with(|state| { - { - let mut handler_state = state.handler_state.borrow_mut(); - handler_state.context.call_function(); + let mut async_trait_fn = false; + + // Examine each attribute argument + for arg in args { + if let NestedMeta::Meta(Meta::NameValue(name_value)) = arg { + if name_value.path.is_ident("async_trait_fn") { + if let Lit::Bool(lit_bool) = name_value.lit { + async_trait_fn = lit_bool.value(); } - }).unwrap_or_else(|e| - // TODO(RES-152): fail if there's an error and if we're in some kind of strict mode? - () - ); + } + } + } + + // We need three different ways to invoke the wrapped function. + // One is when the function is in an async_trait, as this will get desugared + // into a Pin>. There, we will want to await the result even though + // the function itself is not async. The other is when the function is async, + // in which case we want to await the result. The last is when the function is + // synchronous, in which case we just want to call it. + let call = if async_trait_fn { + quote! { + #body.await + } + } else if asyncness.is_some() { + quote! { + (|| async move { + #body + })().await + } + } else { + quote! { + (move || { + #body + })() + } + }; + let with_instrumentation = quote! { + TLA_INSTRUMENTATION_STATE.try_with(|state| { + { + let mut handler_state = state.handler_state.borrow_mut(); + handler_state.context.call_function(); + } + }).unwrap_or_else(|e| { + // TODO(RES-152): fail if there's an error and if we're in some kind of strict mode? + println!("Couldn't find TLA_INSTRUMENTATION_STATE when calling a tla_function; ignoring for the moment"); + }); + let res = #call; + TLA_INSTRUMENTATION_STATE.try_with(|state| { + { + let mut handler_state = state.handler_state.borrow_mut(); + handler_state.context.return_from_function(); + } + }).unwrap_or_else(|e| + // TODO(RES-152): fail if there's an error and if we're in some kind of strict mode? + () + ); + res + }; - let res = #call; - TLA_INSTRUMENTATION_STATE.try_with(|state| { - { - let mut handler_state = state.handler_state.borrow_mut(); - handler_state.context.return_from_function(); - } - }).unwrap_or_else(|e| - // TODO(RES-152): fail if there's an error and if we're in some kind of strict mode? - () - ); - res + let output = if async_trait_fn { + quote! { + #(#attrs)* #vis #sig { + Box::pin(async move { + #with_instrumentation + }) + } + } + } else { + quote! { + #(#attrs)* #vis #sig { + #with_instrumentation + } } }; From d469ea2221d2b450259f27880c5f9d724e7d9862 Mon Sep 17 00:00:00 2001 From: Carly Gundy <47304080+cgundy@users.noreply.github.com> Date: Mon, 13 Jan 2025 13:15:08 +0100 Subject: [PATCH 60/98] chore(IDX): generate-ci updates (#3413) Adding `exit 1` to the script if a commit needs to be pushed to signal that the current state of the code is incorrect. --------- Co-authored-by: IDX GitHub Automation --- .github/workflows/ci-generate-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-generate-ci.yml b/.github/workflows/ci-generate-ci.yml index 17fc90db937..1ecf196331e 100644 --- a/.github/workflows/ci-generate-ci.yml +++ b/.github/workflows/ci-generate-ci.yml @@ -47,10 +47,11 @@ jobs: if [ -n "$(git status --porcelain)" ]; then git config --global user.name "IDX GitHub Automation" - git config --global user.email "IDX GitHub Automation" + git config --global user.email "idx@dfinity.org" git add . git commit -m "IDX GitHub Automation" git push + exit 1 else echo "git working tree clean - no changes to be committed" fi From cf2f2cc97af7790331604296a8341e2e6d20744e Mon Sep 17 00:00:00 2001 From: Rostislav Rumenov Date: Mon, 13 Jan 2025 02:20:52 -1000 Subject: [PATCH 61/98] fix: Make the consensus manager API resemble a classic channel interface (#3233) The MR brings the consensus manager API closer to a normal channel API --------- Co-authored-by: Daniel Sharifi <40335219+DSharifi@users.noreply.github.com> --- rs/p2p/artifact_manager/src/lib.rs | 67 ++++----- rs/p2p/consensus_manager/src/lib.rs | 38 ++++- rs/p2p/consensus_manager/src/receiver.rs | 1 + rs/p2p/test_utils/src/lib.rs | 29 ++-- rs/p2p/test_utils/src/turmoil.rs | 40 +++-- rs/replica/setup_ic_network/src/lib.rs | 183 +++++++++++------------ 6 files changed, 178 insertions(+), 180 deletions(-) diff --git a/rs/p2p/artifact_manager/src/lib.rs b/rs/p2p/artifact_manager/src/lib.rs index 3fd2cd14d74..92949b68976 100644 --- a/rs/p2p/artifact_manager/src/lib.rs +++ b/rs/p2p/artifact_manager/src/lib.rs @@ -20,13 +20,11 @@ use std::{ time::Duration, }; use tokio::{ - sync::mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender}, + sync::mpsc::{Sender, UnboundedReceiver}, time::timeout, }; use tracing::instrument; -type ArtifactEventSender = UnboundedSender>; - /// Metrics for a client artifact processor. struct ArtifactProcessorMetrics { /// The processing time histogram. @@ -136,26 +134,18 @@ pub fn run_artifact_processor( time_source: Arc, metrics_registry: MetricsRegistry, client: Box>, - send_advert: Sender>, + outbound_tx: Sender>, + inbound_rx: UnboundedReceiver>, initial_artifacts: Vec, -) -> (Box, ArtifactEventSender) { - // Making this channel bounded can be problematic since we don't have true multiplexing - // of P2P messages. - // Possible scenario is - adverts+chunks arrive on the same channel, slow consensus - // will result on slow consuption of chunks. Slow consumption of chunks will in turn - // result in slower consumptions of adverts. Ideally adverts are consumed at rate - // independent of consensus. - #[allow(clippy::disallowed_methods)] - let (sender, receiver) = unbounded_channel(); +) -> Box { let shutdown = Arc::new(AtomicBool::new(false)); - // Spawn the processor thread let shutdown_cl = shutdown.clone(); let handle = ThreadBuilder::new() .name(format!("{}_Processor", Artifact::NAME)) .spawn(move || { for artifact in initial_artifacts { - let _ = send_advert.blocking_send(ArtifactTransmit::Deliver(ArtifactWithOpt { + let _ = outbound_tx.blocking_send(ArtifactTransmit::Deliver(ArtifactWithOpt { artifact, is_latency_sensitive: false, })); @@ -163,18 +153,14 @@ pub fn run_artifact_processor( process_messages( time_source, client, - send_advert, - receiver, + outbound_tx, + inbound_rx, ArtifactProcessorMetrics::new(metrics_registry, Artifact::NAME.to_string()), shutdown_cl, ); }) .unwrap(); - - ( - Box::new(ArtifactProcessorJoinGuard::new(handle, shutdown)), - sender, - ) + Box::new(ArtifactProcessorJoinGuard::new(handle, shutdown)) } // The artifact processor thread loop @@ -243,7 +229,8 @@ const ARTIFACT_MANAGER_TIMER_DURATION_MSEC: u64 = 200; pub fn create_ingress_handlers< PoolIngress: MutablePool + Send + Sync + ValidatedPoolReader + 'static, >( - send_advert: Sender>, + outbound_tx: Sender>, + inbound_rx: UnboundedReceiver>, time_source: Arc, ingress_pool: Arc>, ingress_handler: Arc< @@ -254,46 +241,41 @@ pub fn create_ingress_handlers< + Sync, >, metrics_registry: MetricsRegistry, -) -> ( - UnboundedSender>, - Box, -) { +) -> Box { let client = IngressProcessor::new(ingress_pool.clone(), ingress_handler); - let (jh, sender) = run_artifact_processor( + run_artifact_processor( time_source.clone(), metrics_registry, Box::new(client), - send_advert, + outbound_tx, + inbound_rx, vec![], - ); - (sender, jh) + ) } -/// Starts the event loop that pools consensus for updates on what needs to be replicated. +/// Starts the event loop that polls consensus for updates on what needs to be replicated. pub fn create_artifact_handler< Artifact: IdentifiableArtifact + Send + Sync + 'static, Pool: MutablePool + Send + Sync + ValidatedPoolReader + 'static, C: PoolMutationsProducer>::Mutations> + 'static, >( - send_advert: Sender>, + outbound_tx: Sender>, + inbound_rx: UnboundedReceiver>, change_set_producer: C, time_source: Arc, pool: Arc>, metrics_registry: MetricsRegistry, -) -> ( - UnboundedSender>, - Box, -) { +) -> Box { let inital_artifacts: Vec<_> = pool.read().unwrap().get_all_for_broadcast().collect(); let client = Processor::new(pool, change_set_producer); - let (jh, sender) = run_artifact_processor( + run_artifact_processor( time_source.clone(), metrics_registry, Box::new(client), - send_advert, + outbound_tx, + inbound_rx, inital_artifacts, - ); - (sender, jh) + ) } // TODO: make it private, it is used only for tests outside of this crate @@ -472,11 +454,14 @@ mod tests { let time_source = Arc::new(SysTimeSource::new()); let (send_tx, mut send_rx) = tokio::sync::mpsc::channel(100); + #[allow(clippy::disallowed_methods)] + let (_, inbound_rx) = tokio::sync::mpsc::unbounded_channel(); run_artifact_processor::( time_source, MetricsRegistry::default(), Box::new(DummyProcessor), send_tx, + inbound_rx, (0..10).map(Into::into).collect(), ); diff --git a/rs/p2p/consensus_manager/src/lib.rs b/rs/p2p/consensus_manager/src/lib.rs index bb2ee7d8bcf..3b957c05fde 100644 --- a/rs/p2p/consensus_manager/src/lib.rs +++ b/rs/p2p/consensus_manager/src/lib.rs @@ -16,7 +16,7 @@ use phantom_newtype::AmountOf; use tokio::{ runtime::Handle, sync::{ - mpsc::{Receiver, UnboundedSender}, + mpsc::{Receiver, Sender, UnboundedReceiver, UnboundedSender}, watch, }, }; @@ -28,7 +28,13 @@ mod sender; type StartConsensusManagerFn = Box, watch::Receiver) -> Vec>; -pub struct ConsensusManagerBuilder { +/// Same order of magnitude as the number of active artifacts. +const MAX_OUTBOUND_CHANNEL_SIZE: usize = 100_000; + +pub type AbortableBroadcastSender = Sender>; +pub type AbortableBroadcastReceiver = UnboundedReceiver>; + +pub struct AbortableBroadcastChannelBuilder { log: ReplicaLogger, metrics_registry: MetricsRegistry, rt_handle: Handle, @@ -36,7 +42,7 @@ pub struct ConsensusManagerBuilder { router: Option, } -impl ConsensusManagerBuilder { +impl AbortableBroadcastChannelBuilder { pub fn new(log: ReplicaLogger, rt_handle: Handle, metrics_registry: MetricsRegistry) -> Self { Self { log, @@ -47,18 +53,32 @@ impl ConsensusManagerBuilder { } } - pub fn add_client< + /// Creates a channel for the corresponding artifact. The channel is used to broadcast artifacts within the subnet. + pub fn abortable_broadcast_channel< Artifact: IdentifiableArtifact, WireArtifact: PbArtifact, F: FnOnce(Arc) -> D + 'static, D: ArtifactAssembler, >( &mut self, - outbound_artifacts_rx: Receiver>, - inbound_artifacts_tx: UnboundedSender>, (assembler, assembler_router): (F, Router), slot_limit: usize, + ) -> ( + AbortableBroadcastSender, + AbortableBroadcastReceiver, + // TODO: remove this by introducing a new channel from the http handler into the processor + UnboundedSender>, ) { + let (outbound_tx, outbound_rx) = tokio::sync::mpsc::channel(MAX_OUTBOUND_CHANNEL_SIZE); + // Making this channel bounded can be problematic since we don't have true multiplexing + // of P2P messages. + // Possible scenario is - adverts+chunks arrive on the same channel, slow consensus + // will result on slow consuption of chunks. Slow consumption of chunks will in turn + // result in slower consumptions of adverts. Ideally adverts are consumed at rate + // independent of consensus. + #[allow(clippy::disallowed_methods)] + let (inbound_tx, inbound_rx) = tokio::sync::mpsc::unbounded_channel(); + assert!(uri_prefix::() .chars() .all(char::is_alphabetic)); @@ -68,14 +88,15 @@ impl ConsensusManagerBuilder { let rt_handle = self.rt_handle.clone(); let metrics_registry = self.metrics_registry.clone(); + let inbound_tx_c = inbound_tx.clone(); let builder = move |transport: Arc, topology_watcher| { start_consensus_manager( log, &metrics_registry, rt_handle, - outbound_artifacts_rx, + outbound_rx, adverts_from_peers_rx, - inbound_artifacts_tx, + inbound_tx, assembler(transport.clone()), transport, topology_watcher, @@ -92,6 +113,7 @@ impl ConsensusManagerBuilder { ); self.clients.push(Box::new(builder)); + (outbound_tx, inbound_rx, inbound_tx_c) } pub fn router(&mut self) -> Router { diff --git a/rs/p2p/consensus_manager/src/receiver.rs b/rs/p2p/consensus_manager/src/receiver.rs index a448158b3d5..2d1a7e31ae1 100644 --- a/rs/p2p/consensus_manager/src/receiver.rs +++ b/rs/p2p/consensus_manager/src/receiver.rs @@ -652,6 +652,7 @@ mod tests { fn new() -> Self { let (_, adverts_received) = tokio::sync::mpsc::channel(100); + #[allow(clippy::disallowed_methods)] let (sender, unvalidated_artifact_receiver) = tokio::sync::mpsc::unbounded_channel(); let (_, topology_watcher) = watch::channel(SubnetTopology::default()); let artifact_assembler = diff --git a/rs/p2p/test_utils/src/lib.rs b/rs/p2p/test_utils/src/lib.rs index 7d749c41c3d..4135223ca9c 100644 --- a/rs/p2p/test_utils/src/lib.rs +++ b/rs/p2p/test_utils/src/lib.rs @@ -449,30 +449,31 @@ pub fn start_consensus_manager( processor: TestConsensus, ) -> ( Box, - ic_consensus_manager::ConsensusManagerBuilder, + ic_consensus_manager::AbortableBroadcastChannelBuilder, ) { let _enter = rt_handle.enter(); let pool = Arc::new(RwLock::new(processor)); - let (artifact_processor_jh, artifact_manager_event_rx, artifact_sender) = - start_test_processor(pool.clone(), pool.clone().read().unwrap().clone()); let bouncer_factory = Arc::new(pool.clone().read().unwrap().clone()); - let mut cm1 = ic_consensus_manager::ConsensusManagerBuilder::new( + let downloader = FetchArtifact::new( log.clone(), rt_handle.clone(), + pool.clone(), + bouncer_factory, MetricsRegistry::default(), ); - let downloader = FetchArtifact::new( - log, - rt_handle, - pool, - bouncer_factory, + + let mut cm1 = ic_consensus_manager::AbortableBroadcastChannelBuilder::new( + log.clone(), + rt_handle.clone(), MetricsRegistry::default(), ); - cm1.add_client( - artifact_manager_event_rx, - artifact_sender, - downloader, - usize::MAX, + let (outbound_tx, inbound_rx, _) = cm1.abortable_broadcast_channel(downloader, usize::MAX); + + let artifact_processor_jh = start_test_processor( + outbound_tx, + inbound_rx, + pool.clone(), + pool.clone().read().unwrap().clone(), ); (artifact_processor_jh, cm1) } diff --git a/rs/p2p/test_utils/src/turmoil.rs b/rs/p2p/test_utils/src/turmoil.rs index 3096d4453ab..c484641fb89 100644 --- a/rs/p2p/test_utils/src/turmoil.rs +++ b/rs/p2p/test_utils/src/turmoil.rs @@ -346,7 +346,7 @@ pub fn add_transport_to_sim( async move { let metrics_registry = MetricsRegistry::default(); - let mut consensus_builder = ic_consensus_manager::ConsensusManagerBuilder::new( + let mut consensus_builder = ic_consensus_manager::AbortableBroadcastChannelBuilder::new( log.clone(), tokio::runtime::Handle::current(), metrics_registry, @@ -370,25 +370,22 @@ pub fn add_transport_to_sim( }; let _artifact_processor_jh = if let Some(consensus) = consensus_manager_clone { - let (artifact_processor_jh, artifact_manager_event_rx, artifact_sender) = - start_test_processor( - consensus.clone(), - consensus.clone().read().unwrap().clone(), - ); let bouncer_factory = Arc::new(consensus.clone().read().unwrap().clone()); - let downloader = FetchArtifact::new( log.clone(), tokio::runtime::Handle::current(), - consensus, + consensus.clone(), bouncer_factory, MetricsRegistry::default(), ); - consensus_builder.add_client( - artifact_manager_event_rx, - artifact_sender, - downloader, - usize::MAX, + let (outbound_tx, inbound_tx, _) = + consensus_builder.abortable_broadcast_channel(downloader, usize::MAX); + + let artifact_processor_jh = start_test_processor( + outbound_tx, + inbound_tx, + consensus.clone(), + consensus.clone().read().unwrap().clone(), ); router = Some(router.unwrap_or_default().merge(consensus_builder.router())); @@ -442,22 +439,19 @@ pub fn waiter_fut( #[allow(clippy::type_complexity)] pub fn start_test_processor( + outbound_tx: mpsc::Sender>, + inbound_rx: mpsc::UnboundedReceiver>, pool: Arc>>, change_set_producer: TestConsensus, -) -> ( - Box, - mpsc::Receiver>, - mpsc::UnboundedSender>, -) { - let (tx, rx) = tokio::sync::mpsc::channel(1000); +) -> Box { let time_source = Arc::new(SysTimeSource::new()); let client = ic_artifact_manager::Processor::new(pool, change_set_producer); - let (jh, sender) = run_artifact_processor( + run_artifact_processor( time_source, MetricsRegistry::default(), Box::new(client), - tx, + outbound_tx, + inbound_rx, vec![], - ); - (jh, rx, sender) + ) } diff --git a/rs/replica/setup_ic_network/src/lib.rs b/rs/replica/setup_ic_network/src/lib.rs index 982cddc301c..44824366df2 100644 --- a/rs/replica/setup_ic_network/src/lib.rs +++ b/rs/replica/setup_ic_network/src/lib.rs @@ -15,7 +15,8 @@ use ic_consensus::{ consensus::{ConsensusBouncer, ConsensusImpl}, idkg, }; -use ic_consensus_manager::ConsensusManagerBuilder; +use ic_consensus_dkg::DkgBouncer; +use ic_consensus_manager::AbortableBroadcastChannelBuilder; use ic_consensus_utils::{crypto::ConsensusCrypto, pool_reader::PoolReader}; use ic_crypto_interfaces_sig_verification::IngressSigVerifier; use ic_crypto_tls_interfaces::TlsConfig; @@ -67,7 +68,6 @@ use tower_http::trace::TraceLayer; /// advertising the blocks. const HASHES_IN_BLOCKS_FEATURE_ENABLED: bool = false; -pub const MAX_ADVERT_BUFFER: usize = 100_000; /// This limit is used to protect against a malicious peer advertising many ingress messages. /// If no malicious peers are present the ingress pools are bounded by a separate limit. const SLOT_TABLE_LIMIT_INGRESS: usize = 50_000; @@ -246,11 +246,11 @@ fn start_consensus( Arc>, UnboundedSender>, Vec>, - ConsensusManagerBuilder, + AbortableBroadcastChannelBuilder, ) { let time_source = Arc::new(SysTimeSource::new()); - let mut new_p2p_consensus: ic_consensus_manager::ConsensusManagerBuilder = - ic_consensus_manager::ConsensusManagerBuilder::new( + let mut new_p2p_consensus: ic_consensus_manager::AbortableBroadcastChannelBuilder = + ic_consensus_manager::AbortableBroadcastChannelBuilder::new( log.clone(), rt_handle.clone(), metrics_registry.clone(), @@ -305,13 +305,6 @@ fn start_consensus( &PoolReader::new(&*consensus_pool.read().unwrap()), ))); - let (consensus_tx, consensus_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - let (certification_tx, certification_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - let (dkg_tx, dkg_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - let (ingress_tx, ingress_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - let (idkg_tx, idkg_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - let (http_outcalls_tx, http_outcalls_rx) = tokio::sync::mpsc::channel(MAX_ADVERT_BUFFER); - { let consensus_impl = ConsensusImpl::new( replica_config.clone(), @@ -337,53 +330,43 @@ fn start_consensus( let consensus_pool = Arc::clone(&consensus_pool); - // Create the consensus client. - let (client, jh) = create_artifact_handler( - consensus_tx, - consensus_impl, - time_source.clone(), - consensus_pool.clone(), - metrics_registry.clone(), - ); - - join_handles.push(jh); - let bouncer = Arc::new(ConsensusBouncer::new(metrics_registry, message_router)); - if HASHES_IN_BLOCKS_FEATURE_ENABLED { + let (outbound_tx, inbound_rx, _) = if HASHES_IN_BLOCKS_FEATURE_ENABLED { let assembler = ic_artifact_downloader::FetchStrippedConsensusArtifact::new( log.clone(), rt_handle.clone(), - consensus_pool, + consensus_pool.clone(), artifact_pools.ingress_pool.clone(), bouncer, metrics_registry.clone(), node_id, ); - new_p2p_consensus.add_client(consensus_rx, client, assembler, SLOT_TABLE_NO_LIMIT); + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT) } else { let assembler = ic_artifact_downloader::FetchArtifact::new( log.clone(), rt_handle.clone(), - consensus_pool, + consensus_pool.clone(), bouncer, metrics_registry.clone(), ); - new_p2p_consensus.add_client(consensus_rx, client, assembler, SLOT_TABLE_NO_LIMIT); + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT) }; - }; - let ingress_sender = { - // Create the ingress client. - let (client, jh) = create_ingress_handlers( - ingress_tx, - Arc::clone(&time_source) as Arc<_>, - Arc::clone(&artifact_pools.ingress_pool), - ingress_manager, + // Create the consensus client. + let jh = create_artifact_handler( + outbound_tx, + inbound_rx, + consensus_impl, + time_source.clone(), + consensus_pool, metrics_registry.clone(), ); join_handles.push(jh); + }; + let ingress_sender = { let bouncer = Arc::new(IngressBouncer::new(time_source.clone())); let assembler = ic_artifact_downloader::FetchArtifact::new( log.clone(), @@ -393,13 +376,19 @@ fn start_consensus( metrics_registry.clone(), ); - new_p2p_consensus.add_client( - ingress_rx, - client.clone(), - assembler, - SLOT_TABLE_LIMIT_INGRESS, + let (outbound_tx, inbound_rx, inbound_tx) = + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_LIMIT_INGRESS); + // Create the ingress client. + let jh = create_ingress_handlers( + outbound_tx, + inbound_rx, + Arc::clone(&time_source) as Arc<_>, + Arc::clone(&artifact_pools.ingress_pool), + ingress_manager, + metrics_registry.clone(), ); - client + join_handles.push(jh); + inbound_tx }; { @@ -413,32 +402,45 @@ fn start_consensus( log.clone(), max_certified_height_tx, ); + let bouncer = CertifierBouncer::new(metrics_registry, Arc::clone(&consensus_pool_cache)); + let assembler = ic_artifact_downloader::FetchArtifact::new( + log.clone(), + rt_handle.clone(), + artifact_pools.certification_pool.clone(), + Arc::new(bouncer), + metrics_registry.clone(), + ); + let (outbound_tx, inbound_rx, _) = + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT); // Create the certification client. - let (client, jh) = create_artifact_handler( - certification_tx, + let jh = create_artifact_handler( + outbound_tx, + inbound_rx, certifier, Arc::clone(&time_source) as Arc<_>, - Arc::clone(&artifact_pools.certification_pool), + artifact_pools.certification_pool, metrics_registry.clone(), ); join_handles.push(jh); + }; - let bouncer = CertifierBouncer::new(metrics_registry, Arc::clone(&consensus_pool_cache)); + { + let bouncer = Arc::new(DkgBouncer::new(metrics_registry)); let assembler = ic_artifact_downloader::FetchArtifact::new( log.clone(), rt_handle.clone(), - artifact_pools.certification_pool, - Arc::new(bouncer), + artifact_pools.dkg_pool.clone(), + bouncer, metrics_registry.clone(), ); - new_p2p_consensus.add_client(certification_rx, client, assembler, SLOT_TABLE_NO_LIMIT); - }; - { + let (outbound_tx, inbound_rx, _) = + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT); // Create the DKG client. - let (client, jh) = create_artifact_handler( - dkg_tx, + let jh = create_artifact_handler( + outbound_tx, + inbound_rx, ic_consensus_dkg::DkgImpl::new( node_id, Arc::clone(&consensus_crypto), @@ -448,22 +450,11 @@ fn start_consensus( log.clone(), ), Arc::clone(&time_source) as Arc<_>, - Arc::clone(&artifact_pools.dkg_pool), - metrics_registry.clone(), - ); - join_handles.push(jh); - - let bouncer = Arc::new(ic_consensus_dkg::DkgBouncer::new(metrics_registry)); - let assembler = ic_artifact_downloader::FetchArtifact::new( - log.clone(), - rt_handle.clone(), artifact_pools.dkg_pool, - bouncer, metrics_registry.clone(), ); - new_p2p_consensus.add_client(dkg_rx, client, assembler, SLOT_TABLE_NO_LIMIT); + join_handles.push(jh); }; - { let finalized = consensus_pool_cache.finalized_block(); let chain_key_config = @@ -478,9 +469,26 @@ fn start_consensus( finalized.payload.as_ref().is_summary(), finalized.payload.as_ref().as_idkg().is_some(), ); + let bouncer = Arc::new(idkg::IDkgBouncer::new( + metrics_registry, + subnet_id, + consensus_pool.read().unwrap().get_block_cache(), + Arc::clone(&state_reader), + )); + let assembler = ic_artifact_downloader::FetchArtifact::new( + log.clone(), + rt_handle.clone(), + artifact_pools.idkg_pool.clone(), + bouncer, + metrics_registry.clone(), + ); + + let (outbound_tx, inbound_rx, _) = + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT); - let (client, jh) = create_artifact_handler( - idkg_tx, + let jh = create_artifact_handler( + outbound_tx, + inbound_rx, idkg::IDkgImpl::new( node_id, consensus_pool.read().unwrap().get_block_cache(), @@ -491,31 +499,32 @@ fn start_consensus( malicious_flags, ), Arc::clone(&time_source) as Arc<_>, - Arc::clone(&artifact_pools.idkg_pool), + artifact_pools.idkg_pool, metrics_registry.clone(), ); - join_handles.push(jh); + }; - let bouncer = Arc::new(idkg::IDkgBouncer::new( - metrics_registry, - subnet_id, - consensus_pool.read().unwrap().get_block_cache(), + { + let bouncer = Arc::new(CanisterHttpGossipImpl::new( + Arc::clone(&consensus_pool_cache), Arc::clone(&state_reader), + log.clone(), )); let assembler = ic_artifact_downloader::FetchArtifact::new( log.clone(), rt_handle.clone(), - artifact_pools.idkg_pool, + artifact_pools.canister_http_pool.clone(), bouncer, metrics_registry.clone(), ); - new_p2p_consensus.add_client(idkg_rx, client, assembler, SLOT_TABLE_NO_LIMIT); - }; - { - let (client, jh) = create_artifact_handler( - http_outcalls_tx, + let (outbound_tx, inbound_rx, _) = + new_p2p_consensus.abortable_broadcast_channel(assembler, SLOT_TABLE_NO_LIMIT); + + let jh = create_artifact_handler( + outbound_tx, + inbound_rx, CanisterHttpPoolManagerImpl::new( Arc::clone(&state_reader), Arc::new(Mutex::new(canister_http_adapter_client)), @@ -527,24 +536,10 @@ fn start_consensus( log.clone(), ), Arc::clone(&time_source) as Arc<_>, - Arc::clone(&artifact_pools.canister_http_pool), - metrics_registry.clone(), - ); - join_handles.push(jh); - - let bouncer = Arc::new(CanisterHttpGossipImpl::new( - Arc::clone(&consensus_pool_cache), - Arc::clone(&state_reader), - log.clone(), - )); - let assembler = ic_artifact_downloader::FetchArtifact::new( - log.clone(), - rt_handle.clone(), artifact_pools.canister_http_pool, - bouncer, metrics_registry.clone(), ); - new_p2p_consensus.add_client(http_outcalls_rx, client, assembler, SLOT_TABLE_NO_LIMIT); + join_handles.push(jh); }; ( From 7fb826ac7bdd462d626229d8c7c1474e50d03cfc Mon Sep 17 00:00:00 2001 From: przydatek Date: Mon, 13 Jan 2025 13:22:25 +0100 Subject: [PATCH 62/98] test: add a test for fetching long assets with chunkwise certification (#3218) Add an integration test for boundary nodes, testing the feature of fetching long assets with chunk-wise certification. As a side-effect, refactor `asset_canister`-test-helper, to enable deployment with custom WASMs. --- MODULE.bazel | 9 ++ rs/tests/boundary_nodes/BUILD.bazel | 3 + .../bn_integration_on_playnet_test.rs | 10 +- .../boundary_nodes/bn_integration_test.rs | 10 +- .../boundary_nodes/custom_domains/setup.rs | 2 +- .../integration_test_common/src/lib.rs | 150 +++++++++++++++++- rs/tests/driver/src/driver/asset_canister.rs | 18 ++- 7 files changed, 186 insertions(+), 16 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 12ba3cb1a37..9a67389dc26 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -518,6 +518,15 @@ http_file( url = "https://github.com/dfinity/sdk/raw/0.14.2/src/distributed/assetstorage.wasm.gz", ) +# Asset canister that certifies long assets chunk-wise + +http_file( + name = "long_asset_canister", + downloaded_file_path = "http_gateway_canister_custom_assets.wasm.gz", + sha256 = "eedcbf986c67fd4ebe3042094604a9a5703e825e56433e2509a6a4d0384ccf95", + url = "https://github.com/dfinity/http-gateway/raw/refs/heads/main/examples/http-gateway/canister/http_gateway_canister_custom_assets.wasm.gz", +) + # Old version of wallet canister http_file( diff --git a/rs/tests/boundary_nodes/BUILD.bazel b/rs/tests/boundary_nodes/BUILD.bazel index 6916aa14f96..058bb5ed0a2 100644 --- a/rs/tests/boundary_nodes/BUILD.bazel +++ b/rs/tests/boundary_nodes/BUILD.bazel @@ -10,6 +10,7 @@ TEST_CANISTERS_RUNTIME_DEPS = [ "//rs/tests/test_canisters/http_counter", "//rs/tests/test_canisters/kv_store", "@asset_canister//file", + "@long_asset_canister//file", ] system_test_nns( @@ -18,6 +19,7 @@ system_test_nns( "KV_STORE_WASM_PATH": "$(rootpath //rs/tests/test_canisters/kv_store)", "HTTP_COUNTER_WASM_PATH": "$(rootpath //rs/tests/test_canisters/http_counter)", "ASSET_CANISTER_WASM_PATH": "$(rootpath @asset_canister//file)", + "LONG_ASSET_CANISTER_WASM_PATH": "$(rootpath @long_asset_canister//file)", }, extra_head_nns_tags = [], # don't run the head_nns variant on nightly since it aleady runs on long_test. tags = [ @@ -59,6 +61,7 @@ system_test_nns( "KV_STORE_WASM_PATH": "$(rootpath //rs/tests/test_canisters/kv_store)", "HTTP_COUNTER_WASM_PATH": "$(rootpath //rs/tests/test_canisters/http_counter)", "ASSET_CANISTER_WASM_PATH": "$(rootpath @asset_canister//file)", + "LONG_ASSET_CANISTER_WASM_PATH": "$(rootpath @long_asset_canister//file)", }, flaky = True, tags = [ diff --git a/rs/tests/boundary_nodes/bn_integration_on_playnet_test.rs b/rs/tests/boundary_nodes/bn_integration_on_playnet_test.rs index 5e33e17da73..32c8dde0658 100644 --- a/rs/tests/boundary_nodes/bn_integration_on_playnet_test.rs +++ b/rs/tests/boundary_nodes/bn_integration_on_playnet_test.rs @@ -4,9 +4,10 @@ use anyhow::Result; use ic_boundary_nodes_integration_test_common::{ api_call_test, api_canister_read_state_test, api_query_test, api_status_test, - api_subnet_read_state_test, api_sync_call_test, asset_canister_test, canister_denylist_test, - content_type_headers_test, cors_headers_test, http_endpoints_test, proxy_http_canister_test, - redirect_http_to_https_test, redirect_to_dashboard_test, + api_subnet_read_state_test, api_sync_call_test, canister_denylist_test, + content_type_headers_test, cors_headers_test, http_endpoints_test, legacy_asset_canister_test, + long_asset_canister_test, proxy_http_canister_test, redirect_http_to_https_test, + redirect_to_dashboard_test, }; use ic_boundary_nodes_system_test_utils::{ constants::BOUNDARY_NODE_NAME, helpers::BoundaryNodeHttpsConfig, setup::setup_ic_with_bn, @@ -34,7 +35,8 @@ fn main() -> Result<()> { .add_test(systest!(api_sync_call_test)) .add_test(systest!(api_canister_read_state_test)) .add_test(systest!(api_subnet_read_state_test)) - .add_test(systest!(asset_canister_test)) + .add_test(systest!(legacy_asset_canister_test)) + .add_test(systest!(long_asset_canister_test)) .add_test(systest!(content_type_headers_test)) .add_test(systest!(cors_headers_test)) .add_test(systest!(proxy_http_canister_test)) diff --git a/rs/tests/boundary_nodes/bn_integration_test.rs b/rs/tests/boundary_nodes/bn_integration_test.rs index 7c858087557..8a3100593b6 100644 --- a/rs/tests/boundary_nodes/bn_integration_test.rs +++ b/rs/tests/boundary_nodes/bn_integration_test.rs @@ -4,9 +4,10 @@ use anyhow::Result; use ic_boundary_nodes_integration_test_common::{ api_call_test, api_canister_read_state_test, api_query_test, api_status_test, - api_subnet_read_state_test, api_sync_call_test, asset_canister_test, canister_denylist_test, - content_type_headers_test, cors_headers_test, http_endpoints_test, proxy_http_canister_test, - redirect_http_to_https_test, redirect_to_dashboard_test, + api_subnet_read_state_test, api_sync_call_test, canister_denylist_test, + content_type_headers_test, cors_headers_test, http_endpoints_test, legacy_asset_canister_test, + long_asset_canister_test, proxy_http_canister_test, redirect_http_to_https_test, + redirect_to_dashboard_test, }; use ic_boundary_nodes_system_test_utils::{ constants::BOUNDARY_NODE_NAME, helpers::BoundaryNodeHttpsConfig, setup::setup_ic_with_bn, @@ -34,9 +35,10 @@ fn main() -> Result<()> { .add_test(systest!(api_sync_call_test)) .add_test(systest!(api_canister_read_state_test)) .add_test(systest!(api_subnet_read_state_test)) - .add_test(systest!(asset_canister_test)) .add_test(systest!(content_type_headers_test)) .add_test(systest!(cors_headers_test)) + .add_test(systest!(legacy_asset_canister_test)) + .add_test(systest!(long_asset_canister_test)) .add_test(systest!(proxy_http_canister_test)) .add_test(systest!(redirect_http_to_https_test)) .add_test(systest!(redirect_to_dashboard_test)) diff --git a/rs/tests/boundary_nodes/custom_domains/setup.rs b/rs/tests/boundary_nodes/custom_domains/setup.rs index ddd2ff996ee..c614b003412 100644 --- a/rs/tests/boundary_nodes/custom_domains/setup.rs +++ b/rs/tests/boundary_nodes/custom_domains/setup.rs @@ -883,7 +883,7 @@ pub async fn setup_asset_canister( index_content: Option<&str>, ) -> Result { let asset_canister = env - .deploy_asset_canister() + .deploy_legacy_asset_canister() .await .expect("Could not install asset canister"); diff --git a/rs/tests/boundary_nodes/integration_test_common/src/lib.rs b/rs/tests/boundary_nodes/integration_test_common/src/lib.rs index 84fb9a56cb8..0553cfef2ed 100644 --- a/rs/tests/boundary_nodes/integration_test_common/src/lib.rs +++ b/rs/tests/boundary_nodes/integration_test_common/src/lib.rs @@ -345,7 +345,7 @@ Coverage:: asset Canisters behave as expected end::catalog[] */ -pub fn asset_canister_test(env: TestEnv) { +pub fn legacy_asset_canister_test(env: TestEnv) { let logger_orig = env.logger(); let boundary_node = env .get_deployed_boundary_node(BOUNDARY_NODE_NAME) @@ -357,7 +357,7 @@ pub fn asset_canister_test(env: TestEnv) { info!(&logger_orig, "Creating asset canister"); let asset_canister_orig = rt - .block_on(env.deploy_asset_canister()) + .block_on(env.deploy_legacy_asset_canister()) .expect("Could not install asset canister"); let http_client_builder = ClientBuilder::new(); @@ -754,6 +754,150 @@ pub fn asset_canister_test(env: TestEnv) { .expect("test suite failed"); } +// Constants copied from long asset canister: +const ASSET_CHUNK_SIZE: usize = 2_000_000; + +const ONE_CHUNK_ASSET_LEN: usize = ASSET_CHUNK_SIZE; +const TWO_CHUNKS_ASSET_LEN: usize = ASSET_CHUNK_SIZE + 1; +const SIX_CHUNKS_ASSET_LEN: usize = 5 * ASSET_CHUNK_SIZE + 12; + +pub fn long_asset_canister_test(env: TestEnv) { + let logger_orig = env.logger(); + let boundary_node = env + .get_deployed_boundary_node(BOUNDARY_NODE_NAME) + .unwrap() + .get_snapshot() + .unwrap(); + + let rt = runtime(); + + info!(&logger_orig, "Creating asset canister"); + let asset_canister_orig = rt + .block_on(env.deploy_long_asset_canister()) + .expect("Could not install asset canister"); + + let http_client_builder = ClientBuilder::new(); + let (client_builder, host_orig) = if let Some(playnet) = boundary_node.get_playnet() { + ( + http_client_builder, + format!("{0}.{playnet}", asset_canister_orig.canister_id), + ) + } else { + let host = format!("{0}.ic0.app", asset_canister_orig.canister_id); + let bn_addr = SocketAddrV6::new(boundary_node.ipv6(), 0, 0, 0).into(); + let client_builder = http_client_builder + .danger_accept_invalid_certs(true) + .resolve(&host, bn_addr); + (client_builder, host) + }; + let http_client = client_builder.build().unwrap(); + + let futs = FuturesUnordered::new(); + futs.push(rt.spawn({ + let host = host_orig.clone(); + let logger = logger_orig.clone(); + let http_client = http_client.clone(); + let name = "Requesting a single chunk asset"; + info!(&logger, "Starting subtest {}", name); + + async move { + info!(&logger, "Requesting /long_asset_one_chunk ..."); + let res = http_client + .get(format!("https://{host}/long_asset_one_chunk")) + .header("accept-encoding", "gzip") + .send() + .await? + .bytes() + .await? + .to_vec(); + + if res.len() != ONE_CHUNK_ASSET_LEN { + bail!("/long_asset_one_chunk response did not match uploaded content") + } + + Ok(()) + } + })); + + futs.push(rt.spawn({ + let host = host_orig.clone(); + let logger = logger_orig.clone(); + let http_client = http_client.clone(); + let name = "Requesting a two chunk asset"; + info!(&logger, "Starting subtest {}", name); + + async move { + info!(&logger, "Requesting /long_asset_two_chunks ..."); + let res = http_client + .get(format!("https://{host}/long_asset_two_chunks")) + .header("accept-encoding", "gzip") + .send() + .await? + .bytes() + .await? + .to_vec(); + + if res.len() != TWO_CHUNKS_ASSET_LEN { + bail!("/long_asset_two_chunks response did not match uploaded content") + } + + Ok(()) + } + })); + + futs.push(rt.spawn({ + let host = host_orig.clone(); + let logger = logger_orig.clone(); + let http_client = http_client.clone(); + let name = "Requesting a six chunk asset"; + info!(&logger, "Starting subtest {}", name); + + async move { + info!(&logger, "Requesting /long_asset_six_chunks ..."); + let res = http_client + .get(format!("https://{host}/long_asset_six_chunks")) + .header("accept-encoding", "gzip") + .send() + .await? + .bytes() + .await? + .to_vec(); + + if res.len() != SIX_CHUNKS_ASSET_LEN { + bail!("/long_asset_six_chunks response did not match uploaded content") + } + + Ok(()) + } + })); + + let logger = logger_orig.clone(); + rt.block_on(async move { + let mut cnt_err = 0; + info!(&logger, "Waiting for subtests"); + + for fut in futs { + match fut.await { + Ok(Err(err)) => { + error!(logger, "test failed: {}", err); + cnt_err += 1; + } + Err(err) => { + error!(logger, "test panicked: {}", err); + cnt_err += 1; + } + _ => {} + } + } + + match cnt_err { + 0 => Ok(()), + _ => bail!("failed with {cnt_err} errors"), + } + }) + .expect("test suite failed"); +} + /* tag::catalog[] Title:: Boundary nodes HTTP canister test @@ -1325,7 +1469,7 @@ pub fn http_endpoints_test(env: TestEnv) { let rt = runtime(); info!(&logger_orig, "Creating asset canister"); - let asset_canister_orig = rt.block_on(env.deploy_asset_canister()).unwrap(); + let asset_canister_orig = rt.block_on(env.deploy_legacy_asset_canister()).unwrap(); info!(&logger_orig, "Uploading static assets"); #[derive(Clone)] diff --git a/rs/tests/driver/src/driver/asset_canister.rs b/rs/tests/driver/src/driver/asset_canister.rs index ea41ffd3188..a343b74d2e3 100644 --- a/rs/tests/driver/src/driver/asset_canister.rs +++ b/rs/tests/driver/src/driver/asset_canister.rs @@ -16,7 +16,9 @@ use tokio::task; #[async_trait] pub trait DeployAssetCanister { - async fn deploy_asset_canister(&self) -> Result; + async fn deploy_legacy_asset_canister(&self) -> Result; + async fn deploy_long_asset_canister(&self) -> Result; + async fn deploy_asset_canister(&self, wasm_env_var_name: &str) -> Result; } #[async_trait] @@ -24,17 +26,25 @@ impl DeployAssetCanister for T where T: HasTestEnv + Send + Sync, { - async fn deploy_asset_canister(&self) -> Result { + async fn deploy_legacy_asset_canister(&self) -> Result { + self.deploy_asset_canister("ASSET_CANISTER_WASM_PATH").await + } + async fn deploy_long_asset_canister(&self) -> Result { + self.deploy_asset_canister("LONG_ASSET_CANISTER_WASM_PATH") + .await + } + async fn deploy_asset_canister(&self, wasm_env_var_name: &str) -> Result { let env = self.test_env(); let logger = env.logger(); let app_node = env.get_first_healthy_application_node_snapshot(); let canister_id = task::spawn_blocking({ let app_node = app_node.clone(); + let wasm_env_var_name = wasm_env_var_name.to_string(); move || { app_node.create_and_install_canister_with_arg( - &env::var("ASSET_CANISTER_WASM_PATH") - .expect("ASSET_CANISTER_WASM_PATH not set"), + &env::var(wasm_env_var_name.clone()) + .unwrap_or_else(|_| panic!("{} not set", wasm_env_var_name)), None, ) } From a23113f399a2895e167cf5f96ad5203e1d5f5957 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 13 Jan 2025 14:37:18 +0200 Subject: [PATCH 63/98] test: Add test for taking a snapshot that triggers storage reservation (#3395) This is a redo of #3360. Matching on the exact number of bytes requested can be flaky apparently so instead focus on matching only on the required amount of cycles in the error message which is the focus of the test anyway. --- .../tests/storage_reservation.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/rs/execution_environment/tests/storage_reservation.rs b/rs/execution_environment/tests/storage_reservation.rs index 8c9e4598235..d60bbc77211 100644 --- a/rs/execution_environment/tests/storage_reservation.rs +++ b/rs/execution_environment/tests/storage_reservation.rs @@ -1,5 +1,6 @@ use ic_config::execution_environment::Config as ExecutionConfig; use ic_config::subnet_config::SubnetConfig; +use ic_error_types::ErrorCode; use ic_management_canister_types::TakeCanisterSnapshotArgs; use ic_management_canister_types::{self as ic00, CanisterInstallMode, EmptyBlob, Payload}; use ic_registry_subnet_type::SubnetType; @@ -168,3 +169,43 @@ fn test_storage_reservation_triggered_in_canister_snapshot_with_enough_cycles_av reserved_balance_before_snapshot ); } + +#[test] +fn test_storage_reservation_triggered_in_canister_snapshot_without_enough_cycles_available() { + // This test verifies that a canister cannot take a snapshot if it does not have enough + // cycles to cover the storage reservation triggered by the snapshot operation. The main + // point of the test is to verify that the error message is informative and includes the + // amount of cycles required to cover the storage reservation. + // + // The error message is produced by running the test once and checking the output. Calculating + // the exact amounts is hard to do in advance. Note that any changes to cycles cost or how + // the reservation mechanism works may require updating the error message in the test. + + let (env, canister_id) = setup( + SUBNET_MEMORY_THRESHOLD, + SUBNET_MEMORY_CAPACITY, + Some(300_400_000_000), + ); + assert_eq!(reserved_balance(&env, canister_id), 0); + + // Grow memory in update call, should trigger storage reservation. + let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(3000).build()); + let reserved_balance_before_snapshot = reserved_balance(&env, canister_id); + assert_gt!(reserved_balance_before_snapshot, 0); // Storage reservation is triggered. + + // Take a snapshot to trigger more storage reservation. The canister does not have + // enough cycles in its balance, so this should fail. + let res = env.take_canister_snapshot(TakeCanisterSnapshotArgs::new(canister_id, None)); + match res { + Ok(_) => panic!("Expected an error but got Ok(_)"), + Err(err) => { + assert_eq!(err.code(), ErrorCode::InsufficientCyclesInMemoryGrow); + // Match on a substring of the error message. Due to a difference in instructions consumed on + // Mac vs Linux, we cannot match on the exact number of cycles but we only need to verify it's + // a non-zero amount. + assert!(err + .description() + .contains("due to insufficient cycles. At least 339_603_")); + } + } +} From 4a7957ba68b97f608efaf38807b8d685915ae653 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 13 Jan 2025 07:55:29 -0500 Subject: [PATCH 64/98] chore: Log HTTP request body on signature verification failure (#3239) There have been reports both internally and in support channels of ingress messages failing signature verification. So far these have not been reproducible, and the cause is unknown. To assist debugging, if verification fails log the HTTP request body. --- rs/http_endpoints/public/src/call.rs | 2 +- rs/http_endpoints/public/src/common.rs | 18 ++++++++++++++---- rs/http_endpoints/public/src/query.rs | 2 +- .../public/src/read_state/canister.rs | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/rs/http_endpoints/public/src/call.rs b/rs/http_endpoints/public/src/call.rs index a02984f6a5d..d2a3a1bc3f1 100644 --- a/rs/http_endpoints/public/src/call.rs +++ b/rs/http_endpoints/public/src/call.rs @@ -251,7 +251,7 @@ impl IngressValidator { message: "".into(), })? .map_err(|validation_error| { - validation_error_to_http_error(message_id, validation_error, &log) + validation_error_to_http_error(msg.as_ref(), validation_error, &log) })?; let ingress_filter = ingress_filter.lock().unwrap().clone(); diff --git a/rs/http_endpoints/public/src/common.rs b/rs/http_endpoints/public/src/common.rs index 1f40f4c7e35..60d34d92d35 100644 --- a/rs/http_endpoints/public/src/common.rs +++ b/rs/http_endpoints/public/src/common.rs @@ -20,7 +20,7 @@ use ic_replicated_state::ReplicatedState; use ic_types::{ crypto::threshold_sig::ThresholdSigPublicKey, malicious_flags::MaliciousFlags, - messages::{HttpRequest, HttpRequestContent, MessageId}, + messages::{HttpRequest, HttpRequestContent}, RegistryVersion, SubnetId, Time, }; use ic_validator::{ @@ -246,12 +246,22 @@ impl IntoResponse for CborUserError { } } -pub(crate) fn validation_error_to_http_error( - message_id: MessageId, +pub(crate) fn validation_error_to_http_error( + request: &HttpRequest, err: RequestValidationError, log: &ReplicaLogger, ) -> HttpError { - info!(log, "msg_id: {}, err: {}", message_id, err); + let message_id = request.id(); + match err { + RequestValidationError::InvalidSignature(_) => { + info!( + log, + "msg_id: {}, err: {}, request: {:?}", message_id, err, request + ) + } + _ => info!(log, "msg_id: {}, err: {}", message_id, err), + } + HttpError { status: StatusCode::BAD_REQUEST, message: format!("{err}"), diff --git a/rs/http_endpoints/public/src/query.rs b/rs/http_endpoints/public/src/query.rs index a68bdcceeb4..27bc9b465b1 100644 --- a/rs/http_endpoints/public/src/query.rs +++ b/rs/http_endpoints/public/src/query.rs @@ -194,7 +194,7 @@ pub(crate) async fn query( { Ok(Ok(_)) => {} Ok(Err(err)) => { - let http_err = validation_error_to_http_error(request.id(), err, &log); + let http_err = validation_error_to_http_error(&request, err, &log); return (http_err.status, http_err.message).into_response(); } Err(_) => { diff --git a/rs/http_endpoints/public/src/read_state/canister.rs b/rs/http_endpoints/public/src/read_state/canister.rs index 1a491c8f036..1a9f191695b 100644 --- a/rs/http_endpoints/public/src/read_state/canister.rs +++ b/rs/http_endpoints/public/src/read_state/canister.rs @@ -169,7 +169,7 @@ pub(crate) async fn canister_read_state( match validator.validate_request(&request_c, current_time(), &root_of_trust_provider) { Ok(targets) => targets, Err(err) => { - let http_err = validation_error_to_http_error(request.id(), err, &log); + let http_err = validation_error_to_http_error(&request, err, &log); return (http_err.status, http_err.message).into_response(); } }; From 8d79795caed869aa3c6aeaa682ce63c0b0e39e8d Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" <189003650+pr-automation-bot-public[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:38:06 +0100 Subject: [PATCH 65/98] chore: Update Mainnet IC revisions subnets file (#3418) Update mainnet revisions file to include the latest version released on the mainnet. This PR is created automatically using [`mainnet_revisions.py`](https://github.com/dfinity/ic/blob/master/ci/src/mainnet_revisions/mainnet_revisions.py) Co-authored-by: CI Automation --- mainnet-subnet-revisions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainnet-subnet-revisions.json b/mainnet-subnet-revisions.json index c29b115e706..02ebe42e34c 100644 --- a/mainnet-subnet-revisions.json +++ b/mainnet-subnet-revisions.json @@ -1,6 +1,6 @@ { "subnets": { - "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe": "d69648b2f5a3d90fb515824314ac2f868cbf499a", + "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe": "43670245ed6919790e7858813c7e838c6fbcedf5", "io67a-2jmkw-zup3h-snbwi-g6a5n-rm5dn-b6png-lvdpl-nqnto-yih6l-gqe": "43670245ed6919790e7858813c7e838c6fbcedf5" } } \ No newline at end of file From c16efb0730e89ca94eb4baa7cf195715f50100d4 Mon Sep 17 00:00:00 2001 From: Adam Bratschi-Kaye Date: Mon, 13 Jan 2025 14:40:11 +0100 Subject: [PATCH 66/98] feat(EXC-1795): Limit cache disk space (#3366) EXC-1795 Add the ability for the LRU cache to limit space used on disk as well as in memory and use this in the `CompilationCache` so that it doesn't grow to large. --- Cargo.lock | 1 + rs/embedders/src/compilation_cache.rs | 22 +- rs/embedders/src/serialized_module.rs | 19 +- rs/execution_environment/src/hypervisor.rs | 36 +- .../src/query_handler/query_cache.rs | 38 ++- .../src/query_handler/query_cache/tests.rs | 72 ++-- .../src/execution_environment/errors.rs | 10 +- rs/types/types/src/ingress.rs | 12 +- rs/types/types/src/lib.rs | 50 ++- rs/types/wasm_types/src/lib.rs | 10 +- rs/utils/lru_cache/BUILD.bazel | 4 +- rs/utils/lru_cache/Cargo.toml | 3 + rs/utils/lru_cache/src/lib.rs | 321 ++++++++++++++---- 13 files changed, 450 insertions(+), 148 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 909606d2516..ea77ce2b3f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13318,6 +13318,7 @@ version = "0.9.0" dependencies = [ "ic-types", "lru", + "proptest", ] [[package]] diff --git a/rs/embedders/src/compilation_cache.rs b/rs/embedders/src/compilation_cache.rs index 2ef9a6cdf96..73f9f98d092 100644 --- a/rs/embedders/src/compilation_cache.rs +++ b/rs/embedders/src/compilation_cache.rs @@ -15,10 +15,12 @@ use crate::{ }; use ic_interfaces::execution_environment::{HypervisorError, HypervisorResult}; use ic_replicated_state::canister_state::execution_state::WasmMetadata; -use ic_types::{methods::WasmMethod, NumBytes, NumInstructions}; +use ic_types::{methods::WasmMethod, MemoryDiskBytes, NumBytes, NumInstructions}; use ic_utils_lru_cache::LruCache; use ic_wasm_types::{CanisterModule, WasmHash}; +const GB: u64 = 1024 * 1024 * 1024; + /// Stores the serialized modules of wasm code that has already been compiled so /// that it can be used again without recompiling. pub enum CompilationCache { @@ -36,10 +38,26 @@ pub enum CompilationCache { }, } +impl MemoryDiskBytes for CompilationCache { + fn memory_bytes(&self) -> usize { + match self { + CompilationCache::Memory { cache } => cache.lock().unwrap().memory_bytes(), + CompilationCache::Disk { cache, .. } => cache.lock().unwrap().memory_bytes(), + } + } + + fn disk_bytes(&self) -> usize { + match self { + CompilationCache::Memory { cache } => cache.lock().unwrap().disk_bytes(), + CompilationCache::Disk { cache, .. } => cache.lock().unwrap().disk_bytes(), + } + } +} + impl CompilationCache { pub fn new(capacity: NumBytes) -> Self { Self::Memory { - cache: Mutex::new(LruCache::new(capacity)), + cache: Mutex::new(LruCache::new(capacity, NumBytes::from(GB))), } } diff --git a/rs/embedders/src/serialized_module.rs b/rs/embedders/src/serialized_module.rs index db8f8954c15..41d99b7e7a9 100644 --- a/rs/embedders/src/serialized_module.rs +++ b/rs/embedders/src/serialized_module.rs @@ -10,7 +10,7 @@ use std::{ use ic_interfaces::execution_environment::{HypervisorError, HypervisorResult}; use ic_replicated_state::canister_state::execution_state::WasmMetadata; -use ic_types::{methods::WasmMethod, CountBytes, NumInstructions}; +use ic_types::{methods::WasmMethod, MemoryDiskBytes, NumInstructions}; use ic_wasm_types::WasmEngineError; use nix::sys::mman::{mmap, MapFlags, ProtFlags}; use serde::{Deserialize, Serialize}; @@ -82,10 +82,14 @@ pub struct SerializedModule { pub is_wasm64: bool, } -impl CountBytes for SerializedModule { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for SerializedModule { + fn memory_bytes(&self) -> usize { self.bytes.0.len() } + + fn disk_bytes(&self) -> usize { + 0 + } } impl SerializedModule { @@ -147,10 +151,15 @@ pub struct OnDiskSerializedModule { pub is_wasm64: bool, } -impl CountBytes for OnDiskSerializedModule { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for OnDiskSerializedModule { + fn memory_bytes(&self) -> usize { std::mem::size_of::() } + + fn disk_bytes(&self) -> usize { + (self.bytes.metadata().unwrap().len() + self.initial_state_data.metadata().unwrap().len()) + as usize + } } impl OnDiskSerializedModule { diff --git a/rs/execution_environment/src/hypervisor.rs b/rs/execution_environment/src/hypervisor.rs index 6bbc702b7aa..4e472eff012 100644 --- a/rs/execution_environment/src/hypervisor.rs +++ b/rs/execution_environment/src/hypervisor.rs @@ -21,11 +21,11 @@ use ic_replicated_state::{NetworkTopology, ReplicatedState}; use ic_system_api::ExecutionParameters; use ic_system_api::{sandbox_safe_system_state::SandboxSafeSystemState, ApiType}; use ic_types::{ - messages::RequestMetadata, methods::FuncRef, CanisterId, NumBytes, NumInstructions, SubnetId, - Time, + messages::RequestMetadata, methods::FuncRef, CanisterId, MemoryDiskBytes, NumBytes, + NumInstructions, SubnetId, Time, }; use ic_wasm_types::CanisterModule; -use prometheus::{Histogram, HistogramVec, IntCounter, IntGauge}; +use prometheus::{Histogram, HistogramVec, IntCounter, IntGauge, IntGaugeVec}; use std::{ path::{Path, PathBuf}, sync::Arc, @@ -50,6 +50,7 @@ pub struct HypervisorMetrics { mmap_count: HistogramVec, mprotect_count: HistogramVec, copy_page_count: HistogramVec, + compilation_cache_size: IntGaugeVec, } impl HypervisorMetrics { @@ -124,6 +125,8 @@ impl HypervisorMetrics { decimal_buckets_with_zero(0,8), &["api_type", "memory_type"] ), + compilation_cache_size: metrics_registry.int_gauge_vec("hypervisor_compilation_cache_size", "Bytes in memory and on disk used by the compilation cache.", &["location"], + ), } } @@ -184,7 +187,12 @@ impl HypervisorMetrics { } } - fn observe_compilation_metrics(&self, compilation_result: &CompilationResult) { + fn observe_compilation_metrics( + &self, + compilation_result: &CompilationResult, + cache_memory_size: usize, + cache_disk_size: usize, + ) { let CompilationResult { largest_function_instruction_count, compilation_time, @@ -194,6 +202,12 @@ impl HypervisorMetrics { .observe(largest_function_instruction_count.get() as f64); self.compile.observe(compilation_time.as_secs_f64()); self.max_complexity.observe(*max_complexity as f64); + self.compilation_cache_size + .with_label_values(&["memory"]) + .set(cache_memory_size as i64); + self.compilation_cache_size + .with_label_values(&["disk"]) + .set(cache_disk_size as i64); } } @@ -255,8 +269,11 @@ impl Hypervisor { match creation_result { Ok((execution_state, compilation_cost, compilation_result)) => { if let Some(compilation_result) = compilation_result { - self.metrics - .observe_compilation_metrics(&compilation_result); + self.metrics.observe_compilation_metrics( + &compilation_result, + self.compilation_cache.memory_bytes(), + self.compilation_cache.disk_bytes(), + ); } round_limits.instructions -= as_round_instructions( compilation_cost_handling.adjusted_compilation_cost(compilation_cost), @@ -489,8 +506,11 @@ impl Hypervisor { execution_state, ); if let Some(compilation_result) = compilation_result { - self.metrics - .observe_compilation_metrics(&compilation_result); + self.metrics.observe_compilation_metrics( + &compilation_result, + self.compilation_cache.memory_bytes(), + self.compilation_cache.disk_bytes(), + ); } self.metrics.observe(&execution_result, api_type_str); diff --git a/rs/execution_environment/src/query_handler/query_cache.rs b/rs/execution_environment/src/query_handler/query_cache.rs index 0c6a1752998..43dcecc809b 100644 --- a/rs/execution_environment/src/query_handler/query_cache.rs +++ b/rs/execution_environment/src/query_handler/query_cache.rs @@ -8,7 +8,7 @@ use ic_types::{ batch::QueryStats, ingress::WasmResult, messages::{Query, QuerySource}, - CountBytes, Cycles, PrincipalId, Time, UserId, + Cycles, MemoryDiskBytes, PrincipalId, Time, UserId, }; use ic_utils_lru_cache::LruCache; use prometheus::{Histogram, IntCounter, IntGauge}; @@ -140,10 +140,14 @@ pub(crate) struct EntryKey { pub method_payload: Vec, } -impl CountBytes for EntryKey { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for EntryKey { + fn memory_bytes(&self) -> usize { size_of_val(self) + self.method_name.len() + self.method_payload.len() } + + fn disk_bytes(&self) -> usize { + 0 + } } impl From<&Query> for EntryKey { @@ -211,9 +215,13 @@ pub(crate) struct EntryValue { ignore_canister_balances: bool, } -impl CountBytes for EntryValue { - fn count_bytes(&self) -> usize { - size_of_val(self) + self.result.count_bytes() +impl MemoryDiskBytes for EntryValue { + fn memory_bytes(&self) -> usize { + size_of_val(self) + self.result.memory_bytes() + } + + fn disk_bytes(&self) -> usize { + 0 } } @@ -377,9 +385,13 @@ pub(crate) struct QueryCache { pub(crate) metrics: QueryCacheMetrics, } -impl CountBytes for QueryCache { - fn count_bytes(&self) -> usize { - size_of_val(self) + self.cache.lock().unwrap().count_bytes() +impl MemoryDiskBytes for QueryCache { + fn memory_bytes(&self) -> usize { + size_of_val(self) + self.cache.lock().unwrap().memory_bytes() + } + + fn disk_bytes(&self) -> usize { + 0 } } @@ -392,7 +404,7 @@ impl QueryCache { data_certificate_expiry_time: Duration, ) -> Self { QueryCache { - cache: Mutex::new(LruCache::new(capacity)), + cache: Mutex::new(LruCache::new(capacity, NumBytes::from(0))), max_expiry_time, data_certificate_expiry_time, metrics: QueryCacheMetrics::new(metrics_registry), @@ -422,7 +434,7 @@ impl QueryCache { // The cache entry is no longer valid, remove it. cache.pop(key); // Update the `count_bytes` metric. - self.metrics.count_bytes.set(cache.count_bytes() as i64); + self.metrics.count_bytes.set(cache.memory_bytes() as i64); } } None @@ -470,8 +482,8 @@ impl QueryCache { let d = evicted_value.elapsed_seconds(now); self.metrics.evicted_entries_duration.observe(d); } - let count_bytes = cache.count_bytes() as i64; - self.metrics.count_bytes.set(count_bytes); + let memory_bytes = cache.memory_bytes() as i64; + self.metrics.count_bytes.set(memory_bytes); self.metrics.len.set(cache.len() as i64); } } diff --git a/rs/execution_environment/src/query_handler/query_cache/tests.rs b/rs/execution_environment/src/query_handler/query_cache/tests.rs index 009c6beb9d9..45a74ced43c 100644 --- a/rs/execution_environment/src/query_handler/query_cache/tests.rs +++ b/rs/execution_environment/src/query_handler/query_cache/tests.rs @@ -16,7 +16,7 @@ use ic_types::{ batch::QueryStats, ingress::WasmResult, messages::{CanisterTask, Query, QuerySource}, - time, CountBytes, + time, MemoryDiskBytes, }; use ic_types_test_utils::ids::subnet_test_id; use ic_universal_canister::call_args; @@ -166,7 +166,7 @@ fn query_cache_reports_hits_and_misses_metrics() { } #[test] -fn query_cache_reports_evicted_entries_and_count_bytes_metrics() { +fn query_cache_reports_evicted_entries_and_memory_bytes_metrics() { const QUERY_CACHE_SIZE: usize = 2; /// Includes some room for the keys, headers etc. const QUERY_CACHE_CAPACITY: usize = REPLY_SIZE * (QUERY_CACHE_SIZE + 1); @@ -202,16 +202,16 @@ fn query_cache_reports_evicted_entries_and_count_bytes_metrics() { ); assert_eq!(0, m.invalidated_entries.get()); - let count_bytes = m.count_bytes.get() as usize; + let memory_bytes = m.count_bytes.get() as usize; // We can't match the size exactly, as it includes the key and the captured environment. // But we can assert that the sum of the sizes should be: - // REPLY_SIZE < count_bytes < REPLY_SIZE * 2 - assert!(REPLY_SIZE < count_bytes); - assert!(REPLY_SIZE * 2 * QUERY_CACHE_SIZE > count_bytes); + // REPLY_SIZE < memory_bytes < REPLY_SIZE * 2 + assert!(REPLY_SIZE < memory_bytes); + assert!(REPLY_SIZE * 2 * QUERY_CACHE_SIZE > memory_bytes); } #[test] -fn query_cache_reports_count_bytes_metric_on_invalidation() { +fn query_cache_reports_memory_bytes_metric_on_invalidation() { let mut test = builder_with_query_caching().build(); let a_id = test.universal_canister().unwrap(); let key = EntryKey { @@ -225,8 +225,8 @@ fn query_cache_reports_count_bytes_metric_on_invalidation() { let m = query_cache_metrics(&test); assert_eq!(0, m.hits.get()); assert_eq!(0, m.misses.get()); - let initial_count_bytes = m.count_bytes.get(); - assert!((initial_count_bytes as usize) < BIG_REPLY_SIZE); + let initial_memory_bytes = m.count_bytes.get(); + assert!((initial_memory_bytes as usize) < BIG_REPLY_SIZE); // Push a big result into the cache. let big_result = Ok(WasmResult::Reply(vec![0; BIG_REPLY_SIZE])); @@ -243,8 +243,8 @@ fn query_cache_reports_count_bytes_metric_on_invalidation() { ); assert_eq!(0, m.hits.get()); assert_eq!(1, m.misses.get()); - let count_bytes = m.count_bytes.get(); - assert!(((count_bytes - initial_count_bytes) as usize) > BIG_REPLY_SIZE); + let memory_bytes = m.count_bytes.get(); + assert!(((memory_bytes - initial_memory_bytes) as usize) > BIG_REPLY_SIZE); // Bump up the version test.canister_state_mut(a_id).system_state.canister_version += 1; @@ -255,8 +255,8 @@ fn query_cache_reports_count_bytes_metric_on_invalidation() { let m = query_cache_metrics(&test); assert_eq!(0, m.hits.get()); assert_eq!(1, m.misses.get()); - let final_count_bytes = m.count_bytes.get(); - assert!((final_count_bytes as usize) < BIG_REPLY_SIZE); + let final_memory_bytes = m.count_bytes.get(); + assert!((final_memory_bytes as usize) < BIG_REPLY_SIZE); } #[test] @@ -765,18 +765,18 @@ fn query_cache_frees_memory_after_invalidated_entries() { .build(); let id = test.canister_from_wat(QUERY_CACHE_WAT).unwrap(); - let count_bytes = query_cache(&test).count_bytes(); + let memory_bytes = query_cache(&test).memory_bytes(); // Initially the cache should be empty, i.e. less than 1MB. - assert!(count_bytes < BIG_RESPONSE_SIZE); + assert!(memory_bytes < BIG_RESPONSE_SIZE); // The 1MB result will be cached internally. let res = test .non_replicated_query(id, "canister_balance_sized_reply", vec![]) .unwrap(); - assert_eq!(BIG_RESPONSE_SIZE, res.count_bytes()); - let count_bytes = query_cache(&test).count_bytes(); + assert_eq!(BIG_RESPONSE_SIZE, res.memory_bytes()); + let memory_bytes = query_cache(&test).memory_bytes(); // After the first reply, the cache should have more than 1MB of data. - assert!(count_bytes > BIG_RESPONSE_SIZE); + assert!(memory_bytes > BIG_RESPONSE_SIZE); // Set the canister balance to 42, so the second reply will have just 42 bytes. test.canister_state_mut(id).system_state.remove_cycles( @@ -788,11 +788,11 @@ fn query_cache_frees_memory_after_invalidated_entries() { let res = test .non_replicated_query(id, "canister_balance_sized_reply", vec![]) .unwrap(); - assert_eq!(SMALL_RESPONSE_SIZE, res.count_bytes()); - let count_bytes = query_cache(&test).count_bytes(); + assert_eq!(SMALL_RESPONSE_SIZE, res.memory_bytes()); + let memory_bytes = query_cache(&test).memory_bytes(); // The second 42 reply should invalidate and replace the first 1MB reply in the cache. - assert!(count_bytes > SMALL_RESPONSE_SIZE); - assert!(count_bytes < BIG_RESPONSE_SIZE); + assert!(memory_bytes > SMALL_RESPONSE_SIZE); + assert!(memory_bytes < BIG_RESPONSE_SIZE); } #[test] @@ -803,8 +803,8 @@ fn query_cache_respects_cache_capacity() { let id = test.universal_canister().unwrap(); // Initially the cache should be empty, i.e. less than REPLY_SIZE. - let count_bytes = query_cache(&test).count_bytes(); - assert!(count_bytes < REPLY_SIZE); + let memory_bytes = query_cache(&test).memory_bytes(); + assert!(memory_bytes < REPLY_SIZE); // All replies should hit the same cache entry. for _ in 0..ITERATIONS { @@ -812,9 +812,9 @@ fn query_cache_respects_cache_capacity() { let _res = test.non_replicated_query(id, "query", wasm().reply_data(&[1; REPLY_SIZE / 2]).build()); // Now there should be only one reply in the cache. - let count_bytes = query_cache(&test).count_bytes(); - assert!(count_bytes > REPLY_SIZE); - assert!(count_bytes < QUERY_CACHE_CAPACITY); + let memory_bytes = query_cache(&test).memory_bytes(); + assert!(memory_bytes > REPLY_SIZE); + assert!(memory_bytes < QUERY_CACHE_CAPACITY); } // Now the replies should hit another entry. @@ -822,9 +822,9 @@ fn query_cache_respects_cache_capacity() { let _res = test.non_replicated_query(id, "query", wasm().reply_data(&[2; REPLY_SIZE / 2]).build()); // Now there should be two replies in the cache. - let count_bytes = query_cache(&test).count_bytes(); - assert!(count_bytes > REPLY_SIZE * 2); - assert!(count_bytes < QUERY_CACHE_CAPACITY); + let memory_bytes = query_cache(&test).memory_bytes(); + assert!(memory_bytes > REPLY_SIZE * 2); + assert!(memory_bytes < QUERY_CACHE_CAPACITY); } // Now the replies should evict the first entry. @@ -832,9 +832,9 @@ fn query_cache_respects_cache_capacity() { let _res = test.non_replicated_query(id, "query", wasm().reply_data(&[3; REPLY_SIZE / 2]).build()); // There should be still just two replies in the cache. - let count_bytes = query_cache(&test).count_bytes(); - assert!(count_bytes > REPLY_SIZE * 2); - assert!(count_bytes < QUERY_CACHE_CAPACITY); + let memory_bytes = query_cache(&test).memory_bytes(); + assert!(memory_bytes > REPLY_SIZE * 2); + assert!(memory_bytes < QUERY_CACHE_CAPACITY); } } @@ -844,13 +844,13 @@ fn query_cache_works_with_zero_cache_capacity() { let id = test.universal_canister().unwrap(); // Even with zero capacity the cache data structure uses some bytes for the pointers etc. - let initial_count_bytes = query_cache(&test).count_bytes(); + let initial_memory_bytes = query_cache(&test).memory_bytes(); // Replies should not change the initial (zero) capacity. for _ in 0..ITERATIONS { let _res = test.non_replicated_query(id, "query", wasm().reply_data(&[1]).build()); - let count_bytes = query_cache(&test).count_bytes(); - assert_eq!(initial_count_bytes, count_bytes); + let memory_bytes = query_cache(&test).memory_bytes(); + assert_eq!(initial_memory_bytes, memory_bytes); } } diff --git a/rs/interfaces/src/execution_environment/errors.rs b/rs/interfaces/src/execution_environment/errors.rs index 765d808b496..073967a0323 100644 --- a/rs/interfaces/src/execution_environment/errors.rs +++ b/rs/interfaces/src/execution_environment/errors.rs @@ -1,6 +1,6 @@ use ic_base_types::{NumBytes, PrincipalIdBlobParseError}; use ic_error_types::UserError; -use ic_types::{methods::WasmMethod, CanisterId, CountBytes, Cycles, NumInstructions}; +use ic_types::{methods::WasmMethod, CanisterId, Cycles, MemoryDiskBytes, NumInstructions}; use ic_wasm_types::{ doc_ref, AsErrorHelp, ErrorHelp, WasmEngineError, WasmInstrumentationError, WasmValidationError, }; @@ -385,10 +385,14 @@ impl std::fmt::Display for HypervisorError { } } -impl CountBytes for HypervisorError { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for HypervisorError { + fn memory_bytes(&self) -> usize { std::mem::size_of::() } + + fn disk_bytes(&self) -> usize { + 0 + } } impl AsErrorHelp for HypervisorError { diff --git a/rs/types/types/src/ingress.rs b/rs/types/types/src/ingress.rs index 60ff68a0b63..3985fcd80ab 100644 --- a/rs/types/types/src/ingress.rs +++ b/rs/types/types/src/ingress.rs @@ -1,7 +1,7 @@ //! Ingress types. use crate::artifact::IngressMessageId; -use crate::{CanisterId, CountBytes, PrincipalId, Time, UserId}; +use crate::{CanisterId, MemoryDiskBytes, PrincipalId, Time, UserId}; use ic_error_types::{ErrorCode, UserError}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; @@ -107,7 +107,7 @@ impl IngressStatus { pub fn payload_bytes(&self) -> usize { match self { IngressStatus::Known { state, .. } => match state { - IngressState::Completed(result) => result.count_bytes(), + IngressState::Completed(result) => result.memory_bytes(), IngressState::Failed(error) => error.description().as_bytes().len(), _ => 0, }, @@ -176,13 +176,17 @@ pub enum WasmResult { Reject(String), } -impl CountBytes for WasmResult { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for WasmResult { + fn memory_bytes(&self) -> usize { match self { WasmResult::Reply(bytes) => bytes.len(), WasmResult::Reject(string) => string.as_bytes().len(), } } + + fn disk_bytes(&self) -> usize { + 0 + } } impl WasmResult { diff --git a/rs/types/types/src/lib.rs b/rs/types/types/src/lib.rs index 2f5f8951ac0..aa2f743e5ea 100644 --- a/rs/types/types/src/lib.rs +++ b/rs/types/types/src/lib.rs @@ -529,30 +529,56 @@ pub trait CountBytes { fn count_bytes(&self) -> usize; } -impl CountBytes for Time { - fn count_bytes(&self) -> usize { +/// Allow an object to reprt its own byte size on disk and in memory. Not +/// necessarilly exact. +pub trait MemoryDiskBytes { + fn memory_bytes(&self) -> usize; + fn disk_bytes(&self) -> usize; +} + +impl MemoryDiskBytes for Time { + fn memory_bytes(&self) -> usize { 8 } + + fn disk_bytes(&self) -> usize { + 0 + } } -impl CountBytes for Result { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for Result { + fn memory_bytes(&self) -> usize { + match self { + Ok(result) => result.memory_bytes(), + Err(err) => err.memory_bytes(), + } + } + + fn disk_bytes(&self) -> usize { match self { - Ok(result) => result.count_bytes(), - Err(err) => err.count_bytes(), + Ok(result) => result.disk_bytes(), + Err(err) => err.disk_bytes(), } } } -impl CountBytes for Arc { - fn count_bytes(&self) -> usize { - self.as_ref().count_bytes() +impl MemoryDiskBytes for Arc { + fn memory_bytes(&self) -> usize { + self.as_ref().memory_bytes() + } + + fn disk_bytes(&self) -> usize { + self.as_ref().disk_bytes() } } -// Implementing `CountBytes` in `ic_error_types` introduces a circular dependency. -impl CountBytes for ic_error_types::UserError { - fn count_bytes(&self) -> usize { +// Implementing `MemoryDiskBytes` in `ic_error_types` introduces a circular dependency. +impl MemoryDiskBytes for ic_error_types::UserError { + fn memory_bytes(&self) -> usize { self.count_bytes() } + + fn disk_bytes(&self) -> usize { + 0 + } } diff --git a/rs/types/wasm_types/src/lib.rs b/rs/types/wasm_types/src/lib.rs index 611e3d3431c..91a6390e4ff 100644 --- a/rs/types/wasm_types/src/lib.rs +++ b/rs/types/wasm_types/src/lib.rs @@ -6,7 +6,7 @@ pub use errors::{ doc_ref, AsErrorHelp, ErrorHelp, WasmEngineError, WasmError, WasmInstrumentationError, WasmValidationError, }; -use ic_types::CountBytes; +use ic_types::MemoryDiskBytes; use ic_utils::byte_slice_fmt::truncate_and_format; use ic_validate_eq::ValidateEq; use ic_validate_eq_derive::ValidateEq; @@ -174,10 +174,14 @@ impl TryFrom> for WasmHash { } } -impl CountBytes for WasmHash { - fn count_bytes(&self) -> usize { +impl MemoryDiskBytes for WasmHash { + fn memory_bytes(&self) -> usize { self.0.len() } + + fn disk_bytes(&self) -> usize { + 0 + } } impl std::fmt::Display for WasmHash { diff --git a/rs/utils/lru_cache/BUILD.bazel b/rs/utils/lru_cache/BUILD.bazel index a148d9cb8fd..7b07074ae14 100644 --- a/rs/utils/lru_cache/BUILD.bazel +++ b/rs/utils/lru_cache/BUILD.bazel @@ -17,7 +17,9 @@ rust_library( rust_test( name = "lru_cache_test", crate = ":lru_cache", - deps = [], + deps = [ + "@crate_index//:proptest", + ], ) rust_doc_test( diff --git a/rs/utils/lru_cache/Cargo.toml b/rs/utils/lru_cache/Cargo.toml index f6218e6897c..cdf5ebe48b5 100644 --- a/rs/utils/lru_cache/Cargo.toml +++ b/rs/utils/lru_cache/Cargo.toml @@ -11,3 +11,6 @@ documentation.workspace = true [dependencies] ic-types = { path = "../../types/types" } lru = { version = "0.7.8", default-features = false } + +[dev-dependencies] +proptest = { workspace = true } diff --git a/rs/utils/lru_cache/src/lib.rs b/rs/utils/lru_cache/src/lib.rs index c181fd32343..e6a5a14ea53 100644 --- a/rs/utils/lru_cache/src/lib.rs +++ b/rs/utils/lru_cache/src/lib.rs @@ -1,4 +1,4 @@ -use ic_types::{CountBytes, NumBytes}; +use ic_types::{MemoryDiskBytes, NumBytes}; use std::hash::Hash; /// The upper bound on cache item size and cache capacity. @@ -11,38 +11,48 @@ const MAX_SIZE: usize = usize::MAX / 2; /// sizes of the cached items does not exceed the pre-configured capacity. pub struct LruCache where - K: CountBytes + Eq + Hash, - V: CountBytes, + K: MemoryDiskBytes + Eq + Hash, + V: MemoryDiskBytes, { cache: lru::LruCache, - capacity: usize, - size: usize, + memory_capacity: usize, + disk_capacity: usize, + memory_size: usize, + disk_size: usize, } -impl CountBytes for LruCache +impl MemoryDiskBytes for LruCache where - K: CountBytes + Eq + Hash, - V: CountBytes, + K: MemoryDiskBytes + Eq + Hash, + V: MemoryDiskBytes, { - fn count_bytes(&self) -> usize { - self.size + fn memory_bytes(&self) -> usize { + self.memory_size + } + + fn disk_bytes(&self) -> usize { + self.disk_size } } impl LruCache where - K: CountBytes + Eq + Hash, - V: CountBytes, + K: MemoryDiskBytes + Eq + Hash, + V: MemoryDiskBytes, { - /// Constructs a new LRU cache with the given capacity. - /// The capacity must not exceed `MAX_SIZE = (2^63 - 1)`. - pub fn new(capacity: NumBytes) -> Self { - let capacity = capacity.get() as usize; - assert!(capacity <= MAX_SIZE); + /// Constructs a new LRU cache with the given memory and disk capacity. The + /// capacities must not exceed `MAX_SIZE = (2^63 - 1)`. + pub fn new(memory_capacity: NumBytes, disk_capacity: NumBytes) -> Self { + let memory_capacity = memory_capacity.get() as usize; + let disk_capacity = disk_capacity.get() as usize; + assert!(memory_capacity <= MAX_SIZE); + assert!(disk_capacity <= MAX_SIZE); let lru_cache = Self { cache: lru::LruCache::unbounded(), - capacity, - size: 0, + memory_capacity, + disk_capacity, + memory_size: 0, + disk_size: 0, }; lru_cache.check_invariants(); lru_cache @@ -50,7 +60,10 @@ where /// Creates a new LRU Cache that never automatically evicts items. pub fn unbounded() -> Self { - Self::new(NumBytes::new(MAX_SIZE as u64)) + Self::new( + NumBytes::new(MAX_SIZE as u64), + NumBytes::new(MAX_SIZE as u64), + ) } /// Returns the value corresponding to the given key. @@ -63,21 +76,31 @@ where /// the cache or other cache entries are evicted (due to the cache capacity), /// then it returns the old entry's key-value pairs. Otherwise, returns an empty vector. pub fn push(&mut self, key: K, value: V) -> Vec<(K, V)> { - let size = key.count_bytes() + value.count_bytes(); - assert!(size <= MAX_SIZE); + let memory_size = key.memory_bytes() + value.memory_bytes(); + assert!(memory_size <= MAX_SIZE); + let disk_size = key.disk_bytes() + value.disk_bytes(); + assert!(disk_size <= MAX_SIZE); let removed_entry = self.cache.push(key, value); if let Some((removed_key, removed_value)) = &removed_entry { - let removed_size = removed_key.count_bytes() + removed_value.count_bytes(); - debug_assert!(self.size >= removed_size); - // This cannot underflow because we know that `self.size` is + let memory_removed_size = removed_key.memory_bytes() + removed_value.memory_bytes(); + debug_assert!(self.memory_size >= memory_removed_size); + // This cannot underflow because we know that `self.memory_size` is // the sum of sizes of all items in the cache. - self.size -= removed_size; + self.memory_size -= memory_removed_size; + + let disk_removed_size = removed_key.disk_bytes() + removed_value.disk_bytes(); + debug_assert!(self.disk_size >= disk_removed_size); + // This cannot underflow because we know that `self.disk_size` is + // the sum of sizes of all items in the cache. + self.disk_size -= disk_removed_size; } // This cannot overflow because we know that - // `self.size <= self.capacity <= MAX_SIZE` - // and `size <= MAX_SIZE == usize::MAX / 2`. - self.size += size; + // `self.memory_size <= self.memory_capacity <= MAX_SIZE` + // and `memory_size <= MAX_SIZE == usize::MAX / 2`. + self.memory_size += memory_size; + // Similar as for `memory_size``. + self.disk_size += disk_size; let mut evicted_entries = self.evict(); self.check_invariants(); @@ -89,9 +112,14 @@ where /// `None` if it does not exist. pub fn pop(&mut self, key: &K) -> Option { if let Some((key, value)) = self.cache.pop_entry(key) { - let size = key.count_bytes() + value.count_bytes(); - debug_assert!(self.size >= size); - self.size -= size; + let memory_size = key.memory_bytes() + value.memory_bytes(); + debug_assert!(self.memory_size >= memory_size); + self.memory_size -= memory_size; + + let disk_size = key.disk_bytes() + value.disk_bytes(); + debug_assert!(self.disk_size >= disk_size); + self.disk_size -= disk_size; + self.check_invariants(); Some(value) } else { @@ -102,7 +130,8 @@ where /// Clears the cache by removing all items. pub fn clear(&mut self) { self.cache.clear(); - self.size = 0; + self.memory_size = 0; + self.disk_size = 0; self.check_invariants(); } @@ -120,14 +149,20 @@ where /// Returns the vector of evicted key-value pairs. fn evict(&mut self) -> Vec<(K, V)> { let mut ret = vec![]; - while self.size > self.capacity { + while self.memory_size > self.memory_capacity || self.disk_size > self.disk_capacity { match self.cache.pop_lru() { Some((key, value)) => { - let size = key.count_bytes() + value.count_bytes(); - debug_assert!(self.size >= size); - // This cannot underflow because we know that `self.size` is - // the sum of sizes of all items in the cache. - self.size -= size; + let memory_size = key.memory_bytes() + value.memory_bytes(); + debug_assert!(self.memory_size >= memory_size); + // This cannot underflow because we know that `self.memory_size` is + // the sum of memory sizes of all items in the cache. + self.memory_size = self.memory_size.saturating_sub(memory_size); + + let disk_size = key.disk_bytes() + value.disk_bytes(); + debug_assert!(self.disk_size >= disk_size); + // This cannot underflow because we know that `self.disk_size` is + // the sum of disk sizes of all items in the cache. + self.disk_size = self.disk_size.saturating_sub(disk_size); ret.push((key, value)); } @@ -143,14 +178,22 @@ where #[cfg(debug_assertions)] if self.len() < 1_000 { debug_assert_eq!( - self.size, + self.memory_size, + self.cache + .iter() + .map(|(key, value)| key.memory_bytes() + value.memory_bytes()) + .sum::() + ); + debug_assert_eq!( + self.disk_size, self.cache .iter() - .map(|(key, value)| key.count_bytes() + value.count_bytes()) + .map(|(key, value)| key.disk_bytes() + value.disk_bytes()) .sum::() ); } - debug_assert!(self.size <= self.capacity); + debug_assert!(self.memory_size <= self.memory_capacity); + debug_assert!(self.disk_size <= self.disk_capacity); } } @@ -161,24 +204,45 @@ mod tests { #[derive(Eq, PartialEq, Hash, Debug)] struct ValueSize(u32, usize); - impl CountBytes for ValueSize { - fn count_bytes(&self) -> usize { + impl MemoryDiskBytes for ValueSize { + fn memory_bytes(&self) -> usize { + self.1 + } + + fn disk_bytes(&self) -> usize { + 0 + } + } + + #[derive(Eq, PartialEq, Hash, Debug)] + struct MemoryDiskValue(u32, usize, usize); + + impl MemoryDiskBytes for MemoryDiskValue { + fn memory_bytes(&self) -> usize { self.1 } + + fn disk_bytes(&self) -> usize { + self.2 + } } #[derive(Eq, PartialEq, Hash, Debug)] struct Key(u32); - impl CountBytes for Key { - fn count_bytes(&self) -> usize { + impl MemoryDiskBytes for Key { + fn memory_bytes(&self) -> usize { + 0 + } + + fn disk_bytes(&self) -> usize { 0 } } #[test] fn lru_cache_single_entry() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); assert!(lru.get(&Key(0)).is_none()); @@ -201,7 +265,7 @@ mod tests { #[test] fn lru_cache_multiple_entries() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); for i in 0..20 { lru.push(Key(i), ValueSize(i, 1)); @@ -219,7 +283,7 @@ mod tests { #[test] fn lru_cache_value_eviction() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); assert!(lru.get(&Key(0)).is_none()); @@ -269,7 +333,7 @@ mod tests { #[test] fn lru_cache_key_eviction() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); assert!(lru.get(&ValueSize(0, 10)).is_none()); @@ -325,7 +389,7 @@ mod tests { #[test] fn lru_cache_key_and_value_eviction() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); let evicted = lru.push(ValueSize(0, 5), ValueSize(42, 5)); assert_eq!(*lru.get(&ValueSize(0, 5)).unwrap(), ValueSize(42, 5)); @@ -359,7 +423,7 @@ mod tests { #[test] fn lru_cache_clear() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); lru.push(Key(0), ValueSize(0, 10)); lru.clear(); assert!(lru.get(&Key(0)).is_none()); @@ -367,7 +431,7 @@ mod tests { #[test] fn lru_cache_pop() { - let mut lru = LruCache::::new(NumBytes::new(10)); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(0)); lru.push(Key(0), ValueSize(0, 5)); lru.push(Key(1), ValueSize(1, 5)); lru.pop(&Key(0)); @@ -379,25 +443,160 @@ mod tests { #[test] fn lru_cache_count_bytes_and_len() { - let mut lru = LruCache::::new(NumBytes::new(10)); - assert_eq!(0, lru.count_bytes()); + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(20)); + assert_eq!(0, lru.memory_bytes()); + assert_eq!(0, lru.disk_bytes()); assert_eq!(0, lru.len()); assert!(lru.is_empty()); - lru.push(Key(0), ValueSize(0, 4)); - assert_eq!(4, lru.count_bytes()); + lru.push(Key(0), MemoryDiskValue(0, 4, 10)); + assert_eq!(4, lru.memory_bytes()); + assert_eq!(10, lru.disk_bytes()); assert_eq!(1, lru.len()); assert!(!lru.is_empty()); - lru.push(Key(1), ValueSize(1, 6)); - assert_eq!(10, lru.count_bytes()); + lru.push(Key(1), MemoryDiskValue(1, 6, 2)); + assert_eq!(10, lru.memory_bytes()); + assert_eq!(12, lru.disk_bytes()); assert_eq!(2, lru.len()); assert!(!lru.is_empty()); lru.pop(&Key(0)); - assert_eq!(6, lru.count_bytes()); + assert_eq!(6, lru.memory_bytes()); + assert_eq!(2, lru.disk_bytes()); assert_eq!(1, lru.len()); assert!(!lru.is_empty()); lru.pop(&Key(1)); - assert_eq!(0, lru.count_bytes()); + assert_eq!(0, lru.memory_bytes()); + assert_eq!(0, lru.disk_bytes()); assert_eq!(0, lru.len()); assert!(lru.is_empty()); } + + #[test] + fn lru_cache_disk_and_memory_single_entry() { + let mut lru = LruCache::::new(NumBytes::new(10), NumBytes::new(20)); + + assert!(lru.get(&Key(0)).is_none()); + + // Can't insert a value if memory or disk is too large. + let evicted = lru.push(Key(0), MemoryDiskValue(42, 11, 0)); + assert_eq!(lru.get(&Key(0)), None); + assert_eq!(evicted, vec![(Key(0), MemoryDiskValue(42, 11, 0))]); + + let evicted = lru.push(Key(0), MemoryDiskValue(42, 0, 21)); + assert_eq!(lru.get(&Key(0)), None); + assert_eq!(evicted, vec![(Key(0), MemoryDiskValue(42, 0, 21))]); + + // Can insert if both sizes fit. + let evicted = lru.push(Key(0), MemoryDiskValue(42, 10, 20)); + assert_eq!(*lru.get(&Key(0)).unwrap(), MemoryDiskValue(42, 10, 20)); + assert_eq!(evicted, vec![]); + + // Inserting a new value removes the old one if memory or disk is + // non-zero (since both are at capacity). + let evicted = lru.push(Key(1), MemoryDiskValue(42, 1, 0)); + assert_eq!(*lru.get(&Key(1)).unwrap(), MemoryDiskValue(42, 1, 0)); + assert_eq!(evicted, vec![(Key(0), MemoryDiskValue(42, 10, 20))]); + + lru.clear(); + let _ = lru.push(Key(0), MemoryDiskValue(42, 10, 20)); + let evicted = lru.push(Key(1), MemoryDiskValue(42, 0, 1)); + assert_eq!(*lru.get(&Key(1)).unwrap(), MemoryDiskValue(42, 0, 1)); + assert_eq!(evicted, vec![(Key(0), MemoryDiskValue(42, 10, 20))]); + } + + #[test] + fn lru_cache_key_and_value_eviction_mixing_memory_and_disk() { + let mut lru = + LruCache::::new(NumBytes::new(10), NumBytes::new(10)); + + let evicted = lru.push(MemoryDiskValue(0, 5, 1), MemoryDiskValue(42, 5, 1)); + assert_eq!( + *lru.get(&MemoryDiskValue(0, 5, 1)).unwrap(), + MemoryDiskValue(42, 5, 1) + ); + assert_eq!(evicted, vec![]); + + let evicted = lru.push(MemoryDiskValue(1, 0, 0), MemoryDiskValue(20, 0, 0)); + assert_eq!( + *lru.get(&MemoryDiskValue(0, 5, 1)).unwrap(), + MemoryDiskValue(42, 5, 1) + ); + assert_eq!( + *lru.get(&MemoryDiskValue(1, 0, 0)).unwrap(), + MemoryDiskValue(20, 0, 0) + ); + assert_eq!(evicted, vec![]); + + let evicted = lru.push(MemoryDiskValue(2, 5, 1), MemoryDiskValue(10, 5, 1)); + assert!(lru.get(&MemoryDiskValue(0, 5, 1)).is_none()); + assert_eq!( + *lru.get(&MemoryDiskValue(1, 0, 0)).unwrap(), + MemoryDiskValue(20, 0, 0) + ); + assert_eq!( + *lru.get(&MemoryDiskValue(2, 5, 1)).unwrap(), + MemoryDiskValue(10, 5, 1) + ); + // The least recently used is the first entry. + assert_eq!( + evicted, + vec![(MemoryDiskValue(0, 5, 1), MemoryDiskValue(42, 5, 1))] + ); + + let evicted = lru.push(MemoryDiskValue(3, 4, 9), MemoryDiskValue(30, 0, 1)); + assert!(lru.get(&MemoryDiskValue(1, 0, 0)).is_none()); + assert!(lru.get(&MemoryDiskValue(2, 5, 1)).is_none()); + assert_eq!( + *lru.get(&MemoryDiskValue(3, 4, 9)).unwrap(), + MemoryDiskValue(30, 0, 1) + ); + // Now the second and third entries are evicted. + assert_eq!( + evicted, + vec![ + (MemoryDiskValue(1, 0, 0), MemoryDiskValue(20, 0, 0)), + (MemoryDiskValue(2, 5, 1), MemoryDiskValue(10, 5, 1)) + ] + ); + } + + mod proptests { + use super::*; + use proptest::prelude::*; + + fn arb_value() -> impl Strategy { + (0..100_u32, 0..50_usize, 0..50_usize).prop_map(|(a, b, c)| MemoryDiskValue(a, b, c)) + } + + proptest! { + /// Proptest checking that the internal invariants are maintained + /// and that the total space of inserted entries equals the total + /// space of evicted entries plus the space of the cache itself. + #[test] + fn test_invariants(entries in prop::collection::vec((arb_value(), arb_value()), 100)) { + let mut lru = LruCache::::new(NumBytes::new(100), NumBytes::new(100)); + let mut total_memory = 0; + let mut total_disk = 0; + let mut evicted_memory = 0; + let mut evicted_disk = 0; + + fn update(memory: &mut usize, disk: &mut usize, k: &MemoryDiskValue, v: &MemoryDiskValue) { + *memory += k.memory_bytes(); + *memory += v.memory_bytes(); + *disk += k.disk_bytes(); + *disk += v.disk_bytes(); + } + + for (k,v) in entries { + update(&mut total_memory, &mut total_disk, &k, &v); + let evicted = lru.push(k,v); + for (k,v) in evicted { + update(&mut evicted_memory, &mut evicted_disk, &k, &v); + } + + assert_eq!(total_memory, evicted_memory + lru.memory_bytes()); + assert_eq!(total_disk, evicted_disk + lru.disk_bytes()); + } + } + } + } } From ad9ac37a629063180283f86bc4f6c0b43b64f432 Mon Sep 17 00:00:00 2001 From: venkkatesh-sekar <94061546+venkkatesh-sekar@users.noreply.github.com> Date: Mon, 13 Jan 2025 15:08:10 +0100 Subject: [PATCH 67/98] feat(fuzzing): Improve Wasm compilation fuzzer (#3380) This PR tries to improve the coverage of arbitrary Wasms generated by the wasm fuzzers. 1. Compilation fuzzer: - Added checks for non determinism in compilation errors. - The arbitrary Wasm module provided to the fuzzer has the current probability distribution ``` // 33% - Random bytes // 33% - Wasm with arbitrary wasm-smith config + maybe invalid functions // 33% - IC compliant wasm + maybe invalid functions ``` 2. `ICWasmModule` will generate both wasm32 and wasm64 modules. EmbeddersConfig and System API imports are handled accordingly. 3. Unify EmbeddersConfig in `ic_wasm.rs` --- rs/embedders/fuzz/BUILD.bazel | 3 +- .../compile_wasm_using_embedder.rs | 3 +- rs/embedders/fuzz/src/compile.rs | 128 ++++++++++++--- rs/embedders/fuzz/src/differential.rs | 153 ++++++++++-------- rs/embedders/fuzz/src/ic_wasm.rs | 31 +++- rs/embedders/fuzz/src/imports.rs | 35 ++-- rs/embedders/fuzz/src/wasm_executor.rs | 15 +- rs/embedders/fuzz/src/wasmtime.rs | 8 +- rs/embedders/fuzz/src/ws2wasm.rs | 5 +- .../fuzz_targets/execute_system_api_call.rs | 41 +++-- 10 files changed, 270 insertions(+), 152 deletions(-) diff --git a/rs/embedders/fuzz/BUILD.bazel b/rs/embedders/fuzz/BUILD.bazel index 0dc8718a006..493b36377ef 100644 --- a/rs/embedders/fuzz/BUILD.bazel +++ b/rs/embedders/fuzz/BUILD.bazel @@ -41,6 +41,7 @@ rust_library( "//rs/types/types", "//rs/types/wasm_types", "@crate_index//:arbitrary", + "@crate_index//:futures", "@crate_index//:lazy_static", "@crate_index//:libfuzzer-sys", "@crate_index//:tokio", @@ -121,7 +122,7 @@ rust_fuzz_test_binary_afl( deps = [":wasm_fuzzers"] + ["@crate_index//:libfuzzer-sys"], ) -rust_fuzz_test_binary( +rust_fuzz_test_binary_afl( name = "compile_wasm_using_embedder", srcs = ["fuzz_targets/compile_wasm_using_embedder.rs"], proc_macro_deps = MACRO_DEPENDENCIES, diff --git a/rs/embedders/fuzz/fuzz_targets/compile_wasm_using_embedder.rs b/rs/embedders/fuzz/fuzz_targets/compile_wasm_using_embedder.rs index 921bbcb232a..8f3dc85f78c 100644 --- a/rs/embedders/fuzz/fuzz_targets/compile_wasm_using_embedder.rs +++ b/rs/embedders/fuzz/fuzz_targets/compile_wasm_using_embedder.rs @@ -1,8 +1,7 @@ #![no_main] use libfuzzer_sys::fuzz_target; use wasm_fuzzers::compile::run_fuzzer; -use wasm_fuzzers::compile::MaybeInvalidModule; -fuzz_target!(|module: MaybeInvalidModule| { +fuzz_target!(|module: &[u8]| { run_fuzzer(module); }); diff --git a/rs/embedders/fuzz/src/compile.rs b/rs/embedders/fuzz/src/compile.rs index 1af30a58758..e552de23070 100644 --- a/rs/embedders/fuzz/src/compile.rs +++ b/rs/embedders/fuzz/src/compile.rs @@ -1,44 +1,134 @@ +use crate::ic_wasm::{generate_exports, ic_embedders_config, ic_wasm_config}; use arbitrary::{Arbitrary, Result, Unstructured}; -use ic_config::embedders::Config as EmbeddersConfig; -use ic_config::flag_status::FlagStatus; use ic_embedders::{wasm_utils::compile, WasmtimeEmbedder}; use ic_logger::replica_logger::no_op_logger; use ic_wasm_types::BinaryEncodedWasm; -use wasm_smith::{Config, Module}; +use std::time::Duration; +use tokio::runtime::Runtime; +use wasm_smith::{Config, MemoryOffsetChoices, Module}; #[derive(Debug)] -pub struct MaybeInvalidModule(pub Module); +pub struct MaybeInvalidModule { + pub module: Module, + pub memory64_enabled: bool, +} + +const MAX_PARALLEL_EXECUTIONS: usize = 4; impl<'a> Arbitrary<'a> for MaybeInvalidModule { fn arbitrary(u: &mut Unstructured<'a>) -> Result { - let mut config = Config::arbitrary(u)?; + let mut config = if u.ratio(1, 2)? { + let memory64_enabled = u.ratio(2, 3)?; + let mut config = ic_wasm_config(ic_embedders_config(memory64_enabled)); + config.exports = generate_exports(ic_embedders_config(memory64_enabled), u)?; + config.min_data_segments = 2; + config.max_data_segments = 10; + config + } else { + Config::arbitrary(u)? + }; config.allow_invalid_funcs = true; - Ok(MaybeInvalidModule(Module::new(config, u)?)) + config.memory_offset_choices = MemoryOffsetChoices(40, 20, 40); + Ok(MaybeInvalidModule { + module: Module::new(config.clone(), u)?, + memory64_enabled: config.memory64_enabled, + }) } } #[inline(always)] -pub fn run_fuzzer(module: MaybeInvalidModule) { - let mut config = EmbeddersConfig::default(); - config.feature_flags.wasm64 = FlagStatus::Enabled; - let wasm = module.0.to_bytes(); - let binary_wasm = BinaryEncodedWasm::new(wasm); - let embedder = WasmtimeEmbedder::new(config, no_op_logger()); - - let (_, _) = compile(&embedder, &binary_wasm); +pub fn run_fuzzer(bytes: &[u8]) { + let config; + let mut u = Unstructured::new(bytes); + + // Arbitrary Wasm module generation probabilities + // 33% - Random bytes + // 33% - Wasm with arbitrary wasm-smith config + maybe invalid functions + // 33% - IC compliant wasm + maybe invalid functions + + // Only used w/ random bytes + let memory64_enabled = u.ratio(1, 2).unwrap_or(false); + + let wasm = if u.ratio(1, 3).unwrap_or(false) + || bytes.len() < ::size_hint(0).0 + { + config = ic_embedders_config(memory64_enabled); + raw_wasm_bytes(bytes) + } else { + let data = ::arbitrary_take_rest(u); + + match data { + Ok(data) => { + config = ic_embedders_config(data.memory64_enabled); + data.module.to_bytes() + } + Err(_) => { + config = ic_embedders_config(memory64_enabled); + raw_wasm_bytes(bytes) + } + } + }; + + let rt: Runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(6) + .max_blocking_threads(2) + .enable_all() + .build() + .unwrap_or_else(|err| panic!("Could not create tokio runtime: {}", err)); + + let futs = (0..MAX_PARALLEL_EXECUTIONS) + .map(|_| { + rt.spawn({ + let wasm = wasm.clone(); + let binary_wasm = BinaryEncodedWasm::new(wasm); + let embedder = WasmtimeEmbedder::new(config.clone(), no_op_logger()); + + async move { compile(&embedder, &binary_wasm) } + }) + }) + .collect::>(); + + rt.block_on(async move { + // The omitted field is EmbedderCache(Result, HypervisorError>) + // 1. InstancePre doesn't implement PartialEq + // 2. HypervisorError is the same in compilation_result which is checked for equality + + let result = futures::future::join_all(futs) + .await + .into_iter() + .map(|r| r.expect("Failed to join tasks")) + .map(|(_, compilation_result)| { + if let Ok(mut r) = compilation_result { + r.0.compilation_time = Duration::from_millis(1); + Ok(r) + } else { + compilation_result + } + }) + .collect::>(); + + let first = result.first(); + + if let Some(first) = first { + assert!(result.iter().all(|r| r == first)); + } + }); +} + +#[inline(always)] +fn raw_wasm_bytes(data: &[u8]) -> Vec { + let mut wasm: Vec = b"\x00asm".to_vec(); + wasm.extend_from_slice(data); + wasm } #[cfg(test)] mod tests { use super::*; - use arbitrary::{Arbitrary, Unstructured}; #[test] fn test_compile_wasm_using_embedder_single_run() { let arbitrary_str: &str = "this is a test string"; - let unstrucutred = Unstructured::new(arbitrary_str.as_bytes()); - let module = ::arbitrary_take_rest(unstrucutred) - .expect("Unable to extract wasm from Unstructured data"); - run_fuzzer(module); + run_fuzzer(arbitrary_str.as_bytes()); } } diff --git a/rs/embedders/fuzz/src/differential.rs b/rs/embedders/fuzz/src/differential.rs index deb60a00d3c..5c0192f46a6 100644 --- a/rs/embedders/fuzz/src/differential.rs +++ b/rs/embedders/fuzz/src/differential.rs @@ -1,6 +1,4 @@ -use crate::ic_wasm::ICWasmModule; -use ic_config::embedders::Config as EmbeddersConfig; -use ic_config::flag_status::FlagStatus; +use crate::ic_wasm::{ic_embedders_config, ICWasmModule}; use ic_embedders::InstanceRunResult; use ic_interfaces::execution_environment::HypervisorResult; use ic_interfaces::execution_environment::SystemApi; @@ -11,10 +9,18 @@ use ic_types::methods::{FuncRef, WasmMethod}; use std::collections::BTreeSet; use tokio::runtime::Runtime; +const MAX_PARALLEL_EXECUTIONS: usize = 2; +type DeterministicExecutionResult = Vec<( + HypervisorResult>, + HypervisorResult, + u64, +)>; + #[inline(always)] pub fn run_fuzzer(module: ICWasmModule) { let wasm = module.module.to_bytes(); let wasm_methods: BTreeSet = module.exported_functions; + let memory64_enabled = module.config.memory64_enabled; if wasm_methods.is_empty() { return; @@ -29,88 +35,99 @@ pub fn run_fuzzer(module: ICWasmModule) { .build() .unwrap_or_else(|err| panic!("Could not create tokio runtime: {}", err)); - let first_execution = rt.spawn({ - let wasm = wasm.clone(); - let wasm_methods = wasm_methods.clone(); - - async move { execute_wasm(wasm, wasm_methods) } - }); + let futs = (0..MAX_PARALLEL_EXECUTIONS) + .map(|_| { + rt.spawn({ + let wasm = wasm.clone(); + let wasm_methods = wasm_methods.clone(); - let second_execution = rt.spawn(async move { execute_wasm(wasm, wasm_methods) }); + async move { execute_wasm(wasm, wasm_methods, memory64_enabled) } + }) + }) + .collect::>(); rt.block_on(async move { - let first = first_execution.await.unwrap(); - let second = second_execution.await.unwrap(); - - // same size - assert_eq!(first.len(), second.len()); - - for (x, y) in std::iter::zip(first, second) { - // execution result must be same - assert_eq!(x.0, y.0); - - // instructions used must be same - assert_eq!(x.2, y.2); - - match (x.1, y.1) { - (Ok(run_x), Ok(run_y)) => { - assert_eq!(run_x.wasm_dirty_pages, run_y.wasm_dirty_pages); - assert_eq!( - run_x.stable_memory_dirty_pages, - run_y.stable_memory_dirty_pages - ); - - // special treatment because of NaN - let globals_x = run_x.exported_globals; - let globals_y = run_y.exported_globals; - for (g_x, g_y) in std::iter::zip(globals_x, globals_y) { - match (g_x, g_y) { - (Global::F32(f_x), Global::F32(f_y)) => { - if !f_x.is_nan() && !f_y.is_nan() { - assert_eq!(f_x, f_y); - } else { - // should hold because of canonicalization - assert_eq!(f_x.to_bits(), f_y.to_bits()); - } - } - (Global::F64(f_x), Global::F64(f_y)) => { - if !f_x.is_nan() && !f_y.is_nan() { - assert_eq!(f_x, f_y); - } else { - // should hold because of canonicalization - assert_eq!(f_x.to_bits(), f_y.to_bits()); - } + let result = futures::future::join_all(futs) + .await + .into_iter() + .map(|r| r.expect("Failed to join tasks")) + .collect::>(); + + let first = result.first(); + + if let Some(first) = first { + result + .iter() + .for_each(|r| equal(first.to_vec(), r.to_vec())); + } + }); +} + +// Panics if the results are not equal +fn equal(first: DeterministicExecutionResult, second: DeterministicExecutionResult) { + // same size + assert_eq!(first.len(), second.len()); + + for (x, y) in std::iter::zip(first, second) { + // execution result must be same + assert_eq!(x.0, y.0); + + // instructions used must be same + assert_eq!(x.2, y.2); + + match (x.1, y.1) { + (Ok(run_x), Ok(run_y)) => { + assert_eq!(run_x.wasm_dirty_pages, run_y.wasm_dirty_pages); + assert_eq!( + run_x.stable_memory_dirty_pages, + run_y.stable_memory_dirty_pages + ); + + // special treatment because of NaN + let globals_x = run_x.exported_globals; + let globals_y = run_y.exported_globals; + for (g_x, g_y) in std::iter::zip(globals_x, globals_y) { + match (g_x, g_y) { + (Global::F32(f_x), Global::F32(f_y)) => { + if !f_x.is_nan() && !f_y.is_nan() { + assert_eq!(f_x, f_y); + } else { + // should hold because of canonicalization + assert_eq!(f_x.to_bits(), f_y.to_bits()); } - (_, _) => { - assert_eq!(g_x, g_y); + } + (Global::F64(f_x), Global::F64(f_y)) => { + if !f_x.is_nan() && !f_y.is_nan() { + assert_eq!(f_x, f_y); + } else { + // should hold because of canonicalization + assert_eq!(f_x.to_bits(), f_y.to_bits()); } } + (_, _) => { + assert_eq!(g_x, g_y); + } } } - (Err(e_x), Err(e_y)) => { - assert_eq!(e_x, e_y); - } - (_, _) => { - panic!("Instance results doesn't match"); - } + } + (Err(e_x), Err(e_y)) => { + assert_eq!(e_x, e_y); + } + (_, _) => { + panic!("Instance results doesn't match"); } } - }); + } } #[inline(always)] fn execute_wasm( wasm: Vec, wasm_methods: BTreeSet, -) -> Vec<( - HypervisorResult>, - HypervisorResult, - u64, -)> { + memory64_enabled: bool, +) -> DeterministicExecutionResult { let mut result = vec![]; - let mut config = EmbeddersConfig::default(); - config.feature_flags.write_barrier = FlagStatus::Enabled; - config.feature_flags.wasm64 = FlagStatus::Enabled; + let config = ic_embedders_config(memory64_enabled); let instance_result = WasmtimeInstanceBuilder::new() .with_wasm(wasm) .with_config(config) diff --git a/rs/embedders/fuzz/src/ic_wasm.rs b/rs/embedders/fuzz/src/ic_wasm.rs index 73f788290d9..05ef46a01c9 100644 --- a/rs/embedders/fuzz/src/ic_wasm.rs +++ b/rs/embedders/fuzz/src/ic_wasm.rs @@ -1,6 +1,7 @@ use crate::imports::system_api_imports; use arbitrary::{Arbitrary, Result, Unstructured}; use ic_config::embedders::Config as EmbeddersConfig; +use ic_config::flag_status::FlagStatus; use ic_embedders::wasm_utils::validation::{RESERVED_SYMBOLS, WASM_FUNCTION_SIZE_LIMIT}; use ic_replicated_state::Global; use ic_types::methods::WasmMethod; @@ -16,7 +17,8 @@ use wasm_smith::{Config, Module}; use wasmparser::*; lazy_static! { - static ref SYSTEM_API_IMPORTS: Vec = system_api_imports(); + static ref SYSTEM_API_IMPORTS_WASM32: Vec = system_api_imports(ic_embedders_config(false)); + static ref SYSTEM_API_IMPORTS_WASM64: Vec = system_api_imports(ic_embedders_config(true)); } #[derive(Debug)] @@ -34,7 +36,8 @@ pub struct ICWasmModule { impl<'a> Arbitrary<'a> for ICWasmModule { fn arbitrary(u: &mut Unstructured<'a>) -> Result { - let embedder_config = EmbeddersConfig::new(); + let memory64_enabled = u.ratio(2, 3)?; + let embedder_config = ic_embedders_config(memory64_enabled); let exports = generate_exports(embedder_config.clone(), u)?; let mut config = ic_wasm_config(embedder_config); config.exports = exports; @@ -130,7 +133,8 @@ impl ICWasmModule { } } -fn ic_wasm_config(embedder_config: EmbeddersConfig) -> Config { +pub fn ic_wasm_config(embedder_config: EmbeddersConfig) -> Config { + let memory64_enabled = embedder_config.feature_flags.wasm64 == FlagStatus::Enabled; Config { min_funcs: 10, min_exports: 10, @@ -148,18 +152,33 @@ fn ic_wasm_config(embedder_config: EmbeddersConfig) -> Config { bulk_memory_enabled: true, reference_types_enabled: true, simd_enabled: true, - memory64_enabled: true, + memory64_enabled, threads_enabled: false, relaxed_simd_enabled: false, canonicalize_nans: false, exceptions_enabled: false, - available_imports: Some(SYSTEM_API_IMPORTS.to_vec()), + available_imports: Some(if memory64_enabled { + SYSTEM_API_IMPORTS_WASM64.to_vec() + } else { + SYSTEM_API_IMPORTS_WASM32.to_vec() + }), ..Default::default() } } +pub fn ic_embedders_config(memory64_enabled: bool) -> EmbeddersConfig { + let mut config = EmbeddersConfig::default(); + config.feature_flags.write_barrier = FlagStatus::Enabled; + if memory64_enabled { + config.feature_flags.wasm64 = FlagStatus::Enabled; + } else { + config.feature_flags.wasm64 = FlagStatus::Disabled; + } + config +} + fn get_persisted_global(g: wasmparser::Global) -> Option { match g.ty.content_type { ValType::I32 => Some(Global::I32( @@ -200,7 +219,7 @@ fn get_persisted_global(g: wasmparser::Global) -> Option { } } -fn generate_exports( +pub fn generate_exports( embedder_config: EmbeddersConfig, u: &mut Unstructured, ) -> Result>> { diff --git a/rs/embedders/fuzz/src/imports.rs b/rs/embedders/fuzz/src/imports.rs index 8ab106e8b8c..e0b34a85bfe 100644 --- a/rs/embedders/fuzz/src/imports.rs +++ b/rs/embedders/fuzz/src/imports.rs @@ -20,12 +20,7 @@ use wasm_encoder::{ }; use wasmtime::{Engine, Extern, Store, StoreLimits, ValType}; -pub(crate) fn system_api_imports() -> Vec { - let system_api_type = WasmMemoryType::Wasm64; - let mut config = EmbeddersConfig::default(); - config.feature_flags.write_barrier = FlagStatus::Enabled; - config.feature_flags.wasm64 = FlagStatus::Enabled; - +pub(crate) fn system_api_imports(config: EmbeddersConfig) -> Vec { let engine = Engine::new(&WasmtimeEmbedder::wasmtime_execution_config(&config)) .expect("Failed to initialize Wasmtime engine"); let api_type = ApiType::init(UNIX_EPOCH, vec![], user_test_id(24).get()); @@ -60,13 +55,27 @@ pub(crate) fn system_api_imports() -> Vec { }, ); let mut linker: wasmtime::Linker = wasmtime::Linker::new(&engine); - system_api::syscalls::( - &mut linker, - config.feature_flags, - config.stable_memory_dirty_page_limit, - config.stable_memory_accessed_page_limit, - system_api_type, - ); + + match config.feature_flags.wasm64 { + FlagStatus::Enabled => { + system_api::syscalls::( + &mut linker, + config.feature_flags, + config.stable_memory_dirty_page_limit, + config.stable_memory_accessed_page_limit, + WasmMemoryType::Wasm64, + ); + } + FlagStatus::Disabled => { + system_api::syscalls::( + &mut linker, + config.feature_flags, + config.stable_memory_dirty_page_limit, + config.stable_memory_accessed_page_limit, + WasmMemoryType::Wasm32, + ); + } + } // to avoid store move let mut system_api_imports: Vec<(&str, &str, wasmtime::Func)> = linker diff --git a/rs/embedders/fuzz/src/wasm_executor.rs b/rs/embedders/fuzz/src/wasm_executor.rs index 7946e421c79..81c0e605eb0 100644 --- a/rs/embedders/fuzz/src/wasm_executor.rs +++ b/rs/embedders/fuzz/src/wasm_executor.rs @@ -1,8 +1,6 @@ -use crate::ic_wasm::ICWasmModule; +use crate::ic_wasm::{ic_embedders_config, ICWasmModule}; use ic_config::{ - embedders::{Config, FeatureFlags}, - execution_environment::Config as HypervisorConfig, - flag_status::FlagStatus, + execution_environment::Config as HypervisorConfig, flag_status::FlagStatus, subnet_config::SchedulerConfig, }; use ic_cycles_account_manager::ResourceSaturation; @@ -59,14 +57,7 @@ pub fn run_fuzzer(module: ICWasmModule) { let wasm_methods: BTreeSet = module.exported_functions; let log = no_op_logger(); - let embedder_config = Config { - feature_flags: FeatureFlags { - write_barrier: FlagStatus::Enabled, - wasm64: FlagStatus::Enabled, - ..Default::default() - }, - ..Default::default() - }; + let embedder_config = ic_embedders_config(module.config.memory64_enabled); let metrics_registry = MetricsRegistry::new(); let fd_factory = Arc::new(TestPageAllocatorFileDescriptorImpl::new()); diff --git a/rs/embedders/fuzz/src/wasmtime.rs b/rs/embedders/fuzz/src/wasmtime.rs index 739eec0d854..b2911eb33b1 100644 --- a/rs/embedders/fuzz/src/wasmtime.rs +++ b/rs/embedders/fuzz/src/wasmtime.rs @@ -1,6 +1,4 @@ -use crate::ic_wasm::ICWasmModule; -use ic_config::embedders::Config as EmbeddersConfig; -use ic_config::flag_status::FlagStatus; +use crate::ic_wasm::{ic_embedders_config, ICWasmModule}; use ic_test_utilities_embedders::WasmtimeInstanceBuilder; use ic_types::methods::{FuncRef, WasmMethod}; use libfuzzer_sys::Corpus; @@ -11,9 +9,7 @@ pub fn run_fuzzer(module: ICWasmModule) -> Corpus { let wasm = module.module.to_bytes(); let wasm_methods: BTreeSet = module.exported_functions; - let mut config = EmbeddersConfig::default(); - config.feature_flags.write_barrier = FlagStatus::Enabled; - config.feature_flags.wasm64 = FlagStatus::Enabled; + let config = ic_embedders_config(module.config.memory64_enabled); let instance_result = WasmtimeInstanceBuilder::new() .with_wasm(wasm) diff --git a/rs/embedders/fuzz/src/ws2wasm.rs b/rs/embedders/fuzz/src/ws2wasm.rs index 6a7dfd152a8..c9e9f8797f2 100644 --- a/rs/embedders/fuzz/src/ws2wasm.rs +++ b/rs/embedders/fuzz/src/ws2wasm.rs @@ -1,6 +1,5 @@ use arbitrary::{Arbitrary, Unstructured}; use clap::Parser; -use ic_config::embedders::Config as EmbeddersConfig; use ic_logger::replica_logger::no_op_logger; use std::fs::File; use std::io; @@ -8,7 +7,7 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::PathBuf; use std::sync::Arc; -use wasm_fuzzers::ic_wasm::ICWasmModule; +use wasm_fuzzers::ic_wasm::{ic_embedders_config, ICWasmModule}; use wasmprinter::print_bytes; use ic_embedders::{ @@ -57,7 +56,7 @@ fn main() -> io::Result<()> { let instrumentation = CommandLineArgs::parse().inst; if instrumentation { - let config = EmbeddersConfig::default(); + let config = ic_embedders_config(module.config.memory64_enabled); let decoded = decode_wasm(config.wasm_max_size, Arc::new(wasm)) .expect("failed to decode canister module"); let embedder = WasmtimeEmbedder::new(config, no_op_logger()); diff --git a/rs/execution_environment/fuzz/fuzz_targets/execute_system_api_call.rs b/rs/execution_environment/fuzz/fuzz_targets/execute_system_api_call.rs index de4b8439809..7b3e5f1414d 100644 --- a/rs/execution_environment/fuzz/fuzz_targets/execute_system_api_call.rs +++ b/rs/execution_environment/fuzz/fuzz_targets/execute_system_api_call.rs @@ -1,8 +1,4 @@ -use ic_config::{ - embedders::Config as EmbeddersConfig, embedders::FeatureFlags, - execution_environment::Config as ExecutionConfig, flag_status::FlagStatus, - subnet_config::SubnetConfig, -}; +use ic_config::{execution_environment::Config as ExecutionConfig, subnet_config::SubnetConfig}; use ic_management_canister_types::{CanisterInstallMode, CanisterSettingsArgsBuilder}; use ic_registry_subnet_type::SubnetType; use ic_state_machine_tests::{StateMachine, StateMachineBuilder, StateMachineConfig}; @@ -10,10 +6,11 @@ use ic_types::{CanisterId, Cycles, NumBytes}; use libfuzzer_sys::fuzz_target; use std::cell::RefCell; -use wasm_fuzzers::ic_wasm::ICWasmModule; +use wasm_fuzzers::ic_wasm::{ic_embedders_config, ICWasmModule}; thread_local! { - static ENV: RefCell<(StateMachine, CanisterId)> = RefCell::new(setup_env()); + static ENV_32: RefCell<(StateMachine, CanisterId)> = RefCell::new(setup_env(false)); + static ENV_64: RefCell<(StateMachine, CanisterId)> = RefCell::new(setup_env(true)); } const HELLO_WORLD_WAT: &str = r#" @@ -30,7 +27,7 @@ fn main() { } fuzz_target!(|data: ICWasmModule| { - with_env(|env, canister_id| { + with_env(data.config.memory64_enabled, |env, canister_id| { let wasm = data.module.to_bytes(); if env .install_wasm_in_mode(*canister_id, CanisterInstallMode::Reinstall, wasm, vec![]) @@ -44,29 +41,29 @@ fuzz_target!(|data: ICWasmModule| { }); }); -fn with_env(f: F) -> R +fn with_env(memory64_enabled: bool, f: F) -> R where F: FnOnce(&StateMachine, &CanisterId) -> R, { - ENV.with(|env| { - let env_ref = env.borrow(); - f(&env_ref.0, &env_ref.1) // Pass references to the closure - }) + if memory64_enabled { + ENV_64.with(|env| { + let env_ref = env.borrow(); + f(&env_ref.0, &env_ref.1) + }) + } else { + ENV_32.with(|env| { + let env_ref = env.borrow(); + f(&env_ref.0, &env_ref.1) + }) + } } // A setup function to initialize StateMachine with a dummy canister and expose the cansiter_id. // The same canister_id and StateMachine reference is used in the fuzzing runs, where the // canister is reinstalled under the same canister_id -fn setup_env() -> (StateMachine, CanisterId) { +fn setup_env(memory64_enabled: bool) -> (StateMachine, CanisterId) { let exec_config = ExecutionConfig { - embedders_config: EmbeddersConfig { - feature_flags: FeatureFlags { - write_barrier: FlagStatus::Enabled, - wasm64: FlagStatus::Enabled, // Enable wasm64 to match generated ICWasmModule. - ..Default::default() - }, - ..Default::default() - }, + embedders_config: ic_embedders_config(memory64_enabled), max_compilation_cache_size: NumBytes::new(10 * 1024 * 1024), // 10MiB ..Default::default() }; From 250955b0edcaeef4f824b3c1c2ffce13c13b5f4f Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Mon, 13 Jan 2025 15:32:59 +0100 Subject: [PATCH 68/98] test(crypto): CRP-2667 refactor vetKD key share creation vault tests (#3251) Removes code duplication in the unit tests of `VetKdCspVault::create_encrypted_vetkd_key_share`. Addresses CRP-2667, originating from [this comment](https://github.com/dfinity/ic/pull/2989#pullrequestreview-2493214662). --- .../src/vault/local_csp_vault/vetkd/tests.rs | 263 ++++++++---------- 1 file changed, 113 insertions(+), 150 deletions(-) diff --git a/rs/crypto/internal/crypto_service_provider/src/vault/local_csp_vault/vetkd/tests.rs b/rs/crypto/internal/crypto_service_provider/src/vault/local_csp_vault/vetkd/tests.rs index ae543665a57..6a5e13a5c32 100644 --- a/rs/crypto/internal/crypto_service_provider/src/vault/local_csp_vault/vetkd/tests.rs +++ b/rs/crypto/internal/crypto_service_provider/src/vault/local_csp_vault/vetkd/tests.rs @@ -15,7 +15,7 @@ use rand_chacha::ChaCha20Rng; #[test] fn should_correctly_create_encrypted_vetkd_key_share() { - let rng = reproducible_rng(); + let rng = &mut reproducible_rng(); let result = create_encrypted_vetkd_key_share(rng); @@ -24,7 +24,7 @@ fn should_correctly_create_encrypted_vetkd_key_share() { #[test] fn should_correctly_create_encrypted_vetkd_key_share_for_smoke_test_vector() { - let rng = ChaCha20Rng::seed_from_u64(123); + let rng = &mut ChaCha20Rng::seed_from_u64(123); let result = create_encrypted_vetkd_key_share(rng); @@ -32,80 +32,36 @@ fn should_correctly_create_encrypted_vetkd_key_share_for_smoke_test_vector() { result, Ok(VetKdEncryptedKeyShareContent( hex::decode( - "8fb20ba0025e22ebc546852eca21e324cfc96c8b7b127b9c6790d5f5a2d1a7\ - 2ad7c18c852215b44e3fe0315203b9565fafc0c7d8178ba92f0d6dca8c79d48\ - 8c9f9ebf1469af0ebad6908c0edbd4c546a21ba9e1530732de2748f1c54ddbb\ - 2a6406a9ad976f0487ec4d0063aec5f27301eeaeb47d3977d9a472dacdc8ad7\ - 546c1f26453229d6f1aa612ea109e1ad4a05d9352b91693c734f7207002e2f9\ - da6ac9dac0aefe136247b46d44c763d33718604c6340e8c9c9fe388af7e3c93\ - 3fc9255", + "a8d7c58088640a9639267c5843824ee31f6ed8c6a90ea31e05a12459ea2498\ + f3e68e13f62604d027660883213c90ea72810bcecee58b883fb62118e538243\ + 03718e6876ea400d083beb0439d3934122a4c4b2e58e3f145305b9a0c0a00e3\ + 2dd808574dec2605dbc7f122fe593ca0c07ca92720d0f17b7d53c9c68dbb93d\ + 489078859e5e5fe2b6612ac9536fe7f8b463cac948e6db97908b7f5a67b33b3\ + e60a1c160889ef49448519a84be1aba0611829a7cca180cbbdf94f7b2cda2db\ + 6b14c65", ) .expect("invalid test vector") )) ); } -fn create_encrypted_vetkd_key_share( - mut rng: R, +fn create_encrypted_vetkd_key_share( + rng: &mut R, ) -> Result { - let master_secret_key = Scalar::random(&mut rng); - let master_public_key = G2Affine::from(G2Affine::generator() * &master_secret_key); - let encryption_public_key = TransportSecretKey::generate(&mut rng).public_key(); - let key_id = KeyId::from([123; 32]); - - let mut node_sks = MockSecretKeyStore::new(); - node_sks - .expect_get() - .times(1) - .withf(move |key_id_| *key_id_ == key_id) - .return_const(Some(CspSecretKey::ThresBls12_381( - threshold_types::SecretKeyBytes::from(&master_secret_key), - ))); - - let derivation_path = ExtendedDerivationPath { - caller: canister_test_id(234).get(), - derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], - }; - let derivation_id = b"some-derivation-id".to_vec(); - - let vault = LocalCspVault::builder_for_test() - .with_rng(rng) - .with_mock_stores() - .with_node_secret_key_store(node_sks) - .build(); - - vault.create_encrypted_vetkd_key_share( - key_id, - master_public_key.serialize().to_vec(), - encryption_public_key.serialize().to_vec(), - derivation_path, - derivation_id, - ) + let test_env = CreateVetKdKeyShareTestSetup::new(rng); + + test_env.create_encrypted_vetkd_key_share() } #[test] fn should_fail_to_create_key_share_with_invalid_master_public_key() { let rng = &mut reproducible_rng(); - let invalid_master_public_key = b"invalid-master-public-key".to_vec(); - let encryption_public_key = TransportSecretKey::generate(rng).public_key(); - let key_id = KeyId::from([123; 32]); - - let derivation_path = ExtendedDerivationPath { - caller: canister_test_id(234).get(), - derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], - }; - let derivation_id = b"some-derivation-id".to_vec(); + let mut test_env = CreateVetKdKeyShareTestSetup::new(rng); + test_env.master_public_key = b"invalid-master-public-key".to_vec(); + test_env.secret_key_store_override = Some(MockSecretKeyStore::new()); - let vault = LocalCspVault::builder_for_test().with_mock_stores().build(); - - let result = vault.create_encrypted_vetkd_key_share( - key_id, - invalid_master_public_key, - encryption_public_key.serialize().to_vec(), - derivation_path, - derivation_id, - ); + let result = test_env.create_encrypted_vetkd_key_share(); assert_matches!( result, Err(VetKdEncryptedKeyShareCreationVaultError::InvalidArgument(error)) @@ -115,31 +71,13 @@ fn should_fail_to_create_key_share_with_invalid_master_public_key() { #[test] fn should_fail_to_create_key_share_with_invalid_encryption_public_key() { - let mut rng = reproducible_rng(); + let rng = &mut reproducible_rng(); - let master_secret_key = Scalar::random(&mut rng); - let master_public_key = G2Affine::from(G2Affine::generator() * &master_secret_key); - let invalid_encryption_public_key = b"invalid-encryption-public-key".to_vec(); - let key_id = KeyId::from([123; 32]); - - let derivation_path = ExtendedDerivationPath { - caller: canister_test_id(234).get(), - derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], - }; - let derivation_id = b"some-derivation-id".to_vec(); - - let vault = LocalCspVault::builder_for_test() - .with_rng(rng) - .with_mock_stores() - .build(); - - let result = vault.create_encrypted_vetkd_key_share( - key_id, - master_public_key.serialize().to_vec(), - invalid_encryption_public_key, - derivation_path, - derivation_id, - ); + let mut test_env = CreateVetKdKeyShareTestSetup::new(rng); + test_env.transport_public_key = b"invalid-encryption-public-key".to_vec(); + test_env.secret_key_store_override = Some(MockSecretKeyStore::new()); + + let result = test_env.create_encrypted_vetkd_key_share(); assert_matches!( result, Err(VetKdEncryptedKeyShareCreationVaultError::InvalidArgument(error)) @@ -150,38 +88,11 @@ fn should_fail_to_create_key_share_with_invalid_encryption_public_key() { #[test] fn should_fail_to_create_key_share_if_key_is_missing_in_secret_key_store() { let mut rng = reproducible_rng(); + let mut test_env = CreateVetKdKeyShareTestSetup::new(&mut rng); - let master_secret_key = Scalar::random(&mut rng); - let master_public_key = G2Affine::from(G2Affine::generator() * &master_secret_key); - let encryption_public_key = TransportSecretKey::generate(&mut rng).public_key(); - let key_id = KeyId::from([123; 32]); - - let mut node_sks = MockSecretKeyStore::new(); - node_sks - .expect_get() - .times(1) - .withf(move |key_id_| *key_id_ == key_id) - .return_const(None); - - let derivation_path = ExtendedDerivationPath { - caller: canister_test_id(234).get(), - derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], - }; - let derivation_id = b"some-derivation-id".to_vec(); - - let vault = LocalCspVault::builder_for_test() - .with_rng(rng) - .with_mock_stores() - .with_node_secret_key_store(node_sks) - .build(); - - let result = vault.create_encrypted_vetkd_key_share( - key_id, - master_public_key.serialize().to_vec(), - encryption_public_key.serialize().to_vec(), - derivation_path, - derivation_id, - ); + test_env.secret_key_store_return_override = Some(None); + + let result = test_env.create_encrypted_vetkd_key_share(); assert_matches!( result, Err(VetKdEncryptedKeyShareCreationVaultError::InvalidArgument(error)) @@ -192,43 +103,95 @@ fn should_fail_to_create_key_share_if_key_is_missing_in_secret_key_store() { #[test] fn should_fail_to_create_key_share_if_key_in_secret_key_store_has_wrong_type() { let mut rng = reproducible_rng(); + let mut test_env = CreateVetKdKeyShareTestSetup::new(&mut rng); - let master_secret_key = Scalar::random(&mut rng); - let master_public_key = G2Affine::from(G2Affine::generator() * &master_secret_key); - let encryption_public_key = TransportSecretKey::generate(&mut rng).public_key(); - let key_id = KeyId::from([123; 32]); - - let mut node_sks = MockSecretKeyStore::new(); - node_sks - .expect_get() - .times(1) - .withf(move |key_id_| *key_id_ == key_id) - .return_const(Some(CspSecretKey::MultiBls12_381( - multi_types::SecretKeyBytes::from(&master_secret_key), - ))); - - let derivation_path = ExtendedDerivationPath { - caller: canister_test_id(234).get(), - derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], - }; - let derivation_id = b"some-derivation-id".to_vec(); - - let vault = LocalCspVault::builder_for_test() - .with_rng(rng) - .with_mock_stores() - .with_node_secret_key_store(node_sks) - .build(); - - let result = vault.create_encrypted_vetkd_key_share( - key_id, - master_public_key.serialize().to_vec(), - encryption_public_key.serialize().to_vec(), - derivation_path, - derivation_id, - ); + test_env.secret_key_store_return_override = Some(Some(CspSecretKey::MultiBls12_381( + multi_types::SecretKeyBytes::from(&test_env.master_secret_key), + ))); + + let result = test_env.create_encrypted_vetkd_key_share(); assert_matches!( result, Err(VetKdEncryptedKeyShareCreationVaultError::InvalidArgument(error)) if error.contains("wrong secret key type") ); } + +struct CreateVetKdKeyShareTestSetup { + key_id: KeyId, + master_public_key: Vec, + transport_public_key: Vec, + derivation_path: ExtendedDerivationPath, + derivation_id: Vec, + master_secret_key: Scalar, + rng: ChaCha20Rng, + secret_key_store_override: Option, + secret_key_store_return_override: Option>, +} + +impl CreateVetKdKeyShareTestSetup { + pub fn new(rng: &mut R) -> Self { + let master_secret_key = Scalar::random(rng); + let master_public_key = G2Affine::from(G2Affine::generator() * &master_secret_key); + let transport_secret_key = TransportSecretKey::generate(rng); + let key_id = KeyId::from([123; 32]); + let derivation_path = ExtendedDerivationPath { + caller: canister_test_id(234).get(), + derivation_path: vec![b"some".to_vec(), b"derivation".to_vec(), b"path".to_vec()], + }; + let derivation_id = b"some-derivation-id".to_vec(); + let rng = ChaCha20Rng::from_seed(rng.gen()); + + Self { + master_secret_key, + master_public_key: master_public_key.serialize().to_vec(), + transport_public_key: transport_secret_key.public_key().serialize().to_vec(), + key_id, + derivation_path, + derivation_id, + rng, + secret_key_store_override: None, + secret_key_store_return_override: None, + } + } + + pub fn create_encrypted_vetkd_key_share( + self, + ) -> Result { + let node_sks = if let Some(node_sks_override) = self.secret_key_store_override { + node_sks_override + } else { + let return_value = if let Some(opt_sk) = self.secret_key_store_return_override { + opt_sk + } else { + Some(CspSecretKey::ThresBls12_381( + threshold_types::SecretKeyBytes::from(&self.master_secret_key), + )) + }; + let mut node_sks = MockSecretKeyStore::new(); + node_sks + .expect_get() + .times(1) + .withf({ + let self_key_id = self.key_id; + move |key_id_| key_id_ == &self_key_id + }) + .return_const(return_value); + node_sks + }; + + let vault = LocalCspVault::builder_for_test() + .with_rng(self.rng) + .with_mock_stores() + .with_node_secret_key_store(node_sks) + .build(); + + vault.create_encrypted_vetkd_key_share( + self.key_id, + self.master_public_key.clone(), + self.transport_public_key.clone(), + self.derivation_path.clone(), + self.derivation_id.clone(), + ) + } +} From 92ae5bc28b947e59b2dfdbe06722c6412623b670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Mon, 13 Jan 2025 16:01:07 +0100 Subject: [PATCH 69/98] test(ICP_Ledger): FI-1506: Remove flaky flag from ICP ledger and index tests (#3410) After limiting parallelization and dedicating more resources to running the tests, they are no longer flaky (no flakiness observed in the past week). This PR therefore removes the flaky flag, so that failures would show up and wouldn't be masked by automatic flakiness-retries. --- rs/ledger_suite/icp/index/BUILD.bazel | 1 - rs/ledger_suite/icp/ledger/BUILD.bazel | 1 - 2 files changed, 2 deletions(-) diff --git a/rs/ledger_suite/icp/index/BUILD.bazel b/rs/ledger_suite/icp/index/BUILD.bazel index cef900eb663..c9acf1f5001 100644 --- a/rs/ledger_suite/icp/index/BUILD.bazel +++ b/rs/ledger_suite/icp/index/BUILD.bazel @@ -102,7 +102,6 @@ rust_ic_test( "LEDGER_CANISTER_NOTIFY_METHOD_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm-notify-method)", "LEDGER_CANISTER_WASM_PATH": "$(rootpath //rs/ledger_suite/icp/ledger:ledger-canister-wasm)", }, - flaky = True, tags = ["cpu:4"], deps = [":ic-icp-index"] + DEPENDENCIES + DEV_DEPENDENCIES, ) diff --git a/rs/ledger_suite/icp/ledger/BUILD.bazel b/rs/ledger_suite/icp/ledger/BUILD.bazel index 0d9bea50cb9..ffe62605d7f 100644 --- a/rs/ledger_suite/icp/ledger/BUILD.bazel +++ b/rs/ledger_suite/icp/ledger/BUILD.bazel @@ -129,7 +129,6 @@ rust_ic_test( "LEDGER_CANISTER_NEXT_VERSION_WASM_PATH": "$(rootpath :ledger-canister-wasm-next-version)", "LEDGER_CANISTER_LOW_LIMITS_WASM_PATH": "$(rootpath :ledger-canister-wasm-low-limits)", }, - flaky = True, tags = ["cpu:4"], deps = [ # Keep sorted. From 4e0a28df696589a039061aed0b7179ba3c9989f5 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 13 Jan 2025 17:38:48 +0200 Subject: [PATCH 70/98] fix: Account instructions for bytes accessed and dirty pages on system subnets (#3396) This is another change that aims to make system subnets behave closer to application subnets. --- rs/config/src/subnet_config.rs | 3 +- .../tests/wasmtime_random_memory_writes.rs | 184 +++++++----------- .../src/execution/update/tests.rs | 10 +- rs/system_api/src/lib.rs | 7 +- 4 files changed, 78 insertions(+), 126 deletions(-) diff --git a/rs/config/src/subnet_config.rs b/rs/config/src/subnet_config.rs index 3724a39fa5d..0bbefe812c5 100644 --- a/rs/config/src/subnet_config.rs +++ b/rs/config/src/subnet_config.rs @@ -140,7 +140,6 @@ const DEFAULT_REFERENCE_SUBNET_SIZE: usize = 13; /// Costs for each newly created dirty page in stable memory. const DEFAULT_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(1_000); -const SYSTEM_SUBNET_DIRTY_PAGE_OVERHEAD: NumInstructions = NumInstructions::new(0); /// Accumulated priority reset interval, rounds. /// @@ -341,7 +340,7 @@ impl SchedulerConfig { // This limit should be high enough (1000T) to effectively disable // rate-limiting for the system subnets. install_code_rate_limit: NumInstructions::from(1_000_000_000_000_000), - dirty_page_overhead: SYSTEM_SUBNET_DIRTY_PAGE_OVERHEAD, + dirty_page_overhead: DEFAULT_DIRTY_PAGE_OVERHEAD, accumulated_priority_reset_interval: ACCUMULATED_PRIORITY_RESET_INTERVAL, upload_wasm_chunk_instructions: NumInstructions::from(0), canister_snapshot_baseline_instructions: NumInstructions::from(0), diff --git a/rs/embedders/tests/wasmtime_random_memory_writes.rs b/rs/embedders/tests/wasmtime_random_memory_writes.rs index 14eb3700fa0..beb4733dbcb 100644 --- a/rs/embedders/tests/wasmtime_random_memory_writes.rs +++ b/rs/embedders/tests/wasmtime_random_memory_writes.rs @@ -980,126 +980,90 @@ mod tests { #[test] fn test_proportional_instructions_consumption_to_data_size() { - with_test_replica_logger(|log| { - let subnet_type = SubnetType::Application; - let dst: u32 = 0; - - let dirty_heap_cost = match EmbeddersConfig::default().metering_type { - ic_config::embedders::MeteringType::New => SchedulerConfig::application_subnet() - .dirty_page_overhead - .get(), - _ => 0, - }; + for subnet_type in [ + SubnetType::Application, + SubnetType::VerifiedApplication, + SubnetType::System, + ] { + with_test_replica_logger(|log| { + let dst: u32 = 0; + + let dirty_heap_cost = match EmbeddersConfig::default().metering_type { + ic_config::embedders::MeteringType::New => match subnet_type { + SubnetType::System => { + SchedulerConfig::system_subnet().dirty_page_overhead.get() + } + SubnetType::Application => SchedulerConfig::application_subnet() + .dirty_page_overhead + .get(), + SubnetType::VerifiedApplication => { + SchedulerConfig::verified_application_subnet() + .dirty_page_overhead + .get() + } + }, + _ => 0, + }; - let mut payload: Vec = dst.to_le_bytes().to_vec(); - payload.extend(random_payload()); - let payload_size = payload.len() - 4; + let mut payload: Vec = dst.to_le_bytes().to_vec(); + payload.extend(random_payload()); + let payload_size = payload.len() - 4; - let mut double_size_payload: Vec = payload.clone(); - double_size_payload.extend(random_payload()); + let mut double_size_payload: Vec = payload.clone(); + double_size_payload.extend(random_payload()); - let (instructions_consumed_without_data, dry_run_stats) = run_and_get_stats( - log.clone(), - "write_bytes", - dst.to_le_bytes().to_vec(), - MAX_NUM_INSTRUCTIONS, - subnet_type, - ) - .unwrap(); - let dry_run_dirty_heap = dry_run_stats.wasm_dirty_pages.len() as u64; - - { - // Number of instructions consumed only for copying the payload. - let (consumed_instructions, run_stats) = run_and_get_stats( + let (instructions_consumed_without_data, dry_run_stats) = run_and_get_stats( log.clone(), "write_bytes", - payload, - MAX_NUM_INSTRUCTIONS, - subnet_type, - ) - .unwrap(); - let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; - let consumed_instructions = - consumed_instructions - instructions_consumed_without_data; - assert_eq!( - (consumed_instructions.get() - dirty_heap * dirty_heap_cost) as usize, - (payload_size / BYTES_PER_INSTRUCTION) - - (dry_run_dirty_heap * dirty_heap_cost) as usize, - ); - } - - { - // Number of instructions consumed increased with the size of the data. - let (consumed_instructions, run_stats) = run_and_get_stats( - log, - "write_bytes", - double_size_payload, + dst.to_le_bytes().to_vec(), MAX_NUM_INSTRUCTIONS, subnet_type, ) .unwrap(); - let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; - let consumed_instructions = - consumed_instructions - instructions_consumed_without_data; - - assert_eq!( - (consumed_instructions.get() - dirty_heap * dirty_heap_cost) as usize, - (2 * payload_size / BYTES_PER_INSTRUCTION) - - (dry_run_dirty_heap * dirty_heap_cost) as usize - ); - } - }) - } - - #[test] - fn test_no_instructions_consumption_based_on_data_size_on_system_subnet() { - with_test_replica_logger(|log| { - let subnet_type = SubnetType::System; - let dst: u32 = 0; - - let mut payload: Vec = dst.to_le_bytes().to_vec(); - payload.extend(random_payload()); - - let mut double_size_payload: Vec = payload.clone(); - double_size_payload.extend(random_payload()); - - let instructions_consumed_without_data = get_num_instructions_consumed( - log.clone(), - "write_bytes", - dst.to_le_bytes().to_vec(), - MAX_NUM_INSTRUCTIONS, - subnet_type, - ) - .unwrap(); - - { - // Number of instructions consumed for copying the payload is zero. - let consumed_instructions = get_num_instructions_consumed( - log.clone(), - "write_bytes", - payload, - MAX_NUM_INSTRUCTIONS, - subnet_type, - ) - .unwrap() - - instructions_consumed_without_data; - assert_eq!(consumed_instructions.get(), 0); - } + let dry_run_dirty_heap = dry_run_stats.wasm_dirty_pages.len() as u64; + + { + // Number of instructions consumed only for copying the payload. + let (consumed_instructions, run_stats) = run_and_get_stats( + log.clone(), + "write_bytes", + payload, + MAX_NUM_INSTRUCTIONS, + subnet_type, + ) + .unwrap(); + let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; + let consumed_instructions = + consumed_instructions - instructions_consumed_without_data; + assert_eq!( + (consumed_instructions.get() - dirty_heap * dirty_heap_cost) as usize, + (payload_size / BYTES_PER_INSTRUCTION) + - (dry_run_dirty_heap * dirty_heap_cost) as usize, + ); + } - { - // Number of instructions consumed for copying the payload is zero. - let consumed_instructions = get_num_instructions_consumed( - log, - "write_bytes", - double_size_payload, - MAX_NUM_INSTRUCTIONS, - subnet_type, - ) - .unwrap() - - instructions_consumed_without_data; - assert_eq!(consumed_instructions.get(), 0); - } - }) + { + // Number of instructions consumed increased with the size of the data. + let (consumed_instructions, run_stats) = run_and_get_stats( + log, + "write_bytes", + double_size_payload, + MAX_NUM_INSTRUCTIONS, + subnet_type, + ) + .unwrap(); + let dirty_heap = run_stats.wasm_dirty_pages.len() as u64; + let consumed_instructions = + consumed_instructions - instructions_consumed_without_data; + + assert_eq!( + (consumed_instructions.get() - dirty_heap * dirty_heap_cost) as usize, + (2 * payload_size / BYTES_PER_INSTRUCTION) + - (dry_run_dirty_heap * dirty_heap_cost) as usize + ); + } + }) + } } fn run_and_get_stats( diff --git a/rs/execution_environment/src/execution/update/tests.rs b/rs/execution_environment/src/execution/update/tests.rs index f8673ace1e6..2cd76a57e7e 100644 --- a/rs/execution_environment/src/execution/update/tests.rs +++ b/rs/execution_environment/src/execution/update/tests.rs @@ -3,7 +3,6 @@ use std::time::Duration; use assert_matches::assert_matches; use ic_base_types::NumSeconds; -use ic_config::subnet_config::SchedulerConfig; use ic_error_types::ErrorCode; use ic_interfaces::execution_environment::SubnetAvailableMemory; use ic_registry_subnet_type::SubnetType; @@ -352,7 +351,7 @@ fn dts_update_concurrent_cycles_change_fails() { } #[test] -fn dirty_pages_are_free_on_system_subnet() { +fn dirty_pages_cost_the_same_on_app_and_system_subnets() { fn instructions_to_write_stable_byte(mut test: ExecutionTest) -> NumInstructions { let initial_cycles = Cycles::new(1_000_000_000_000); let a_id = test.universal_canister_with_cycles(initial_cycles).unwrap(); @@ -376,12 +375,7 @@ fn dirty_pages_are_free_on_system_subnet() { .build(); let app_instructions = instructions_to_write_stable_byte(app_test); - // Can't check for equality because there are other charges that are omitted - // on system subnets. - assert!( - app_instructions - > system_instructions + SchedulerConfig::application_subnet().dirty_page_overhead - ); + assert_eq!(app_instructions, system_instructions); } #[test] diff --git a/rs/system_api/src/lib.rs b/rs/system_api/src/lib.rs index 4a0c6575bc3..4925252e6f7 100644 --- a/rs/system_api/src/lib.rs +++ b/rs/system_api/src/lib.rs @@ -1639,12 +1639,7 @@ impl SystemApi for SystemApiImpl { } fn get_num_instructions_from_bytes(&self, num_bytes: NumBytes) -> NumInstructions { - match self.sandbox_safe_system_state.subnet_type { - SubnetType::System => NumInstructions::from(0), - SubnetType::VerifiedApplication | SubnetType::Application => { - NumInstructions::from(num_bytes.get()) - } - } + NumInstructions::from(num_bytes.get()) } fn stable_memory_dirty_pages(&self) -> Vec<(PageIndex, &PageBytes)> { From a358756a6fef81b8d3d6bf70c56f2886097825a9 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Mon, 13 Jan 2025 11:00:45 -0600 Subject: [PATCH 71/98] refactor: clean up the SNS Governance API type definitions (#3392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SNS Governance API types are for manual editing, but still have a bunch of stuff left over from when they were autogenerated. 1. Replaced `::core::option::Option` with `Option` and similar 2. Removed `prost` derives. API types aren't ever serialized to `proto`. Why not get rid of the `prost` derives? They make things really confusing and hard to edit, and lead to us accidentally serializing the wrong types (see the previous PR). I also removed other derives like `comparable::Comparable` which I don't think we normally see on our types. 3. Added additional derives for things like Debug and Default (which previously `prost` was giving us). 4. Remove the `// This file is @generated by prost-build.` comment These changes were pretty much done all mechanically. Sorry for not splitting them up into separate commits Now we should be able to start evolving our API types and our internal types independently! [← Previous PR](https://github.com/dfinity/ic/pull/3391) --- .../api/src/ic_sns_governance.pb.v1.rs | 2367 +++-------------- 1 file changed, 442 insertions(+), 1925 deletions(-) diff --git a/rs/sns/governance/api/src/ic_sns_governance.pb.v1.rs b/rs/sns/governance/api/src/ic_sns_governance.pb.v1.rs index da87417e25f..09f66dafdbe 100644 --- a/rs/sns/governance/api/src/ic_sns_governance.pb.v1.rs +++ b/rs/sns/governance/api/src/ic_sns_governance.pb.v1.rs @@ -1,90 +1,57 @@ -// This file is @generated by prost-build. +use std::collections::BTreeMap; + /// A principal with a particular set of permissions over a neuron. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronPermission { /// The principal that has the permissions. - #[prost(message, optional, tag = "1")] - pub principal: ::core::option::Option<::ic_base_types::PrincipalId>, + pub principal: Option<::ic_base_types::PrincipalId>, /// The list of permissions that this principal has. - #[prost(enumeration = "NeuronPermissionType", repeated, tag = "2")] - pub permission_type: ::prost::alloc::vec::Vec, + pub permission_type: Vec, } /// The id of a specific neuron, which equals the neuron's subaccount on the ledger canister /// (the account that holds the neuron's staked tokens). #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Eq, - std::hash::Hash, - Clone, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, Eq, std::hash::Hash, Clone, PartialEq, )] pub struct NeuronId { - #[prost(bytes = "vec", tag = "1")] #[serde(with = "serde_bytes")] - pub id: ::prost::alloc::vec::Vec, + pub id: Vec, } /// A sequence of NeuronIds, which is used to get prost to generate a type isomorphic to Option>. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronIds { - #[prost(message, repeated, tag = "1")] - pub neuron_ids: ::prost::alloc::vec::Vec, + pub neuron_ids: Vec, } /// The id of a specific proposal. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable, serde::Serialize)] -#[self_describing] -#[derive(Clone, Copy, PartialEq, ::prost::Message)] -pub struct ProposalId { - #[prost(uint64, tag = "1")] - pub id: u64, -} #[derive( + Default, candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, + serde::Serialize, Clone, + Copy, PartialEq, - ::prost::Message, )] +pub struct ProposalId { + pub id: u64, +} +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct DisburseMaturityInProgress { /// This field is the quantity of maturity in e8s that has been decremented from a Neuron to /// be modulated and disbursed as SNS tokens. - #[prost(uint64, tag = "1")] pub amount_e8s: u64, - #[prost(uint64, tag = "2")] pub timestamp_of_disbursement_seconds: u64, - #[prost(message, optional, tag = "3")] - pub account_to_disburse_to: ::core::option::Option, - #[prost(uint64, optional, tag = "4")] - pub finalize_disbursement_timestamp_seconds: ::core::option::Option, + pub account_to_disburse_to: Option, + pub finalize_disbursement_timestamp_seconds: Option, } /// A neuron in the governance system. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[compare_default] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Neuron { /// The unique id of this neuron. - #[prost(message, optional, tag = "1")] - pub id: ::core::option::Option, + pub id: Option, /// The principal or list of principals with a particular set of permissions over a neuron. - #[prost(message, repeated, tag = "2")] - pub permissions: ::prost::alloc::vec::Vec, + pub permissions: Vec, /// The cached record of the neuron's staked governance tokens, measured in /// fractions of 10E-8 of a governance token. /// @@ -92,7 +59,6 @@ pub struct Neuron { /// that can be set by each SNS. Neurons that are created by claiming a neuron, spawning a neuron, /// or splitting a neuron must have at least that stake (in the case of splitting both the parent neuron /// and the new neuron must have at least that stake). - #[prost(uint64, tag = "3")] pub cached_neuron_stake_e8s: u64, /// TODO NNS1-1052 - Update if this ticket is done and fees are burned / minted instead of tracked in this attribute. /// @@ -100,10 +66,8 @@ pub struct Neuron { /// due to making proposals that were subsequently rejected. /// Must be smaller than 'cached_neuron_stake_e8s'. When a neuron is /// disbursed, these governance tokens will be burned. - #[prost(uint64, tag = "4")] pub neuron_fees_e8s: u64, /// The timestamp, in seconds from the Unix epoch, when the neuron was created. - #[prost(uint64, tag = "5")] pub created_timestamp_seconds: u64, /// The timestamp, in seconds from the Unix epoch, when this neuron has entered /// the non-dissolving state. This is either the creation time or the last time at @@ -112,30 +76,25 @@ pub struct Neuron { /// This value is meaningless when the neuron is dissolving, since a /// dissolving neurons always has age zero. The canonical value of /// this field for a dissolving neuron is `u64::MAX`. - #[prost(uint64, tag = "6")] pub aging_since_timestamp_seconds: u64, /// The neuron's followees, specified as a map of proposal functions IDs to followees neuron IDs. /// The map's keys are represented by integers as Protobuf does not support enum keys in maps. - #[prost(btree_map = "uint64, message", tag = "11")] - pub followees: ::prost::alloc::collections::BTreeMap, + pub followees: BTreeMap, /// The accumulated unstaked maturity of the neuron, measured in "e8s equivalent", i.e., in equivalent of /// 10E-8 of a governance token. /// /// The unit is "equivalent" to insist that, while this quantity is on the /// same scale as the governance token, maturity is not directly convertible to /// governance tokens: conversion requires a minting event and the conversion rate is variable. - #[prost(uint64, tag = "12")] pub maturity_e8s_equivalent: u64, /// A percentage multiplier to be applied when calculating the voting power of a neuron. /// The multiplier's unit is a integer percentage in the range of 0 to 100. The /// voting_power_percentage_multiplier can only be less than 100 for a developer neuron /// that is created at SNS initialization. - #[prost(uint64, tag = "13")] pub voting_power_percentage_multiplier: u64, /// The ID of the NNS neuron whose Community Fund participation resulted in the /// creation of this SNS neuron. - #[prost(uint64, optional, tag = "14")] - pub source_nns_neuron_id: ::core::option::Option, + pub source_nns_neuron_id: Option, /// The accumulated staked maturity of the neuron, in "e8s equivalent" (see /// "maturity_e8s_equivalent"). Staked maturity becomes regular maturity once /// the neuron is dissolved. @@ -145,12 +104,10 @@ pub struct Neuron { /// and rewards. Once the neuron is dissolved, this maturity will be "moved" /// to 'maturity_e8s_equivalent' and will be able to be spawned (with maturity /// modulation). - #[prost(uint64, optional, tag = "15")] - pub staked_maturity_e8s_equivalent: ::core::option::Option, + pub staked_maturity_e8s_equivalent: Option, /// If set and true the maturity rewarded to this neuron for voting will be /// automatically staked and will contribute to the neuron's voting power. - #[prost(bool, optional, tag = "16")] - pub auto_stake_maturity: ::core::option::Option, + pub auto_stake_maturity: Option, /// The duration that this neuron is vesting. /// /// A neuron that is vesting is non-dissolving and cannot start dissolving until the vesting duration has elapsed. @@ -159,14 +116,12 @@ pub struct Neuron { /// for a particular SNS instance might be 1 year, but the devs of the project may set their vesting duration to 3 /// years and dissolve delay to 1 year in order to prove that they are making a minimum 4 year commitment to the /// project. - #[prost(uint64, optional, tag = "17")] - pub vesting_period_seconds: ::core::option::Option, + pub vesting_period_seconds: Option, /// Disburse maturity operations that are currently underway. /// The entries are sorted by `timestamp_of_disbursement_seconds`-values, /// with the oldest entries first, i.e. it holds for all i that: /// entry\[i\].timestamp_of_disbursement_seconds <= entry\[i+1\].timestamp_of_disbursement_seconds - #[prost(message, repeated, tag = "18")] - pub disburse_maturity_in_progress: ::prost::alloc::vec::Vec, + pub disburse_maturity_in_progress: Vec, /// The neuron's dissolve state, specifying whether the neuron is dissolving, /// non-dissolving, or dissolved. /// @@ -182,23 +137,14 @@ pub struct Neuron { /// `Dissolved`. All other states represent the dissolved /// state. That is, (a) `when_dissolved_timestamp_seconds` is set and in the past, /// (b) `when_dissolved_timestamp_seconds` is set to zero, (c) neither value is set. - #[prost(oneof = "neuron::DissolveState", tags = "7, 8")] - pub dissolve_state: ::core::option::Option, + pub dissolve_state: Option, } /// Nested message and enum types in `Neuron`. pub mod neuron { /// A list of a neuron's followees for a specific function. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Followees { - #[prost(message, repeated, tag = "1")] - pub followees: ::prost::alloc::vec::Vec, + pub followees: Vec, } /// The neuron's dissolve state, specifying whether the neuron is dissolving, /// non-dissolving, or dissolved. @@ -215,15 +161,7 @@ pub mod neuron { /// `Dissolved`. All other states represent the dissolved /// state. That is, (a) `when_dissolved_timestamp_seconds` is set and in the past, /// (b) `when_dissolved_timestamp_seconds` is set to zero, (c) neither value is set. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub enum DissolveState { /// When the dissolve timer is running, this stores the timestamp, /// in seconds from the Unix epoch, at which the neuron is dissolved. @@ -232,7 +170,6 @@ pub mod neuron { /// may pause dissolving, in which case `dissolve_delay_seconds` /// will get assigned to: `when_dissolved_timestamp_seconds - /// `. - #[prost(uint64, tag = "7")] WhenDissolvedTimestampSeconds(u64), /// When the dissolve timer is stopped, this stores how much time, /// in seconds, the dissolve timer will be started with if the neuron is set back to 'Dissolving'. @@ -241,7 +178,6 @@ pub mod neuron { /// dissolving, in which case `when_dissolved_timestamp_seconds` /// will get assigned to: ` + /// dissolve_delay_seconds`. - #[prost(uint64, tag = "8")] DissolveDelaySeconds(u64), } } @@ -257,77 +193,46 @@ pub mod neuron { /// /// Note that the target, validator and rendering methods can all coexist in /// the same canister or be on different canisters. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NervousSystemFunction { /// The unique id of this function. /// /// Ids 0-999 are reserved for native governance proposals and can't /// be used by generic NervousSystemFunction's. - #[prost(uint64, tag = "1")] pub id: u64, /// A short (<256 chars) description of the NervousSystemFunction. - #[prost(string, tag = "2")] - pub name: ::prost::alloc::string::String, + pub name: String, /// An optional description of what the NervousSystemFunction does. - #[prost(string, optional, tag = "3")] - pub description: ::core::option::Option<::prost::alloc::string::String>, - #[prost(oneof = "nervous_system_function::FunctionType", tags = "4, 5")] - pub function_type: ::core::option::Option, + pub description: Option, + pub function_type: Option, } /// Nested message and enum types in `NervousSystemFunction`. pub mod nervous_system_function { - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GenericNervousSystemFunction { /// The id of the target canister that will be called to execute the proposal. - #[prost(message, optional, tag = "2")] - pub target_canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub target_canister_id: Option<::ic_base_types::PrincipalId>, /// The name of the method that will be called to execute the proposal. /// The signature of the method must be equivalent to the following: /// (proposal_data: ProposalData) -> Result<(), String>. - #[prost(string, optional, tag = "3")] - pub target_method_name: ::core::option::Option<::prost::alloc::string::String>, + pub target_method_name: Option, /// The id of the canister that will be called to validate the proposal before /// it is put up for a vote. - #[prost(message, optional, tag = "4")] - pub validator_canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub validator_canister_id: Option<::ic_base_types::PrincipalId>, /// The name of the method that will be called to validate the proposal /// before it is put up for a vote. /// The signature of the method must be equivalent to the following: /// (proposal_data: ProposalData) -> Result - #[prost(string, optional, tag = "5")] - pub validator_method_name: ::core::option::Option<::prost::alloc::string::String>, + pub validator_method_name: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum FunctionType { /// Whether this is a native function (i.e. a Action::Motion or /// Action::UpgradeSnsControlledCanister) or one of user-defined /// NervousSystemFunctions. - #[prost(message, tag = "4")] NativeNervousSystemFunction(super::Empty), /// Whether this is a GenericNervousSystemFunction which can call /// any canister. - #[prost(message, tag = "5")] GenericNervousSystemFunction(GenericNervousSystemFunction), } } @@ -335,92 +240,53 @@ pub mod nervous_system_function { /// that is not build into the standard SNS and calls a canister outside /// the SNS for execution. /// The canister and method to call are derived from the `function_id`. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ExecuteGenericNervousSystemFunction { /// This enum value determines what canister to call and what /// function to call on that canister. /// /// 'function_id` must be in the range `\[1000--u64:MAX\]` as this /// can't be used to execute native functions. - #[prost(uint64, tag = "1")] pub function_id: u64, /// The payload of the nervous system function's payload. - #[prost(bytes = "vec", tag = "2")] #[serde(with = "serde_bytes")] - pub payload: ::prost::alloc::vec::Vec, + pub payload: Vec, } /// A proposal function that should guide the future strategy of the SNS's /// ecosystem but does not have immediate effect in the sense that a method is executed. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[self_describing] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Motion { /// The text of the motion, which can at most be 100kib. - #[prost(string, tag = "1")] - pub motion_text: ::prost::alloc::string::String, + pub motion_text: String, } /// A proposal function that upgrades a canister that is controlled by the /// SNS governance canister. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct UpgradeSnsControlledCanister { /// The id of the canister that is upgraded. - #[prost(message, optional, tag = "1")] - pub canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub canister_id: Option<::ic_base_types::PrincipalId>, /// The new wasm module that the canister is upgraded to. - #[prost(bytes = "vec", tag = "2")] #[serde(with = "serde_bytes")] - pub new_canister_wasm: ::prost::alloc::vec::Vec, + pub new_canister_wasm: Vec, /// Arguments passed to the post-upgrade method of the new wasm module. - #[prost(bytes = "vec", optional, tag = "3")] #[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")] - pub canister_upgrade_arg: ::core::option::Option<::prost::alloc::vec::Vec>, + pub canister_upgrade_arg: Option>, /// Canister install_code mode. - #[prost( - enumeration = "::ic_protobuf::types::v1::CanisterInstallMode", - optional, - tag = "4" - )] - pub mode: ::core::option::Option, + pub mode: Option, } /// A proposal to transfer SNS treasury funds to (optionally a Subaccount of) the /// target principal. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct TransferSnsTreasuryFunds { - #[prost(enumeration = "transfer_sns_treasury_funds::TransferFrom", tag = "1")] pub from_treasury: i32, /// The amount to transfer, in e8s. - #[prost(uint64, tag = "2")] pub amount_e8s: u64, /// An optional memo to use for the transfer. - #[prost(uint64, optional, tag = "3")] - pub memo: ::core::option::Option, + pub memo: Option, /// The principal to transfer the funds to. - #[prost(message, optional, tag = "4")] - pub to_principal: ::core::option::Option<::ic_base_types::PrincipalId>, + pub to_principal: Option<::ic_base_types::PrincipalId>, /// An (optional) Subaccount of the principal to transfer the funds to. - #[prost(message, optional, tag = "5")] - pub to_subaccount: ::core::option::Option, + pub to_subaccount: Option, } /// Nested message and enum types in `TransferSnsTreasuryFunds`. pub mod transfer_sns_treasury_funds { @@ -429,16 +295,14 @@ pub mod transfer_sns_treasury_funds { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum TransferFrom { @@ -459,7 +323,7 @@ pub mod transfer_sns_treasury_funds { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "TRANSFER_FROM_UNSPECIFIED" => Some(Self::Unspecified), "TRANSFER_FROM_ICP_TREASURY" => Some(Self::IcpTreasury), @@ -471,212 +335,113 @@ pub mod transfer_sns_treasury_funds { } /// A proposal function that changes the ledger's parameters. /// Fields with None values will remain unchanged. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ManageLedgerParameters { - #[prost(uint64, optional, tag = "1")] - pub transfer_fee: ::core::option::Option, - #[prost(string, optional, tag = "2")] - pub token_name: ::core::option::Option<::prost::alloc::string::String>, - #[prost(string, optional, tag = "3")] - pub token_symbol: ::core::option::Option<::prost::alloc::string::String>, - #[prost(string, optional, tag = "4")] - pub token_logo: ::core::option::Option<::prost::alloc::string::String>, + pub transfer_fee: Option, + pub token_name: Option, + pub token_symbol: Option, + pub token_logo: Option, } /// A proposal to mint SNS tokens to (optionally a Subaccount of) the /// target principal. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct MintSnsTokens { /// The amount to transfer, in e8s. - #[prost(uint64, optional, tag = "1")] - pub amount_e8s: ::core::option::Option, + pub amount_e8s: Option, /// An optional memo to use for the transfer. - #[prost(uint64, optional, tag = "2")] - pub memo: ::core::option::Option, + pub memo: Option, /// The principal to transfer the funds to. - #[prost(message, optional, tag = "3")] - pub to_principal: ::core::option::Option<::ic_base_types::PrincipalId>, + pub to_principal: Option<::ic_base_types::PrincipalId>, /// An (optional) Subaccount of the principal to transfer the funds to. - #[prost(message, optional, tag = "4")] - pub to_subaccount: ::core::option::Option, + pub to_subaccount: Option, } /// A proposal function to change the values of SNS metadata. /// Fields with None values will remain unchanged. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ManageSnsMetadata { /// Base64 representation of the logo. Max length is 341334 characters, roughly 256 Kb. - #[prost(string, optional, tag = "1")] - pub logo: ::core::option::Option<::prost::alloc::string::String>, + pub logo: Option, /// Url string, must be between 10 and 256 characters. - #[prost(string, optional, tag = "2")] - pub url: ::core::option::Option<::prost::alloc::string::String>, + pub url: Option, /// Name string, must be between 4 and 255 characters. - #[prost(string, optional, tag = "3")] - pub name: ::core::option::Option<::prost::alloc::string::String>, + pub name: Option, /// Description string, must be between 10 and 10000 characters. - #[prost(string, optional, tag = "4")] - pub description: ::core::option::Option<::prost::alloc::string::String>, + pub description: Option, } /// A proposal function to upgrade the SNS to the next version. The versions are such that only /// one kind of canister will update at the same time. /// This returns an error if the canister cannot be upgraded or no upgrades are available. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct UpgradeSnsToNextVersion {} /// A proposal to register a list of dapps in the root canister. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct RegisterDappCanisters { /// The canister IDs to be registered (i.e. under the management of the SNS). /// The canisters must be already controlled by the SNS root canister before /// making this proposal. Any controllers besides the root canister will be /// removed when the proposal is executed. /// At least one canister ID is required. - #[prost(message, repeated, tag = "1")] - pub canister_ids: ::prost::alloc::vec::Vec<::ic_base_types::PrincipalId>, + pub canister_ids: Vec<::ic_base_types::PrincipalId>, } /// A proposal to remove a list of dapps from the SNS and assign them to new controllers -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct DeregisterDappCanisters { /// The canister IDs to be deregistered (i.e. removed from the management of the SNS). - #[prost(message, repeated, tag = "1")] - pub canister_ids: ::prost::alloc::vec::Vec<::ic_base_types::PrincipalId>, + pub canister_ids: Vec<::ic_base_types::PrincipalId>, /// The new controllers for the deregistered canisters. - #[prost(message, repeated, tag = "2")] - pub new_controllers: ::prost::alloc::vec::Vec<::ic_base_types::PrincipalId>, + pub new_controllers: Vec<::ic_base_types::PrincipalId>, } /// A proposal to manage the settings of one or more dapp canisters. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ManageDappCanisterSettings { /// The canister IDs of the dapp canisters to be modified. - #[prost(message, repeated, tag = "1")] - pub canister_ids: ::prost::alloc::vec::Vec<::ic_base_types::PrincipalId>, + pub canister_ids: Vec<::ic_base_types::PrincipalId>, /// Below are fields under CanisterSettings defined at /// - #[prost(uint64, optional, tag = "2")] - pub compute_allocation: ::core::option::Option, - #[prost(uint64, optional, tag = "3")] - pub memory_allocation: ::core::option::Option, - #[prost(uint64, optional, tag = "4")] - pub freezing_threshold: ::core::option::Option, - #[prost(uint64, optional, tag = "5")] - pub reserved_cycles_limit: ::core::option::Option, - #[prost(enumeration = "LogVisibility", optional, tag = "6")] - pub log_visibility: ::core::option::Option, - #[prost(uint64, optional, tag = "7")] - pub wasm_memory_limit: ::core::option::Option, - #[prost(uint64, optional, tag = "8")] - pub wasm_memory_threshold: ::core::option::Option, + pub compute_allocation: Option, + pub memory_allocation: Option, + pub freezing_threshold: Option, + pub reserved_cycles_limit: Option, + pub log_visibility: Option, + pub wasm_memory_limit: Option, + pub wasm_memory_threshold: Option, } /// Unlike `Governance.Version`, this message has optional fields and is the recommended one /// to use in APIs that can evolve. For example, the SNS Governance could eventually support /// a shorthand notation for SNS versions, enabling clients to specify SNS versions without having /// to set each individual SNS framework canister's WASM hash. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct SnsVersion { /// The hash of the Governance canister WASM. - #[prost(bytes = "vec", optional, tag = "1")] - pub governance_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub governance_wasm_hash: Option>, /// The hash of the Swap canister WASM. - #[prost(bytes = "vec", optional, tag = "2")] - pub swap_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub swap_wasm_hash: Option>, /// The hash of the Root canister WASM. - #[prost(bytes = "vec", optional, tag = "3")] - pub root_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub root_wasm_hash: Option>, /// The hash of the Index canister WASM. - #[prost(bytes = "vec", optional, tag = "4")] - pub index_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub index_wasm_hash: Option>, /// The hash of the Ledger canister WASM. - #[prost(bytes = "vec", optional, tag = "5")] - pub ledger_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub ledger_wasm_hash: Option>, /// The hash of the Ledger Archive canister WASM. - #[prost(bytes = "vec", optional, tag = "6")] - pub archive_wasm_hash: ::core::option::Option<::prost::alloc::vec::Vec>, + pub archive_wasm_hash: Option>, } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct AdvanceSnsTargetVersion { /// If not specified, the target will advance to the latest SNS version known to this SNS. - #[prost(message, optional, tag = "1")] - pub new_target: ::core::option::Option, + pub new_target: Option, } /// A proposal is the immutable input of a proposal submission. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[compare_default] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Proposal { /// The proposal's title as a text, which can be at most 256 bytes. - #[prost(string, tag = "1")] - pub title: ::prost::alloc::string::String, + pub title: String, /// The description of the proposal which is a short text, composed /// using a maximum of 30000 bytes of characters. - #[prost(string, tag = "2")] - pub summary: ::prost::alloc::string::String, + pub summary: String, /// The web address of additional content required to evaluate the /// proposal, specified using HTTPS. The URL string must not be longer than /// 2000 bytes. - #[prost(string, tag = "3")] - pub url: ::prost::alloc::string::String, + pub url: String, /// The action that the proposal proposes to take on adoption. /// /// Each action is associated with an function id that can be used for following. @@ -686,11 +451,7 @@ pub struct Proposal { /// /// See `impl From<&Action> for u64` in src/types.rs for the implementation /// of this mapping. - #[prost( - oneof = "proposal::Action", - tags = "4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19" - )] - pub action: ::core::option::Option, + pub action: Option, } /// Nested message and enum types in `Proposal`. pub mod proposal { @@ -703,24 +464,20 @@ pub mod proposal { /// /// See `impl From<&Action> for u64` in src/types.rs for the implementation /// of this mapping. - #[derive( - candid::CandidType, candid::Deserialize, comparable::Comparable, strum_macros::EnumIter, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug)] #[allow(clippy::large_enum_variant)] - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq)] pub enum Action { /// The `Unspecified` action is used as a fallback when /// following. That is, if no followees are specified for a given /// action, the followees for this action are used instead. /// /// Id = 0. - #[prost(message, tag = "4")] Unspecified(super::Empty), /// A motion that should guide the future strategy of the SNS's ecosystem /// but does not have immediate effect in the sense that a method is executed. /// /// Id = 1. - #[prost(message, tag = "5")] Motion(super::Motion), /// Change the nervous system's parameters. /// Note that a change of a parameter will only affect future actions where @@ -732,98 +489,78 @@ pub mod proposal { /// neurons created before this change may have less stake. /// /// Id = 2. - #[prost(message, tag = "6")] ManageNervousSystemParameters(super::NervousSystemParameters), /// Upgrade a canister that is controlled by the SNS governance canister. /// /// Id = 3. - #[prost(message, tag = "7")] UpgradeSnsControlledCanister(super::UpgradeSnsControlledCanister), /// Add a new NervousSystemFunction, of generic type, to be executable by proposal. /// /// Id = 4. - #[prost(message, tag = "8")] AddGenericNervousSystemFunction(super::NervousSystemFunction), /// Remove a NervousSystemFunction, of generic type, from being executable by proposal. /// /// Id = 5. - #[prost(uint64, tag = "9")] RemoveGenericNervousSystemFunction(u64), /// Execute a method outside the SNS canisters. /// /// Ids \in \[1000, u64::MAX\]. - #[prost(message, tag = "10")] ExecuteGenericNervousSystemFunction(super::ExecuteGenericNervousSystemFunction), /// Execute an upgrade to next version on the blessed SNS upgrade path. /// /// Id = 7. - #[prost(message, tag = "11")] UpgradeSnsToNextVersion(super::UpgradeSnsToNextVersion), /// Modify values of SnsMetadata. /// /// Id = 8. - #[prost(message, tag = "12")] ManageSnsMetadata(super::ManageSnsMetadata), /// Transfer SNS treasury funds (ICP or SNS token) to an account. /// Id = 9. - #[prost(message, tag = "13")] TransferSnsTreasuryFunds(super::TransferSnsTreasuryFunds), /// Register one or more dapp canister(s) in the SNS root canister. /// /// Id = 10. - #[prost(message, tag = "14")] RegisterDappCanisters(super::RegisterDappCanisters), /// Deregister one or more dapp canister(s) in the SNS root canister. /// /// Id = 11. - #[prost(message, tag = "15")] DeregisterDappCanisters(super::DeregisterDappCanisters), /// Mint SNS tokens to an account. /// /// Id = 12. - #[prost(message, tag = "16")] MintSnsTokens(super::MintSnsTokens), /// Change some parameters on the ledger. /// /// Id = 13. - #[prost(message, tag = "17")] ManageLedgerParameters(super::ManageLedgerParameters), /// Change canister settings for one or more dapp canister(s). /// /// Id = 14. - #[prost(message, tag = "18")] ManageDappCanisterSettings(super::ManageDappCanisterSettings), /// Advance SNS target version. /// /// Id = 15. - #[prost(message, tag = "19")] AdvanceSnsTargetVersion(super::AdvanceSnsTargetVersion), } } -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[compare_default] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GovernanceError { - #[prost(enumeration = "governance_error::ErrorType", tag = "1")] pub error_type: i32, - #[prost(string, tag = "2")] - pub error_message: ::prost::alloc::string::String, + pub error_message: String, } /// Nested message and enum types in `GovernanceError`. pub mod governance_error { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum ErrorType { @@ -911,7 +648,7 @@ pub mod governance_error { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "ERROR_TYPE_UNSPECIFIED" => Some(Self::Unspecified), "ERROR_TYPE_UNAVAILABLE" => Some(Self::Unavailable), @@ -942,73 +679,46 @@ pub mod governance_error { /// automatically caused by a neuron following other neurons. /// /// Once a ballot's vote is set it cannot be changed. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[self_describing] -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct Ballot { /// The ballot's vote. - #[prost(enumeration = "Vote", tag = "1")] pub vote: i32, /// The voting power associated with the ballot. The voting power of a ballot /// associated with a neuron and a proposal is set at the proposal's creation /// time to the neuron's voting power at that time. - #[prost(uint64, tag = "2")] pub voting_power: u64, /// The time when the ballot's vote was populated with a decision (YES or NO, not /// UNDECIDED) in seconds since the UNIX epoch. This is only meaningful once a /// decision has been made and set to zero when the proposal associated with the /// ballot is created. - #[prost(uint64, tag = "3")] pub cast_timestamp_seconds: u64, } /// A tally of votes associated with a proposal. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[self_describing] -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct Tally { /// The time when this tally was made, in seconds from the Unix epoch. - #[prost(uint64, tag = "1")] pub timestamp_seconds: u64, /// The number of yes votes, in voting power unit. - #[prost(uint64, tag = "2")] pub yes: u64, /// The number of no votes, in voting power unit. - #[prost(uint64, tag = "3")] pub no: u64, /// The total voting power unit of eligible neurons that can vote /// on the proposal that this tally is associated with (i.e., the sum /// of the voting power of yes, no, and undecided votes). /// This should always be greater than or equal to yes + no. - #[prost(uint64, tag = "4")] pub total: u64, } /// The wait-for-quiet state associated with a proposal, storing the /// data relevant to the "wait-for-quiet" implementation. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct WaitForQuietState { /// The current deadline of the proposal associated with this /// WaitForQuietState, in seconds from the Unix epoch. - #[prost(uint64, tag = "1")] pub current_deadline_timestamp_seconds: u64, } /// The ProposalData that contains everything related to a proposal: /// the proposal itself (immutable), as well as mutable data such as ballots. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ProposalData { /// The proposal's action. /// Types 0-999 are reserved for current (and future) core governance @@ -1031,61 +741,49 @@ pub struct ProposalData { /// Id 13 - ManageLedgerParameters proposals. /// Id 14 - ManageDappCanisterSettings proposals. /// Id 15 - AdvanceSnsTargetVersion proposals. - #[prost(uint64, tag = "1")] pub action: u64, /// This is stored here temporarily. It is also stored on the map /// that contains proposals. /// /// The unique id for this proposal. - #[prost(message, optional, tag = "2")] - pub id: ::core::option::Option, + pub id: Option, /// The NeuronId of the Neuron that made this proposal. - #[prost(message, optional, tag = "3")] - pub proposer: ::core::option::Option, + pub proposer: Option, /// The amount of governance tokens in e8s to be /// charged to the proposer if the proposal is rejected. - #[prost(uint64, tag = "4")] pub reject_cost_e8s: u64, /// The proposal originally submitted. - #[prost(message, optional, tag = "5")] - pub proposal: ::core::option::Option, + pub proposal: Option, /// The timestamp, in seconds from the Unix epoch, /// when this proposal was made. - #[prost(uint64, tag = "6")] pub proposal_creation_timestamp_seconds: u64, /// The ballots associated with a proposal, given as a map which /// maps the neurons' NeuronId to the neurons' ballots. This is /// only present as long as the proposal is not settled with /// respect to rewards. - #[prost(btree_map = "string, message", tag = "7")] - pub ballots: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, Ballot>, + pub ballots: BTreeMap, /// The latest tally. The tally is computed only for open proposals when /// they are processed. Once a proposal is decided, i.e., /// ProposalDecisionStatus isn't open anymore, the tally never changes /// again. (But the ballots may still change as neurons may vote after /// the proposal has been decided.) - #[prost(message, optional, tag = "8")] - pub latest_tally: ::core::option::Option, + pub latest_tally: Option, /// The timestamp, in seconds since the Unix epoch, when this proposal /// was adopted or rejected. If not specified, the proposal is still 'open'. - #[prost(uint64, tag = "9")] pub decided_timestamp_seconds: u64, /// The timestamp, in seconds since the Unix epoch, when the (previously /// adopted) proposal has been executed. If not specified (i.e., still has /// the default value zero), the proposal has not (yet) been executed /// successfully. - #[prost(uint64, tag = "10")] pub executed_timestamp_seconds: u64, /// The timestamp, in seconds since the Unix epoch, when the (previously /// adopted) proposal has failed to be executed. If not specified (i.e., /// still has the default value zero), the proposal has not (yet) failed /// to execute. - #[prost(uint64, tag = "11")] pub failed_timestamp_seconds: u64, /// The reason why the (previously adopted) proposal has failed to execute. /// If not specified, the proposal has not (yet) failed to execute. - #[prost(message, optional, tag = "12")] - pub failure_reason: ::core::option::Option, + pub failure_reason: Option, /// OBSOLETE: Superseded by reward_event_end_timestamp_seconds. However, old /// proposals use this (old) field, not the new one, since they predate the new /// field. Therefore, to correctly detect whether a proposal has been rewarded, @@ -1099,11 +797,9 @@ pub struct ProposalData { /// no reward event taking this proposal into consideration happened yet. /// /// This field matches field round in RewardEvent. - #[prost(uint64, tag = "13")] pub reward_event_round: u64, /// The proposal's wait-for-quiet state. This needs to be saved in stable memory. - #[prost(message, optional, tag = "14")] - pub wait_for_quiet_state: ::core::option::Option, + pub wait_for_quiet_state: Option, /// The proposal's payload rendered as text, for display in text/UI frontends. /// This is set if the proposal is considered valid at time of submission. /// @@ -1113,8 +809,7 @@ pub struct ProposalData { /// Proposals with action of type GenericNervousSystemFunction provide no /// guarantee on the style of rendering as this is performed by the /// GenericNervousSystemFunction validator_canister. - #[prost(string, optional, tag = "15")] - pub payload_text_rendering: ::core::option::Option<::prost::alloc::string::String>, + pub payload_text_rendering: Option, /// Deprecated. From now on, this field will be set to true when new proposals /// are created. However, there ARE old proposals where this is set to false. /// @@ -1122,149 +817,83 @@ pub struct ProposalData { /// directly to Settled /// /// TODO(NNS1-2731): Delete this. - #[prost(bool, tag = "16")] pub is_eligible_for_rewards: bool, /// The initial voting period of the proposal, identical in meaning to the one in /// NervousSystemParameters, and duplicated here so the parameters can be changed /// without affecting existing proposals. - #[prost(uint64, tag = "17")] pub initial_voting_period_seconds: u64, /// The wait_for_quiet_deadline_increase_seconds of the proposal, identical in /// meaning to the one in NervousSystemParameters, and duplicated here so the /// parameters can be changed without affecting existing proposals. - #[prost(uint64, tag = "18")] pub wait_for_quiet_deadline_increase_seconds: u64, /// If populated, then the proposal is considered "settled" in terms of voting /// rewards. Prior to distribution of rewards, but after votes are no longer /// accepted, it is considered "ready to settle". - #[prost(uint64, optional, tag = "19")] - pub reward_event_end_timestamp_seconds: ::core::option::Option, + pub reward_event_end_timestamp_seconds: Option, /// Minimum "yes" votes needed for proposal adoption, as a fraction of the /// total voting power. Example: 300 basis points represents a requirement that /// 3% of the total voting power votes to adopt the proposal. - #[prost(message, optional, tag = "20")] - pub minimum_yes_proportion_of_total: - ::core::option::Option<::ic_nervous_system_proto::pb::v1::Percentage>, + pub minimum_yes_proportion_of_total: Option<::ic_nervous_system_proto::pb::v1::Percentage>, /// Minimum "yes" votes needed for proposal adoption, as a fraction of the /// exercised voting power. Example: 50_000 basis points represents a /// requirement that 50% of the exercised voting power votes to adopt the /// proposal. - #[prost(message, optional, tag = "21")] - pub minimum_yes_proportion_of_exercised: - ::core::option::Option<::ic_nervous_system_proto::pb::v1::Percentage>, + pub minimum_yes_proportion_of_exercised: Option<::ic_nervous_system_proto::pb::v1::Percentage>, /// In general, this holds data retrieved at proposal submission/creation time and used later /// during execution. This varies based on the action of the proposal. - #[prost(oneof = "proposal_data::ActionAuxiliary", tags = "22, 23, 24")] - pub action_auxiliary: ::core::option::Option, + pub action_auxiliary: Option, } /// Nested message and enum types in `ProposalData`. pub mod proposal_data { - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct TransferSnsTreasuryFundsActionAuxiliary { - #[prost(message, optional, tag = "1")] - pub valuation: ::core::option::Option, + pub valuation: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct MintSnsTokensActionAuxiliary { - #[prost(message, optional, tag = "1")] - pub valuation: ::core::option::Option, + pub valuation: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct AdvanceSnsTargetVersionActionAuxiliary { /// Corresponds to the Some(target_version) from an AdvanceSnsTargetVersion proposal, or /// to the last SNS version known to this SNS at the time of AdvanceSnsTargetVersion creation. - #[prost(message, optional, tag = "1")] - pub target_version: ::core::option::Option, + pub target_version: Option, } /// In general, this holds data retrieved at proposal submission/creation time and used later /// during execution. This varies based on the action of the proposal. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum ActionAuxiliary { - #[prost(message, tag = "22")] TransferSnsTreasuryFunds(TransferSnsTreasuryFundsActionAuxiliary), - #[prost(message, tag = "23")] MintSnsTokens(MintSnsTokensActionAuxiliary), - #[prost(message, tag = "24")] AdvanceSnsTargetVersion(AdvanceSnsTargetVersionActionAuxiliary), } } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Valuation { - #[prost(enumeration = "valuation::Token", optional, tag = "1")] - pub token: ::core::option::Option, - #[prost(message, optional, tag = "2")] - pub account: ::core::option::Option, - #[prost(uint64, optional, tag = "3")] - pub timestamp_seconds: ::core::option::Option, - #[prost(message, optional, tag = "4")] - pub valuation_factors: ::core::option::Option, + pub token: Option, + pub account: Option, + pub timestamp_seconds: Option, + pub valuation_factors: Option, } /// Nested message and enum types in `Valuation`. pub mod valuation { - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ValuationFactors { - #[prost(message, optional, tag = "1")] - pub tokens: ::core::option::Option<::ic_nervous_system_proto::pb::v1::Tokens>, - #[prost(message, optional, tag = "2")] - pub icps_per_token: ::core::option::Option<::ic_nervous_system_proto::pb::v1::Decimal>, - #[prost(message, optional, tag = "3")] - pub xdrs_per_icp: ::core::option::Option<::ic_nervous_system_proto::pb::v1::Decimal>, + pub tokens: Option<::ic_nervous_system_proto::pb::v1::Tokens>, + pub icps_per_token: Option<::ic_nervous_system_proto::pb::v1::Decimal>, + pub xdrs_per_icp: Option<::ic_nervous_system_proto::pb::v1::Decimal>, } #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum Token { @@ -1285,7 +914,7 @@ pub mod valuation { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "TOKEN_UNSPECIFIED" => Some(Self::Unspecified), "TOKEN_ICP" => Some(Self::Icp), @@ -1304,29 +933,19 @@ pub mod valuation { /// on the subnet). /// /// Required invariant: the canister code assumes that all system parameters are always set. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NervousSystemParameters { /// The number of e8s (10E-8 of a token) that a rejected /// proposal costs the proposer. - #[prost(uint64, optional, tag = "1")] - pub reject_cost_e8s: ::core::option::Option, + pub reject_cost_e8s: Option, /// The minimum number of e8s (10E-8 of a token) that can be staked in a neuron. /// /// To ensure that staking and disbursing of the neuron work, the chosen value /// must be larger than the transaction_fee_e8s. - #[prost(uint64, optional, tag = "2")] - pub neuron_minimum_stake_e8s: ::core::option::Option, + pub neuron_minimum_stake_e8s: Option, /// The transaction fee that must be paid for ledger transactions (except /// minting and burning governance tokens). - #[prost(uint64, optional, tag = "3")] - pub transaction_fee_e8s: ::core::option::Option, + pub transaction_fee_e8s: Option, /// The maximum number of proposals to keep, per action. When the /// total number of proposals for a given action is greater than this /// number, the oldest proposals that have reached final decision state @@ -1335,8 +954,7 @@ pub struct NervousSystemParameters { /// /// The number must be larger than zero and at most be as large as the /// defined ceiling MAX_PROPOSALS_TO_KEEP_PER_ACTION_CEILING. - #[prost(uint32, optional, tag = "4")] - pub max_proposals_to_keep_per_action: ::core::option::Option, + pub max_proposals_to_keep_per_action: Option, /// The initial voting period of a newly created proposal. /// A proposal's voting period may then be further increased during /// a proposal's lifecycle due to the wait-for-quiet algorithm. @@ -1344,8 +962,7 @@ pub struct NervousSystemParameters { /// The voting period must be between (inclusive) the defined floor /// INITIAL_VOTING_PERIOD_SECONDS_FLOOR and ceiling /// INITIAL_VOTING_PERIOD_SECONDS_CEILING. - #[prost(uint64, optional, tag = "5")] - pub initial_voting_period_seconds: ::core::option::Option, + pub initial_voting_period_seconds: Option, /// The wait for quiet algorithm extends the voting period of a proposal when /// there is a flip in the majority vote during the proposal's voting period. /// This parameter determines the maximum time period that the voting period @@ -1356,8 +973,7 @@ pub struct NervousSystemParameters { /// The maximum total voting period extension is 2 * wait_for_quiet_deadline_increase_seconds. /// For more information, see the wiki page on the wait-for-quiet algorithm: /// - #[prost(uint64, optional, tag = "18")] - pub wait_for_quiet_deadline_increase_seconds: ::core::option::Option, + pub wait_for_quiet_deadline_increase_seconds: Option, /// TODO NNS1-2169: This field currently has no effect. /// TODO NNS1-2169: Design and implement this feature. /// @@ -1367,34 +983,28 @@ pub struct NervousSystemParameters { /// If unset, neurons will have no followees by default. /// The set of followees for each function can be at most of size /// max_followees_per_function. - #[prost(message, optional, tag = "6")] - pub default_followees: ::core::option::Option, + pub default_followees: Option, /// The maximum number of allowed neurons. When this maximum is reached, no new /// neurons will be created until some are removed. /// /// This number must be larger than zero and at most as large as the defined /// ceiling MAX_NUMBER_OF_NEURONS_CEILING. - #[prost(uint64, optional, tag = "7")] - pub max_number_of_neurons: ::core::option::Option, + pub max_number_of_neurons: Option, /// The minimum dissolve delay a neuron must have to be eligible to vote. /// /// The chosen value must be smaller than max_dissolve_delay_seconds. - #[prost(uint64, optional, tag = "8")] - pub neuron_minimum_dissolve_delay_to_vote_seconds: ::core::option::Option, + pub neuron_minimum_dissolve_delay_to_vote_seconds: Option, /// The maximum number of followees each neuron can establish for each nervous system function. /// /// This number can be at most as large as the defined ceiling /// MAX_FOLLOWEES_PER_FUNCTION_CEILING. - #[prost(uint64, optional, tag = "9")] - pub max_followees_per_function: ::core::option::Option, + pub max_followees_per_function: Option, /// The maximum dissolve delay that a neuron can have. That is, the maximum /// that a neuron's dissolve delay can be increased to. The maximum is also enforced /// when saturating the dissolve delay bonus in the voting power computation. - #[prost(uint64, optional, tag = "10")] - pub max_dissolve_delay_seconds: ::core::option::Option, + pub max_dissolve_delay_seconds: Option, /// The age of a neuron that saturates the age bonus for the voting power computation. - #[prost(uint64, optional, tag = "12")] - pub max_neuron_age_for_age_bonus: ::core::option::Option, + pub max_neuron_age_for_age_bonus: Option, /// The max number of proposals for which ballots are still stored, i.e., /// unsettled proposals. If this number of proposals is reached, new proposals /// can only be added in exceptional cases (for few proposals it is defined @@ -1403,26 +1013,21 @@ pub struct NervousSystemParameters { /// /// This number must be larger than zero and at most as large as the defined /// ceiling MAX_NUMBER_OF_PROPOSALS_WITH_BALLOTS_CEILING. - #[prost(uint64, optional, tag = "14")] - pub max_number_of_proposals_with_ballots: ::core::option::Option, + pub max_number_of_proposals_with_ballots: Option, /// The default set of neuron permissions granted to the principal claiming a neuron. - #[prost(message, optional, tag = "15")] - pub neuron_claimer_permissions: ::core::option::Option, + pub neuron_claimer_permissions: Option, /// The superset of neuron permissions a principal with permission /// `NeuronPermissionType::ManagePrincipals` for a given neuron can grant to another /// principal for this same neuron. /// If this set changes via a ManageNervousSystemParameters proposal, previous /// neurons' permissions will be unchanged and only newly granted permissions will be affected. - #[prost(message, optional, tag = "16")] - pub neuron_grantable_permissions: ::core::option::Option, + pub neuron_grantable_permissions: Option, /// The maximum number of principals that can have permissions for a neuron - #[prost(uint64, optional, tag = "17")] - pub max_number_of_principals_per_neuron: ::core::option::Option, + pub max_number_of_principals_per_neuron: Option, /// When this field is not populated, voting rewards are "disabled". Once this /// is set, it probably should not be changed, because the results would /// probably be pretty confusing. - #[prost(message, optional, tag = "19")] - pub voting_rewards_parameters: ::core::option::Option, + pub voting_rewards_parameters: Option, /// E.g. if a large dissolve delay can double the voting power of a neuron, /// then this field would have a value of 100, indicating a maximum of /// 100% additional voting power. @@ -1430,14 +1035,12 @@ pub struct NervousSystemParameters { /// For no bonus, this should be set to 0. /// /// To achieve functionality equivalent to NNS, this should be set to 100. - #[prost(uint64, optional, tag = "20")] - pub max_dissolve_delay_bonus_percentage: ::core::option::Option, + pub max_dissolve_delay_bonus_percentage: Option, /// Analogous to the previous field (see the previous comment), /// but this one relates to neuron age instead of dissolve delay. /// /// To achieve functionality equivalent to NNS, this should be set to 25. - #[prost(uint64, optional, tag = "21")] - pub max_age_bonus_percentage: ::core::option::Option, + pub max_age_bonus_percentage: Option, /// By default, maturity modulation is enabled; however, an SNS can use this /// field to disable it. When disabled, this canister will still poll the /// Cycles Minting Canister (CMC), and store the value received therefrom. @@ -1446,18 +1049,9 @@ pub struct NervousSystemParameters { /// The reason we call this "disabled" instead of (positive) "enabled" is so /// that the PB default (bool fields are false) and our application default /// (enabled) agree. - #[prost(bool, optional, tag = "22")] - pub maturity_modulation_disabled: ::core::option::Option, + pub maturity_modulation_disabled: Option, } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct VotingRewardsParameters { /// The amount of time between reward events. /// @@ -1473,14 +1067,12 @@ pub struct VotingRewardsParameters { /// within a few seconds of this. /// /// This supersedes super.reward_distribution_period_seconds. - #[prost(uint64, optional, tag = "1")] - pub round_duration_seconds: ::core::option::Option, + pub round_duration_seconds: Option, /// The amount of time that the growth rate changes (presumably, decreases) /// from the initial growth rate to the final growth rate. (See the two /// *_reward_rate_basis_points fields bellow.) The transition is quadratic, and /// levels out at the end of the growth rate transition period. - #[prost(uint64, optional, tag = "3")] - pub reward_rate_transition_duration_seconds: ::core::option::Option, + pub reward_rate_transition_duration_seconds: Option, /// The amount of rewards is proportional to token_supply * current_rate. In /// turn, current_rate is somewhere between `initial_reward_rate_basis_points` /// and `final_reward_rate_basis_points`. In the first reward period, it is the @@ -1490,37 +1082,19 @@ pub struct VotingRewardsParameters { /// quadratic, and levels out at the end of the growth rate transition period. /// /// (A basis point is one in ten thousand.) - #[prost(uint64, optional, tag = "4")] - pub initial_reward_rate_basis_points: ::core::option::Option, - #[prost(uint64, optional, tag = "5")] - pub final_reward_rate_basis_points: ::core::option::Option, + pub initial_reward_rate_basis_points: Option, + pub final_reward_rate_basis_points: Option, } /// The set of default followees that every newly created neuron will follow per function. /// This is specified as a mapping of proposal functions to followees for that function. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct DefaultFollowees { - #[prost(btree_map = "uint64, message", tag = "1")] - pub followees: ::prost::alloc::collections::BTreeMap, + pub followees: BTreeMap, } /// A wrapper for a list of neuron permissions. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronPermissionList { - #[prost(enumeration = "NeuronPermissionType", repeated, tag = "1")] - pub permissions: ::prost::alloc::vec::Vec, + pub permissions: Vec, } /// A record of when voting rewards were determined, and neuron maturity /// increased for participation in voting on proposals. @@ -1531,14 +1105,7 @@ pub struct NeuronPermissionList { /// To make it a little easier to eventually deduplicate NNS and SNS governance /// code, tags should be chosen so that it is new to BOTH this and the NNS /// RewardEvent. (This also applies to other message definitions.) -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct RewardEvent { /// DEPRECATED: Use end_timestamp_seconds instead. /// @@ -1554,23 +1121,19 @@ pub struct RewardEvent { /// it was not possible to process a reward event for a while. This means that /// successive values in this field might not be consecutive, but they usually /// are. - #[prost(uint64, tag = "1")] pub round: u64, /// Not to be confused with round_end_timestampe_seconds. This is just used to /// record when the calculation (of voting rewards) was performed, not the time /// range/events (i.e. proposals) that was operated on. - #[prost(uint64, tag = "2")] pub actual_timestamp_seconds: u64, /// The list of proposals that were taken into account during /// this reward event. - #[prost(message, repeated, tag = "3")] - pub settled_proposals: ::prost::alloc::vec::Vec, + pub settled_proposals: Vec, /// The total amount of reward that was distributed during this reward event. /// /// The unit is "e8s equivalent" to insist that, while this quantity is on /// the same scale as governance tokens, maturity is not directly convertible /// to governance tokens: conversion requires a minting event. - #[prost(uint64, tag = "4")] pub distributed_e8s_equivalent: u64, /// All proposals that were "ready to settle" up to this time were /// considered. @@ -1587,8 +1150,7 @@ pub struct RewardEvent { /// Being able to change round duration does not exist in NNS (yet), and there /// is (currently) no intention to add that feature, but it could be done by /// making similar changes. - #[prost(uint64, optional, tag = "5")] - pub end_timestamp_seconds: ::core::option::Option, + pub end_timestamp_seconds: Option, /// In some cases, the rewards that would have been distributed in one round are /// "rolled over" into the next reward event. This field keeps track of how many /// rounds have passed since the last time rewards were distributed (rather @@ -1607,8 +1169,7 @@ pub struct RewardEvent { /// settled to distribute rewards for. /// /// In both of these cases, the rewards purse rolls over into the next round. - #[prost(uint64, optional, tag = "6")] - pub rounds_since_last_distribution: ::core::option::Option, + pub rounds_since_last_distribution: Option, /// The total amount of rewards that was available during the reward event. /// /// The e8s_equivalent_to_be_rolled_over method returns this when @@ -1619,32 +1180,25 @@ pub struct RewardEvent { /// Warning: There is a field with the same name in NNS, but different tags are /// used. Also, this uses the `optional` keyword (whereas, the NNS analog does /// not). - #[prost(uint64, optional, tag = "8")] - pub total_available_e8s_equivalent: ::core::option::Option, + pub total_available_e8s_equivalent: Option, } /// The representation of the whole governance system, containing all /// information about the governance system that must be kept /// across upgrades of the governance system, i.e. kept in stable memory. -#[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] -#[compare_default] -#[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Governance { /// The current set of neurons registered in governance as a map from /// neuron IDs to neurons. - #[prost(btree_map = "string, message", tag = "1")] - pub neurons: ::prost::alloc::collections::BTreeMap<::prost::alloc::string::String, Neuron>, + pub neurons: BTreeMap, /// The current set of proposals registered in governance as a map /// from proposal IDs to the proposals' data. - #[prost(btree_map = "uint64, message", tag = "2")] - pub proposals: ::prost::alloc::collections::BTreeMap, + pub proposals: BTreeMap, /// The nervous system parameters that define and can be set by /// each nervous system. - #[prost(message, optional, tag = "8")] - pub parameters: ::core::option::Option, + pub parameters: Option, /// TODO IC-1168: update when rewards are introduced /// The latest reward event. - #[prost(message, optional, tag = "9")] - pub latest_reward_event: ::core::option::Option, + pub latest_reward_event: Option, /// The in-flight neuron ledger commands as a map from neuron IDs /// to commands. /// @@ -1666,87 +1220,54 @@ pub struct Governance { /// Because we know exactly what was going on, we should have the /// information necessary to reconcile the state, using custom code /// added on upgrade, if necessary. - #[prost(btree_map = "string, message", tag = "10")] - pub in_flight_commands: ::prost::alloc::collections::BTreeMap< - ::prost::alloc::string::String, - governance::NeuronInFlightCommand, - >, + pub in_flight_commands: BTreeMap, /// The timestamp that is considered genesis for the governance /// system, in seconds since the Unix epoch. That is, the time /// at which `canister_init` was run for the governance canister. - #[prost(uint64, tag = "11")] pub genesis_timestamp_seconds: u64, - #[prost(message, optional, tag = "13")] - pub metrics: ::core::option::Option, + pub metrics: Option, /// The canister ID of the ledger canister. - #[prost(message, optional, tag = "16")] - pub ledger_canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub ledger_canister_id: Option<::ic_base_types::PrincipalId>, /// The canister ID of the root canister. - #[prost(message, optional, tag = "17")] - pub root_canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub root_canister_id: Option<::ic_base_types::PrincipalId>, /// ID to NervousSystemFunction (which has an id field). - #[prost(btree_map = "uint64, message", tag = "18")] - pub id_to_nervous_system_functions: - ::prost::alloc::collections::BTreeMap, - #[prost(enumeration = "governance::Mode", tag = "19")] + pub id_to_nervous_system_functions: BTreeMap, pub mode: i32, /// The canister ID of the swap canister. /// /// When this is unpopulated, mode should be Normal, and when this is /// populated, mode should be PreInitializationSwap. - #[prost(message, optional, tag = "20")] - pub swap_canister_id: ::core::option::Option<::ic_base_types::PrincipalId>, - #[prost(message, optional, tag = "21")] - pub sns_metadata: ::core::option::Option, + pub swap_canister_id: Option<::ic_base_types::PrincipalId>, + pub sns_metadata: Option, /// The initialization parameters used to spawn an SNS - #[prost(string, tag = "22")] - pub sns_initialization_parameters: ::prost::alloc::string::String, + pub sns_initialization_parameters: String, /// Current version that this SNS is running. - #[prost(message, optional, tag = "23")] - pub deployed_version: ::core::option::Option, + pub deployed_version: Option, /// Version SNS is in process of upgrading to. - #[prost(message, optional, tag = "24")] - pub pending_version: ::core::option::Option, - #[prost(message, optional, tag = "30")] - pub target_version: ::core::option::Option, + pub pending_version: Option, + pub target_version: Option, /// True if the run_periodic_tasks function is currently finalizing disburse maturity, meaning /// that it should finish before being called again. - #[prost(bool, optional, tag = "25")] - pub is_finalizing_disburse_maturity: ::core::option::Option, - #[prost(message, optional, tag = "26")] - pub maturity_modulation: ::core::option::Option, - #[prost(message, optional, tag = "29")] - pub cached_upgrade_steps: ::core::option::Option, + pub is_finalizing_disburse_maturity: Option, + pub maturity_modulation: Option, + pub cached_upgrade_steps: Option, /// Information about the timers that perform periodic tasks of this Governance canister. - #[prost(message, optional, tag = "31")] - pub timers: ::core::option::Option<::ic_nervous_system_proto::pb::v1::Timers>, - #[prost(message, optional, tag = "32")] - pub upgrade_journal: ::core::option::Option, + pub timers: Option<::ic_nervous_system_proto::pb::v1::Timers>, + pub upgrade_journal: Option, } /// Nested message and enum types in `Governance`. pub mod governance { + use super::*; use crate::format_full_hash; use serde::ser::SerializeStruct; /// The commands that require a neuron lock. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronInFlightCommand { /// The timestamp at which the command was issued, for debugging /// purposes. - #[prost(uint64, tag = "1")] pub timestamp: u64, - #[prost( - oneof = "neuron_in_flight_command::Command", - tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 20" - )] - pub command: ::core::option::Option, + pub command: Option, } /// Nested message and enum types in `NeuronInFlightCommand`. pub mod neuron_in_flight_command { @@ -1758,67 +1279,36 @@ pub mod governance { /// no value in actually storing the command itself, and this placeholder /// can generally be used in all sync cases. #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq, )] pub struct SyncCommand {} - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum Command { - #[prost(message, tag = "2")] Disburse(super::super::manage_neuron::Disburse), - #[prost(message, tag = "3")] Split(super::super::manage_neuron::Split), - #[prost(message, tag = "4")] MergeMaturity(super::super::manage_neuron::MergeMaturity), - #[prost(message, tag = "5")] DisburseMaturity(super::super::manage_neuron::DisburseMaturity), - #[prost(message, tag = "6")] ClaimOrRefreshNeuron(super::super::manage_neuron::ClaimOrRefresh), - #[prost(message, tag = "7")] AddNeuronPermissions(super::super::manage_neuron::AddNeuronPermissions), - #[prost(message, tag = "8")] RemoveNeuronPermissions(super::super::manage_neuron::RemoveNeuronPermissions), - #[prost(message, tag = "9")] Configure(super::super::manage_neuron::Configure), - #[prost(message, tag = "10")] Follow(super::super::manage_neuron::Follow), - #[prost(message, tag = "11")] MakeProposal(super::super::Proposal), - #[prost(message, tag = "12")] RegisterVote(super::super::manage_neuron::RegisterVote), - #[prost(message, tag = "13")] FinalizeDisburseMaturity(super::super::manage_neuron::FinalizeDisburseMaturity), - #[prost(message, tag = "20")] SyncCommand(SyncCommand), } } /// Metrics that are too costly to compute each time when they are /// requested. - #[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] - #[compare_default] - #[derive(Clone, PartialEq, ::prost::Message)] + #[derive(candid::CandidType, candid::Deserialize, Debug, Default, Clone, PartialEq)] pub struct GovernanceCachedMetrics { /// The timestamp when these metrics were computed, as seconds since /// Unix epoch. - #[prost(uint64, tag = "1")] pub timestamp_seconds: u64, /// The total supply of governance tokens in the ledger canister. - #[prost(uint64, tag = "2")] pub total_supply_governance_tokens: u64, /// The number of dissolving neurons (i.e., in NeuronState::Dissolving). - #[prost(uint64, tag = "3")] pub dissolving_neurons_count: u64, /// The number of staked governance tokens in dissolving neurons /// (i.e., in NeuronState::Dissolving) grouped by the neurons' dissolve delay @@ -1826,16 +1316,13 @@ pub mod governance { /// This is given as a map from dissolve delays (rounded to years) /// to the sum of staked tokens in the dissolving neurons that have this /// dissolve delay. - #[prost(btree_map = "uint64, double", tag = "4")] - pub dissolving_neurons_e8s_buckets: ::prost::alloc::collections::BTreeMap, + pub dissolving_neurons_e8s_buckets: BTreeMap, /// The number of dissolving neurons (i.e., in NeuronState::Dissolving) /// grouped by their dissolve delay rounded to years. /// This is given as a map from dissolve delays (rounded to years) to /// the number of dissolving neurons that have this dissolve delay. - #[prost(btree_map = "uint64, uint64", tag = "5")] - pub dissolving_neurons_count_buckets: ::prost::alloc::collections::BTreeMap, + pub dissolving_neurons_count_buckets: BTreeMap, /// The number of non-dissolving neurons (i.e., in NeuronState::NotDissolving). - #[prost(uint64, tag = "6")] pub not_dissolving_neurons_count: u64, /// The number of staked governance tokens in non-dissolving neurons /// (i.e., in NeuronState::NotDissolving) grouped by the neurons' dissolve delay @@ -1843,65 +1330,45 @@ pub mod governance { /// This is given as a map from dissolve delays (rounded to years) /// to the sum of staked tokens in the non-dissolving neurons that have this /// dissolve delay. - #[prost(btree_map = "uint64, double", tag = "7")] - pub not_dissolving_neurons_e8s_buckets: ::prost::alloc::collections::BTreeMap, + pub not_dissolving_neurons_e8s_buckets: BTreeMap, /// The number of non-dissolving neurons (i.e., in NeuronState::NotDissolving) /// grouped by their dissolve delay rounded to years. /// This is given as a map from dissolve delays (rounded to years) to /// the number of non-dissolving neurons that have this dissolve delay. - #[prost(btree_map = "uint64, uint64", tag = "8")] - pub not_dissolving_neurons_count_buckets: ::prost::alloc::collections::BTreeMap, + pub not_dissolving_neurons_count_buckets: BTreeMap, /// The number of dissolved neurons (i.e., in NeuronState::Dissolved). - #[prost(uint64, tag = "9")] pub dissolved_neurons_count: u64, /// The number of staked governance tokens in dissolved neurons /// (i.e., in NeuronState::Dissolved). - #[prost(uint64, tag = "10")] pub dissolved_neurons_e8s: u64, /// The number of neurons that are garbage collectable, i.e., that /// have a cached stake smaller than the ledger transaction fee. - #[prost(uint64, tag = "11")] pub garbage_collectable_neurons_count: u64, /// The number of neurons that have an invalid stake, i.e., that /// have a cached stake that is larger than zero but smaller than the /// minimum neuron stake defined in the nervous system parameters. - #[prost(uint64, tag = "12")] pub neurons_with_invalid_stake_count: u64, /// The total amount of governance tokens that are staked in neurons, /// measured in fractions of 10E-8 of a governance token. - #[prost(uint64, tag = "13")] pub total_staked_e8s: u64, /// TODO: rather than taking six months, it would be more interesting to take the respective SNS's eligibility boarder here. /// The number of neurons with a dissolve delay of less than six months. - #[prost(uint64, tag = "14")] pub neurons_with_less_than_6_months_dissolve_delay_count: u64, /// The number of governance tokens in neurons with a dissolve delay of /// less than six months. - #[prost(uint64, tag = "15")] pub neurons_with_less_than_6_months_dissolve_delay_e8s: u64, } /// Metadata about this SNS. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct SnsMetadata { /// The logo for the SNS project represented as a base64 encoded string. - #[prost(string, optional, tag = "1")] - pub logo: ::core::option::Option<::prost::alloc::string::String>, + pub logo: Option, /// Url to the dapp controlled by the SNS project. - #[prost(string, optional, tag = "2")] - pub url: ::core::option::Option<::prost::alloc::string::String>, + pub url: Option, /// Name of the SNS project. This may differ from the name of the associated token. - #[prost(string, optional, tag = "3")] - pub name: ::core::option::Option<::prost::alloc::string::String>, + pub name: Option, /// Description of the SNS project. - #[prost(string, optional, tag = "4")] - pub description: ::core::option::Option<::prost::alloc::string::String>, + pub description: Option, } impl serde::Serialize for Version { @@ -1931,87 +1398,48 @@ pub mod governance { /// A version of the SNS defined by the WASM hashes of its canisters. #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Eq, - std::hash::Hash, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, Eq, std::hash::Hash, Clone, PartialEq, )] pub struct Version { /// The hash of the Root canister WASM. - #[prost(bytes = "vec", tag = "1")] #[serde(with = "serde_bytes")] - pub root_wasm_hash: ::prost::alloc::vec::Vec, + pub root_wasm_hash: Vec, /// The hash of the Governance canister WASM. - #[prost(bytes = "vec", tag = "2")] #[serde(with = "serde_bytes")] - pub governance_wasm_hash: ::prost::alloc::vec::Vec, + pub governance_wasm_hash: Vec, /// The hash of the Ledger canister WASM. - #[prost(bytes = "vec", tag = "3")] #[serde(with = "serde_bytes")] - pub ledger_wasm_hash: ::prost::alloc::vec::Vec, + pub ledger_wasm_hash: Vec, /// The hash of the Swap canister WASM. - #[prost(bytes = "vec", tag = "4")] #[serde(with = "serde_bytes")] - pub swap_wasm_hash: ::prost::alloc::vec::Vec, + pub swap_wasm_hash: Vec, /// The hash of the Ledger Archive canister WASM. - #[prost(bytes = "vec", tag = "5")] #[serde(with = "serde_bytes")] - pub archive_wasm_hash: ::prost::alloc::vec::Vec, + pub archive_wasm_hash: Vec, /// The hash of the Index canister WASM. - #[prost(bytes = "vec", tag = "6")] #[serde(with = "serde_bytes")] - pub index_wasm_hash: ::prost::alloc::vec::Vec, + pub index_wasm_hash: Vec, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct Versions { - #[prost(message, repeated, tag = "1")] - pub versions: ::prost::alloc::vec::Vec, + pub versions: Vec, } /// An upgrade in progress, defined as a version target and a time at which it is considered failed. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct PendingVersion { /// Version to be upgraded to - #[prost(message, optional, tag = "1")] - pub target_version: ::core::option::Option, + pub target_version: Option, /// Seconds since UNIX epoch to mark this as a failed version if not in sync with current version - #[prost(uint64, tag = "2")] pub mark_failed_at_seconds: u64, /// Lock to avoid checking over and over again. Also, it is a counter for how many times we have attempted to check, /// allowing us to fail in case we otherwise have gotten stuck. - #[prost(uint64, tag = "3")] pub checking_upgrade_lock: u64, /// The proposal that initiated this upgrade - #[prost(uint64, optional, tag = "4")] - pub proposal_id: ::core::option::Option, + pub proposal_id: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct MaturityModulation { /// When X maturity is disbursed, the amount that goes to the destination /// account is X * (1 + y) where y = current_basis_points / 10_000. @@ -2020,52 +1448,37 @@ pub mod governance { /// /// There is a positive relationship between the price of ICP (in XDR) and /// this value. - #[prost(int32, optional, tag = "1")] - pub current_basis_points: ::core::option::Option, + pub current_basis_points: Option, /// When current_basis_points was last updated (seconds since UNIX epoch). - #[prost(uint64, optional, tag = "2")] - pub updated_at_timestamp_seconds: ::core::option::Option, + pub updated_at_timestamp_seconds: Option, } /// The sns's local cache of the upgrade steps recieved from SNS-W. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct CachedUpgradeSteps { /// The upgrade steps that have been returned from SNS-W the last time we /// called list_upgrade_steps. - #[prost(message, optional, tag = "1")] - pub upgrade_steps: ::core::option::Option, + pub upgrade_steps: Option, /// The timestamp of the request we sent to list_upgrade_steps. /// It's possible that this is greater than the response_timestamp_seconds, because /// we update it as soon as we send the request, and only update the /// response_timestamp and the upgrade_steps when we receive the response. /// The primary use of this is that we can avoid calling list_upgrade_steps /// more frequently than necessary. - #[prost(uint64, optional, tag = "2")] - pub requested_timestamp_seconds: ::core::option::Option, + pub requested_timestamp_seconds: Option, /// The timestamp of the response we received from list_upgrade_steps (stored in upgrade_steps). - #[prost(uint64, optional, tag = "3")] - pub response_timestamp_seconds: ::core::option::Option, + pub response_timestamp_seconds: Option, } #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, - strum_macros::EnumIter, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum Mode { @@ -2090,7 +1503,7 @@ pub mod governance { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "MODE_UNSPECIFIED" => Some(Self::Unspecified), "MODE_NORMAL" => Some(Self::Normal), @@ -2101,114 +1514,50 @@ pub mod governance { } } /// Request message for 'get_metadata'. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetMetadataRequest {} /// Response message for 'get_metadata'. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetMetadataResponse { - #[prost(string, optional, tag = "1")] - pub logo: ::core::option::Option<::prost::alloc::string::String>, - #[prost(string, optional, tag = "2")] - pub url: ::core::option::Option<::prost::alloc::string::String>, - #[prost(string, optional, tag = "3")] - pub name: ::core::option::Option<::prost::alloc::string::String>, - #[prost(string, optional, tag = "4")] - pub description: ::core::option::Option<::prost::alloc::string::String>, + pub logo: Option, + pub url: Option, + pub name: Option, + pub description: Option, } /// Request message for 'get_sns_initialization_parameters' -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetSnsInitializationParametersRequest {} /// Response message for 'get_sns_initialization_parameters' -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetSnsInitializationParametersResponse { - #[prost(string, tag = "1")] - pub sns_initialization_parameters: ::prost::alloc::string::String, + pub sns_initialization_parameters: String, } /// Request for the SNS's currently running version. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetRunningSnsVersionRequest {} /// Response with the SNS's currently running version and any upgrades /// that are in progress. /// GetUpgradeJournal is a superior API to this one that should -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetRunningSnsVersionResponse { /// The currently deployed version of the SNS. - #[prost(message, optional, tag = "1")] - pub deployed_version: ::core::option::Option, + pub deployed_version: Option, /// The upgrade in progress, if any. - #[prost(message, optional, tag = "2")] - pub pending_version: - ::core::option::Option, + pub pending_version: Option, } /// Nested message and enum types in `GetRunningSnsVersionResponse`. pub mod get_running_sns_version_response { /// The same as PendingVersion (stored in the governance proto). They are separated to make it easy to change one without changing the other. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct UpgradeInProgress { /// Version to be upgraded to - #[prost(message, optional, tag = "1")] - pub target_version: ::core::option::Option, + pub target_version: Option, /// Seconds since UNIX epoch to mark this as a failed version if not in sync with current version - #[prost(uint64, tag = "2")] pub mark_failed_at_seconds: u64, /// Lock to avoid checking over and over again. Also, it is a counter for how many times we have attempted to check, /// allowing us to fail in case we otherwise have gotten stuck. - #[prost(uint64, tag = "3")] pub checking_upgrade_lock: u64, /// The proposal that initiated this upgrade - #[prost(uint64, tag = "4")] pub proposal_id: u64, } } @@ -2216,174 +1565,74 @@ pub mod get_running_sns_version_response { /// Failed if it is past the time when it should have been marked as failed. /// This is useful in the case where the asynchronous process may have failed to /// complete -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct FailStuckUpgradeInProgressRequest {} /// Response to FailStuckUpgradeInProgressRequest -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct FailStuckUpgradeInProgressResponse {} /// Empty message to use in oneof fields that represent empty /// enums. #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - Copy, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, Copy, PartialEq, )] pub struct Empty {} /// An operation that modifies a neuron. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ManageNeuron { /// The modified neuron's subaccount which also serves as the neuron's ID. - #[prost(bytes = "vec", tag = "1")] #[serde(with = "serde_bytes")] - pub subaccount: ::prost::alloc::vec::Vec, - #[prost( - oneof = "manage_neuron::Command", - tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13" - )] - pub command: ::core::option::Option, + pub subaccount: Vec, + pub command: Option, } /// Nested message and enum types in `ManageNeuron`. pub mod manage_neuron { /// The operation that increases a neuron's dissolve delay. It can be /// increased up to a maximum defined in the nervous system parameters. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct IncreaseDissolveDelay { /// The additional dissolve delay that should be added to the neuron's /// current dissolve delay. - #[prost(uint32, tag = "1")] pub additional_dissolve_delay_seconds: u32, } /// The operation that starts dissolving a neuron, i.e., changes a neuron's /// state such that it is dissolving. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct StartDissolving {} /// The operation that stops dissolving a neuron, i.e., changes a neuron's /// state such that it is non-dissolving. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct StopDissolving {} /// An (idempotent) alternative to IncreaseDissolveDelay where the dissolve delay /// is passed as an absolute timestamp in seconds since the Unix epoch. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct SetDissolveTimestamp { /// The time when the neuron (newly) should become dissolved, in seconds /// since the Unix epoch. - #[prost(uint64, tag = "1")] pub dissolve_timestamp_seconds: u64, } /// Changes auto-stake maturity for this Neuron. While on, auto-stake /// maturity will cause all the maturity generated by voting rewards /// to this neuron to be automatically staked and contribute to the /// voting power of the neuron. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct ChangeAutoStakeMaturity { - #[prost(bool, tag = "1")] pub requested_setting_for_auto_stake_maturity: bool, } /// Commands that only configure a given neuron, but do not interact /// with the outside world. They all require the caller to have /// `NeuronPermissionType::ConfigureDissolveState` for the neuron. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct Configure { - #[prost(oneof = "configure::Operation", tags = "1, 2, 3, 4, 5")] - pub operation: ::core::option::Option, + pub operation: Option, } /// Nested message and enum types in `Configure`. pub mod configure { - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub enum Operation { - #[prost(message, tag = "1")] IncreaseDissolveDelay(super::IncreaseDissolveDelay), - #[prost(message, tag = "2")] StartDissolving(super::StartDissolving), - #[prost(message, tag = "3")] StopDissolving(super::StopDissolving), - #[prost(message, tag = "4")] SetDissolveTimestamp(super::SetDissolveTimestamp), - #[prost(message, tag = "5")] ChangeAutoStakeMaturity(super::ChangeAutoStakeMaturity), } } @@ -2392,36 +1641,20 @@ pub mod manage_neuron { /// Thereby, the neuron's accumulated fees are burned and (if relevant in /// the given nervous system) the token equivalent of the neuron's accumulated /// maturity are minted and also transferred to the specified account. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Disburse { /// The (optional) amount to disburse out of the neuron. If not specified the cached /// stake is used. - #[prost(message, optional, tag = "1")] - pub amount: ::core::option::Option, + pub amount: Option, /// The ledger account to which the disbursed tokens are transferred. - #[prost(message, optional, tag = "2")] - pub to_account: ::core::option::Option, + pub to_account: Option, } /// Nested message and enum types in `Disburse`. pub mod disburse { #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq, )] pub struct Amount { - #[prost(uint64, tag = "1")] pub e8s: u64, } } @@ -2434,97 +1667,51 @@ pub mod manage_neuron { /// the dissolve state. The parent neuron's fees and maturity (if applicable in the given /// nervous system) remain in the parent neuron and the child neuron's fees and maturity /// are initialized to be zero. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct Split { /// The amount of governance tokens (in measured in fractions of 10E-8 of /// a governance token) to be split to the child neuron. - #[prost(uint64, tag = "1")] pub amount_e8s: u64, /// The nonce that is used to compute the child neuron's /// subaccount which also serves as the child neuron's ID. This nonce /// is also used as the memo field in the ledger transfer that transfers /// the stake from the parent to the child neuron. - #[prost(uint64, tag = "2")] pub memo: u64, } /// The operation that merges a given percentage of a neuron's maturity (if applicable /// to the nervous system) to the neuron's stake. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct MergeMaturity { /// The percentage of maturity to merge, from 1 to 100. - #[prost(uint32, tag = "1")] pub percentage_to_merge: u32, } /// Stake the maturity of a neuron. /// The caller can choose a percentage of of the current maturity to stake. /// If 'percentage_to_stake' is not provided, all of the neuron's current /// maturity will be staked. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct StakeMaturity { /// The percentage of maturity to stake, from 1 to 100 (inclusive). - #[prost(uint32, optional, tag = "1")] - pub percentage_to_stake: ::core::option::Option, + pub percentage_to_stake: Option, } /// Disburse the maturity of a neuron to any ledger account. If an account /// is not specified, the caller's account will be used. The caller can choose /// a percentage of the current maturity to disburse to the ledger account. The /// resulting amount to disburse must be greater than or equal to the /// transaction fee. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct DisburseMaturity { /// The percentage to disburse, from 1 to 100 - #[prost(uint32, tag = "1")] pub percentage_to_disburse: u32, /// The (optional) principal to which to transfer the stake. - #[prost(message, optional, tag = "2")] - pub to_account: ::core::option::Option, + pub to_account: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct FinalizeDisburseMaturity { /// The amount to be disbursed in e8s of the governance token. - #[prost(uint64, tag = "1")] pub amount_to_be_disbursed_e8s: u64, /// The principal to which to transfer the stake (required). - #[prost(message, optional, tag = "2")] - pub to_account: ::core::option::Option, + pub to_account: Option, } /// The operation that adds a new follow relation to a neuron, specifying /// that it follows a set of followee neurons for a given proposal function. @@ -2546,85 +1733,42 @@ pub mod manage_neuron { /// then it becomes a catch-all follow rule, which will be used to vote /// automatically on proposals with actions for which no /// specific rule has been specified. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Follow { /// The function id of the proposal function defining for which proposals /// this follow relation is relevant. - #[prost(uint64, tag = "1")] pub function_id: u64, /// The list of followee neurons, specified by their neuron ID. - #[prost(message, repeated, tag = "2")] - pub followees: ::prost::alloc::vec::Vec, + pub followees: Vec, } /// The operation that registers a given vote from the neuron for a given /// proposal (a directly cast vote as opposed to a vote that is cast as /// a result of a follow relation). - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct RegisterVote { /// The ID of the proposal that the vote is cast for. - #[prost(message, optional, tag = "1")] - pub proposal: ::core::option::Option, + pub proposal: Option, /// The vote that is cast to adopt or reject the proposal. - #[prost(enumeration = "super::Vote", tag = "2")] pub vote: i32, } /// The operation that claims a new neuron (if it does not exist yet) or /// refreshes the stake of the neuron (if it already exists). - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ClaimOrRefresh { - #[prost(oneof = "claim_or_refresh::By", tags = "2, 3")] - pub by: ::core::option::Option, + pub by: Option, } /// Nested message and enum types in `ClaimOrRefresh`. pub mod claim_or_refresh { /// (see MemoAndController below) - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct MemoAndController { /// The memo(nonce) that is used to compute the neuron's subaccount /// (where the tokens were staked to). - #[prost(uint64, tag = "1")] pub memo: u64, /// The principal for which the neuron should be claimed. - #[prost(message, optional, tag = "2")] - pub controller: ::core::option::Option<::ic_base_types::PrincipalId>, + pub controller: Option<::ic_base_types::PrincipalId>, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum By { /// The memo and principal used to define the neuron to be claimed /// or refreshed. Specifically, the memo (nonce) and the given principal @@ -2633,12 +1777,10 @@ pub mod manage_neuron { /// refreshing a neuron were transferred to. /// If 'controller' is omitted, the id of the principal who calls this /// operation will be used. - #[prost(message, tag = "2")] MemoAndController(MemoAndController), /// The neuron ID of a neuron that should be refreshed. This just serves /// as an alternative way to specify a neuron to be refreshed, but cannot /// be used to claim new neurons. - #[prost(message, tag = "3")] NeuronId(super::super::Empty), } } @@ -2647,386 +1789,177 @@ pub mod manage_neuron { /// If the PrincipalId doesn't have existing permissions, a new entry will be added for it /// with the provided permissions. If a principalId already has permissions for the neuron, /// the new permissions will be added to the existing set. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct AddNeuronPermissions { /// The PrincipalId that the permissions will be granted to. - #[prost(message, optional, tag = "1")] - pub principal_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub principal_id: Option<::ic_base_types::PrincipalId>, /// The set of permissions that will be granted to the PrincipalId. - #[prost(message, optional, tag = "2")] - pub permissions_to_add: ::core::option::Option, + pub permissions_to_add: Option, } /// Remove a set of permissions from the Neuron for the given PrincipalId. If a PrincipalId has all of /// its permissions removed, it will be removed from the neuron's permissions list. This is a dangerous /// operation as its possible to remove all permissions for a neuron and no longer be able to modify /// it's state, i.e. disbursing the neuron back into the governance token. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct RemoveNeuronPermissions { /// The PrincipalId that the permissions will be revoked from. - #[prost(message, optional, tag = "1")] - pub principal_id: ::core::option::Option<::ic_base_types::PrincipalId>, + pub principal_id: Option<::ic_base_types::PrincipalId>, /// The set of permissions that will be revoked from the PrincipalId. - #[prost(message, optional, tag = "2")] - pub permissions_to_remove: ::core::option::Option, + pub permissions_to_remove: Option, } - #[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] + #[derive(candid::CandidType, candid::Deserialize, Debug)] #[allow(clippy::large_enum_variant)] - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq)] pub enum Command { - #[prost(message, tag = "2")] Configure(Configure), - #[prost(message, tag = "3")] Disburse(Disburse), - #[prost(message, tag = "4")] Follow(Follow), /// Making a proposal is defined by a proposal, which contains the proposer neuron. /// Making a proposal will implicitly cast a yes vote for the proposing neuron. - #[prost(message, tag = "5")] MakeProposal(super::Proposal), - #[prost(message, tag = "6")] RegisterVote(RegisterVote), - #[prost(message, tag = "7")] Split(Split), - #[prost(message, tag = "8")] ClaimOrRefresh(ClaimOrRefresh), - #[prost(message, tag = "9")] MergeMaturity(MergeMaturity), - #[prost(message, tag = "10")] DisburseMaturity(DisburseMaturity), - #[prost(message, tag = "11")] AddNeuronPermissions(AddNeuronPermissions), - #[prost(message, tag = "12")] RemoveNeuronPermissions(RemoveNeuronPermissions), - #[prost(message, tag = "13")] StakeMaturity(StakeMaturity), } } /// The response of a ManageNeuron command. /// There is a dedicated response type for each `ManageNeuron.command` field. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ManageNeuronResponse { - #[prost( - oneof = "manage_neuron_response::Command", - tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13" - )] - pub command: ::core::option::Option, + pub command: Option, } /// Nested message and enum types in `ManageNeuronResponse`. pub mod manage_neuron_response { /// The response to the ManageNeuron command 'configure'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct ConfigureResponse {} /// The response to the ManageNeuron command 'disburse'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct DisburseResponse { /// The block height of the ledger where the tokens were disbursed to the /// given account. - #[prost(uint64, tag = "1")] pub transfer_block_height: u64, } /// The response to the ManageNeuron command 'merge_maturity'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct MergeMaturityResponse { /// The maturity that was merged in fractions of /// 10E-8 of a governance token. - #[prost(uint64, tag = "1")] pub merged_maturity_e8s: u64, /// The resulting cached stake of the modified neuron /// in fractions of 10E-8 of a governance token. - #[prost(uint64, tag = "2")] pub new_stake_e8s: u64, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct DisburseMaturityResponse { /// This field is deprecated and is populated with the same value as `amount_deducted_e8s`. - #[prost(uint64, tag = "2")] pub amount_disbursed_e8s: u64, /// The amount of maturity in e8s of the governance token deducted from the Neuron. /// This amount will undergo maturity modulation if enabled, and may be increased or /// decreased at the time of disbursement. - #[prost(uint64, optional, tag = "3")] - pub amount_deducted_e8s: ::core::option::Option, + pub amount_deducted_e8s: Option, } - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct StakeMaturityResponse { - #[prost(uint64, tag = "1")] pub maturity_e8s: u64, - #[prost(uint64, tag = "2")] pub staked_maturity_e8s: u64, } /// The response to the ManageNeuron command 'follow'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct FollowResponse {} /// The response to the ManageNeuron command 'make_proposal'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct MakeProposalResponse { /// The ID of the created proposal. - #[prost(message, optional, tag = "1")] - pub proposal_id: ::core::option::Option, + pub proposal_id: Option, } /// The response to the ManageNeuron command 'register_vote'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct RegisterVoteResponse {} /// The response to the ManageNeuron command 'split'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct SplitResponse { /// The ID of the 'child neuron' that was newly created. - #[prost(message, optional, tag = "1")] - pub created_neuron_id: ::core::option::Option, + pub created_neuron_id: Option, } /// The response to the ManageNeuron command 'claim_or_refresh'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ClaimOrRefreshResponse { /// The neuron ID of the neuron that was newly claimed or /// refreshed. - #[prost(message, optional, tag = "1")] - pub refreshed_neuron_id: ::core::option::Option, + pub refreshed_neuron_id: Option, } /// The response to the ManageNeuron command 'add_neuron_permissions'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct AddNeuronPermissionsResponse {} /// The response to the ManageNeuron command 'remove_neuron_permissions'. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct RemoveNeuronPermissionsResponse {} - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum Command { - #[prost(message, tag = "1")] Error(super::GovernanceError), - #[prost(message, tag = "2")] Configure(ConfigureResponse), - #[prost(message, tag = "3")] Disburse(DisburseResponse), - #[prost(message, tag = "4")] Follow(FollowResponse), - #[prost(message, tag = "5")] MakeProposal(MakeProposalResponse), - #[prost(message, tag = "6")] RegisterVote(RegisterVoteResponse), - #[prost(message, tag = "7")] Split(SplitResponse), - #[prost(message, tag = "8")] ClaimOrRefresh(ClaimOrRefreshResponse), - #[prost(message, tag = "9")] MergeMaturity(MergeMaturityResponse), - #[prost(message, tag = "10")] DisburseMaturity(DisburseMaturityResponse), - #[prost(message, tag = "11")] AddNeuronPermission(AddNeuronPermissionsResponse), - #[prost(message, tag = "12")] RemoveNeuronPermission(RemoveNeuronPermissionsResponse), - #[prost(message, tag = "13")] StakeMaturity(StakeMaturityResponse), } } /// An operation that attempts to get a neuron by a given neuron ID. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetNeuron { - #[prost(message, optional, tag = "1")] - pub neuron_id: ::core::option::Option, + pub neuron_id: Option, } /// A response to the GetNeuron command. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetNeuronResponse { /// The response to a GetNeuron command is either an error or /// the requested neuron. - #[prost(oneof = "get_neuron_response::Result", tags = "1, 2")] - pub result: ::core::option::Option, + pub result: Option, } /// Nested message and enum types in `GetNeuronResponse`. pub mod get_neuron_response { /// The response to a GetNeuron command is either an error or /// the requested neuron. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum Result { - #[prost(message, tag = "1")] Error(super::GovernanceError), - #[prost(message, tag = "2")] Neuron(super::Neuron), } } -/// An operation that attempts to get a proposal by a given proposal ID. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +/// An operation that attempts to get a proposal by a given proposal ID. +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetProposal { - #[prost(message, optional, tag = "1")] - pub proposal_id: ::core::option::Option, + pub proposal_id: Option, } /// A response to the GetProposal command. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetProposalResponse { /// The response to a GetProposal command is either an error or /// the proposal data corresponding to the requested proposal. - #[prost(oneof = "get_proposal_response::Result", tags = "1, 2")] - pub result: ::core::option::Option, + pub result: Option, } /// Nested message and enum types in `GetProposalResponse`. pub mod get_proposal_response { /// The response to a GetProposal command is either an error or /// the proposal data corresponding to the requested proposal. - #[derive(candid::CandidType, candid::Deserialize, comparable::Comparable)] + #[derive(candid::CandidType, candid::Deserialize, Debug)] #[allow(clippy::large_enum_variant)] - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq)] pub enum Result { - #[prost(message, tag = "1")] Error(super::GovernanceError), - #[prost(message, tag = "2")] Proposal(super::ProposalData), } } @@ -3037,18 +1970,10 @@ pub mod get_proposal_response { /// Proposals are stored using an increasing id where the most recent proposals /// have the highest ids. ListProposals reverses the list and paginates backwards /// using `before_proposal`, so the first element returned is the latest proposal. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ListProposals { /// Limit the number of Proposals returned in each page, from 1 to 100. /// If a value outside of this range is provided, 100 will be used. - #[prost(uint32, tag = "1")] pub limit: u32, /// The proposal ID specifying which proposals to return. /// This should be set to the last proposal of the previously returned page and @@ -3056,12 +1981,10 @@ pub struct ListProposals { /// If this is specified, then only the proposals that have a proposal ID strictly /// lower than the specified one are returned. If this is not specified /// then the list of proposals starts with the most recent proposal's ID. - #[prost(message, optional, tag = "2")] - pub before_proposal: ::core::option::Option, + pub before_proposal: Option, /// A list of proposal types, specifying that proposals of the given /// types should be excluded in this list. - #[prost(uint64, repeated, tag = "3")] - pub exclude_type: ::prost::alloc::vec::Vec, + pub exclude_type: Vec, /// A list of proposal reward statuses, specifying that only proposals that /// that have one of the define reward statuses should be included /// in the list. @@ -3070,48 +1993,29 @@ pub struct ListProposals { /// Example: If users are only interested in proposals for which they can /// receive voting rewards they can use this to filter for proposals /// with reward status PROPOSAL_REWARD_STATUS_ACCEPT_VOTES. - #[prost(enumeration = "ProposalRewardStatus", repeated, tag = "4")] - pub include_reward_status: ::prost::alloc::vec::Vec, + pub include_reward_status: Vec, /// A list of proposal decision statuses, specifying that only proposals that /// that have one of the define decision statuses should be included /// in the list. /// If this list is empty, no restriction is applied. - #[prost(enumeration = "ProposalDecisionStatus", repeated, tag = "5")] - pub include_status: ::prost::alloc::vec::Vec, + pub include_status: Vec, } /// A response to the ListProposals command. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ListProposalsResponse { /// The returned list of proposals' ProposalData. - #[prost(message, repeated, tag = "1")] - pub proposals: ::prost::alloc::vec::Vec, + pub proposals: Vec, /// Whether ballots cast by the caller are included in the returned proposals. - #[prost(bool, optional, tag = "2")] - pub include_ballots_by_caller: ::core::option::Option, + pub include_ballots_by_caller: Option, } /// An operation that lists all neurons tracked in the Governance state in a /// paginated fashion. /// Listing of all neurons can be accomplished using `limit` and `start_page_at`. /// To only list neurons associated with a given principal, use `of_principal`. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ListNeurons { /// Limit the number of Neurons returned in each page, from 1 to 100. /// If a value outside of this range is provided, 100 will be used. - #[prost(uint32, tag = "1")] pub limit: u32, /// Used to indicate where the next page of Neurons should start. Should be /// set to the last neuron of the previously returned page and will not be @@ -3119,708 +2023,333 @@ pub struct ListNeurons { /// size limit starting at the "0th" Neuron. Neurons are not kept in any specific /// order, but their ordering is deterministic, so this can be used to return all /// the neurons one page at a time. - #[prost(message, optional, tag = "2")] - pub start_page_at: ::core::option::Option, + pub start_page_at: Option, /// A principal ID, specifying that only neurons for which this principal has /// any permissions should be included in the list. /// If this is not specified, no restriction is applied. - #[prost(message, optional, tag = "3")] - pub of_principal: ::core::option::Option<::ic_base_types::PrincipalId>, + pub of_principal: Option<::ic_base_types::PrincipalId>, } /// A response to the ListNeurons command. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ListNeuronsResponse { /// The returned list of neurons. - #[prost(message, repeated, tag = "1")] - pub neurons: ::prost::alloc::vec::Vec, + pub neurons: Vec, } /// The response to the list_nervous_system_functions query. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ListNervousSystemFunctionsResponse { /// Current set of nervous system function, both native and user-defined, /// that can be executed by proposal. - #[prost(message, repeated, tag = "1")] - pub functions: ::prost::alloc::vec::Vec, + pub functions: Vec, /// Set of nervous system function ids that are reserved and cannot be /// used to add new NervousSystemFunctions. - #[prost(uint64, repeated, tag = "2")] - pub reserved_ids: ::prost::alloc::vec::Vec, + pub reserved_ids: Vec, } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct SetMode { - #[prost(enumeration = "governance::Mode", tag = "1")] pub mode: i32, } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct SetModeResponse {} -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetMode {} -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetModeResponse { - #[prost(enumeration = "governance::Mode", optional, tag = "1")] - pub mode: ::core::option::Option, + pub mode: Option, } /// The request for the `claim_swap_neurons` method. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ClaimSwapNeuronsRequest { /// The set of parameters that define the neurons created in `claim_swap_neurons`. For /// each NeuronRecipe, one neuron will be created. - #[prost(message, optional, tag = "2")] - pub neuron_recipes: ::core::option::Option, + pub neuron_recipes: Option, } /// Nested message and enum types in `ClaimSwapNeuronsRequest`. pub mod claim_swap_neurons_request { /// Replacement for NeuronParameters. Contains the information needed to set up /// a neuron for a swap participant. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronRecipe { /// The principal that should be the controller of the SNS neuron - #[prost(message, optional, tag = "1")] - pub controller: ::core::option::Option<::ic_base_types::PrincipalId>, + pub controller: Option<::ic_base_types::PrincipalId>, /// The ID of the SNS neuron - #[prost(message, optional, tag = "2")] - pub neuron_id: ::core::option::Option, + pub neuron_id: Option, /// The SNS neuron's stake in e8s (10E-8 of a token) - #[prost(uint64, optional, tag = "3")] - pub stake_e8s: ::core::option::Option, + pub stake_e8s: Option, /// The duration in seconds that the neuron's dissolve delay will be set to. - #[prost(uint64, optional, tag = "4")] - pub dissolve_delay_seconds: ::core::option::Option, + pub dissolve_delay_seconds: Option, /// The neurons this neuron should follow - #[prost(message, optional, tag = "5")] - pub followees: ::core::option::Option, - #[prost(oneof = "neuron_recipe::Participant", tags = "6, 7")] - pub participant: ::core::option::Option, + pub followees: Option, + pub participant: Option, } /// Nested message and enum types in `NeuronRecipe`. pub mod neuron_recipe { /// The info that for a participant in the Neurons' Fund - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronsFund { /// The neuron ID of the NNS neuron that participated in the Neurons' Fund. - #[prost(uint64, optional, tag = "1")] - pub nns_neuron_id: ::core::option::Option, + pub nns_neuron_id: Option, /// The controller of the NNS neuron that participated in the Neurons' Fund. - #[prost(message, optional, tag = "2")] - pub nns_neuron_controller: ::core::option::Option<::ic_base_types::PrincipalId>, + pub nns_neuron_controller: Option<::ic_base_types::PrincipalId>, /// The hotkeys of the NNS neuron that participated in the Neurons' Fund. - #[prost(message, optional, tag = "3")] - pub nns_neuron_hotkeys: - ::core::option::Option<::ic_nervous_system_proto::pb::v1::Principals>, + pub nns_neuron_hotkeys: Option<::ic_nervous_system_proto::pb::v1::Principals>, } /// The info that for a direct participant #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq, )] pub struct Direct {} - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum Participant { - #[prost(message, tag = "6")] Direct(Direct), - #[prost(message, tag = "7")] NeuronsFund(NeuronsFund), } } /// Needed to cause prost to generate a type isomorphic to /// Optional>. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct NeuronRecipes { - #[prost(message, repeated, tag = "1")] - pub neuron_recipes: ::prost::alloc::vec::Vec, + pub neuron_recipes: Vec, } } /// The response for the `claim_swap_neurons` method. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ClaimSwapNeuronsResponse { /// ClaimSwapNeurons will either return an error, in which /// no requested neurons were claimed, or a vector with /// various neuron statuses for the requested neuron ids. - #[prost( - oneof = "claim_swap_neurons_response::ClaimSwapNeuronsResult", - tags = "4, 5" - )] - pub claim_swap_neurons_result: - ::core::option::Option, + pub claim_swap_neurons_result: Option, } /// Nested message and enum types in `ClaimSwapNeuronsResponse`. pub mod claim_swap_neurons_response { /// The ok result from `claim_swap_neurons. For every requested neuron, /// a SwapNeuron message is returned, and should equal the count of /// `ClaimSwapNeuronsRequest.neuron_recipes`. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct ClaimedSwapNeurons { - #[prost(message, repeated, tag = "1")] - pub swap_neurons: ::prost::alloc::vec::Vec, + pub swap_neurons: Vec, } /// SwapNeuron associates the status of a neuron attempting to be /// claimed with a NeuronId. The `id` field will correspond with a /// `ClaimSwapNeuronsRequest.neuron_recipes.neuron_id` field in /// the request object used in `claim_swap_neurons`. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, - )] + #[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct SwapNeuron { - #[prost(message, optional, tag = "1")] - pub id: ::core::option::Option, + pub id: Option, /// The status of claiming of a requested Sale neuron. - #[prost(enumeration = "super::ClaimedSwapNeuronStatus", tag = "2")] pub status: i32, } /// ClaimSwapNeurons will either return an error, in which /// no requested neurons were claimed, or a vector with /// various neuron statuses for the requested neuron ids. - #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Oneof, - )] + #[derive(candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub enum ClaimSwapNeuronsResult { - #[prost(message, tag = "4")] Ok(ClaimedSwapNeurons), - #[prost(enumeration = "super::ClaimSwapNeuronsError", tag = "5")] Err(i32), } } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetMaturityModulationRequest {} -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetMaturityModulationResponse { - #[prost(message, optional, tag = "1")] - pub maturity_modulation: ::core::option::Option, + pub maturity_modulation: Option, } /// A request to add maturity to a neuron. The associated endpoint is only /// available when governance is compiled with the `test` feature enabled. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct AddMaturityRequest { - #[prost(message, optional, tag = "1")] - pub id: ::core::option::Option, - #[prost(uint64, optional, tag = "2")] - pub amount_e8s: ::core::option::Option, + pub id: Option, + pub amount_e8s: Option, } /// The response to a request to add maturity to a neuron. The associated endpoint is only /// available when governance is compiled with the `test` feature enabled. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct AddMaturityResponse { - #[prost(uint64, optional, tag = "1")] - pub new_maturity_e8s: ::core::option::Option, + pub new_maturity_e8s: Option, } /// A test-only API that advances the target version of the SNS. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct AdvanceTargetVersionRequest { - #[prost(message, optional, tag = "1")] - pub target_version: ::core::option::Option, + pub target_version: Option, } /// The response to a request to advance the target version of the SNS. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct AdvanceTargetVersionResponse {} /// A test-only API that refreshes the cached upgrade steps. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct RefreshCachedUpgradeStepsRequest {} /// The response to a request to refresh the cached upgrade steps. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct RefreshCachedUpgradeStepsResponse {} /// Represents a single entry in the upgrade journal. #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeJournalEntry { - #[prost(uint64, optional, tag = "6")] - pub timestamp_seconds: ::core::option::Option, - #[prost(oneof = "upgrade_journal_entry::Event", tags = "1, 7, 2, 3, 4, 5")] - pub event: ::core::option::Option, + pub timestamp_seconds: Option, + pub event: Option, } /// Nested message and enum types in `UpgradeJournalEntry`. pub mod upgrade_journal_entry { #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeStepsRefreshed { - #[prost(message, optional, tag = "2")] - pub upgrade_steps: ::core::option::Option, + pub upgrade_steps: Option, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeStepsReset { - #[prost(string, optional, tag = "1")] - pub human_readable: ::core::option::Option<::prost::alloc::string::String>, - #[prost(message, optional, tag = "2")] - pub upgrade_steps: ::core::option::Option, + pub human_readable: Option, + pub upgrade_steps: Option, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct TargetVersionSet { - #[prost(message, optional, tag = "1")] - pub old_target_version: ::core::option::Option, - #[prost(message, optional, tag = "2")] - pub new_target_version: ::core::option::Option, + pub old_target_version: Option, + pub new_target_version: Option, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct TargetVersionReset { - #[prost(message, optional, tag = "1")] - pub old_target_version: ::core::option::Option, - #[prost(message, optional, tag = "2")] - pub new_target_version: ::core::option::Option, - #[prost(string, optional, tag = "3")] - pub human_readable: ::core::option::Option<::prost::alloc::string::String>, + pub old_target_version: Option, + pub new_target_version: Option, + pub human_readable: Option, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeStarted { - #[prost(message, optional, tag = "1")] - pub current_version: ::core::option::Option, - #[prost(message, optional, tag = "2")] - pub expected_version: ::core::option::Option, - #[prost(oneof = "upgrade_started::Reason", tags = "3, 4")] - pub reason: ::core::option::Option, + pub current_version: Option, + pub expected_version: Option, + pub reason: Option, } /// Nested message and enum types in `UpgradeStarted`. pub mod upgrade_started { #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - Copy, - PartialEq, - ::prost::Oneof, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, Copy, PartialEq, )] pub enum Reason { - #[prost(message, tag = "3")] UpgradeSnsToNextVersionProposal(super::super::ProposalId), - #[prost(message, tag = "4")] BehindTargetVersion(super::super::Empty), } } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeOutcome { - #[prost(string, optional, tag = "1")] - pub human_readable: ::core::option::Option<::prost::alloc::string::String>, - #[prost(oneof = "upgrade_outcome::Status", tags = "2, 3, 4, 5")] - pub status: ::core::option::Option, + pub human_readable: Option, + pub status: Option, } /// Nested message and enum types in `UpgradeOutcome`. pub mod upgrade_outcome { #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct InvalidState { - #[prost(message, optional, tag = "1")] - pub version: ::core::option::Option, + pub version: Option, } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Oneof, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub enum Status { - #[prost(message, tag = "2")] Success(super::super::Empty), - #[prost(message, tag = "3")] Timeout(super::super::Empty), /// The SNS ended up being upgraded to a version that was not the expected one. - #[prost(message, tag = "4")] InvalidState(InvalidState), - #[prost(message, tag = "5")] ExternalFailure(super::super::Empty), } } #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Oneof, + candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub enum Event { - #[prost(message, tag = "1")] UpgradeStepsRefreshed(UpgradeStepsRefreshed), - #[prost(message, tag = "7")] UpgradeStepsReset(UpgradeStepsReset), - #[prost(message, tag = "2")] TargetVersionSet(TargetVersionSet), - #[prost(message, tag = "3")] TargetVersionReset(TargetVersionReset), - #[prost(message, tag = "4")] UpgradeStarted(UpgradeStarted), - #[prost(message, tag = "5")] UpgradeOutcome(UpgradeOutcome), } } /// Needed to cause prost to generate a type isomorphic to Option>. #[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - serde::Serialize, - Clone, - PartialEq, - ::prost::Message, + Default, candid::CandidType, candid::Deserialize, Debug, serde::Serialize, Clone, PartialEq, )] pub struct UpgradeJournal { /// The entries in the upgrade journal. - #[prost(message, repeated, tag = "1")] - pub entries: ::prost::alloc::vec::Vec, + pub entries: Vec, } /// The upgrade journal contains all the information neede to audit previous SNS upgrades and understand its current state. /// It is being implemented as part of the "effortless SNS upgrade" feature. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct GetUpgradeJournalRequest { /// Maximum number of journal entries to return. /// If not specified, defaults to 100. Values larger than 100 will be capped at 100. - #[prost(uint64, optional, tag = "1")] - pub limit: ::core::option::Option, + pub limit: Option, /// The starting index from which to return entries, counting from the oldest entry (0). /// If not specified, return the most recent entries. - #[prost(uint64, optional, tag = "2")] - pub offset: ::core::option::Option, + pub offset: Option, } -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct GetUpgradeJournalResponse { - #[prost(message, optional, tag = "1")] - pub upgrade_steps: ::core::option::Option, - #[prost(uint64, optional, tag = "2")] - pub response_timestamp_seconds: ::core::option::Option, + pub upgrade_steps: Option, + pub response_timestamp_seconds: Option, /// The target version that the SNS will be upgraded to. /// Currently, this field is always None, but in the "effortless SNS upgrade" /// feature, it reflect the version of the SNS that the community has decided to upgrade to. - #[prost(message, optional, tag = "3")] - pub target_version: ::core::option::Option, - #[prost(message, optional, tag = "5")] - pub deployed_version: ::core::option::Option, - #[prost(message, optional, tag = "4")] - pub upgrade_journal: ::core::option::Option, - #[prost(uint64, optional, tag = "6")] - pub upgrade_journal_entry_count: ::core::option::Option, + pub target_version: Option, + pub deployed_version: Option, + pub upgrade_journal: Option, + pub upgrade_journal_entry_count: Option, } /// A request to mint tokens for a particular principal. The associated endpoint /// is only available on SNS governance, and only then when SNS governance is /// compiled with the `test` feature enabled. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct MintTokensRequest { - #[prost(message, optional, tag = "1")] - pub recipient: ::core::option::Option, - #[prost(uint64, optional, tag = "2")] - pub amount_e8s: ::core::option::Option, + pub recipient: Option, + pub amount_e8s: Option, } /// The response to a request to mint tokens for a particular principal. The /// associated endpoint is only available on SNS governance, and only then when /// SNS governance is compiled with the `test` feature enabled. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - Copy, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, Copy, PartialEq)] pub struct MintTokensResponse {} /// A Ledger subaccount. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Subaccount { - #[prost(bytes = "vec", tag = "1")] #[serde(with = "serde_bytes")] - pub subaccount: ::prost::alloc::vec::Vec, + pub subaccount: Vec, } /// A Ledger account identified by the owner of the account `of` and /// the `subaccount`. If the `subaccount` is not specified then the default /// one is used. -#[derive( - candid::CandidType, - candid::Deserialize, - comparable::Comparable, - Clone, - PartialEq, - ::prost::Message, -)] +#[derive(Default, candid::CandidType, candid::Deserialize, Debug, Clone, PartialEq)] pub struct Account { /// The owner of the account. - #[prost(message, optional, tag = "1")] - pub owner: ::core::option::Option<::ic_base_types::PrincipalId>, + pub owner: Option<::ic_base_types::PrincipalId>, /// The subaccount of the account. If not set then the default /// subaccount (all bytes set to 0) is used. - #[prost(message, optional, tag = "2")] - pub subaccount: ::core::option::Option, + pub subaccount: Option, } /// The different types of neuron permissions, i.e., privileges to modify a neuron, /// that principals can have. #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, clap::ValueEnum, - strum_macros::EnumIter, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum NeuronPermissionType { @@ -3877,7 +2406,7 @@ impl NeuronPermissionType { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "NEURON_PERMISSION_TYPE_UNSPECIFIED" => Some(Self::Unspecified), "NEURON_PERMISSION_TYPE_CONFIGURE_DISSOLVE_STATE" => Some(Self::ConfigureDissolveState), @@ -3898,16 +2427,14 @@ impl NeuronPermissionType { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum Vote { @@ -3933,7 +2460,7 @@ impl Vote { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "VOTE_UNSPECIFIED" => Some(Self::Unspecified), "VOTE_YES" => Some(Self::Yes), @@ -3945,16 +2472,14 @@ impl Vote { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum LogVisibility { @@ -3977,7 +2502,7 @@ impl LogVisibility { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "LOG_VISIBILITY_UNSPECIFIED" => Some(Self::Unspecified), "LOG_VISIBILITY_CONTROLLERS" => Some(Self::Controllers), @@ -3989,16 +2514,14 @@ impl LogVisibility { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum ProposalDecisionStatus { @@ -4031,7 +2554,7 @@ impl ProposalDecisionStatus { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "PROPOSAL_DECISION_STATUS_UNSPECIFIED" => Some(Self::Unspecified), "PROPOSAL_DECISION_STATUS_OPEN" => Some(Self::Open), @@ -4047,16 +2570,14 @@ impl ProposalDecisionStatus { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum ProposalRewardStatus { @@ -4088,7 +2609,7 @@ impl ProposalRewardStatus { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "PROPOSAL_REWARD_STATUS_UNSPECIFIED" => Some(Self::Unspecified), "PROPOSAL_REWARD_STATUS_ACCEPT_VOTES" => Some(Self::AcceptVotes), @@ -4105,16 +2626,14 @@ impl ProposalRewardStatus { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum ClaimedSwapNeuronStatus { @@ -4154,7 +2673,7 @@ impl ClaimedSwapNeuronStatus { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "CLAIMED_SWAP_NEURON_STATUS_UNSPECIFIED" => Some(Self::Unspecified), "CLAIMED_SWAP_NEURON_STATUS_SUCCESS" => Some(Self::Success), @@ -4170,16 +2689,14 @@ impl ClaimedSwapNeuronStatus { #[derive( candid::CandidType, candid::Deserialize, - comparable::Comparable, + Debug, Clone, Copy, - Debug, PartialEq, Eq, Hash, PartialOrd, Ord, - ::prost::Enumeration, )] #[repr(i32)] pub enum ClaimSwapNeuronsError { @@ -4206,7 +2723,7 @@ impl ClaimSwapNeuronsError { } } /// Creates an enum from field names used in the ProtoBuf definition. - pub fn from_str_name(value: &str) -> ::core::option::Option { + pub fn from_str_name(value: &str) -> Option { match value { "CLAIM_SWAP_NEURONS_ERROR_UNSPECIFIED" => Some(Self::Unspecified), "CLAIM_SWAP_NEURONS_ERROR_UNAUTHORIZED" => Some(Self::Unauthorized), From cf53688f96ac8d79c4a81dc8260c066d08d78017 Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" <189003650+pr-automation-bot-public[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:54:40 -0800 Subject: [PATCH 72/98] chore: Update Mainnet IC revisions canisters file (#3423) Update mainnet system canisters revisions file to include the latest WASM version released on the mainnet. This PR is created automatically using [`mainnet_revisions.py`](https://github.com/dfinity/ic/blob/master/ci/src/mainnet_revisions/mainnet_revisions.py) Co-authored-by: CI Automation --- mainnet-canister-revisions.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mainnet-canister-revisions.json b/mainnet-canister-revisions.json index f940ecf64b1..f9d79c4935f 100644 --- a/mainnet-canister-revisions.json +++ b/mainnet-canister-revisions.json @@ -44,16 +44,16 @@ "sha256": "98a7b7391608dc4a554d6964bad24157b6aaf890a05bbaad3fcc92033d9c7b02" }, "cycles-minting": { - "rev": "ee52ab3056cf5f39b09b08de70bdd20485c8b2dc", - "sha256": "bbb8995cb749ba9e2c721ff507f5e5313f32e69b1adf3df20e3901ed56a70b42" + "rev": "b5192581ccd35b67fe5a1f795ead9cbcd25956d6", + "sha256": "11c8dedd11741f05990498c90f925e9e37ad60647a65ef47caa59cdba234be6f" }, "genesis-token": { "rev": "4bed17bfc82cddc5691743db6228992cdc2740f4", "sha256": "fd25a4e2e283b498c3be1aaf63cc9b2726264d78a12b12f43ad453ceeb575e7c" }, "governance": { - "rev": "ee52ab3056cf5f39b09b08de70bdd20485c8b2dc", - "sha256": "a23918c2c5d1302e5d1149f557b0fb913ab65931c1bce3ffc94a48e3d14ecbac" + "rev": "b5192581ccd35b67fe5a1f795ead9cbcd25956d6", + "sha256": "5b67e1d273afb691a74ff29e0a495fb2ce7ee31196af58d801a8ce86a7dc4320" }, "index": { "rev": "7c6309cb5bec7ab28ed657ac7672af08a59fc1ba", @@ -64,16 +64,16 @@ "sha256": "a9ed1cb9dda555e0fc1038825eb7b3a6b366f17aa4b88575184c7537e864e551" }, "lifeline": { - "rev": "a0207146be211cdff83321c99e9e70baa62733c7", - "sha256": "76978515223287ece643bc7ca087eb310412b737e2382a73b8ae55fcb458da5b" + "rev": "b5192581ccd35b67fe5a1f795ead9cbcd25956d6", + "sha256": "8c8eb285de53ca5609abd7dc41ba3ec8eeb67708b81469311fd670e6738d7d0a" }, "registry": { - "rev": "86229594d61b433c39fc5331ab818ccb6c6aa6a7", - "sha256": "b0b2a7f37e76fcbab20a861fdf65c34d7ac2ca84a5190d204dfe5e1c50fb383e" + "rev": "b5192581ccd35b67fe5a1f795ead9cbcd25956d6", + "sha256": "771041412d2af4eb681262ca525bce1a87c199b631e17b55e1d7f9abb2cde3e6" }, "root": { - "rev": "c494c2af8bfc70a6501448dc73bf806477388738", - "sha256": "657010591182ce758c86f020d1eade5f7a188072cf0de9c41e2f9d577849c964" + "rev": "b5192581ccd35b67fe5a1f795ead9cbcd25956d6", + "sha256": "d3c702648ca4fb232f349bad7533c400c474a528abf62c05d4b100b4cdb91ce2" }, "sns-wasm": { "rev": "25c1bb0227d9970f5673b908817d7c4962b29911", @@ -84,8 +84,8 @@ "sha256": "f94cf1db965b7042197e5894fef54f5f413bb2ebc607ff0fb59c9d4dfd3babea" }, "sns_governance": { - "rev": "25c1bb0227d9970f5673b908817d7c4962b29911", - "sha256": "51fd3d1a529f3f7bad808b19074e761ce3538282ac8189bd7067b4156360c279" + "rev": "df7d443e6219c462b305152b63ca265171feb6ee", + "sha256": "bd936ef6bb878df87856a0b0c46034a242a88b7f1eeff5439daf6278febca6b7" }, "sns_index": { "rev": "2190613d3b5bcd9b74c382b22d151580b8ac271a", From 66ff2341e84649a79c5276521908fe1ccdccfb4e Mon Sep 17 00:00:00 2001 From: max-dfinity <100170574+max-dfinity@users.noreply.github.com> Date: Mon, 13 Jan 2025 15:18:29 -0800 Subject: [PATCH 73/98] feat(nns-tools): nns_claim_or_refresh helper (#3424) Add a simple way to claim or refresh a neuron (for reference) --- testnet/tools/nns-tools/lib/include.sh | 1 + testnet/tools/nns-tools/lib/nns_neurons.sh | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 testnet/tools/nns-tools/lib/nns_neurons.sh diff --git a/testnet/tools/nns-tools/lib/include.sh b/testnet/tools/nns-tools/lib/include.sh index 3ecb2f7aecc..242fdff03c4 100644 --- a/testnet/tools/nns-tools/lib/include.sh +++ b/testnet/tools/nns-tools/lib/include.sh @@ -24,6 +24,7 @@ source "$LIB_DIR/canisters.sh" source "$LIB_DIR/constants.sh" source "$LIB_DIR/functions.sh" source "$LIB_DIR/installers.sh" +source "$LIB_DIR/nns_neurons.sh" source "$LIB_DIR/proposals.sh" source "$LIB_DIR/sns_upgrades.sh" source "$LIB_DIR/topology.sh" diff --git a/testnet/tools/nns-tools/lib/nns_neurons.sh b/testnet/tools/nns-tools/lib/nns_neurons.sh new file mode 100644 index 00000000000..f73edf268cb --- /dev/null +++ b/testnet/tools/nns-tools/lib/nns_neurons.sh @@ -0,0 +1,32 @@ +##: claim_or_refresh +## Usage: $1 +## Claim or refresh an NNS neuron with a particular ID +## NETWORK: The network to use. +## NEURON_ID: The neuron id to claim or refresh. +## Example: claim_or_refresh ic 1234567890 +nns_claim_or_refresh() { + local network=$1 + local neuron_id=$2 + + local IC=$(repo_root) + local GOV_DID="$IC/rs/nns/governance/canister/governance.did" + + dfx canister \ + --network ic \ + call \ + --candid "$GOV_DID" \ + rrkah-fqaaa-aaaaa-aaaaq-cai \ + manage_neuron "( + record { + id = opt record { id = ${neuron_id}: nat64 }; + command = opt variant { + ClaimOrRefresh = record { + controller = null; + by = opt variant { + NeuronIdOrSubaccount = record { } + } + } + } + } + )" +} From 16ee8b23a6af62a6ccbe9fbb37dfb8a0743be8bf Mon Sep 17 00:00:00 2001 From: jasonz-dfinity <133917836+jasonz-dfinity@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:06:41 -0800 Subject: [PATCH 74/98] chore(nns): Add a comment on MAX_NEURONS_FUND_PARTICIPANTS about its effect on instructions (#3426) In the analysis of the safety of migrating neurons from heap to stable memory, one risk is that the `draw_maturity_from_neurons_fund`/`refund_maturity_to_neurons_fund` can take more instructions since reading from stable structures is more expensive. Therefore, the safety of such operations start to depend on how many neurons are involved in those operations. Adding a comment should help preventing any increase of this constant without considering its implications on the instructions cost. --- rs/nns/governance/src/governance.rs | 12 ++++++++---- rs/nns/governance/src/neuron_store/benches.rs | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index c05c981f953..48a951b8349 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -251,10 +251,14 @@ const NODE_PROVIDER_REWARD_PERIOD_SECONDS: u64 = 2629800; const VALID_MATURITY_MODULATION_BASIS_POINTS_RANGE: RangeInclusive = -500..=500; -/// Maximum allowed number of Neurons' Fund participants that may participate in an SNS swap. -/// Given the maximum number of SNS neurons per swap participant (a.k.a. neuron basket count), -/// this constant can be used to obtain an upper bound for the number of SNS neurons created -/// for the Neurons' Fund participants. See also `MAX_SNS_NEURONS_PER_BASKET`. +/// Maximum allowed number of Neurons' Fund participants that may participate in an SNS swap. Given +/// the maximum number of SNS neurons per swap participant (a.k.a. neuron basket count), this +/// constant can be used to obtain an upper bound for the number of SNS neurons created for the +/// Neurons' Fund participants. See also `MAX_SNS_NEURONS_PER_BASKET`. In addition, this constant +/// also affects the upperbound of instructions needed to draw/refund maturity from/to the Neurons' +/// Fund, so before increasing this constant, the impact on the instructions used by +/// `CreateServiceNervousSystem` proposal execution also needs to be evaluated (currently, each +/// neuron takes ~120K instructions to draw/refund maturity, so the total is ~600M). pub const MAX_NEURONS_FUND_PARTICIPANTS: u64 = 5_000; impl NetworkEconomics { diff --git a/rs/nns/governance/src/neuron_store/benches.rs b/rs/nns/governance/src/neuron_store/benches.rs index 95e2da2699b..ca93870f5c1 100644 --- a/rs/nns/governance/src/neuron_store/benches.rs +++ b/rs/nns/governance/src/neuron_store/benches.rs @@ -404,6 +404,9 @@ fn draw_maturity_from_neurons_fund_stable() -> BenchResult { let mut rng = new_rng(); let mut neuron_store = NeuronStore::new(BTreeMap::new()); let mut neurons_fund_neurons = BTreeSet::new(); + // When extrapolating to `MAX_NEURONS_FUND_PARTICIPANTS` (5K) neurons, the current performance + // of 12M instructions (as of the time of writing) becomes 600M instructions. This is relatively + // small compared to the instruction limit of 50B (or the 40B limit for application subnets). for _ in 0..100 { let neuron = new_neuron_builder(&mut rng, NeuronLocation::Heap, NeuronSize::Typical) .with_maturity_e8s_equivalent(2_000_000_000) From 8bfa3c4f897bb6136363bcdaae5d4544265f29e9 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Tue, 14 Jan 2025 00:26:05 -0600 Subject: [PATCH 75/98] feat(sns): add release runscript to replace runbook in notion (#3430) This PR introduces a simple interactive "runscript" version of our NNS release runbook. A runscript is what I call a program that walks you through a procedure step-by-step, waiting for confirmation before showing the next step. Runscripts have one big advantage over runbooks: They're easy to automate incrementally. Just replace "press enter to continue" with actual automation for specific step. This first version is intentionally simple - it just shows the steps and waits for the user to press enter. But it provides a foundation we can build on to gradually automate pieces of the release process. --- Cargo.lock | 22 ++ Cargo.toml | 1 + .../tools/release-runscript/BUILD.bazel | 31 +++ .../tools/release-runscript/Cargo.toml | 29 +++ .../tools/release-runscript/src/main.rs | 210 ++++++++++++++++++ 5 files changed, 293 insertions(+) create mode 100644 rs/nervous_system/tools/release-runscript/BUILD.bazel create mode 100644 rs/nervous_system/tools/release-runscript/Cargo.toml create mode 100644 rs/nervous_system/tools/release-runscript/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index ea77ce2b3f1..330163c5345 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18429,6 +18429,28 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "release-runscript" +version = "0.9.0" +dependencies = [ + "anyhow", + "candid", + "colored", + "futures", + "ic-agent", + "ic-base-types", + "ic-nervous-system-agent", + "ic-nervous-system-clients", + "ic-nervous-system-common-test-keys", + "ic-nns-common", + "ic-nns-constants", + "rgb", + "serde", + "serde_json", + "tempfile", + "tokio", +] + [[package]] name = "rend" version = "0.4.2" diff --git a/Cargo.toml b/Cargo.toml index 521019dae7b..de382d1e46c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -197,6 +197,7 @@ members = [ "rs/nervous_system/runtime", "rs/nervous_system/string", "rs/nervous_system/temporary", + "rs/nervous_system/tools/release-runscript", "rs/nervous_system/tools/sync-with-released-nervous-system-wasms", "rs/nns/constants", "rs/nns/common", diff --git a/rs/nervous_system/tools/release-runscript/BUILD.bazel b/rs/nervous_system/tools/release-runscript/BUILD.bazel new file mode 100644 index 00000000000..dcdefb981ec --- /dev/null +++ b/rs/nervous_system/tools/release-runscript/BUILD.bazel @@ -0,0 +1,31 @@ +load("@rules_rust//rust:defs.bzl", "rust_binary") + +package(default_visibility = ["//visibility:public"]) + +# See rs/nervous_system/feature_test.md +DEPENDENCIES = [ + # Keep sorted. + "//rs/nervous_system/agent", + "//rs/nervous_system/clients", + "//rs/nns/common", + "//rs/nns/constants", + "//rs/types/base_types", + "@crate_index//:anyhow", + "@crate_index//:candid", + "@crate_index//:colored", + "@crate_index//:futures", + "@crate_index//:ic-agent", + "@crate_index//:rgb", + "@crate_index//:serde", + "@crate_index//:serde_json", + "@crate_index//:tempfile", + "@crate_index//:tokio", +] + +rust_binary( + name = "release-runscript", + srcs = [ + "src/main.rs", + ], + deps = DEPENDENCIES, +) diff --git a/rs/nervous_system/tools/release-runscript/Cargo.toml b/rs/nervous_system/tools/release-runscript/Cargo.toml new file mode 100644 index 00000000000..e603ef296ee --- /dev/null +++ b/rs/nervous_system/tools/release-runscript/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "release-runscript" +version.workspace = true +authors.workspace = true +edition.workspace = true +description.workspace = true +documentation.workspace = true + +[[bin]] +name = "release-runscript" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +candid = { workspace = true } +colored = "2.0.0" +futures = { workspace = true } +ic-agent = { workspace = true } +ic-base-types = { path = "../../../types/base_types" } +ic-nervous-system-agent = { path = "../../agent" } +ic-nervous-system-clients = { path = "../../clients" } +ic-nervous-system-common-test-keys = { path = "../../common/test_keys" } +ic-nns-common = { path = "../../../nns/common" } +ic-nns-constants = { path = "../../../nns/constants" } +rgb = "0.8.37" +serde = { workspace = true } +serde_json = { workspace = true } +tempfile = { workspace = true } +tokio = { workspace = true } diff --git a/rs/nervous_system/tools/release-runscript/src/main.rs b/rs/nervous_system/tools/release-runscript/src/main.rs new file mode 100644 index 00000000000..952e4a9945d --- /dev/null +++ b/rs/nervous_system/tools/release-runscript/src/main.rs @@ -0,0 +1,210 @@ +use colored::*; +use std::io::{self, Write}; + +struct Step { + title: &'static str, + description: &'static str, +} + +fn main() { + let steps = vec![ + Step { + title: "Pick Release Candidate Commit", + description: "Run `./testnet/tools/nns-tools/cmd.sh latest_commit_with_prebuilt_artifacts`. +If you would like to pick a different commit, follow these steps: +2. Go to https://github.com/dfinity/ic/actions/workflows/ci-main.yml?query=branch%3Amaster+event%3Apush+is%3Asuccess +3. Find a recent commit with passing CI Main in the master branch +4. Record this commit (e.g., post to Slack) + +Pre-built artifacts check: +- Install aws tool if needed +- List available files: + aws s3 ls --no-sign-request s3://dfinity-download-public/ic/${COMMIT}/canisters/ +- Note: Our tools download from the analogous https://download.dfinity.systems/... URL", + }, + Step { + title: "Determine Upgrade Targets", + description: "Determine which NNS canisters and/or SNS WASMs need to be upgraded/published. +Only those with 'interesting' changes need to be released. + +Required checks: +1. Run: ./testnet/tools/nns-tools/list-new-commits.sh +2. Check Monday team sync meeting minutes at: + https://docs.google.com/document/d/1CPM1RlMz6UMSUQzqvdP7EDiLMomK4YeuEV7UnxQ9DAE/edit + +For SNS ledger suite (ledger, archive, and index canisters): +- Consult Financial Integrations team +- FI team should contact NNS team Friday morning about significant changes +- FI team should provide the 'Features' section of proposals +- This agreement is new - you may need to remind them +- This applies to ledger, archive, and index canisters", + }, + Step { + title: "Run NNS Upgrade Tests", + description: "Verify the commit you chose at the previous step has a green check on this page: https://github.com/dfinity/ic/actions/workflows/ci-main.yml?query=branch:master+event:push+is:success + +If not, you can also run the upgrade tests manually: + - Follow instructions in: testnet/tools/nns-tools/README.md#upgrade-testing-via-bazel + +2. SNS Testing Note: + - No manual testing needed for SNS + - Covered by sns_release_qualification in CI + - Example: Test at rs/nervous_system/integration_tests/tests/sns_release_qualification.rs", + }, + Step { + title: "Create Proposal Texts", + description: "Create proposal text for each canister to be upgraded. +This can be done in parallel with the previous testing step. + +Instructions: +1. Follow format in: testnet/tools/nns-tools/README.md#nnssns-canister-upgrade-proposal-process +2. Name conventions: + - NNS proposals: nns-*.md + - SNS proposals: sns-*.md +3. Organization: + - Put all proposal files in a dedicated directory + - Keep directory clean (nothing else in there) + - This will help with forum post generation later", + }, + Step { + title: "Submit Proposals", + description: "Submit the proposals on Friday + +Follow detailed instructions at: +testnet/tools/nns-tools/README.md#submit-the-proposals", + }, + Step { + title: "Create Forum Post", + description: "Create a forum post with the following specifications: + +1. Title Format: + 'NNS Updates (: )' + +2. Category: + Governance > NNS proposal discussion + Reference: https://forum.dfinity.org/t/nns-proposal-discussions/34492 + +3. Tags: + - Protocol-canister-management / Service-nervous-system-management + - nns / sns + +4. Content: + - Link to proposals in IC Dashboard + - Include all proposal texts + - Use six consecutive backticks (```````) to wrap proposal text + - Call out any 'interesting' changes, breaking changes, or required actions + +5. Generate Forum Content: + If your proposals are in a dedicated directory: + + For NNS upgrades: + ```bash + ./testnet/tools/nns-tools/cmd.sh \\ + generate_forum_post_nns_upgrades \\ + $PROPOSALS_DIR/nns-*.md \\ + | pbcopy + ``` + + For SNS WASM publishing: + ```bash + ./testnet/tools/nns-tools/cmd.sh \\ + generate_forum_post_sns_wasm_publish \\ + $PROPOSALS_DIR/sns-*.md \\ + | pbcopy + ``` + +6. Required Follow-ups: + - Reply to NNS Updates Aggregation Thread (https://forum.dfinity.org/t/nns-updates-aggregation-thread/23551) + - If SNS canister WASMs were published, update SNS Upgrades Aggregation Thread + (https://forum.dfinity.org/t/sns-upgrade-aggregation-thread/24259/2)", + }, + Step { + title: "Schedule Trusted Neurons Vote", + description: "Schedule calendar event for Trusted Neurons to vote the following Monday. + +Calendar Event Setup: +1. Duplicate a past event from: + https://calendar.google.com/calendar/u/0/r/eventedit/duplicate/MjJvMTdva2xtdGJuZDhoYjRjN2poZzNwM2ogY182NGYwZDdmZDYzYjNlMDYxZjE1Zjk2MTU1NWYzMmFiN2EyZmY3M2NjMWJmM2Q3ZTRkNGI3NGVjYjk1ZWVhM2M0QGc + +2. Use 'NNS Upgrades' calendar + +3. Timing: + - Usually scheduled at 6 pm Central European Time + - For multiple proposals, schedule separate sequential events + +4. Required Fields: + - Date and Time + - Title: Include canister name and proposal ID + - Description: Link to the proposal + +5. Actions: + - Click 'Save' to create event + - Send email invitations when prompted + - If people don't respond, ping @trusted-neurons in #eng-release channel", + }, + Step { + title: "Update Mainnet Canisters", + description: "After proposal execution, update mainnet-canisters.json: + +1. Run the sync command: + bazel run //rs/nervous_system/tools/sync-with-released-nevous-system-wasms + + Note: If you encounter problems, try adding --config=local + +2. Purpose of these changes: + - Tells bazel what versions are running in production + - Used by tests to verify upgrade compatibility + - Maintains build hermeticity + +3. Note on automation: + - There was a ticket for automating this (NNS1-2201) + - Currently marked as won't do", + }, + Step { + title: "Update Changelog", + description: "Update CHANGELOG.md file(s) for each proposal: + +1. For each proposal ID: + ```bash + PROPOSAL_IDS=... + + for PROPOSAL_ID in $PROPOSAL_IDS do + ./testnet/tools/nns-tools/add-release-to-changelog.sh \\ + $PROPOSAL_ID + done + ``` + +2. Best Practice: + - Combine this change with mainnet-canisters.json update in the same PR", + }, + ]; + + println!("{}", "\nNNS Release Runscript".bright_green().bold()); + println!("{}", "===================".bright_green()); + println!("This script will guide you through the NNS release process.\n"); + + for (index, step) in steps.iter().enumerate() { + print_step(index + 1, step); + + print!("\nPress Enter to continue to next step..."); + io::stdout().flush().unwrap(); + let mut input = String::new(); + io::stdin().read_line(&mut input).unwrap(); + + // Clear screen for next step + print!("\x1B[2J\x1B[1;1H"); + } + + println!("{}", "\nRelease process complete!".bright_green().bold()); + println!("Please verify that all steps were completed successfully."); +} + +fn print_step(number: usize, step: &Step) { + println!( + "{} {}", + format!("Step {}:", number).bright_blue().bold(), + step.title.white().bold() + ); + println!("{}", "---".bright_blue()); + println!("{}\n", step.description); +} From d6bb598cfcfa5565f9dcdaa6891669e394d2c08b Mon Sep 17 00:00:00 2001 From: maciejdfinity <122265298+maciejdfinity@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:20:23 +0100 Subject: [PATCH 76/98] test(ICRC_Ledger): canbench benchmarks for icrc2_approve, icrc2_transfer_from and icrc3_get_blocks (#3400) Scopes for `icrc2_approve`, `icrc2_transfer_from` and `icrc3_get_blocks` were added. Scope `before_upgrade` was renamed to `icrc1_transfer`. Since we now test with more approvals, balances and blocks, the benchmark files need to be completely regenerated. --- .../ledger/canbench_results/canbench_u256.yml | 42 +++++--- .../ledger/canbench_results/canbench_u64.yml | 42 +++++--- .../icrc1/ledger/src/benches/benches_u256.rs | 96 ++++++++++++++----- .../icrc1/ledger/src/benches/benches_u64.rs | 93 ++++++++++++++---- .../icrc1/ledger/src/benches/mod.rs | 22 ++++- rs/ledger_suite/icrc1/ledger/src/main.rs | 16 +++- 6 files changed, 230 insertions(+), 81 deletions(-) diff --git a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml index 4fe24655c4a..27a1b10cf2e 100644 --- a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml +++ b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u256.yml @@ -1,42 +1,54 @@ benches: bench_icrc1_transfers: total: - instructions: 13798815361 - heap_increase: 172 - stable_memory_increase: 128 + instructions: 58832813772 + heap_increase: 271 + stable_memory_increase: 256 scopes: - before_upgrade: - instructions: 13630531777 + icrc1_transfer: + instructions: 13635001695 heap_increase: 43 stable_memory_increase: 0 - post_upgrade: - instructions: 118601062 + icrc2_approve: + instructions: 20413485760 + heap_increase: 41 + stable_memory_increase: 128 + icrc2_transfer_from: + instructions: 24042619927 + heap_increase: 5 + stable_memory_increase: 0 + icrc3_get_blocks: + instructions: 7877258 heap_increase: 0 stable_memory_increase: 0 + post_upgrade: + instructions: 354777092 + heap_increase: 53 + stable_memory_increase: 0 pre_upgrade: - instructions: 49679478 + instructions: 149556765 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 168282130 - heap_increase: 129 + instructions: 504335921 + heap_increase: 182 stable_memory_increase: 128 bench_upgrade_baseline: total: - instructions: 8684974 + instructions: 8684182 heap_increase: 258 stable_memory_increase: 128 scopes: post_upgrade: - instructions: 8606422 + instructions: 8605997 heap_increase: 129 stable_memory_increase: 0 pre_upgrade: - instructions: 76145 + instructions: 75778 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 8684285 + instructions: 8683493 heap_increase: 258 stable_memory_increase: 128 -version: 0.1.7 +version: 0.1.8 diff --git a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml index 7e7164f34e5..fd17caa5c7c 100644 --- a/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml +++ b/rs/ledger_suite/icrc1/ledger/canbench_results/canbench_u64.yml @@ -1,42 +1,54 @@ benches: bench_icrc1_transfers: total: - instructions: 13237283790 - heap_increase: 171 - stable_memory_increase: 128 + instructions: 56837535933 + heap_increase: 271 + stable_memory_increase: 256 scopes: - before_upgrade: - instructions: 13068913917 + icrc1_transfer: + instructions: 13071791984 heap_increase: 42 stable_memory_increase: 0 - post_upgrade: - instructions: 118797275 + icrc2_approve: + instructions: 19627513485 + heap_increase: 29 + stable_memory_increase: 128 + icrc2_transfer_from: + instructions: 23404082941 + heap_increase: 18 + stable_memory_increase: 0 + icrc3_get_blocks: + instructions: 7540214 heap_increase: 0 stable_memory_increase: 0 + post_upgrade: + instructions: 353134588 + heap_increase: 53 + stable_memory_increase: 0 pre_upgrade: - instructions: 49569466 + instructions: 149315334 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 168368331 - heap_increase: 129 + instructions: 502451986 + heap_increase: 182 stable_memory_increase: 128 bench_upgrade_baseline: total: - instructions: 8686052 + instructions: 8683414 heap_increase: 258 stable_memory_increase: 128 scopes: post_upgrade: - instructions: 8606533 + instructions: 8604304 heap_increase: 129 stable_memory_increase: 0 pre_upgrade: - instructions: 77112 + instructions: 76703 heap_increase: 129 stable_memory_increase: 128 upgrade: - instructions: 8685363 + instructions: 8682725 heap_increase: 258 stable_memory_increase: 128 -version: 0.1.7 +version: 0.1.8 diff --git a/rs/ledger_suite/icrc1/ledger/src/benches/benches_u256.rs b/rs/ledger_suite/icrc1/ledger/src/benches/benches_u256.rs index c142d92fcc8..2291972e9bd 100644 --- a/rs/ledger_suite/icrc1/ledger/src/benches/benches_u256.rs +++ b/rs/ledger_suite/icrc1/ledger/src/benches/benches_u256.rs @@ -1,16 +1,18 @@ use crate::{ benches::{ - assert_has_num_balances, emulate_archive_blocks, icrc1_transfer, max_length_principal, - mint_tokens, upgrade, NUM_TRANSFERS, + assert_has_num_balances, emulate_archive_blocks, icrc_transfer, mint_tokens, test_account, + test_account_offset, upgrade, NUM_GET_BLOCKS, NUM_OPERATIONS, }, - init_state, Access, Account, LOG, + icrc2_approve_not_async, icrc3_get_blocks, init_state, Access, Account, LOG, }; use assert_matches::assert_matches; use canbench_rs::{bench, BenchResult}; -use candid::Principal; +use candid::{Nat, Principal}; use ic_icrc1_ledger::{FeatureFlags, InitArgs, InitArgsBuilder}; use ic_ledger_canister_core::archive::ArchiveOptions; use icrc_ledger_types::icrc1::transfer::TransferArg; +use icrc_ledger_types::icrc2::approve::ApproveArgs; +use icrc_ledger_types::icrc3::blocks::GetBlocksRequest; const MINTER_PRINCIPAL: Principal = Principal::from_slice(&[0_u8, 0, 0, 0, 2, 48, 0, 156, 1, 1]); @@ -31,22 +33,74 @@ fn bench_icrc1_transfers() -> BenchResult { canbench_rs::bench_fn(|| { { - let _p = canbench_rs::bench_scope("before_upgrade"); - for i in 0..NUM_TRANSFERS { + let _p = canbench_rs::bench_scope("icrc1_transfer"); + for i in 0..NUM_OPERATIONS { let transfer = TransferArg { from_subaccount: account_with_tokens.subaccount, - to: Account { - owner: max_length_principal(i), - subaccount: Some([11_u8; 32]), - }, + to: test_account(i), created_at_time: Some(start_time + i as u64), ..cketh_transfer() }; - let result = icrc1_transfer(account_with_tokens.owner, transfer.clone()); + let result = icrc_transfer(account_with_tokens.owner, None, transfer.clone()); assert_matches!(result, Ok(_)); emulate_archive_blocks::(&LOG); } - assert_has_num_balances(NUM_TRANSFERS + 2); + assert_has_num_balances(NUM_OPERATIONS + 2); + } + { + let _p = canbench_rs::bench_scope("icrc2_approve"); + for i in 0..NUM_OPERATIONS { + let approve = ApproveArgs { + from_subaccount: account_with_tokens.subaccount, + spender: test_account(i), + created_at_time: Some(start_time + i as u64), + amount: u128::MAX.into(), + expected_allowance: Some(0u64.into()), + expires_at: Some(u64::MAX), + fee: None, + memo: Some(MEMO.to_vec().into()), + }; + let result = icrc2_approve_not_async(account_with_tokens.owner, approve.clone()); + assert_matches!(result, Ok(_)); + emulate_archive_blocks::(&LOG); + } + } + { + let _p = canbench_rs::bench_scope("icrc2_transfer_from"); + for i in 0..NUM_OPERATIONS { + let spender = test_account(i); + let transfer = TransferArg { + from_subaccount: account_with_tokens.subaccount, + to: test_account_offset(i), + created_at_time: Some(start_time + i as u64), + ..cketh_transfer() + }; + let result = + icrc_transfer(account_with_tokens.owner, Some(spender), transfer.clone()); + assert_matches!(result, Ok(_)); + emulate_archive_blocks::(&LOG); + } + assert_has_num_balances(2 * NUM_OPERATIONS + 2); + } + for i in 0..NUM_GET_BLOCKS { + let spender = test_account(i); + let transfer = TransferArg { + from_subaccount: account_with_tokens.subaccount, + to: test_account_offset(i), + created_at_time: Some(1_000_000_000 + start_time + i as u64), + ..cketh_transfer() + }; + let result = icrc_transfer(account_with_tokens.owner, Some(spender), transfer.clone()); + assert_matches!(result, Ok(_)); + } + { + let req = GetBlocksRequest { + start: Nat::from(3 * NUM_OPERATIONS), + length: Nat::from(NUM_GET_BLOCKS), + }; + let _p = canbench_rs::bench_scope("icrc3_get_blocks"); + let blocks_res = icrc3_get_blocks(vec![req]); + assert_eq!(blocks_res.blocks.len(), NUM_GET_BLOCKS as usize); } upgrade(); }) @@ -85,6 +139,13 @@ fn cketh_ledger_init_args_with_archive() -> InitArgs { .build() } +const MEMO: [u8; 61] = [ + 0x82_u8, 0x00, 0x83, 0x54, 0x04, 0xc5, 0x63, 0x84, 0x17, 0x78, 0xc9, 0x3f, 0x41, 0xdc, 0x1a, + 0x89, 0x82, 0x1a, 0xe1, 0xc6, 0x75, 0xbb, 0xe8, 0x15, 0x58, 0x20, 0xb5, 0xa1, 0x01, 0xfb, 0x96, + 0xc5, 0xcf, 0x22, 0x4d, 0xf0, 0xd5, 0x02, 0x9b, 0x56, 0xbe, 0x81, 0xfc, 0x65, 0xce, 0x61, 0xf8, + 0x99, 0x11, 0xb7, 0x71, 0x23, 0x27, 0x8a, 0xe7, 0xf4, 0x67, 0xb7, 0x19, 0x01, 0x2c, +]; + /// ckETH ledger transaction 495542 fn cketh_transfer() -> TransferArg { TransferArg { @@ -98,16 +159,7 @@ fn cketh_transfer() -> TransferArg { }, fee: None, created_at_time: None, - memo: Some( - vec![ - 0x82_u8, 0x00, 0x83, 0x54, 0x04, 0xc5, 0x63, 0x84, 0x17, 0x78, 0xc9, 0x3f, 0x41, - 0xdc, 0x1a, 0x89, 0x82, 0x1a, 0xe1, 0xc6, 0x75, 0xbb, 0xe8, 0x15, 0x58, 0x20, 0xb5, - 0xa1, 0x01, 0xfb, 0x96, 0xc5, 0xcf, 0x22, 0x4d, 0xf0, 0xd5, 0x02, 0x9b, 0x56, 0xbe, - 0x81, 0xfc, 0x65, 0xce, 0x61, 0xf8, 0x99, 0x11, 0xb7, 0x71, 0x23, 0x27, 0x8a, 0xe7, - 0xf4, 0x67, 0xb7, 0x19, 0x01, 0x2c, - ] - .into(), - ), + memo: Some(MEMO.to_vec().into()), amount: 19_998_200_000_000_000_000_u128.into(), } } diff --git a/rs/ledger_suite/icrc1/ledger/src/benches/benches_u64.rs b/rs/ledger_suite/icrc1/ledger/src/benches/benches_u64.rs index b3fbce97763..183b545f168 100644 --- a/rs/ledger_suite/icrc1/ledger/src/benches/benches_u64.rs +++ b/rs/ledger_suite/icrc1/ledger/src/benches/benches_u64.rs @@ -1,15 +1,17 @@ use crate::benches::{ - assert_has_num_balances, emulate_archive_blocks, icrc1_transfer, max_length_principal, - mint_tokens, upgrade, NUM_TRANSFERS, + assert_has_num_balances, emulate_archive_blocks, icrc_transfer, mint_tokens, test_account, + test_account_offset, upgrade, NUM_GET_BLOCKS, NUM_OPERATIONS, }; -use crate::{init_state, Access, LOG}; +use crate::{icrc2_approve_not_async, icrc3_get_blocks, init_state, Access, LOG}; use assert_matches::assert_matches; use canbench_rs::{bench, BenchResult}; -use candid::Principal; +use candid::{Nat, Principal}; use ic_icrc1_ledger::{FeatureFlags, InitArgs, InitArgsBuilder}; use ic_ledger_canister_core::archive::ArchiveOptions; use icrc_ledger_types::icrc1::account::Account; use icrc_ledger_types::icrc1::transfer::TransferArg; +use icrc_ledger_types::icrc2::approve::ApproveArgs; +use icrc_ledger_types::icrc3::blocks::GetBlocksRequest; const MINTER_PRINCIPAL: Principal = Principal::from_slice(&[0_u8, 0, 0, 0, 2, 48, 0, 7, 1, 1]); @@ -30,22 +32,74 @@ fn bench_icrc1_transfers() -> BenchResult { canbench_rs::bench_fn(|| { { - let _p = canbench_rs::bench_scope("before_upgrade"); - for i in 0..NUM_TRANSFERS { + let _p = canbench_rs::bench_scope("icrc1_transfer"); + for i in 0..NUM_OPERATIONS { let transfer = TransferArg { from_subaccount: account_with_tokens.subaccount, - to: Account { - owner: max_length_principal(i), - subaccount: Some([11_u8; 32]), - }, + to: test_account(i), created_at_time: Some(start_time + i as u64), ..ckbtc_transfer() }; - let result = icrc1_transfer(account_with_tokens.owner, transfer.clone()); + let result = icrc_transfer(account_with_tokens.owner, None, transfer.clone()); assert_matches!(result, Ok(_)); emulate_archive_blocks::(&LOG); } - assert_has_num_balances(NUM_TRANSFERS + 2); + assert_has_num_balances(NUM_OPERATIONS + 2); + } + { + let _p = canbench_rs::bench_scope("icrc2_approve"); + for i in 0..NUM_OPERATIONS { + let approve = ApproveArgs { + from_subaccount: account_with_tokens.subaccount, + spender: test_account(i), + created_at_time: Some(start_time + i as u64), + amount: u64::MAX.into(), + expected_allowance: Some(0u64.into()), + expires_at: Some(u64::MAX), + fee: None, + memo: Some(MEMO.to_vec().into()), + }; + let result = icrc2_approve_not_async(account_with_tokens.owner, approve.clone()); + assert_matches!(result, Ok(_)); + emulate_archive_blocks::(&LOG); + } + } + { + let _p = canbench_rs::bench_scope("icrc2_transfer_from"); + for i in 0..NUM_OPERATIONS { + let spender = test_account(i); + let transfer = TransferArg { + from_subaccount: account_with_tokens.subaccount, + to: test_account_offset(i), + created_at_time: Some(start_time + i as u64), + ..ckbtc_transfer() + }; + let result = + icrc_transfer(account_with_tokens.owner, Some(spender), transfer.clone()); + assert_matches!(result, Ok(_)); + emulate_archive_blocks::(&LOG); + } + assert_has_num_balances(2 * NUM_OPERATIONS + 2); + } + for i in 0..NUM_GET_BLOCKS { + let spender = test_account(i); + let transfer = TransferArg { + from_subaccount: account_with_tokens.subaccount, + to: test_account_offset(i), + created_at_time: Some(1_000_000_000 + start_time + i as u64), + ..ckbtc_transfer() + }; + let result = icrc_transfer(account_with_tokens.owner, Some(spender), transfer.clone()); + assert_matches!(result, Ok(_)); + } + { + let req = GetBlocksRequest { + start: Nat::from(3 * NUM_OPERATIONS), + length: Nat::from(NUM_GET_BLOCKS), + }; + let _p = canbench_rs::bench_scope("icrc3_get_blocks"); + let blocks_res = icrc3_get_blocks(vec![req]); + assert_eq!(blocks_res.blocks.len(), NUM_GET_BLOCKS as usize); } upgrade(); }) @@ -84,6 +138,12 @@ fn ckbtc_ledger_init_args_with_archive() -> InitArgs { .build() } +const MEMO: [u8; 41] = [ + 0x82_u8, 0x00, 0x83, 0x58, 0x20, 0x18, 0x19, 0xcc, 0xd2, 0x28, 0xad, 0x2e, 0x83, 0xc6, 0xc8, + 0x63, 0x99, 0xa0, 0xd7, 0xd0, 0x2e, 0xe9, 0x75, 0x96, 0x95, 0x86, 0xf3, 0x47, 0x85, 0xf6, 0xaf, + 0x99, 0x00, 0x1e, 0x08, 0x8b, 0xa0, 0x02, 0x19, 0x07, 0xd0, +]; + /// ckBTC ledger transaction 1604556 fn ckbtc_transfer() -> TransferArg { TransferArg { @@ -97,14 +157,7 @@ fn ckbtc_transfer() -> TransferArg { }, fee: None, created_at_time: None, - memo: Some( - vec![ - 0x82_u8, 0x00, 0x83, 0x58, 0x20, 0x18, 0x19, 0xcc, 0xd2, 0x28, 0xad, 0x2e, 0x83, - 0xc6, 0xc8, 0x63, 0x99, 0xa0, 0xd7, 0xd0, 0x2e, 0xe9, 0x75, 0x96, 0x95, 0x86, 0xf3, - 0x47, 0x85, 0xf6, 0xaf, 0x99, 0x00, 0x1e, 0x08, 0x8b, 0xa0, 0x02, 0x19, 0x07, 0xd0, - ] - .into(), - ), + memo: Some(MEMO.to_vec().into()), amount: 167_708_u32.into(), } } diff --git a/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs b/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs index 68d36334239..bd27b926857 100644 --- a/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs +++ b/rs/ledger_suite/icrc1/ledger/src/benches/mod.rs @@ -12,7 +12,8 @@ mod benches_u256; #[cfg(not(feature = "u256-tokens"))] mod benches_u64; -pub const NUM_TRANSFERS: u32 = 10_000; +pub const NUM_OPERATIONS: u32 = 10_000; +pub const NUM_GET_BLOCKS: u32 = 100; pub fn upgrade() { let _p = canbench_rs::bench_scope("upgrade"); @@ -20,8 +21,9 @@ pub fn upgrade() { post_upgrade(None); } -pub fn icrc1_transfer( +pub fn icrc_transfer( from: Principal, + spender: Option, arg: TransferArg, ) -> Result> { let from_account = Account { @@ -31,7 +33,7 @@ pub fn icrc1_transfer( execute_transfer_not_async( from_account, arg.to, - None, + spender, arg.fee, arg.amount, arg.memo, @@ -52,14 +54,26 @@ pub fn max_length_principal(index: u32) -> Principal { Principal::from_slice(&principal) } +pub fn test_account(i: u32) -> Account { + Account { + owner: max_length_principal(i), + subaccount: Some([11_u8; 32]), + } +} + +pub fn test_account_offset(i: u32) -> Account { + test_account(1_000_000_000 + i) +} + fn mint_tokens>(minter: Principal, amount: T) -> Account { let account_with_tokens = Account { owner: max_length_principal(u32::MAX), subaccount: Some([255_u8; 32]), }; assert_matches!( - icrc1_transfer( + icrc_transfer( minter, + None, TransferArg { from_subaccount: None, to: account_with_tokens, diff --git a/rs/ledger_suite/icrc1/ledger/src/main.rs b/rs/ledger_suite/icrc1/ledger/src/main.rs index 18643abf59e..154819b4249 100644 --- a/rs/ledger_suite/icrc1/ledger/src/main.rs +++ b/rs/ledger_suite/icrc1/ledger/src/main.rs @@ -1,8 +1,8 @@ #[cfg(feature = "canbench-rs")] mod benches; -use candid::candid_method; use candid::types::number::Nat; +use candid::{candid_method, Principal}; use ic_canister_log::{declare_log_buffer, export, log}; use ic_canisters_http_types::{HttpRequest, HttpResponse, HttpResponseBuilder}; use ic_cdk::api::stable::StableReader; @@ -810,15 +810,13 @@ fn get_data_certificate() -> DataCertificate { } } -#[update] -#[candid_method(update)] -async fn icrc2_approve(arg: ApproveArgs) -> Result { +fn icrc2_approve_not_async(caller: Principal, arg: ApproveArgs) -> Result { panic_if_not_ready(); let block_idx = Access::with_ledger_mut(|ledger| { let now = TimeStamp::from_nanos_since_unix_epoch(ic_cdk::api::time()); let from_account = Account { - owner: ic_cdk::api::caller(), + owner: caller, subaccount: arg.from_subaccount, }; if from_account.owner == arg.spender.owner { @@ -881,6 +879,14 @@ async fn icrc2_approve(arg: ApproveArgs) -> Result { Ok(block_idx) })?; + Ok(block_idx) +} + +#[update] +#[candid_method(update)] +async fn icrc2_approve(arg: ApproveArgs) -> Result { + let block_idx = icrc2_approve_not_async(ic_cdk::api::caller(), arg)?; + // NB. we need to set the certified data before the first async call to make sure that the // blockchain state agrees with the certificate while archiving is in progress. ic_cdk::api::set_certified_data(&Access::with_ledger(Ledger::root_hash)); From 6b7b92b24a33bb024902cb97cbfc3296441c4020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Tue, 14 Jan 2025 10:11:22 +0100 Subject: [PATCH 77/98] test(ICRC_Ledger): FI-1043: Verify ICRC ledger and archive block equality (#3404) Verify that the candid `Block` type returned by the ICRC ledger and archive canisters are the same. --- rs/ledger_suite/icrc1/archive/BUILD.bazel | 1 + rs/ledger_suite/icrc1/archive/src/main.rs | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/rs/ledger_suite/icrc1/archive/BUILD.bazel b/rs/ledger_suite/icrc1/archive/BUILD.bazel index d21998270ec..b6db17976c0 100644 --- a/rs/ledger_suite/icrc1/archive/BUILD.bazel +++ b/rs/ledger_suite/icrc1/archive/BUILD.bazel @@ -56,6 +56,7 @@ rust_test( crate = ":_wasm_archive_canister", data = [ ":archive.did", + "//rs/ledger_suite/icrc1/ledger:ledger.did", ], env = { "CARGO_MANIFEST_DIR": "rs/ledger_suite/icrc1/archive", diff --git a/rs/ledger_suite/icrc1/archive/src/main.rs b/rs/ledger_suite/icrc1/archive/src/main.rs index a8d8eb3c5e1..f629929c889 100644 --- a/rs/ledger_suite/icrc1/archive/src/main.rs +++ b/rs/ledger_suite/icrc1/archive/src/main.rs @@ -436,3 +436,31 @@ fn check_candid_interface() { ) .expect("the ledger interface is not compatible with archive.did"); } + +#[test] +fn check_archive_and_ledger_block_equality() { + // check that ledger.did and archive.did agree on the block format + let manifest_dir = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + let ledger_did_file = manifest_dir.join("../ledger/ledger.did"); + let archive_did_file = manifest_dir.join("archive.did"); + let mut ledger_env = candid_parser::utils::CandidSource::File(ledger_did_file.as_path()) + .load() + .unwrap() + .0; + let archive_env = candid_parser::utils::CandidSource::File(archive_did_file.as_path()) + .load() + .unwrap() + .0; + let ledger_block_type = ledger_env.find_type("Block").unwrap().to_owned(); + let archive_block_type = archive_env.find_type("Block").unwrap().to_owned(); + + let mut gamma = std::collections::HashSet::new(); + let archive_block_type = ledger_env.merge_type(archive_env, archive_block_type.clone()); + candid::types::subtype::equal( + &mut gamma, + &ledger_env, + &ledger_block_type, + &archive_block_type, + ) + .expect("Ledger and Archive block types are different"); +} From cc125603960c419b0d22ffdbdbf288fa11fc5fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Tue, 14 Jan 2025 10:42:22 +0100 Subject: [PATCH 78/98] test(ICRC_Index): FI-1042: Verify ICRC ledger and index block equality (#3403) Verify that the candid `Block` type returned by the ICRC ledger and index canisters are the same. --- rs/ledger_suite/icrc1/index-ng/BUILD.bazel | 5 +++- rs/ledger_suite/icrc1/index-ng/src/main.rs | 28 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/rs/ledger_suite/icrc1/index-ng/BUILD.bazel b/rs/ledger_suite/icrc1/index-ng/BUILD.bazel index 832eb1a3c60..1c80cd0f10c 100644 --- a/rs/ledger_suite/icrc1/index-ng/BUILD.bazel +++ b/rs/ledger_suite/icrc1/index-ng/BUILD.bazel @@ -79,7 +79,10 @@ rust_library( rust_test( name = "index_ng_unit_test", crate = ":_wasm_index_ng_canister", - data = [":index-ng.did"], + data = [ + ":index-ng.did", + "//rs/ledger_suite/icrc1/ledger:ledger.did", + ], deps = [ # Keep sorted. "//rs/ledger_suite/icrc1/test_utils", diff --git a/rs/ledger_suite/icrc1/index-ng/src/main.rs b/rs/ledger_suite/icrc1/index-ng/src/main.rs index 644cd22bdaf..66cd8a876ee 100644 --- a/rs/ledger_suite/icrc1/index-ng/src/main.rs +++ b/rs/ledger_suite/icrc1/index-ng/src/main.rs @@ -1204,3 +1204,31 @@ fn check_candid_interface() { ) }); } + +#[test] +fn check_index_and_ledger_block_equality() { + // check that ledger.did and index-ng.did agree on the block format + let manifest_dir = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + let ledger_did_file = manifest_dir.join("../ledger/ledger.did"); + let index_did_file = manifest_dir.join("index-ng.did"); + let mut ledger_env = candid_parser::utils::CandidSource::File(ledger_did_file.as_path()) + .load() + .unwrap() + .0; + let index_env = candid_parser::utils::CandidSource::File(index_did_file.as_path()) + .load() + .unwrap() + .0; + let ledger_block_type = ledger_env.find_type("Block").unwrap().to_owned(); + let index_block_type = index_env.find_type("Block").unwrap().to_owned(); + + let mut gamma = std::collections::HashSet::new(); + let index_block_type = ledger_env.merge_type(index_env, index_block_type.clone()); + candid::types::subtype::equal( + &mut gamma, + &ledger_env, + &ledger_block_type, + &index_block_type, + ) + .expect("Ledger and Index block types are different"); +} From eb32930c0118638130eb548cd18f332f5225028d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Bj=C3=B6rkqvist?= Date: Tue, 14 Jan 2025 10:55:00 +0100 Subject: [PATCH 79/98] test(ICP_Ledger): FI-1036: Add ICP ledger and index encoded block response compatibility (#3398) Add a test that verifies the ICP ledger and index encoded block response type compatibility. Since the response types are not exactly the same, the best we can do is a Candid subtype check. --- rs/ledger_suite/icp/index/BUILD.bazel | 5 +++- rs/ledger_suite/icp/index/src/main.rs | 35 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/rs/ledger_suite/icp/index/BUILD.bazel b/rs/ledger_suite/icp/index/BUILD.bazel index c9acf1f5001..7c11c0c3a05 100644 --- a/rs/ledger_suite/icp/index/BUILD.bazel +++ b/rs/ledger_suite/icp/index/BUILD.bazel @@ -79,7 +79,10 @@ rust_test( rust_test( name = "ic_icp_index_canister_test", crate = ":_wasm_ic-icp-index-canister", - data = [":index.did"], + data = [ + ":index.did", + "//rs/ledger_suite/icp:ledger.did", + ], env = { "CARGO_MANIFEST_DIR": "rs/ledger_suite/icp/index", }, diff --git a/rs/ledger_suite/icp/index/src/main.rs b/rs/ledger_suite/icp/index/src/main.rs index 0867d6ab041..a14dee429f9 100644 --- a/rs/ledger_suite/icp/index/src/main.rs +++ b/rs/ledger_suite/icp/index/src/main.rs @@ -751,3 +751,38 @@ fn check_candid_interface_compatibility() { ) .unwrap(); } + +#[test] +fn check_index_and_ledger_encoded_block_compatibility() { + // check that ledger.did and index.did agree on the encoded block format + let manifest_dir = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + let ledger_did_file = manifest_dir.join("../ledger.did"); + let index_did_file = manifest_dir.join("./index.did"); + let mut ledger_env = candid_parser::utils::CandidSource::File(ledger_did_file.as_path()) + .load() + .unwrap() + .0; + let index_env = candid_parser::utils::CandidSource::File(index_did_file.as_path()) + .load() + .unwrap() + .0; + let ledger_encoded_block_response_type = ledger_env + .find_type("QueryEncodedBlocksResponse") + .unwrap() + .to_owned(); + let index_encoded_block_response_type = + index_env.find_type("GetBlocksResponse").unwrap().to_owned(); + + let mut gamma = std::collections::HashSet::new(); + let index_encoded_block_response_type = + ledger_env.merge_type(index_env, index_encoded_block_response_type.clone()); + // Check if the ledger `query_encoded_blocks` response <: the index `get_blocks` response, + // i.e., if the index response type is a subtype of the ledger response type. + candid::types::subtype::subtype( + &mut gamma, + &ledger_env, + &ledger_encoded_block_response_type, + &index_encoded_block_response_type, + ) + .expect("Ledger and Index encoded block types are different"); +} From a1421407941a002610b4e55a23a5b47f3a850f34 Mon Sep 17 00:00:00 2001 From: Oleksandr Tkachenko <108659113+altkdf@users.noreply.github.com> Date: Tue, 14 Jan 2025 11:02:56 +0100 Subject: [PATCH 80/98] test(PocketIC): add Schnorr `aux` types and tests (#3422) --- Cargo.lock | 1 + MODULE.bazel | 4 +- packages/pocket-ic/BUILD.bazel | 1 + packages/pocket-ic/Cargo.toml | 1 + packages/pocket-ic/src/management_canister.rs | 23 +++ .../pocket-ic/test_canister/src/canister.rs | 14 ++ .../pocket-ic/tests/management_canister.rs | 5 + packages/pocket-ic/tests/tests.rs | 133 ++++++++++++------ 8 files changed, 135 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 330163c5345..1e410db98ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17125,6 +17125,7 @@ version = "6.0.0" dependencies = [ "backoff", "base64 0.13.1", + "bitcoin 0.28.2", "candid", "candid_parser", "ed25519-dalek", diff --git a/MODULE.bazel b/MODULE.bazel index 9a67389dc26..d0e9fbe3a2d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -863,8 +863,8 @@ http_file( http_file( name = "management_canister_did", downloaded_file_path = "ic.did", - sha256 = "31d4654d60b364420a2e52f546f06b2255dc78ac8c2d768271f004b8946e92cb", - url = "https://raw.githubusercontent.com/dfinity/portal/407ec5b92d06618c4df9f52e98514c5f4f44313e/docs/references/_attachments/ic.did", + sha256 = "0e92d8b9c2cf3d3fca166b76b2d3b8a2464d9b2b61117d8b2f63222b388d8dd1", + url = "https://raw.githubusercontent.com/dfinity/portal/78c93aa37ef17dc67484079d1a4bf58a10a63106/docs/references/_attachments/ic.did", ) # Mozilla CA certificate store in PEM format diff --git a/packages/pocket-ic/BUILD.bazel b/packages/pocket-ic/BUILD.bazel index 56cbb3fed7e..57e445d9270 100644 --- a/packages/pocket-ic/BUILD.bazel +++ b/packages/pocket-ic/BUILD.bazel @@ -33,6 +33,7 @@ MACRO_DEPENDENCIES = [ TEST_DEPENDENCIES = [ # Keep sorted. "//rs/types/error_types", + "@crate_index//:bitcoin", "@crate_index//:candid_parser", "@crate_index//:ed25519-dalek", "@crate_index//:flate2", diff --git a/packages/pocket-ic/Cargo.toml b/packages/pocket-ic/Cargo.toml index 01e3ad0f479..fbf1a1555bf 100644 --- a/packages/pocket-ic/Cargo.toml +++ b/packages/pocket-ic/Cargo.toml @@ -46,6 +46,7 @@ tracing-subscriber = { workspace = true } wslpath = "0.0.2" [dev-dependencies] +bitcoin = { workspace = true } candid_parser = { workspace = true } ed25519-dalek = { workspace = true } flate2 = { workspace = true } diff --git a/packages/pocket-ic/src/management_canister.rs b/packages/pocket-ic/src/management_canister.rs index 1878e6728e2..e76660c5237 100644 --- a/packages/pocket-ic/src/management_canister.rs +++ b/packages/pocket-ic/src/management_canister.rs @@ -1,6 +1,7 @@ use candid::{CandidType, Deserialize, Principal}; pub type CanisterId = Principal; +pub type SubnetId = Principal; #[derive(CandidType, Deserialize, Debug, Clone)] pub struct CanisterIdRecord { @@ -234,6 +235,11 @@ pub struct CanisterInfoArgs { pub num_requested_changes: Option, } +#[derive(CandidType, Deserialize, Debug, Clone)] +pub struct SubnetInfoArgs { + pub subnet_id: SubnetId, +} + #[derive(CandidType, Deserialize, Debug, Clone)] pub enum ChangeOrigin { #[serde(rename = "from_user")] @@ -292,6 +298,11 @@ pub struct CanisterInfoResult { pub total_num_changes: u64, } +#[derive(CandidType, Deserialize, Debug, Clone)] +pub struct SubnetInfoResult { + pub replica_version: String, +} + // raw randomness pub type RawRandResult = Vec; @@ -455,6 +466,18 @@ pub struct SignWithSchnorrArgs { pub key_id: SignWithSchnorrArgsKeyId, pub derivation_path: Vec>, pub message: Vec, + pub aux: Option, +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub enum SignWithSchnorrAux { + #[serde(rename = "bip341")] + Bip341(SignWithBip341Aux), +} + +#[derive(CandidType, Deserialize, Debug, Clone)] +pub struct SignWithBip341Aux { + pub merkle_root_hash: Vec, } #[derive(CandidType, Deserialize, Debug, Clone)] diff --git a/packages/pocket-ic/test_canister/src/canister.rs b/packages/pocket-ic/test_canister/src/canister.rs index 53cd4ffad6c..8f8fe0b6a2d 100644 --- a/packages/pocket-ic/test_canister/src/canister.rs +++ b/packages/pocket-ic/test_canister/src/canister.rs @@ -109,6 +109,18 @@ struct SignWithSchnorrArgument { pub message: Vec, pub derivation_path: Vec>, pub key_id: SchnorrKeyId, + pub aux: Option, +} + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub enum SignWithSchnorrAux { + #[serde(rename = "bip341")] + Bip341(SignWithBip341Aux), +} + +#[derive(CandidType, Serialize, Deserialize, Debug)] +pub struct SignWithBip341Aux { + pub merkle_root_hash: ByteBuf, } #[derive(CandidType, Deserialize, Debug)] @@ -144,11 +156,13 @@ async fn sign_with_schnorr( message: Vec, derivation_path: Vec>, key_id: SchnorrKeyId, + aux: Option, ) -> Result, String> { let internal_request = SignWithSchnorrArgument { message, derivation_path, key_id, + aux, }; let (internal_reply,): (SignWithSchnorrResponse,) = ic_cdk::api::call::call_with_payment( diff --git a/packages/pocket-ic/tests/management_canister.rs b/packages/pocket-ic/tests/management_canister.rs index b6e813729eb..fe1c68e261e 100644 --- a/packages/pocket-ic/tests/management_canister.rs +++ b/packages/pocket-ic/tests/management_canister.rs @@ -61,6 +61,11 @@ fn canister_info(_: CanisterInfoArgs) -> CanisterInfoResult { unreachable!() } +#[update] +fn subnet_info(_: SubnetInfoArgs) -> SubnetInfoResult { + unreachable!() +} + #[update] fn delete_canister(_: CanisterIdRecord) { unreachable!() diff --git a/packages/pocket-ic/tests/tests.rs b/packages/pocket-ic/tests/tests.rs index 295ed91d115..8b9d39c40d5 100644 --- a/packages/pocket-ic/tests/tests.rs +++ b/packages/pocket-ic/tests/tests.rs @@ -5,7 +5,7 @@ use ic_transport_types::EnvelopeContent::ReadState; use pocket_ic::management_canister::{ CanisterId, CanisterIdRecord, CanisterInstallMode, CanisterSettings, EcdsaPublicKeyResult, HttpRequestResult, ProvisionalCreateCanisterWithCyclesArgs, SchnorrAlgorithm, - SchnorrPublicKeyArgsKeyId, SchnorrPublicKeyResult, + SchnorrPublicKeyArgsKeyId, SchnorrPublicKeyResult, SignWithBip341Aux, SignWithSchnorrAux, }; use pocket_ic::{ common::rest::{ @@ -946,53 +946,96 @@ fn test_schnorr() { // We define the message, derivation path, and ECDSA key ID to use in this test. let message = b"Hello, world!==================="; // must be of length 32 bytes for BIP340 let derivation_path = vec!["my message".as_bytes().to_vec()]; + let some_aux: Option = + Some(SignWithSchnorrAux::Bip341(SignWithBip341Aux { + merkle_root_hash: b"Hello, aux!=====================".to_vec(), + })); for algorithm in [SchnorrAlgorithm::Bip340Secp256K1, SchnorrAlgorithm::Ed25519] { for name in ["key_1", "test_key_1", "dfx_test_key"] { - let key_id = SchnorrPublicKeyArgsKeyId { - algorithm: algorithm.clone(), - name: name.to_string(), - }; - - // We get the Schnorr public key and signature via update calls to the test canister. - let schnorr_public_key = update_candid::< - (Option, _, _), - (Result,), - >( - &pic, - canister, - "schnorr_public_key", - (None, derivation_path.clone(), key_id.clone()), - ) - .unwrap() - .0 - .unwrap(); - let schnorr_signature = update_candid::<_, (Result, String>,)>( - &pic, - canister, - "sign_with_schnorr", - (message, derivation_path.clone(), key_id.clone()), - ) - .unwrap() - .0 - .unwrap(); + for aux in [None, some_aux.clone()] { + let key_id = SchnorrPublicKeyArgsKeyId { + algorithm: algorithm.clone(), + name: name.to_string(), + }; - // We verify the Schnorr signature. - match key_id.algorithm { - SchnorrAlgorithm::Bip340Secp256K1 => { - use k256::ecdsa::signature::hazmat::PrehashVerifier; - use k256::schnorr::{Signature, VerifyingKey}; - let vk = VerifyingKey::from_bytes(&schnorr_public_key.public_key[1..]).unwrap(); - let sig = Signature::try_from(schnorr_signature.as_slice()).unwrap(); - vk.verify_prehash(message, &sig).unwrap(); - } - SchnorrAlgorithm::Ed25519 => { - use ed25519_dalek::{Signature, Verifier, VerifyingKey}; - let pk: [u8; 32] = schnorr_public_key.public_key.try_into().unwrap(); - let vk = VerifyingKey::from_bytes(&pk).unwrap(); - let signature = Signature::from_slice(&schnorr_signature).unwrap(); - vk.verify(message, &signature).unwrap(); - } - }; + // We get the Schnorr public key and signature via update calls to the test canister. + let schnorr_public_key = update_candid::< + (Option, _, _), + (Result,), + >( + &pic, + canister, + "schnorr_public_key", + (None, derivation_path.clone(), key_id.clone()), + ) + .unwrap() + .0 + .unwrap(); + let schnorr_signature_result = update_candid::<_, (Result, String>,)>( + &pic, + canister, + "sign_with_schnorr", + ( + message, + derivation_path.clone(), + key_id.clone(), + aux.clone(), + ), + ) + .unwrap() + .0; + + // We verify the Schnorr signature. + match key_id.algorithm { + SchnorrAlgorithm::Bip340Secp256K1 => { + use k256::ecdsa::signature::hazmat::PrehashVerifier; + use k256::schnorr::{Signature, VerifyingKey}; + let bip340_public_key = schnorr_public_key.public_key[1..].to_vec(); + let public_key = match aux { + None => bip340_public_key, + Some(SignWithSchnorrAux::Bip341(bip341_aux)) => { + use bitcoin::hashes::Hash; + use bitcoin::schnorr::TapTweak; + let xonly = bitcoin::util::key::XOnlyPublicKey::from_slice( + bip340_public_key.as_slice(), + ) + .unwrap(); + let merkle_root = + bitcoin::util::taproot::TapBranchHash::from_slice( + &bip341_aux.merkle_root_hash, + ) + .unwrap(); + let secp256k1_engine = bitcoin::secp256k1::Secp256k1::new(); + xonly + .tap_tweak(&secp256k1_engine, Some(merkle_root)) + .0 + .to_inner() + .serialize() + .to_vec() + } + }; + let vk = VerifyingKey::from_bytes(&public_key).unwrap(); + let sig = Signature::try_from(schnorr_signature_result.unwrap().as_slice()) + .unwrap(); + + vk.verify_prehash(message, &sig).unwrap(); + } + SchnorrAlgorithm::Ed25519 => { + use ed25519_dalek::{Signature, Verifier, VerifyingKey}; + let pk: [u8; 32] = schnorr_public_key.public_key.try_into().unwrap(); + let vk = VerifyingKey::from_bytes(&pk).unwrap(); + let verification_result = schnorr_signature_result.map(|signature| { + let s = Signature::from_slice(&signature).unwrap(); + vk.verify(message, &s).unwrap(); + }); + assert!( + verification_result.is_ok() == aux.is_none(), + "{:?}", + verification_result + ); + } + }; + } } } } From d7192c042c00a485726ed6643cb593927fd92a35 Mon Sep 17 00:00:00 2001 From: Aleksandr Pakhomov <111274088+pakhomov-dfinity@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:35:08 +0100 Subject: [PATCH 81/98] test: [EXC-1819] Fix flakiness of state_manager_integration_tests (random_canister_input_lsmt) (#3200) The test is flaky since freeing of sandbox threads, commit `4a622c0` (`RUN-1014`), which was modified at `EXC-1681`(`82c76c1`), but not resolved. On top of that `a1e516f` introduced more flakiness. One reason is `StateManager` outliving the `StateMachine` because something holds the `Arc` containing it, yet we remove & recreate tempdir using the same name, ending up with two `StateManagers` accessing the same dir. This is addressed by reordering fields of `StateMachine` to ensure we destruct `StateManager` before the StateDir at `StateMachine::drop` and waiting for the `StateManager` to drop in `StateMachine::into_components`. Another issue is communication with sandbox, it was solved by using fork in `ProptestConfig`. --- rs/state_machine_tests/src/lib.rs | 19 ++++++++++++++++++- rs/state_manager/tests/state_manager.rs | 9 +++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index 87eb8cf6e70..0d5df069cc4 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -1805,7 +1805,7 @@ impl StateMachine { } } - fn into_components(self) -> (Box, u64, Time, u64) { + fn into_components_inner(self) -> (Box, u64, Time, u64) { ( self.state_dir, self.nonce.into_inner(), @@ -1814,6 +1814,23 @@ impl StateMachine { ) } + fn into_components(self) -> (Box, u64, Time, u64) { + let state_manager = Arc::downgrade(&self.state_manager); + let result = self.into_components_inner(); + let mut i = 0i32; + // StateManager is owned by an Arc, that is cloned into multiple components and different + // threads. If we return before all the asynchronous components release the Arc, we may + // end up with to StateManagers writing to the same directory, resulting in a crash. + while state_manager.upgrade().is_some() { + std::thread::sleep(std::time::Duration::from_millis(50)); + i += 1; + if i >= 100 { + panic!("Failed to wait for StateManager drop"); + } + } + result + } + /// Emulates a node restart, including checkpoint recovery. pub fn restart_node(self) -> Self { // We must drop self before setup_form_dir so that we don't have two StateManagers pointing diff --git a/rs/state_manager/tests/state_manager.rs b/rs/state_manager/tests/state_manager.rs index 078e82a6d7f..b82e7b2aceb 100644 --- a/rs/state_manager/tests/state_manager.rs +++ b/rs/state_manager/tests/state_manager.rs @@ -6201,6 +6201,7 @@ fn can_merge_unexpected_number_of_files() { .vmemory_0(); let existing_overlays = pm_layout.existing_overlays().unwrap(); assert_eq!(existing_overlays.len(), NUM_PAGES); // single page per shard + state_manager.flush_tip_channel(); // Copy each shard for heights 1..HEIGHT; now each file is beyond the hard limit, // triggering forced merge for all shards back to one overlay. @@ -7519,8 +7520,12 @@ fn arbitrary_test_canister_op() -> impl Strategy { } proptest! { -// We go for fewer, but longer runs -#![proptest_config(ProptestConfig::with_cases(5))] +#![proptest_config(ProptestConfig { + // Fork to prevent flaky timeouts due to closed sandbox fds + fork: true, + // We go for fewer, but longer runs + ..ProptestConfig::with_cases(5) +})] #[test] fn random_canister_input_lsmt(ops in proptest::collection::vec(arbitrary_test_canister_op(), 1..50)) { From ad6df00098cf25d8df29a469c0a4504979a411c1 Mon Sep 17 00:00:00 2001 From: Igor Novgorodov Date: Tue, 14 Jan 2025 14:18:31 +0100 Subject: [PATCH 82/98] fix: ic-boundary: use numeric ip family in logs (#3437) --- rs/boundary_node/ic_boundary/src/metrics.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rs/boundary_node/ic_boundary/src/metrics.rs b/rs/boundary_node/ic_boundary/src/metrics.rs index d4d363f9788..6b8c1701295 100644 --- a/rs/boundary_node/ic_boundary/src/metrics.rs +++ b/rs/boundary_node/ic_boundary/src/metrics.rs @@ -500,8 +500,17 @@ pub async fn metrics_middleware( let ip_family = request .extensions() .get::>() - .map(|x| x.remote_addr.family()) - .unwrap_or("0"); + .map(|x| { + let f = x.remote_addr.family(); + if f == "v4" { + 4 + } else if f == "v6" { + 6 + } else { + 0 + } + }) + .unwrap_or(0); let remote_addr = request .extensions() From 38a497106eda4577231b1d796b9533ce0921ad12 Mon Sep 17 00:00:00 2001 From: Adam Bratschi-Kaye Date: Tue, 14 Jan 2025 15:38:42 +0100 Subject: [PATCH 83/98] fix(EXC-1834): Ignore empty data segment pages (#3435) EXC-1834 Avoid triggering our critical error alert in the case where a module has empty data segments. --------- Co-authored-by: Venkkatesh Sekar --- rs/embedders/src/wasm_utils.rs | 3 ++ .../tests/execution_test.rs | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/rs/embedders/src/wasm_utils.rs b/rs/embedders/src/wasm_utils.rs index 31e8b4ce0c5..771a5d328f3 100644 --- a/rs/embedders/src/wasm_utils.rs +++ b/rs/embedders/src/wasm_utils.rs @@ -133,6 +133,9 @@ impl Segments { // them into a map page_num -> page. Whenever we map a chunk into its page, // we simply copy its bytes to the right place inside the page. .fold(HashMap::new(), |mut acc, (offset, bytes)| { + if bytes.is_empty() { + return acc; + } let page_num = offset / PAGE_SIZE; let list = acc .entry(PageIndex::new(page_num as u64)) diff --git a/rs/execution_environment/tests/execution_test.rs b/rs/execution_environment/tests/execution_test.rs index 68031280b6f..f8cae43c080 100644 --- a/rs/execution_environment/tests/execution_test.rs +++ b/rs/execution_environment/tests/execution_test.rs @@ -1,5 +1,6 @@ use assert_matches::assert_matches; use candid::Encode; +use canister_test::CanisterInstallMode; use ic_base_types::PrincipalId; use ic_config::{ execution_environment::{Config as HypervisorConfig, DEFAULT_WASM_MEMORY_LIMIT}, @@ -2773,3 +2774,36 @@ fn do_not_initialize_wasm_memory_limit_if_it_is_not_empty() { let wasm_memory_limit = fetch_wasm_memory_limit(&env, canister_id); assert_eq!(wasm_memory_limit, NumBytes::new(10_000_000_000)); } + +/// Even if a Wasm module has inital memory size 0, it is allowed to have data +/// segments of length 0 inserted at address 0. This test checks that such data +/// segments don't trigger any of our critical errors. +#[test] +fn no_critical_error_on_empty_data_segment() { + let env = StateMachine::new(); + let wat: &str = r#" + (module + (memory (;0;) i64 0) + (data (;0;) (i64.const 0) "") + ) + "#; + let _id = env.install_canister_wat(wat, vec![], None); + + // A module with an empty data segment outside of memory should fail to + // install, but not trigger any critical errors. + let wat: &str = r#" + (module + (memory (;0;) i64 0) + (data (;0;) (i64.const 1) "") + ) + "#; + let wasm = wat::parse_str(wat).unwrap(); + let id = env.create_canister(None); + let error = env + .install_wasm_in_mode(id, CanisterInstallMode::Install, wasm, vec![]) + .unwrap_err(); + error.assert_contains( + ErrorCode::CanisterInvalidWasm, + "Wasm module has invalid data segment of 0 bytes at 1.", + ); +} From ba0b355f59df7d7a683b58b5600339c298911480 Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" <189003650+pr-automation-bot-public[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:43:50 +0000 Subject: [PATCH 84/98] chore: Update Mainnet IC revisions subnets file (#3436) Update mainnet revisions file to include the latest version released on the mainnet. This PR is created automatically using [`mainnet_revisions.py`](https://github.com/dfinity/ic/blob/master/ci/src/mainnet_revisions/mainnet_revisions.py) Co-authored-by: CI Automation --- mainnet-subnet-revisions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainnet-subnet-revisions.json b/mainnet-subnet-revisions.json index 02ebe42e34c..2c5e960f9d8 100644 --- a/mainnet-subnet-revisions.json +++ b/mainnet-subnet-revisions.json @@ -1,6 +1,6 @@ { "subnets": { "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe": "43670245ed6919790e7858813c7e838c6fbcedf5", - "io67a-2jmkw-zup3h-snbwi-g6a5n-rm5dn-b6png-lvdpl-nqnto-yih6l-gqe": "43670245ed6919790e7858813c7e838c6fbcedf5" + "io67a-2jmkw-zup3h-snbwi-g6a5n-rm5dn-b6png-lvdpl-nqnto-yih6l-gqe": "aa705aaa621c2e0d4f146f3a1de801edcb0fa0d5" } } \ No newline at end of file From c4739e9ad8a15c78058c1e32a9b29e3c828a4aa6 Mon Sep 17 00:00:00 2001 From: Adam Bratschi-Kaye Date: Tue, 14 Jan 2025 15:51:51 +0100 Subject: [PATCH 85/98] feat(EXC-1800): Use Wasmtime `deserialize_open_file`. (#3412) EXC-1800 When using the on-disk compilation cache, switch to Wasmtime's new `deserialize_open_file` API which allows sandboxes to mmap the existing file so that canister code doesn't take up resident memory in the sandbox. --- rs/embedders/src/wasm_executor.rs | 27 +++++++++++++++--- rs/embedders/src/wasmtime_embedder.rs | 40 ++++++++------------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/rs/embedders/src/wasm_executor.rs b/rs/embedders/src/wasm_executor.rs index ec2de9f11be..e920683064e 100644 --- a/rs/embedders/src/wasm_executor.rs +++ b/rs/embedders/src/wasm_executor.rs @@ -385,6 +385,29 @@ impl WasmExecutorImpl { }) } else { match compilation_cache.get(&wasm_binary.binary) { + Some(Ok(StoredCompilation::Disk(on_disk_serialized_module))) => { + // This path is only used when sandboxing is disabled. + // Otherwise the fd is implicitly duplicated when passed to + // the sandbox process over the unix socket. + let instance_pre = self.wasm_embedder.read_file_and_pre_instantiate( + on_disk_serialized_module + .bytes + .try_clone() + .expect("Unable to duplicate serialzed module file descriptor."), + ); + let cache = EmbedderCache::new(instance_pre.clone()); + *guard = Some(cache.clone()); + match instance_pre { + Ok(_) => Ok(CacheLookup { + cache, + serialized_module: Some(StoredCompilation::Disk( + on_disk_serialized_module, + )), + compilation_result: None, + }), + Err(err) => Err(err), + } + } Some(Ok(StoredCompilation::Memory(serialized_module))) => { let instance_pre = self .wasm_embedder @@ -400,10 +423,6 @@ impl WasmExecutorImpl { Err(err) => Err(err), } } - Some(Ok(StoredCompilation::Disk(_serialized_module))) => { - // TODO(EXC-1780) - panic!("On disk compilation cache not yet supported"); - } Some(Err(err)) => { let cache: HypervisorResult = Err(err.clone()); *guard = Some(EmbedderCache::new(cache)); diff --git a/rs/embedders/src/wasmtime_embedder.rs b/rs/embedders/src/wasmtime_embedder.rs index b9c8dca7577..113ee053de4 100644 --- a/rs/embedders/src/wasmtime_embedder.rs +++ b/rs/embedders/src/wasmtime_embedder.rs @@ -11,8 +11,6 @@ use std::{ convert::TryFrom, fs::File, mem::size_of, - os::fd::{AsRawFd, IntoRawFd}, - os::unix::fs::MetadataExt, sync::{atomic::Ordering, Arc, Mutex}, }; @@ -39,7 +37,6 @@ use ic_types::{ }; use ic_wasm_types::{BinaryEncodedWasm, WasmEngineError}; use memory_tracker::{DirtyPageTracking, PageBitmap, SigsegvMemoryTracker}; -use nix::sys::mman::{mmap, MapFlags, ProtFlags}; use signal_stack::WasmtimeSignalStack; use crate::wasm_utils::instrumentation::{ @@ -336,28 +333,18 @@ impl WasmtimeEmbedder { self.pre_instantiate(&module) } - /// TODO(EXC-1800): Replace this with `wasmtime::Module::deserialize_open_file`. - fn deserialize_from_file(&self, serialized_module: &File) -> HypervisorResult { - let mmap_size = serialized_module.metadata().unwrap().size() as usize; - let mmap_ptr = unsafe { - mmap( - std::ptr::null_mut(), - mmap_size, - ProtFlags::PROT_READ, - MapFlags::MAP_PRIVATE, - serialized_module.as_raw_fd(), - 0, - ) - } - .unwrap_or_else(|err| panic!("Module deserialization failed: {:?}", err)) - as *mut u8; - let bytes = unsafe { std::slice::from_raw_parts(mmap_ptr, mmap_size) }; + fn deserialize_from_file(&self, serialized_module: File) -> HypervisorResult { + // SAFETY: The compilation cache setup guarantees that this file is a + // valid serialized module and will not be modified after initial + // creation. unsafe { - Module::deserialize(&self.create_engine()?, bytes).map_err(|err| { - HypervisorError::WasmEngineError(WasmEngineError::FailedToDeserializeModule( - format!("{:?}", err), - )) - }) + Module::deserialize_open_file(&self.create_engine()?, serialized_module).map_err( + |err| { + HypervisorError::WasmEngineError(WasmEngineError::FailedToDeserializeModule( + format!("{:?}", err), + )) + }, + ) } } @@ -365,10 +352,7 @@ impl WasmtimeEmbedder { &self, serialized_module: File, ) -> HypervisorResult> { - // TODO(EXC-1800): Switch to new wasmtime API and remove leaking the - // file. - let module = self.deserialize_from_file(&serialized_module)?; - let _ = serialized_module.into_raw_fd(); + let module = self.deserialize_from_file(serialized_module)?; self.pre_instantiate(&module) } From f9f2491d302ce74634f487e8971105c81d82ae54 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:16:27 +0100 Subject: [PATCH 86/98] fix: mocked xnet in PocketIC (#3376) This PR fixes an assertion failure in the mocked xnet of PocketIC, reproduced in a new PocketIC test sending 500 inter-canister calls with ~10KB payloads: ``` 2025-01-09T12:14:35.158543Z INFO pocket_ic_server: The PocketIC server is listening on port 43473 thread 'tokio-runtime-worker' panicked at rs/xnet/payload_builder/src/lib.rs:862:25: Slice from 6a7lo-edqtc-nflgn-rbyzy-msh45-ifbmo-xs5bc-p3l2c-my7nk-i47kz-gae has packed byte size 3995437, unpacked byte size 3984588, limit was 3984588 ``` The fix proceeds by reusing the production `XNetSlicePoolImpl` and only mocking the code fetching XNet slices from remote subnets. --- packages/pocket-ic/tests/tests.rs | 32 ++++++ rs/state_machine_tests/src/lib.rs | 123 ++++++++++++----------- rs/xnet/payload_builder/src/lib.rs | 153 +++++++++++++++++------------ 3 files changed, 186 insertions(+), 122 deletions(-) diff --git a/packages/pocket-ic/tests/tests.rs b/packages/pocket-ic/tests/tests.rs index 8b9d39c40d5..196a11777e1 100644 --- a/packages/pocket-ic/tests/tests.rs +++ b/packages/pocket-ic/tests/tests.rs @@ -2171,3 +2171,35 @@ fn await_call_no_ticks() { }; assert_eq!(principal, canister_id.to_string()); } + +#[test] +fn many_intersubnet_calls() { + let pic = PocketIcBuilder::new() + .with_application_subnet() + .with_application_subnet() + .build(); + let canister_1 = pic.create_canister_on_subnet(None, None, pic.topology().get_app_subnets()[0]); + pic.add_cycles(canister_1, 100_000_000_000_000_000); + pic.install_canister(canister_1, test_canister_wasm(), vec![], None); + let canister_2 = pic.create_canister_on_subnet(None, None, pic.topology().get_app_subnets()[1]); + pic.add_cycles(canister_2, 100_000_000_000_000_000); + pic.install_canister(canister_2, test_canister_wasm(), vec![], None); + + let mut msg_ids = vec![]; + let num_msgs: usize = 500; + let msg_size: usize = 10000; + for _ in 0..num_msgs { + let msg_id = pic + .submit_call( + canister_1, + Principal::anonymous(), + "call_with_large_blob", + Encode!(&canister_2, &msg_size).unwrap(), + ) + .unwrap(); + msg_ids.push(msg_id); + } + for msg_id in msg_ids { + pic.await_call(msg_id).unwrap(); + } +} diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index 0d5df069cc4..5031290b05a 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -153,9 +153,8 @@ use ic_types::{ CanisterId, CryptoHashOfState, Cycles, NumBytes, PrincipalId, SubnetId, UserId, }; use ic_xnet_payload_builder::{ - certified_slice_pool::{certified_slice_count_bytes, CertifiedSliceError}, - ExpectedIndices, RefillTaskHandle, XNetPayloadBuilderImpl, XNetPayloadBuilderMetrics, - XNetSlicePool, + certified_slice_pool::CertifiedSlicePool, refill_stream_slice_indices, RefillTaskHandle, + XNetPayloadBuilderImpl, XNetPayloadBuilderMetrics, XNetSlicePoolImpl, }; use rcgen::{CertificateParams, KeyPair}; use serde::Deserialize; @@ -599,72 +598,64 @@ pub trait Subnets: Send + Sync { fn get(&self, subnet_id: SubnetId) -> Option>; } -/// Struct mocking the pool of XNet messages required for -/// instantiating `XNetPayloadBuilderImpl` in `StateMachine`. -struct PocketXNetSlicePoolImpl { - /// Pool of `StateMachine`s from which the XNet messages are fetched. +/// Struct mocking the XNet layer. +struct PocketXNetImpl { + /// Pool of `StateMachine`s from which XNet messages are fetched. subnets: Arc, - /// Subnet ID of the `StateMachine` containing the pool. + /// The certified slice pool of the `StateMachine` for which the XNet layer is mocked. + pool: Arc>, + /// The subnet ID of the `StateMachine` for which the XNet layer is mocked. own_subnet_id: SubnetId, } -impl PocketXNetSlicePoolImpl { - fn new(subnets: Arc, own_subnet_id: SubnetId) -> Self { +impl PocketXNetImpl { + fn new( + subnets: Arc, + pool: Arc>, + own_subnet_id: SubnetId, + ) -> Self { Self { subnets, + pool, own_subnet_id, } } -} -impl XNetSlicePool for PocketXNetSlicePoolImpl { - /// Obtains a certified slice of a stream from a `StateMachine` - /// corresponding to a given subnet ID. - fn take_slice( - &self, - subnet_id: SubnetId, - begin: Option<&ExpectedIndices>, - msg_limit: Option, - byte_limit: Option, - ) -> Result, CertifiedSliceError> { - let sm = self.subnets.get(subnet_id).unwrap(); - let msg_begin = begin.map(|idx| idx.message_index); - // We set `witness_begin` equal to `msg_begin` since all states are certified. - let certified_stream = sm.generate_certified_stream_slice( - self.own_subnet_id, - msg_begin, - msg_begin, - msg_limit, - byte_limit, - ); - Ok(certified_stream - .map(|certified_stream| { - let mut num_bytes = certified_slice_count_bytes(&certified_stream).unwrap(); - // Because `StateMachine::generate_certified_stream_slice` only uses a size estimate - // when constructing a slice (this estimate can be off by at most a few KB), - // we fake the reported slice size if it exceeds the specified size limit to make sure the payload builder will accept the slice as valid and include it into the block. - // This is fine since we don't actually validate the payload in the context of Pocket IC, and so blocks containing - // a XNet slice exceeding the byte limit won't be rejected as invalid. - if let Some(byte_limit) = byte_limit { - if num_bytes > byte_limit { - num_bytes = byte_limit; + fn refill(&self, registry_version: RegistryVersion, log: ReplicaLogger) { + let refill_stream_slice_indices = + refill_stream_slice_indices(self.pool.clone(), self.own_subnet_id); + + for (subnet_id, indices) in refill_stream_slice_indices { + let sm = self.subnets.get(subnet_id).unwrap(); + match sm.generate_certified_stream_slice( + self.own_subnet_id, + Some(indices.witness_begin), + Some(indices.msg_begin), + None, + Some(indices.byte_limit), + ) { + Ok(slice) => { + if indices.witness_begin != indices.msg_begin { + // Pulled a stream suffix, append to pooled slice. + self.pool + .lock() + .unwrap() + .append(subnet_id, slice, registry_version, log.clone()) + .unwrap(); + } else { + // Pulled a complete stream, replace pooled slice (if any). + self.pool + .lock() + .unwrap() + .put(subnet_id, slice, registry_version, log.clone()) + .unwrap(); } } - (certified_stream, num_bytes) - }) - .ok()) + Err(EncodeStreamError::NoStreamForSubnet(_)) => (), + Err(err) => panic!("Unexpected XNetClient error: {}", err), + } + } } - - /// We do not collect any metrics here. - fn observe_pool_size_bytes(&self) {} - - /// We do not cache XNet messages in this mock implementation - /// and thus there is no need for garbage collection. - fn garbage_collect(&self, _new_stream_positions: BTreeMap) {} - - /// We do not cache XNet messages in this mock implementation - /// and thus there is no need for garbage collection. - fn garbage_collect_slice(&self, _subnet_id: SubnetId, _stream_position: ExpectedIndices) {} } /// A custom `QueryStatsPayloadBuilderImpl` that uses a single @@ -825,6 +816,7 @@ pub struct StateMachine { ingress_pool: Arc>, ingress_manager: Arc, pub ingress_filter: Arc>, + pocket_xnet: Arc>>, payload_builder: Arc>>, message_routing: SyncMessageRouting, pub metrics_registry: MetricsRegistry, @@ -1224,7 +1216,12 @@ impl StateMachineBuilder { // Instantiate a `XNetPayloadBuilderImpl`. // We need to use a deterministic PRNG - so we use an arbitrary fixed seed, e.g., 42. let rng = Arc::new(Some(Mutex::new(StdRng::seed_from_u64(42)))); - let xnet_slice_pool_impl = Box::new(PocketXNetSlicePoolImpl::new(subnets, subnet_id)); + let certified_stream_store: Arc = sm.state_manager.clone(); + let certified_slice_pool = Arc::new(Mutex::new(CertifiedSlicePool::new( + certified_stream_store, + &sm.metrics_registry, + ))); + let xnet_slice_pool_impl = Box::new(XNetSlicePoolImpl::new(certified_slice_pool.clone())); let metrics = Arc::new(XNetPayloadBuilderMetrics::new(&sm.metrics_registry)); let xnet_payload_builder = Arc::new(XNetPayloadBuilderImpl::new_from_components( sm.state_manager.clone(), @@ -1262,6 +1259,10 @@ impl StateMachineBuilder { sm.replica_logger.clone(), )); + // Put `PocketXNetImpl` into `StateMachine` + // which contains no `PocketXNetImpl` after creation. + let pocket_xnet_impl = PocketXNetImpl::new(subnets, certified_slice_pool, subnet_id); + *sm.pocket_xnet.write().unwrap() = Some(pocket_xnet_impl); // Instantiate a `PayloadBuilderImpl` and put it into `StateMachine` // which contains no `PayloadBuilderImpl` after creation. *sm.payload_builder.write().unwrap() = Some(PayloadBuilderImpl::new( @@ -1305,6 +1306,7 @@ impl StateMachine { /// because the payload builder contains an `Arc` of this `StateMachine` /// which creates a circular dependency preventing this `StateMachine`s from being dropped. pub fn drop_payload_builder(&self) { + self.pocket_xnet.write().unwrap().take(); self.payload_builder.write().unwrap().take(); } @@ -1349,6 +1351,12 @@ impl StateMachine { membership_version: subnet_record.clone(), context_version: subnet_record, }; + self.pocket_xnet + .read() + .unwrap() + .as_ref() + .unwrap() + .refill(registry_version, self.replica_logger.clone()); let payload_builder = self.payload_builder.read().unwrap(); let payload_builder = payload_builder.as_ref().unwrap(); let batch_payload = payload_builder.get_payload( @@ -1775,6 +1783,7 @@ impl StateMachine { ingress_pool, ingress_manager: ingress_manager.clone(), ingress_filter: Arc::new(Mutex::new(execution_services.ingress_filter)), + pocket_xnet: Arc::new(RwLock::new(None)), // set by `StateMachineBuilder::build_with_subnets` payload_builder: Arc::new(RwLock::new(None)), // set by `StateMachineBuilder::build_with_subnets` ingress_history_reader: execution_services.ingress_history_reader, message_routing, diff --git a/rs/xnet/payload_builder/src/lib.rs b/rs/xnet/payload_builder/src/lib.rs index c54d937a3e6..bbaf916a747 100644 --- a/rs/xnet/payload_builder/src/lib.rs +++ b/rs/xnet/payload_builder/src/lib.rs @@ -1195,6 +1195,85 @@ pub const POOL_SLICE_BYTE_SIZE_MAX: usize = 4 << 20; /// the payload once we're this close to the payload size limit. pub const SLICE_BYTE_SIZE_MIN: usize = 1 << 10; +/// This struct stores stream indices and byte limit used for refilling +/// stream slices of a subnet in a certified slice pool. +pub struct RefillStreamSliceIndices { + pub witness_begin: StreamIndex, + pub msg_begin: StreamIndex, + pub byte_limit: usize, +} + +/// Computes `RefillStreamSliceIndices` for every subnet whose stream slices should be refilled +/// in the given certified slice pool owned by the given subnet. +pub fn refill_stream_slice_indices( + pool_lock: Arc>, + own_subnet_id: SubnetId, +) -> impl Iterator { + let mut result: BTreeMap = BTreeMap::new(); + + let pool_slice_stats = { + let pool = pool_lock.lock().unwrap(); + + if pool.byte_size() > POOL_BYTE_SIZE_SOFT_CAP { + // Abort if pool is already full. + return result.into_iter(); + } + + pool.peers() + // Skip our own subnet, the loopback stream is routed separately. + .filter(|&&subnet_id| subnet_id != own_subnet_id) + .map(|&subnet_id| (subnet_id, pool.slice_stats(subnet_id))) + .collect::>() + }; + + for (subnet_id, slice_stats) in pool_slice_stats { + let (stream_position, messages_begin, msg_count, byte_size) = match slice_stats { + // Have a cached stream position. + (Some(stream_position), messages_begin, msg_count, byte_size) => { + (stream_position, messages_begin, msg_count, byte_size) + } + + // No cached stream position, no pooling / refill necessary. + (None, _, _, _) => continue, + }; + + let (witness_begin, msg_begin, slice_byte_limit) = match messages_begin { + // Existing pooled stream, pull partial slice and append. + Some(messages_begin) if messages_begin == stream_position.message_index => ( + stream_position.message_index, + stream_position.message_index + (msg_count as u64).into(), + POOL_SLICE_BYTE_SIZE_MAX.saturating_sub(byte_size), + ), + + // No pooled stream, or pooled stream does not begin at cached stream position, pull + // complete slice from cached stream position. + _ => ( + stream_position.message_index, + stream_position.message_index, + POOL_SLICE_BYTE_SIZE_MAX, + ), + }; + + if slice_byte_limit < SLICE_BYTE_SIZE_MIN { + // No more space left in the pool for this slice, bail out. + continue; + } + + result.insert( + subnet_id, + RefillStreamSliceIndices { + witness_begin, + msg_begin, + // XNetEndpoint only counts message bytes, allow some overhead (measuread: 350 + // bytes for certification plus base witness, 2% for large payloads). + byte_limit: (slice_byte_limit.saturating_sub(350)) * 98 / 100, + }, + ); + } + + result.into_iter() +} + /// An async task that refills the slice pool. pub struct PoolRefillTask { /// A pool of slices, filled in the background by an async task. @@ -1235,12 +1314,7 @@ impl PoolRefillTask { runtime_handle.spawn(async move { while let Some(registry_version) = refill_receiver.recv().await { - task.refill_pool( - POOL_BYTE_SIZE_SOFT_CAP, - POOL_SLICE_BYTE_SIZE_MAX, - registry_version, - ) - .await; + task.refill_pool(registry_version).await; } }); @@ -1249,68 +1323,17 @@ impl PoolRefillTask { /// Queries all subnets for new slices and puts / appends them to the pool after /// validation against the given registry version. - async fn refill_pool( - &self, - pool_byte_size_soft_cap: usize, - slice_byte_size_max: usize, - registry_version: RegistryVersion, - ) { - let pool_slice_stats = { - let pool = self.pool.lock().unwrap(); - - if pool.byte_size() > pool_byte_size_soft_cap { - // Abort if pool is already full. - return; - } - - pool.peers() - // Skip our own subnet, the loopback stream is routed separately. - .filter(|&&subnet_id| subnet_id != self.endpoint_resolver.subnet_id) - .map(|&subnet_id| (subnet_id, pool.slice_stats(subnet_id))) - .collect::>() - }; - - for (subnet_id, slice_stats) in pool_slice_stats { - let (stream_position, messages_begin, msg_count, byte_size) = match slice_stats { - // Have a cached stream position. - (Some(stream_position), messages_begin, msg_count, byte_size) => { - (stream_position, messages_begin, msg_count, byte_size) - } - - // No cached stream position, no pooling / refill necessary. - (None, _, _, _) => continue, - }; - - let (witness_begin, msg_begin, slice_byte_limit) = match messages_begin { - // Existing pooled stream, pull partial slice and append. - Some(messages_begin) if messages_begin == stream_position.message_index => ( - stream_position.message_index, - stream_position.message_index + (msg_count as u64).into(), - slice_byte_size_max.saturating_sub(byte_size), - ), - - // No pooled stream, or pooled stream does not begin at cached stream position, pull - // complete slice from cached stream position. - _ => ( - stream_position.message_index, - stream_position.message_index, - slice_byte_size_max, - ), - }; - - if slice_byte_limit < SLICE_BYTE_SIZE_MIN { - // No more space left in the pool for this slice, bail out. - continue; - } + async fn refill_pool(&self, registry_version: RegistryVersion) { + let refill_stream_slice_indices = + refill_stream_slice_indices(self.pool.clone(), self.endpoint_resolver.subnet_id); + for (subnet_id, indices) in refill_stream_slice_indices { // `XNetEndpoint` URL of a node on `subnet_id`. let endpoint_locator = match self.endpoint_resolver.xnet_endpoint_url( subnet_id, - witness_begin, - msg_begin, - // XNetEndpoint only counts message bytes, allow some overhead (measuread: 350 - // bytes for certification plus base witness, 2% for large payloads). - (slice_byte_limit.saturating_sub(350)) * 98 / 100, + indices.witness_begin, + indices.msg_begin, + indices.byte_limit, ) { Ok(endpoint_locator) => endpoint_locator, Err(e) => { @@ -1336,7 +1359,7 @@ impl PoolRefillTask { Ok(slice) => { let logger = log.clone(); let res = tokio::task::spawn_blocking(move || { - if witness_begin != msg_begin { + if indices.witness_begin != indices.msg_begin { // Pulled a stream suffix, append to pooled slice. pool.lock() .unwrap() From 56015b7c3cf290bd132d98eb7695a65cbad4232b Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:27:03 +0100 Subject: [PATCH 87/98] feat(governance-tools): Support creating entries in SNS CHANGELOG.md files. (#3416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # How The main difference is that the wording of SNS proposals is different. With these changes, the script can also parse SNS proposal titles. Since the format of SNS titles is similar to those of NNS, this change is straightforward. # References [👈 Previous PR][prev] [prev]: https://github.com/dfinity/ic/pull/3332 --- .../nns-tools/add-release-to-changelog.sh | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/testnet/tools/nns-tools/add-release-to-changelog.sh b/testnet/tools/nns-tools/add-release-to-changelog.sh index e3ca0d7d033..47d94487252 100755 --- a/testnet/tools/nns-tools/add-release-to-changelog.sh +++ b/testnet/tools/nns-tools/add-release-to-changelog.sh @@ -59,13 +59,28 @@ EXECUTED_ON=$( print_purple "Proposal ${PROPOSAL_ID} was executed ${SECONDS_AGO} seconds ago." >&2 # Extract which canister was upgraded, and to what commit. -TITLE=$(echo "${PROPOSAL_INFO}" | jq -r '.proposal[0].summary' | head -n 1) -CANISTER_NAME=$( - echo "${TITLE}" \ - | sed 's/# Upgrade the //' | sed 's/ Canister to Commit .*//' \ - | tr '[:upper:]' '[:lower:]' -) -DESTINATION_COMMIT_ID=$(echo "${TITLE}" | sed 's/# Upgrade the .* Canister to Commit //') +TITLE=$(echo "${PROPOSAL_INFO}" | jq -r '.proposal[0].title[0]') +if grep 'Upgrade the .* Canister to Commit .*' <<<"${TITLE}" &>/dev/null; then + GOVERNANCE_TYPE='NNS' + CANISTER_NAME=$( + echo "${TITLE}" \ + | sed 's/Upgrade the //' | sed 's/ Canister to Commit .*//' \ + | tr '[:upper:]' '[:lower:]' + ) + DESTINATION_COMMIT_ID=$(echo "${TITLE}" | sed 's/Upgrade the .* Canister to Commit //') +elif grep 'Publish SNS .* WASM Built at Commit .*' <<<"${TITLE}" &>/dev/null; then + GOVERNANCE_TYPE='SNS' + CANISTER_NAME=$( + echo "${TITLE}" \ + | sed 's/Publish SNS //' | sed 's/ WASM Built at Commit .*//' \ + | tr '[:upper:]' '[:lower:]' + ) + DESTINATION_COMMIT_ID=$(echo "${TITLE}" | sed 's/Publish SNS .* WASM Built at Commit //') +else + print_red "💀 Unable to parse proposal title: ${TITLE}" >&2 + print_red "(In particular, unable to determine which canister and commit.)" >&2 + exit 1 +fi # Fail if the proposal's commit is not checked out. if [[ $(git rev-parse HEAD) != $DESTINATION_COMMIT_ID* ]]; then @@ -78,7 +93,8 @@ fi # cd to the canister's primary code path. CANISTER_CODE_PATH=$( - get_nns_canister_code_location "${CANISTER_NAME}" \ + get_"$(echo "${GOVERNANCE_TYPE}" | tr '[:upper:]' '[:lower:]')"_canister_code_location \ + "${CANISTER_NAME}" \ | sed "s^${PWD}^.^g" \ | cut -d' ' -f1 ) From e4479ba9d49923759e672ed83e742cd2a371bb61 Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Tue, 14 Jan 2025 17:41:24 +0100 Subject: [PATCH 88/98] chore(IDX): Use repository_ctx.getenv (#3442) This ensures that the repository rule get re-evaluated when the env var changes without having to specify it as a rule input. --- bazel/sanitizers_enabled_env/defs.bzl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bazel/sanitizers_enabled_env/defs.bzl b/bazel/sanitizers_enabled_env/defs.bzl index 091354e0076..a6e65bef9a2 100644 --- a/bazel/sanitizers_enabled_env/defs.bzl +++ b/bazel/sanitizers_enabled_env/defs.bzl @@ -8,7 +8,7 @@ def _impl(repository_ctx): ) repository_ctx.file( "defs.bzl", - content = "SANITIZERS_ENABLED=" + repository_ctx.os.environ.get("SANITIZERS_ENABLED", "0") + "\n", + content = "SANITIZERS_ENABLED=" + repository_ctx.getenv("SANITIZERS_ENABLED", "0") + "\n", executable = False, ) @@ -16,6 +16,5 @@ def sanitizers_enabled_env(name = None): rule = repository_rule( implementation = _impl, local = True, - environ = ["SANITIZERS_ENABLED"], ) rule(name = name) From f72bd1cdb20e307e1c928f951b168cf5940b4801 Mon Sep 17 00:00:00 2001 From: Daniel Wong <97631336+daniel-wong-dfinity-org@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:59:10 +0100 Subject: [PATCH 89/98] feat(governance-tools): Pretty add-release-to-changelog.sh output. (#3417) # More Precisely, What Added a success message. Added emojis. Changed informational messages from purple to cyan. I think dark grey would be best, but we don't (yet) have a function for that; cyan seems like the next best thing. # Why Silence is a highly ambiguous way to communicate. > Explicit is better than implicit. > --Zen of Python --- .../nns-tools/add-release-to-changelog.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/testnet/tools/nns-tools/add-release-to-changelog.sh b/testnet/tools/nns-tools/add-release-to-changelog.sh index 47d94487252..296d6d841bd 100755 --- a/testnet/tools/nns-tools/add-release-to-changelog.sh +++ b/testnet/tools/nns-tools/add-release-to-changelog.sh @@ -25,7 +25,7 @@ cd "$(repo_root)" PWD="$(pwd)" # Fetch the proposal. -print_purple "Fetching proposal ${PROPOSAL_ID}..." >&2 +print_cyan "⏳ Fetching proposal ${PROPOSAL_ID}..." >&2 PROPOSAL_INFO=$( __dfx --quiet \ canister call \ @@ -38,7 +38,7 @@ PROPOSAL_INFO=$( # Unwrap. LEN=$(echo "${PROPOSAL_INFO}" | jq '. | length') if [[ "${LEN}" -ne 1 ]]; then - print_red "Unexpected result from the get_proposal_info method:" >&2 + print_red "💀 Unexpected result from the get_proposal_info method:" >&2 print_red "Should have one element, but has ${LEN}" >&2 exit 1 fi @@ -47,7 +47,7 @@ PROPOSAL_INFO=$(echo "${PROPOSAL_INFO}" | jq '.[0]') # Assert was executed. EXECUTED_TIMESTAMP_SECONDS=$(echo "${PROPOSAL_INFO}" | jq '.executed_timestamp_seconds | tonumber') if [[ "${EXECUTED_TIMESTAMP_SECONDS}" -eq 0 ]]; then - print_red "Proposal ${PROPOSAL_ID} exists, but was not successfully executed." >&2 + print_red "💀 Proposal ${PROPOSAL_ID} exists, but was not successfully executed." >&2 exit 1 fi SECONDS_AGO=$(($(date +%s) - "${EXECUTED_TIMESTAMP_SECONDS}")) @@ -56,7 +56,7 @@ EXECUTED_ON=$( --date=@"${EXECUTED_TIMESTAMP_SECONDS}" \ --iso-8601 ) -print_purple "Proposal ${PROPOSAL_ID} was executed ${SECONDS_AGO} seconds ago." >&2 +print_cyan "🗳️ Proposal ${PROPOSAL_ID} was executed ${SECONDS_AGO} seconds ago." >&2 # Extract which canister was upgraded, and to what commit. TITLE=$(echo "${PROPOSAL_INFO}" | jq -r '.proposal[0].title[0]') @@ -85,7 +85,7 @@ fi # Fail if the proposal's commit is not checked out. if [[ $(git rev-parse HEAD) != $DESTINATION_COMMIT_ID* ]]; then echo >&2 - print_red "You currently have $(git rev-parse HEAD)" >&2 + print_red "💀 You currently have $(git rev-parse HEAD)" >&2 print_red "checked out, but this command only supports being run when" >&2 print_red "the proposal's commit (${DESTINATION_COMMIT_ID}) is checked out." >&2 exit 1 @@ -103,7 +103,7 @@ cd "${CANISTER_CODE_PATH}" # Assert that there is a CHANGELOG.md file. if [[ ! -e CHANGELOG.md ]]; then echo >&2 - print_red "${CANISTER_NAME} has no CHANGELOG.md file." >&2 + print_red "💀 ${CANISTER_NAME} has no CHANGELOG.md file." >&2 exit 1 fi # TODO: Also verify that unreleased_changelog.md exists. @@ -117,7 +117,7 @@ NEW_FEATURES_AND_FIXES=$( ) if [[ -z "${NEW_FEATURES_AND_FIXES}" ]]; then echo >&2 - print_red "The ${CANISTER_NAME} canister has no information in its unreleased_changelog.md." >&2 + print_red "💀 The ${CANISTER_NAME} canister has no information in its unreleased_changelog.md." >&2 exit 1 fi NEW_ENTRY="# ${EXECUTED_ON}: Proposal ${PROPOSAL_ID} @@ -160,3 +160,8 @@ echo -n "${UNRELEASED_CHANGELOG_INTRODUCTION} ## Security """ \ >unreleased_changelog.md + +echo >&2 +print_green '🎉 Success! Added new entry to CHANGELOG.md.' >&2 +print_cyan '💡 Run `git diff` to see the changes. If you are pleased, commit,' >&2 +print_cyan 'push, request review, and merge them into master, per usual.' >&2 From fe42b708759d3d76b543e7ad4699d0136c63e96d Mon Sep 17 00:00:00 2001 From: kpop-dfinity <125868903+kpop-dfinity@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:32:45 +0100 Subject: [PATCH 90/98] test(consensus): modify the test cases in ingress payload serialization/deserialization benchmarks (#3447) Currently we only measure how much it takes to deserialize/serialize ingress payloads with 2000/4000/6000/8000 messages each of size 1KB. With the changes in this PR we will instead measure the following test cases: 1. 1000 messages, 4KB each 2. 2000 messages, 4KB each 3. 1 message, 4MB 4. 1 message, 8MB which resembles more closely the current limits on the ingress payload, from both number of messages and message sizes extremes. Also, in the deserialization benchmark we moved out the `clone()` as it affects the measurements significantly. --- rs/consensus/benches/validate_payload.rs | 58 ++++++++++++++---------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/rs/consensus/benches/validate_payload.rs b/rs/consensus/benches/validate_payload.rs index 00d463268f0..db2b14d1507 100644 --- a/rs/consensus/benches/validate_payload.rs +++ b/rs/consensus/benches/validate_payload.rs @@ -10,7 +10,7 @@ //! in the past payloads, and the user signature is checked eventually, and //! the message validates successfully -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion}; use dkg::DkgDataPayload; use ic_artifact_pool::{consensus_pool::ConsensusPoolImpl, ingress_pool::IngressPoolImpl}; use ic_config::state_manager::Config as StateManagerConfig; @@ -80,7 +80,7 @@ const PAST_PAYLOAD_HEIGHT: u64 = 4; /// Ingress history size: 5 min worth of messages at 1000/sec = 300K. const INGRESS_HISTORY_SIZE: usize = 300_000; -fn run_test(_test_name: &str, test_fn: T) +fn run_test(test_fn: T) where T: FnOnce(Time, &mut ConsensusPoolImpl, &dyn PayloadBuilder), { @@ -233,13 +233,18 @@ fn setup_ingress_state(now: Time, state_manager: &mut StateManagerImpl) { /// Prepares the ingress payload which has 1K x specified number of /// SignedIngress messages. The payload is filled with the specified 'seed' /// bytes -fn prepare_ingress_payload(now: Time, message_count: usize, seed: u8) -> IngressPayload { +fn prepare_ingress_payload( + now: Time, + message_count: usize, + message_size: usize, + seed: u8, +) -> IngressPayload { let mut ingress_msgs = Vec::new(); let expiry = std::time::Duration::from_secs(MAX_INGRESS_TTL.as_secs() - 1); for i in 0..message_count { let ingress = SignedIngressBuilder::new() .method_name("provisional_create_canister_with_cycles") - .method_payload(vec![seed; INGRESS_MESSAGE_SIZE]) + .method_payload(vec![seed; message_size]) .nonce(i as u64) .expiry_time(now + expiry) .canister_id(IC_00) @@ -269,7 +274,7 @@ fn add_past_blocks( for i in 1..=to_add { let mut block = Block::from_parent(&parent); block.rank = Rank(i); - let ingress = prepare_ingress_payload(now, message_count, i as u8); + let ingress = prepare_ingress_payload(now, message_count, INGRESS_MESSAGE_SIZE, i as u8); block.payload = Payload::new( ic_types::crypto::crypto_hash, BlockPayload::Data(DataPayload { @@ -336,7 +341,6 @@ fn validate_payload_benchmark(criterion: &mut Criterion) { for message_count in (50..=850).step_by(50) { run_test( - "validate_payload_benchmark", |now: Time, consensus_pool: &mut ConsensusPoolImpl, payload_builder: &dyn PayloadBuilder| { @@ -344,7 +348,8 @@ fn validate_payload_benchmark(criterion: &mut Criterion) { let pool_reader = PoolReader::new(consensus_pool); let seed = CERTIFIED_HEIGHT + PAST_PAYLOAD_HEIGHT + 10; - let ingress = prepare_ingress_payload(now, message_count, seed as u8); + let ingress = + prepare_ingress_payload(now, message_count, INGRESS_MESSAGE_SIZE, seed as u8); let payload = Payload::new( ic_types::crypto::crypto_hash, BlockPayload::Data(DataPayload { @@ -359,8 +364,7 @@ fn validate_payload_benchmark(criterion: &mut Criterion) { }), ); - let name = format!("validate_payload_{}", message_count); - group.bench_function(&name, |bench| { + group.bench_function(format!("validate_payload_{}", message_count), |bench| { bench.iter(|| { validate_payload(now, &payload, &pool_reader, &tip, payload_builder) .expect("Invalid payload") @@ -372,31 +376,39 @@ fn validate_payload_benchmark(criterion: &mut Criterion) { } fn serialization_benchmark(criterion: &mut Criterion) { - let mut group = criterion.benchmark_group("serialization"); - group.sample_size(30); + let mut group = criterion.benchmark_group("ingress_payload_serialization_deserialization"); + group.sample_size(50); group.measurement_time(std::time::Duration::from_secs(10)); - for message_count in (2000..=8000).step_by(2000) { + for (message_count, message_size_kb, tag) in [ + (1_000, 4_000, "1000x4KB"), + (2_000, 4_000, "2000x4KB"), + (1, 4_000_000, "1x4MB"), + (1, 8_000_000, "1x8MB"), + ] { run_test( - "serialization_benchmark", |now: Time, _: &mut ConsensusPoolImpl, _: &dyn PayloadBuilder| { let seed = CERTIFIED_HEIGHT + PAST_PAYLOAD_HEIGHT + 10; - let ingress = prepare_ingress_payload(now, message_count, seed as u8); - let name = format!("serialization_{}_kb_payload", message_count); - group.bench_function(&name, |bench| { + let ingress = + prepare_ingress_payload(now, message_count, message_size_kb, seed as u8); + + group.bench_function(format!("serialization_{tag}"), |bench| { bench.iter(|| { let proto: pb::IngressPayload = (&ingress).into(); black_box(proto); }) }); - let name = format!("deserialization_{}_kb_payload", message_count); - group.bench_function(&name, |bench| { + + group.bench_function(format!("deserialization_{tag}"), |bench| { let p: pb::IngressPayload = (&ingress).into(); - bench.iter(|| { - let proto = p.clone(); - let deser: IngressPayload = proto.try_into().unwrap(); - black_box(deser); - }) + bench.iter_batched( + || p.clone(), + |proto| { + let deser: IngressPayload = proto.try_into().unwrap(); + black_box(deser); + }, + BatchSize::LargeInput, + ) }); }, ) From 02cba760482130780672553020297cfa0b16cb64 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Tue, 14 Jan 2025 12:00:03 -0600 Subject: [PATCH 91/98] fix(nervous-system-agent): propagate candid encode errors (#3448) Previously we were panicking, even though there was already an error case we could be using to propagate these errors. Pointed out by @aterga --- rs/nervous_system/agent/src/agent_impl.rs | 2 +- rs/nervous_system/agent/src/lib.rs | 6 +++--- rs/nervous_system/agent/src/null_request.rs | 4 ++-- rs/nervous_system/agent/src/pocketic_impl.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rs/nervous_system/agent/src/agent_impl.rs b/rs/nervous_system/agent/src/agent_impl.rs index c70472a01af..586c7c2cbf5 100644 --- a/rs/nervous_system/agent/src/agent_impl.rs +++ b/rs/nervous_system/agent/src/agent_impl.rs @@ -25,7 +25,7 @@ impl CallCanisters for Agent { request: R, ) -> Result { let canister_id = canister_id.into(); - let request_bytes = request.payload(); + let request_bytes = request.payload().map_err(AgentCallError::CandidEncode)?; let response = if request.update() { let request = self .update(&canister_id, request.method()) diff --git a/rs/nervous_system/agent/src/lib.rs b/rs/nervous_system/agent/src/lib.rs index 2308ccd5adb..7bd9d86b2f9 100644 --- a/rs/nervous_system/agent/src/lib.rs +++ b/rs/nervous_system/agent/src/lib.rs @@ -22,7 +22,7 @@ mod sealed { pub trait Request: Send { fn method(&self) -> &'static str; fn update(&self) -> bool; - fn payload(&self) -> Vec; + fn payload(&self) -> Result, candid::Error>; type Response: CandidType + DeserializeOwned; } @@ -33,8 +33,8 @@ impl Request for R { fn update(&self) -> bool { Self::UPDATE } - fn payload(&self) -> Vec { - candid::encode_one(self).unwrap() + fn payload(&self) -> Result, candid::Error> { + candid::encode_one(self) } type Response = ::Response; diff --git a/rs/nervous_system/agent/src/null_request.rs b/rs/nervous_system/agent/src/null_request.rs index 93588d2bbe0..bb288477e8c 100644 --- a/rs/nervous_system/agent/src/null_request.rs +++ b/rs/nervous_system/agent/src/null_request.rs @@ -27,8 +27,8 @@ impl Request for NullRequest { fn update(&self) -> bool { self.update } - fn payload(&self) -> Vec { - Encode!().unwrap() + fn payload(&self) -> Result, candid::Error> { + Encode!() } type Response = T; diff --git a/rs/nervous_system/agent/src/pocketic_impl.rs b/rs/nervous_system/agent/src/pocketic_impl.rs index 44399fffdd6..d9e8b814408 100644 --- a/rs/nervous_system/agent/src/pocketic_impl.rs +++ b/rs/nervous_system/agent/src/pocketic_impl.rs @@ -27,7 +27,7 @@ impl CallCanisters for PocketIc { request: R, ) -> Result { let canister_id = canister_id.into(); - let request_bytes = request.payload(); + let request_bytes = request.payload().map_err(PocketIcCallError::CandidEncode)?; let response = if request.update() { self.update_call( canister_id, From dce918ac820c6f2faba1d28eacf60e1c037a7523 Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Tue, 14 Jan 2025 19:01:41 +0100 Subject: [PATCH 92/98] chore(IDX): bump rules_rust (#3449) This bumps to 0.54.1 which allows us to remove our backported fixes. --- Cargo.Bazel.Fuzzing.json.lock | 576 +++++++++++++++++++--------------- Cargo.Bazel.json.lock | 565 +++++++++++++++++++-------------- WORKSPACE.bazel | 7 +- bazel/rules_rust.patch | 45 --- 4 files changed, 656 insertions(+), 537 deletions(-) delete mode 100644 bazel/rules_rust.patch diff --git a/Cargo.Bazel.Fuzzing.json.lock b/Cargo.Bazel.Fuzzing.json.lock index bcbb23035a8..08fd98a11dc 100644 --- a/Cargo.Bazel.Fuzzing.json.lock +++ b/Cargo.Bazel.Fuzzing.json.lock @@ -1,5 +1,5 @@ { - "checksum": "8fd8fccec5a57eefbac6e6bc61cde6077b347dc896dd713bf649cb70bb4778b1", + "checksum": "befed3db2258ef5e97774c44951feb5c8ca098af84913123d4a8945afeac827c", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -11122,19 +11122,19 @@ "target": "crossterm" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "crossterm 0.27.0", "target": "crossterm" @@ -11268,6 +11268,16 @@ "target": "wasm_bindgen" } ], + "wasm32-wasip1": [ + { + "id": "serde-wasm-bindgen 0.5.0", + "target": "serde_wasm_bindgen" + }, + { + "id": "wasm-bindgen 0.2.95", + "target": "wasm_bindgen" + } + ], "x86_64-apple-darwin": [ { "id": "crossterm 0.27.0", @@ -11280,25 +11290,25 @@ "target": "crossterm" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "crossterm 0.27.0", "target": "crossterm" @@ -11761,12 +11771,6 @@ "target": "iana_time_zone" } ], - "aarch64-fuchsia": [ - { - "id": "iana-time-zone 0.1.59", - "target": "iana_time_zone" - } - ], "aarch64-linux-android": [ { "id": "android-tzdata 0.1.1", @@ -11783,6 +11787,12 @@ "target": "windows_targets" } ], + "aarch64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.59", + "target": "iana_time_zone" + } + ], "aarch64-unknown-linux-gnu": [ { "id": "iana-time-zone 0.1.59", @@ -11891,12 +11901,6 @@ "target": "iana_time_zone" } ], - "x86_64-fuchsia": [ - { - "id": "iana-time-zone 0.1.59", - "target": "iana_time_zone" - } - ], "x86_64-linux-android": [ { "id": "android-tzdata 0.1.1", @@ -11919,6 +11923,12 @@ "target": "iana_time_zone" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.59", + "target": "iana_time_zone" + } + ], "x86_64-unknown-linux-gnu": [ { "id": "iana-time-zone 0.1.59", @@ -15758,7 +15768,7 @@ "target": "signal_hook_mio" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "mio 0.8.10", "target": "mio" @@ -15772,7 +15782,17 @@ "target": "signal_hook_mio" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ + { + "id": "crossterm_winapi 0.9.1", + "target": "crossterm_winapi" + }, + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ], + "aarch64-unknown-fuchsia": [ { "id": "mio 0.8.10", "target": "mio" @@ -15786,16 +15806,6 @@ "target": "signal_hook_mio" } ], - "aarch64-pc-windows-msvc": [ - { - "id": "crossterm_winapi 0.9.1", - "target": "crossterm_winapi" - }, - { - "id": "winapi 0.3.9", - "target": "winapi" - } - ], "aarch64-unknown-linux-gnu": [ { "id": "mio 0.8.10", @@ -16008,7 +16018,7 @@ "target": "signal_hook_mio" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "mio 0.8.10", "target": "mio" @@ -16022,7 +16032,17 @@ "target": "signal_hook_mio" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ + { + "id": "crossterm_winapi 0.9.1", + "target": "crossterm_winapi" + }, + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ], + "x86_64-unknown-freebsd": [ { "id": "mio 0.8.10", "target": "mio" @@ -16036,17 +16056,7 @@ "target": "signal_hook_mio" } ], - "x86_64-pc-windows-msvc": [ - { - "id": "crossterm_winapi 0.9.1", - "target": "crossterm_winapi" - }, - { - "id": "winapi 0.3.9", - "target": "winapi" - } - ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "mio 0.8.10", "target": "mio" @@ -22607,19 +22617,19 @@ "target": "parking" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "parking 2.1.1", "target": "parking" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "parking 2.1.1", "target": "parking" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "parking 2.1.1", "target": "parking" @@ -22739,25 +22749,25 @@ "target": "parking" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "parking 2.1.1", "target": "parking" @@ -22860,19 +22870,19 @@ "target": "parking" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "parking 2.1.1", "target": "parking" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "parking 2.1.1", "target": "parking" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "parking 2.1.1", "target": "parking" @@ -22992,25 +23002,25 @@ "target": "parking" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "parking 2.1.1", "target": "parking" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "parking 2.1.1", "target": "parking" @@ -29105,15 +29115,15 @@ "webpki-roots", "webpki-tokio" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "webpki-roots", "webpki-tokio" ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ "webpki-roots", "webpki-tokio" ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ "webpki-roots", "webpki-tokio" ], @@ -29193,10 +29203,6 @@ "webpki-roots", "webpki-tokio" ], - "x86_64-fuchsia": [ - "webpki-roots", - "webpki-tokio" - ], "x86_64-linux-android": [ "webpki-roots", "webpki-tokio" @@ -29209,6 +29215,10 @@ "webpki-roots", "webpki-tokio" ], + "x86_64-unknown-fuchsia": [ + "webpki-roots", + "webpki-tokio" + ], "x86_64-unknown-linux-gnu": [ "webpki-roots", "webpki-tokio" @@ -29290,19 +29300,19 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" @@ -29422,25 +29432,25 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" @@ -33041,7 +33051,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid 1.5.0": { @@ -33113,7 +33125,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid_transform 1.5.0": { @@ -33189,7 +33203,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid_transform_data 1.5.0": { @@ -33225,7 +33241,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_normalizer 1.5.0": { @@ -33318,7 +33336,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_normalizer_data 1.5.0": { @@ -33354,7 +33374,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_properties 1.5.1": { @@ -33435,7 +33457,9 @@ "version": "1.5.1" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_properties_data 1.5.0": { @@ -33471,7 +33495,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_provider 1.5.0": { @@ -33559,7 +33585,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_provider_macros 1.5.0": { @@ -33612,7 +33640,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "id-arena 2.2.1": { @@ -39107,7 +39137,9 @@ "version": "0.7.3" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "little-loadshedder 0.2.0": { @@ -41709,10 +41741,10 @@ "aarch64-apple-ios-sim": [ "os-ext" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "os-ext" ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ "os-ext" ], "aarch64-unknown-linux-gnu": [ @@ -41757,15 +41789,15 @@ "x86_64-apple-ios": [ "os-ext" ], - "x86_64-fuchsia": [ - "os-ext" - ], "x86_64-linux-android": [ "os-ext" ], "x86_64-unknown-freebsd": [ "os-ext" ], + "x86_64-unknown-fuchsia": [ + "os-ext" + ], "x86_64-unknown-linux-gnu": [ "os-ext" ], @@ -53715,13 +53747,13 @@ "target": "libc" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -53811,19 +53843,19 @@ "target": "libc" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -56068,7 +56100,7 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56098,7 +56130,7 @@ "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56128,7 +56160,7 @@ "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56804,7 +56836,7 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56834,7 +56866,7 @@ "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56864,7 +56896,7 @@ "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -56894,7 +56926,7 @@ "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "async-compression 0.4.4", "target": "async_compression" @@ -57278,7 +57310,7 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -57328,7 +57360,7 @@ "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -57378,7 +57410,7 @@ "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58360,6 +58392,12 @@ "target": "wasm_streams" } ], + "wasm32-wasip1": [ + { + "id": "wasm-streams 0.4.0", + "target": "wasm_streams" + } + ], "x86_64-apple-darwin": [ { "id": "futures-channel 0.3.31", @@ -58460,7 +58498,7 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58510,7 +58548,7 @@ "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58560,7 +58598,7 @@ "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58610,7 +58648,7 @@ "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -60728,7 +60766,7 @@ "time", "use-libc-auxv" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "default", "event", "mm", @@ -60738,7 +60776,7 @@ "time", "use-libc-auxv" ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ "default", "event", "mm", @@ -60914,6 +60952,11 @@ "termios", "use-libc-auxv" ], + "wasm32-wasip1": [ + "default", + "termios", + "use-libc-auxv" + ], "x86_64-apple-darwin": [ "default", "event", @@ -60934,7 +60977,7 @@ "time", "use-libc-auxv" ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ "default", "event", "mm", @@ -60944,7 +60987,7 @@ "time", "use-libc-auxv" ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ "default", "event", "mm", @@ -60954,7 +60997,7 @@ "time", "use-libc-auxv" ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ "default", "event", "mm", @@ -61042,7 +61085,7 @@ "target": "libc" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "errno 0.3.8", "target": "errno", @@ -61053,22 +61096,22 @@ "target": "libc" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "errno 0.3.8", "target": "errno", "alias": "libc_errno" - }, - { - "id": "libc 0.2.158", - "target": "libc" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "errno 0.3.8", "target": "errno", "alias": "libc_errno" + }, + { + "id": "libc 0.2.158", + "target": "libc" } ], "aarch64-unknown-nto-qnx710": [ @@ -61255,7 +61298,7 @@ "target": "libc" } ], - "x86_64-apple-darwin": [ + "wasm32-wasip1": [ { "id": "errno 0.3.8", "target": "errno", @@ -61266,7 +61309,7 @@ "target": "libc" } ], - "x86_64-apple-ios": [ + "x86_64-apple-darwin": [ { "id": "errno 0.3.8", "target": "errno", @@ -61277,7 +61320,7 @@ "target": "libc" } ], - "x86_64-fuchsia": [ + "x86_64-apple-ios": [ { "id": "errno 0.3.8", "target": "errno", @@ -61317,6 +61360,17 @@ "target": "libc" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "errno 0.3.8", + "target": "errno", + "alias": "libc_errno" + }, + { + "id": "libc 0.2.158", + "target": "libc" + } + ], "x86_64-unknown-none": [ { "id": "errno 0.3.8", @@ -67814,15 +67868,15 @@ "aarch64-apple-ios-sim": [ "once" ], - "aarch64-fuchsia": [ - "once" - ], "aarch64-linux-android": [ "once" ], "aarch64-pc-windows-msvc": [ "once" ], + "aarch64-unknown-fuchsia": [ + "once" + ], "aarch64-unknown-linux-gnu": [ "once" ], @@ -67868,9 +67922,6 @@ "x86_64-apple-ios": [ "once" ], - "x86_64-fuchsia": [ - "once" - ], "x86_64-linux-android": [ "once" ], @@ -67880,6 +67931,9 @@ "x86_64-unknown-freebsd": [ "once" ], + "x86_64-unknown-fuchsia": [ + "once" + ], "x86_64-unknown-linux-gnu": [ "once" ], @@ -70030,13 +70084,13 @@ "target": "xattr" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "xattr 0.2.3", "target": "xattr" @@ -70132,19 +70186,19 @@ "target": "xattr" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "xattr 0.2.3", "target": "xattr" @@ -71828,7 +71882,7 @@ "target": "num_threads" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -71838,7 +71892,7 @@ "target": "num_threads" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -71988,7 +72042,7 @@ "target": "num_threads" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -71998,7 +72052,7 @@ "target": "num_threads" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" @@ -72008,7 +72062,7 @@ "target": "num_threads" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -72336,7 +72390,9 @@ "version": "0.7.6" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "tinytemplate 1.2.1": { @@ -72719,7 +72775,7 @@ "target": "socket2" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -72733,7 +72789,17 @@ "target": "socket2" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ + { + "id": "socket2 0.5.7", + "target": "socket2" + }, + { + "id": "windows-sys 0.52.0", + "target": "windows_sys" + } + ], + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -72747,16 +72813,6 @@ "target": "socket2" } ], - "aarch64-pc-windows-msvc": [ - { - "id": "socket2 0.5.7", - "target": "socket2" - }, - { - "id": "windows-sys 0.52.0", - "target": "windows_sys" - } - ], "aarch64-unknown-linux-gnu": [ { "id": "libc 0.2.158", @@ -72993,7 +73049,7 @@ "target": "socket2" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -73007,7 +73063,17 @@ "target": "socket2" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ + { + "id": "socket2 0.5.7", + "target": "socket2" + }, + { + "id": "windows-sys 0.52.0", + "target": "windows_sys" + } + ], + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" @@ -73021,17 +73087,7 @@ "target": "socket2" } ], - "x86_64-pc-windows-msvc": [ - { - "id": "socket2 0.5.7", - "target": "socket2" - }, - { - "id": "windows-sys 0.52.0", - "target": "windows_sys" - } - ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -79939,12 +79995,6 @@ "target": "rustix" } ], - "aarch64-fuchsia": [ - { - "id": "rustix 0.38.32", - "target": "rustix" - } - ], "aarch64-linux-android": [ { "id": "rustix 0.38.32", @@ -79957,6 +80007,12 @@ "target": "windows_sys" } ], + "aarch64-unknown-fuchsia": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], "aarch64-unknown-linux-gnu": [ { "id": "memfd 0.6.4", @@ -80087,12 +80143,6 @@ "target": "rustix" } ], - "x86_64-fuchsia": [ - { - "id": "rustix 0.38.32", - "target": "rustix" - } - ], "x86_64-linux-android": [ { "id": "rustix 0.38.32", @@ -80111,6 +80161,12 @@ "target": "rustix" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], "x86_64-unknown-linux-gnu": [ { "id": "memfd 0.6.4", @@ -84734,7 +84790,9 @@ "version": "0.5.5" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "wsl 0.1.0": { @@ -85397,7 +85455,9 @@ "version": "0.7.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "yoke-derive 0.7.4": { @@ -85454,7 +85514,9 @@ "version": "0.7.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerocopy 0.7.32": { @@ -85620,7 +85682,9 @@ "version": "0.1.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerofrom-derive 0.1.4": { @@ -85677,7 +85741,9 @@ "version": "0.1.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zeroize 1.8.1": { @@ -85855,7 +85921,9 @@ "version": "0.10.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerovec-derive 0.10.3": { @@ -85908,7 +85976,9 @@ "version": "0.10.3" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zstd 0.13.2": { @@ -86166,9 +86236,6 @@ "aarch64-apple-ios-sim": [ "aarch64-apple-ios-sim" ], - "aarch64-fuchsia": [ - "aarch64-fuchsia" - ], "aarch64-linux-android": [ "aarch64-linux-android" ], @@ -86176,6 +86243,9 @@ "aarch64-pc-windows-msvc": [ "aarch64-pc-windows-msvc" ], + "aarch64-unknown-fuchsia": [ + "aarch64-unknown-fuchsia" + ], "aarch64-unknown-linux-gnu": [ "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu" @@ -86218,10 +86288,10 @@ "cfg(all(not(curve25519_dalek_backend = \"fiat\"), not(curve25519_dalek_backend = \"serial\"), target_arch = \"x86_64\"))": [ "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86239,8 +86309,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-nto-qnx710", "armv7-linux-androideabi", "i686-apple-darwin", @@ -86254,11 +86324,12 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-none" ], "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [ @@ -86283,7 +86354,8 @@ "wasm32-unknown-unknown" ], "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\"))": [ - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(all(target_arch = \"wasm32\", target_vendor = \"unknown\", target_os = \"unknown\", target_env = \"\"))": [ "wasm32-unknown-unknown" @@ -86311,8 +86383,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86327,14 +86399,14 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], "cfg(all(unix, not(target_os = \"android\"), not(target_vendor = \"apple\"), not(target_arch = \"wasm32\")))": [ - "aarch64-fuchsia", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86344,16 +86416,16 @@ "i686-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", - "x86_64-fuchsia", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], "cfg(all(unix, not(target_os = \"macos\")))": [ "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86366,9 +86438,9 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86377,9 +86449,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86395,10 +86467,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86407,9 +86479,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86420,10 +86492,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86432,9 +86504,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86445,10 +86517,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86465,17 +86537,17 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" ], "cfg(any(target_arch = \"x86\", target_arch = \"x86_64\", all(any(target_arch = \"aarch64\", target_arch = \"arm\"), any(target_os = \"android\", target_os = \"fuchsia\", target_os = \"linux\"))))": [ - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "arm-unknown-linux-gnueabi", @@ -86488,10 +86560,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86504,10 +86576,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86550,9 +86622,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "arm-unknown-linux-gnueabi", @@ -86566,12 +86638,13 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86625,8 +86698,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86641,9 +86714,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86651,8 +86724,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86667,9 +86740,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86677,8 +86750,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86692,11 +86765,12 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86704,9 +86778,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86722,10 +86796,10 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86734,9 +86808,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86754,12 +86828,13 @@ "s390x-unknown-linux-gnu", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86768,8 +86843,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86788,18 +86863,19 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" ], "cfg(not(any(target_os = \"macos\", target_os = \"ios\", target_os = \"windows\", target_arch = \"wasm32\")))": [ - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86815,9 +86891,9 @@ "s390x-unknown-linux-gnu", "thumbv7em-none-eabi", "thumbv8m.main-none-eabi", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86826,8 +86902,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86846,9 +86922,9 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86857,8 +86933,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86876,11 +86952,12 @@ "thumbv7em-none-eabi", "thumbv8m.main-none-eabi", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86889,9 +86966,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86911,10 +86988,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86923,9 +87000,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86945,10 +87022,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86957,8 +87034,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86977,11 +87054,12 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86990,9 +87068,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -87012,12 +87090,13 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -87027,16 +87106,17 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710" ], "cfg(target_arch = \"wasm32\")": [ "wasm32-unknown-unknown", - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(target_arch = \"x86\")": [ "i686-apple-darwin", @@ -87048,10 +87128,10 @@ "cfg(target_arch = \"x86_64\")": [ "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -87072,8 +87152,8 @@ "cfg(target_os = \"cloudabi\")": [], "cfg(target_os = \"dragonfly\")": [], "cfg(target_os = \"fuchsia\")": [ - "aarch64-fuchsia", - "x86_64-fuchsia" + "aarch64-unknown-fuchsia", + "x86_64-unknown-fuchsia" ], "cfg(target_os = \"haiku\")": [], "cfg(target_os = \"hermit\")": [], @@ -87100,7 +87180,8 @@ ], "cfg(target_os = \"redox\")": [], "cfg(target_os = \"wasi\")": [ - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(target_os = \"windows\")": [ "aarch64-pc-windows-msvc", @@ -87112,8 +87193,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -87128,9 +87209,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -87182,15 +87263,15 @@ "wasm32-wasi": [ "wasm32-wasi" ], + "wasm32-wasip1": [ + "wasm32-wasip1" + ], "x86_64-apple-darwin": [ "x86_64-apple-darwin" ], "x86_64-apple-ios": [ "x86_64-apple-ios" ], - "x86_64-fuchsia": [ - "x86_64-fuchsia" - ], "x86_64-linux-android": [ "x86_64-linux-android" ], @@ -87202,6 +87283,9 @@ "x86_64-unknown-freebsd": [ "x86_64-unknown-freebsd" ], + "x86_64-unknown-fuchsia": [ + "x86_64-unknown-fuchsia" + ], "x86_64-unknown-linux-gnu": [ "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" diff --git a/Cargo.Bazel.json.lock b/Cargo.Bazel.json.lock index d5c0c188242..b5e8dae02b1 100644 --- a/Cargo.Bazel.json.lock +++ b/Cargo.Bazel.json.lock @@ -1,5 +1,5 @@ { - "checksum": "194342fc37fdddbf3dceb1e96cdf4ce10a63ff4ec17867d1a241e3e034c1ad0c", + "checksum": "16c350a57ca08666035e4f0e31f17c9715860d84ed6755b026870a84de503a09", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -11018,19 +11018,19 @@ "target": "crossterm" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "crossterm 0.27.0", "target": "crossterm" @@ -11164,6 +11164,16 @@ "target": "wasm_bindgen" } ], + "wasm32-wasip1": [ + { + "id": "serde-wasm-bindgen 0.5.0", + "target": "serde_wasm_bindgen" + }, + { + "id": "wasm-bindgen 0.2.95", + "target": "wasm_bindgen" + } + ], "x86_64-apple-darwin": [ { "id": "crossterm 0.27.0", @@ -11176,25 +11186,25 @@ "target": "crossterm" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "crossterm 0.27.0", "target": "crossterm" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "crossterm 0.27.0", "target": "crossterm" @@ -11657,12 +11667,6 @@ "target": "iana_time_zone" } ], - "aarch64-fuchsia": [ - { - "id": "iana-time-zone 0.1.59", - "target": "iana_time_zone" - } - ], "aarch64-linux-android": [ { "id": "android-tzdata 0.1.1", @@ -11679,6 +11683,12 @@ "target": "windows_targets" } ], + "aarch64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.59", + "target": "iana_time_zone" + } + ], "aarch64-unknown-linux-gnu": [ { "id": "iana-time-zone 0.1.59", @@ -11787,12 +11797,6 @@ "target": "iana_time_zone" } ], - "x86_64-fuchsia": [ - { - "id": "iana-time-zone 0.1.59", - "target": "iana_time_zone" - } - ], "x86_64-linux-android": [ { "id": "android-tzdata 0.1.1", @@ -11815,6 +11819,12 @@ "target": "iana_time_zone" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.59", + "target": "iana_time_zone" + } + ], "x86_64-unknown-linux-gnu": [ { "id": "iana-time-zone 0.1.59", @@ -15586,7 +15596,7 @@ "target": "signal_hook_mio" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "mio 0.8.10", "target": "mio" @@ -15600,7 +15610,17 @@ "target": "signal_hook_mio" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ + { + "id": "crossterm_winapi 0.9.1", + "target": "crossterm_winapi" + }, + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ], + "aarch64-unknown-fuchsia": [ { "id": "mio 0.8.10", "target": "mio" @@ -15614,16 +15634,6 @@ "target": "signal_hook_mio" } ], - "aarch64-pc-windows-msvc": [ - { - "id": "crossterm_winapi 0.9.1", - "target": "crossterm_winapi" - }, - { - "id": "winapi 0.3.9", - "target": "winapi" - } - ], "aarch64-unknown-linux-gnu": [ { "id": "mio 0.8.10", @@ -15836,7 +15846,7 @@ "target": "signal_hook_mio" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "mio 0.8.10", "target": "mio" @@ -15850,7 +15860,17 @@ "target": "signal_hook_mio" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ + { + "id": "crossterm_winapi 0.9.1", + "target": "crossterm_winapi" + }, + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ], + "x86_64-unknown-freebsd": [ { "id": "mio 0.8.10", "target": "mio" @@ -15864,17 +15884,7 @@ "target": "signal_hook_mio" } ], - "x86_64-pc-windows-msvc": [ - { - "id": "crossterm_winapi 0.9.1", - "target": "crossterm_winapi" - }, - { - "id": "winapi 0.3.9", - "target": "winapi" - } - ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "mio 0.8.10", "target": "mio" @@ -22458,19 +22468,19 @@ "target": "parking" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "parking 2.1.0", "target": "parking" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "parking 2.1.0", "target": "parking" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "parking 2.1.0", "target": "parking" @@ -22590,25 +22600,25 @@ "target": "parking" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "parking 2.1.0", "target": "parking" @@ -22711,19 +22721,19 @@ "target": "parking" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "parking 2.1.0", "target": "parking" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "parking 2.1.0", "target": "parking" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "parking 2.1.0", "target": "parking" @@ -22843,25 +22853,25 @@ "target": "parking" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "parking 2.1.0", "target": "parking" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "parking 2.1.0", "target": "parking" @@ -28960,15 +28970,15 @@ "webpki-roots", "webpki-tokio" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "webpki-roots", "webpki-tokio" ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ "webpki-roots", "webpki-tokio" ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ "webpki-roots", "webpki-tokio" ], @@ -29048,10 +29058,6 @@ "webpki-roots", "webpki-tokio" ], - "x86_64-fuchsia": [ - "webpki-roots", - "webpki-tokio" - ], "x86_64-linux-android": [ "webpki-roots", "webpki-tokio" @@ -29064,6 +29070,10 @@ "webpki-roots", "webpki-tokio" ], + "x86_64-unknown-fuchsia": [ + "webpki-roots", + "webpki-tokio" + ], "x86_64-unknown-linux-gnu": [ "webpki-roots", "webpki-tokio" @@ -29145,19 +29155,19 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" @@ -29277,25 +29287,25 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "webpki-roots 0.26.1", "target": "webpki_roots" @@ -32875,7 +32885,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid 1.5.0": { @@ -32947,7 +32959,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid_transform 1.5.0": { @@ -33023,7 +33037,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_locid_transform_data 1.5.0": { @@ -33059,7 +33075,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_normalizer 1.5.0": { @@ -33152,7 +33170,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_normalizer_data 1.5.0": { @@ -33188,7 +33208,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_properties 1.5.1": { @@ -33269,7 +33291,9 @@ "version": "1.5.1" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_properties_data 1.5.0": { @@ -33305,7 +33329,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_provider 1.5.0": { @@ -33393,7 +33419,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "icu_provider_macros 1.5.0": { @@ -33446,7 +33474,9 @@ "version": "1.5.0" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "id-arena 2.2.1": { @@ -38944,7 +38974,9 @@ "version": "0.7.3" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "little-loadshedder 0.2.0": { @@ -41549,10 +41581,10 @@ "aarch64-apple-ios-sim": [ "os-ext" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "os-ext" ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ "os-ext" ], "aarch64-unknown-linux-gnu": [ @@ -41597,15 +41629,15 @@ "x86_64-apple-ios": [ "os-ext" ], - "x86_64-fuchsia": [ - "os-ext" - ], "x86_64-linux-android": [ "os-ext" ], "x86_64-unknown-freebsd": [ "os-ext" ], + "x86_64-unknown-fuchsia": [ + "os-ext" + ], "x86_64-unknown-linux-gnu": [ "os-ext" ], @@ -53517,13 +53549,13 @@ "target": "libc" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -53613,19 +53645,19 @@ "target": "libc" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -55914,7 +55946,7 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -55944,7 +55976,7 @@ "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -55974,7 +56006,7 @@ "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -56650,7 +56682,7 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -56680,7 +56712,7 @@ "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -56710,7 +56742,7 @@ "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -56740,7 +56772,7 @@ "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "async-compression 0.4.3", "target": "async_compression" @@ -57124,7 +57156,7 @@ "target": "webpki_roots" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -57174,7 +57206,7 @@ "target": "webpki_roots" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -57224,7 +57256,7 @@ "target": "webpki_roots" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58206,6 +58238,12 @@ "target": "wasm_streams" } ], + "wasm32-wasip1": [ + { + "id": "wasm-streams 0.4.0", + "target": "wasm_streams" + } + ], "x86_64-apple-darwin": [ { "id": "futures-channel 0.3.31", @@ -58306,7 +58344,7 @@ "target": "webpki_roots" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58356,7 +58394,7 @@ "target": "webpki_roots" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58406,7 +58444,7 @@ "target": "webpki_roots" } ], - "x86_64-pc-windows-msvc": [ + "x86_64-unknown-freebsd": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -58456,7 +58494,7 @@ "target": "webpki_roots" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "futures-channel 0.3.31", "target": "futures_channel" @@ -60574,7 +60612,7 @@ "time", "use-libc-auxv" ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ "default", "event", "mm", @@ -60584,7 +60622,7 @@ "time", "use-libc-auxv" ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ "default", "event", "mm", @@ -60760,6 +60798,11 @@ "termios", "use-libc-auxv" ], + "wasm32-wasip1": [ + "default", + "termios", + "use-libc-auxv" + ], "x86_64-apple-darwin": [ "default", "event", @@ -60780,7 +60823,7 @@ "time", "use-libc-auxv" ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ "default", "event", "mm", @@ -60790,7 +60833,7 @@ "time", "use-libc-auxv" ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ "default", "event", "mm", @@ -60800,7 +60843,7 @@ "time", "use-libc-auxv" ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ "default", "event", "mm", @@ -60888,7 +60931,7 @@ "target": "libc" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "errno 0.3.8", "target": "errno", @@ -60899,22 +60942,22 @@ "target": "libc" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ { "id": "errno 0.3.8", "target": "errno", "alias": "libc_errno" - }, - { - "id": "libc 0.2.158", - "target": "libc" } ], - "aarch64-pc-windows-msvc": [ + "aarch64-unknown-fuchsia": [ { "id": "errno 0.3.8", "target": "errno", "alias": "libc_errno" + }, + { + "id": "libc 0.2.158", + "target": "libc" } ], "aarch64-unknown-nto-qnx710": [ @@ -61101,7 +61144,7 @@ "target": "libc" } ], - "x86_64-apple-darwin": [ + "wasm32-wasip1": [ { "id": "errno 0.3.8", "target": "errno", @@ -61112,7 +61155,7 @@ "target": "libc" } ], - "x86_64-apple-ios": [ + "x86_64-apple-darwin": [ { "id": "errno 0.3.8", "target": "errno", @@ -61123,7 +61166,7 @@ "target": "libc" } ], - "x86_64-fuchsia": [ + "x86_64-apple-ios": [ { "id": "errno 0.3.8", "target": "errno", @@ -61163,6 +61206,17 @@ "target": "libc" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "errno 0.3.8", + "target": "errno", + "alias": "libc_errno" + }, + { + "id": "libc 0.2.158", + "target": "libc" + } + ], "x86_64-unknown-none": [ { "id": "errno 0.3.8", @@ -67660,15 +67714,15 @@ "aarch64-apple-ios-sim": [ "once" ], - "aarch64-fuchsia": [ - "once" - ], "aarch64-linux-android": [ "once" ], "aarch64-pc-windows-msvc": [ "once" ], + "aarch64-unknown-fuchsia": [ + "once" + ], "aarch64-unknown-linux-gnu": [ "once" ], @@ -67714,9 +67768,6 @@ "x86_64-apple-ios": [ "once" ], - "x86_64-fuchsia": [ - "once" - ], "x86_64-linux-android": [ "once" ], @@ -67726,6 +67777,9 @@ "x86_64-unknown-freebsd": [ "once" ], + "x86_64-unknown-fuchsia": [ + "once" + ], "x86_64-unknown-linux-gnu": [ "once" ], @@ -69876,13 +69930,13 @@ "target": "xattr" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "xattr 0.2.3", "target": "xattr" @@ -69978,19 +70032,19 @@ "target": "xattr" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "xattr 0.2.3", "target": "xattr" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "xattr 0.2.3", "target": "xattr" @@ -71674,7 +71728,7 @@ "target": "num_threads" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -71684,7 +71738,7 @@ "target": "num_threads" } ], - "aarch64-linux-android": [ + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -71834,7 +71888,7 @@ "target": "num_threads" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -71844,7 +71898,7 @@ "target": "num_threads" } ], - "x86_64-linux-android": [ + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" @@ -71854,7 +71908,7 @@ "target": "num_threads" } ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -72182,7 +72236,9 @@ "version": "0.7.6" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "tinytemplate 1.2.1": { @@ -72565,7 +72621,7 @@ "target": "socket2" } ], - "aarch64-fuchsia": [ + "aarch64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -72579,7 +72635,17 @@ "target": "socket2" } ], - "aarch64-linux-android": [ + "aarch64-pc-windows-msvc": [ + { + "id": "socket2 0.5.7", + "target": "socket2" + }, + { + "id": "windows-sys 0.52.0", + "target": "windows_sys" + } + ], + "aarch64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -72593,16 +72659,6 @@ "target": "socket2" } ], - "aarch64-pc-windows-msvc": [ - { - "id": "socket2 0.5.7", - "target": "socket2" - }, - { - "id": "windows-sys 0.52.0", - "target": "windows_sys" - } - ], "aarch64-unknown-linux-gnu": [ { "id": "libc 0.2.158", @@ -72839,7 +72895,7 @@ "target": "socket2" } ], - "x86_64-fuchsia": [ + "x86_64-linux-android": [ { "id": "libc 0.2.158", "target": "libc" @@ -72853,7 +72909,17 @@ "target": "socket2" } ], - "x86_64-linux-android": [ + "x86_64-pc-windows-msvc": [ + { + "id": "socket2 0.5.7", + "target": "socket2" + }, + { + "id": "windows-sys 0.52.0", + "target": "windows_sys" + } + ], + "x86_64-unknown-freebsd": [ { "id": "libc 0.2.158", "target": "libc" @@ -72867,17 +72933,7 @@ "target": "socket2" } ], - "x86_64-pc-windows-msvc": [ - { - "id": "socket2 0.5.7", - "target": "socket2" - }, - { - "id": "windows-sys 0.52.0", - "target": "windows_sys" - } - ], - "x86_64-unknown-freebsd": [ + "x86_64-unknown-fuchsia": [ { "id": "libc 0.2.158", "target": "libc" @@ -79785,12 +79841,6 @@ "target": "rustix" } ], - "aarch64-fuchsia": [ - { - "id": "rustix 0.38.32", - "target": "rustix" - } - ], "aarch64-linux-android": [ { "id": "rustix 0.38.32", @@ -79803,6 +79853,12 @@ "target": "windows_sys" } ], + "aarch64-unknown-fuchsia": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], "aarch64-unknown-linux-gnu": [ { "id": "memfd 0.6.4", @@ -79933,12 +79989,6 @@ "target": "rustix" } ], - "x86_64-fuchsia": [ - { - "id": "rustix 0.38.32", - "target": "rustix" - } - ], "x86_64-linux-android": [ { "id": "rustix 0.38.32", @@ -79957,6 +80007,12 @@ "target": "rustix" } ], + "x86_64-unknown-fuchsia": [ + { + "id": "rustix 0.38.32", + "target": "rustix" + } + ], "x86_64-unknown-linux-gnu": [ { "id": "memfd 0.6.4", @@ -84554,7 +84610,9 @@ "version": "0.5.5" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "wsl 0.1.0": { @@ -85217,7 +85275,9 @@ "version": "0.7.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "yoke-derive 0.7.4": { @@ -85274,7 +85334,9 @@ "version": "0.7.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerocopy 0.7.32": { @@ -85440,7 +85502,9 @@ "version": "0.1.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerofrom-derive 0.1.4": { @@ -85497,7 +85561,9 @@ "version": "0.1.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zeroize 1.8.1": { @@ -85675,7 +85741,9 @@ "version": "0.10.4" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zerovec-derive 0.10.3": { @@ -85728,7 +85796,9 @@ "version": "0.10.3" }, "license": "Unicode-3.0", - "license_ids": [], + "license_ids": [ + "Unicode-3.0" + ], "license_file": "LICENSE" }, "zstd 0.12.4": { @@ -86124,9 +86194,6 @@ "aarch64-apple-ios-sim": [ "aarch64-apple-ios-sim" ], - "aarch64-fuchsia": [ - "aarch64-fuchsia" - ], "aarch64-linux-android": [ "aarch64-linux-android" ], @@ -86134,6 +86201,9 @@ "aarch64-pc-windows-msvc": [ "aarch64-pc-windows-msvc" ], + "aarch64-unknown-fuchsia": [ + "aarch64-unknown-fuchsia" + ], "aarch64-unknown-linux-gnu": [ "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu" @@ -86176,10 +86246,10 @@ "cfg(all(not(curve25519_dalek_backend = \"fiat\"), not(curve25519_dalek_backend = \"serial\"), target_arch = \"x86_64\"))": [ "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86197,8 +86267,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-nto-qnx710", "armv7-linux-androideabi", "i686-apple-darwin", @@ -86212,11 +86282,12 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-none" ], "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [ @@ -86241,7 +86312,8 @@ "wasm32-unknown-unknown" ], "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\"))": [ - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(all(target_arch = \"wasm32\", target_vendor = \"unknown\", target_os = \"unknown\", target_env = \"\"))": [ "wasm32-unknown-unknown" @@ -86269,8 +86341,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86285,14 +86357,14 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], "cfg(all(unix, not(target_os = \"android\"), not(target_vendor = \"apple\"), not(target_arch = \"wasm32\")))": [ - "aarch64-fuchsia", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86302,16 +86374,16 @@ "i686-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", - "x86_64-fuchsia", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], "cfg(all(unix, not(target_os = \"macos\")))": [ "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86324,9 +86396,9 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86335,9 +86407,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86353,10 +86425,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86365,9 +86437,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86378,10 +86450,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86390,9 +86462,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86403,10 +86475,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86416,8 +86488,8 @@ "s390x-unknown-linux-gnu" ], "cfg(any(target_arch = \"x86\", target_arch = \"x86_64\", all(any(target_arch = \"aarch64\", target_arch = \"arm\"), any(target_os = \"android\", target_os = \"fuchsia\", target_os = \"linux\"))))": [ - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "arm-unknown-linux-gnueabi", @@ -86430,10 +86502,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86446,10 +86518,10 @@ "i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86492,9 +86564,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "arm-unknown-linux-gnueabi", @@ -86508,12 +86580,13 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86567,8 +86640,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86583,9 +86656,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86593,8 +86666,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86609,9 +86682,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86619,8 +86692,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86634,11 +86707,12 @@ "powerpc-unknown-linux-gnu", "s390x-unknown-linux-gnu", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -86647,9 +86721,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86667,19 +86741,20 @@ "s390x-unknown-linux-gnu", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" ], "cfg(not(any(target_os = \"macos\", target_os = \"ios\", target_os = \"windows\", target_arch = \"wasm32\")))": [ - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86695,9 +86770,9 @@ "s390x-unknown-linux-gnu", "thumbv7em-none-eabi", "thumbv8m.main-none-eabi", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86706,8 +86781,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86726,9 +86801,9 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86737,8 +86812,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86756,11 +86831,12 @@ "thumbv7em-none-eabi", "thumbv8m.main-none-eabi", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86769,9 +86845,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86791,10 +86867,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86803,9 +86879,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86825,10 +86901,10 @@ "thumbv8m.main-none-eabi", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86837,8 +86913,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86857,11 +86933,12 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86870,9 +86947,9 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -86892,12 +86969,13 @@ "thumbv8m.main-none-eabi", "wasm32-unknown-unknown", "wasm32-wasi", + "wasm32-wasip1", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86907,16 +86985,17 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710" ], "cfg(target_arch = \"wasm32\")": [ "wasm32-unknown-unknown", - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(target_arch = \"x86\")": [ "i686-apple-darwin", @@ -86928,10 +87007,10 @@ "cfg(target_arch = \"x86_64\")": [ "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu", "x86_64-unknown-none" @@ -86952,8 +87031,8 @@ "cfg(target_os = \"cloudabi\")": [], "cfg(target_os = \"dragonfly\")": [], "cfg(target_os = \"fuchsia\")": [ - "aarch64-fuchsia", - "x86_64-fuchsia" + "aarch64-unknown-fuchsia", + "x86_64-unknown-fuchsia" ], "cfg(target_os = \"haiku\")": [], "cfg(target_os = \"hermit\")": [], @@ -86980,7 +87059,8 @@ ], "cfg(target_os = \"redox\")": [], "cfg(target_os = \"wasi\")": [ - "wasm32-wasi" + "wasm32-wasi", + "wasm32-wasip1" ], "cfg(target_os = \"windows\")": [ "aarch64-pc-windows-msvc", @@ -86992,8 +87072,8 @@ "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", - "aarch64-fuchsia", "aarch64-linux-android", + "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-nixos-gnu", "aarch64-unknown-nto-qnx710", @@ -87008,9 +87088,9 @@ "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-apple-ios", - "x86_64-fuchsia", "x86_64-linux-android", "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" ], @@ -87062,15 +87142,15 @@ "wasm32-wasi": [ "wasm32-wasi" ], + "wasm32-wasip1": [ + "wasm32-wasip1" + ], "x86_64-apple-darwin": [ "x86_64-apple-darwin" ], "x86_64-apple-ios": [ "x86_64-apple-ios" ], - "x86_64-fuchsia": [ - "x86_64-fuchsia" - ], "x86_64-linux-android": [ "x86_64-linux-android" ], @@ -87082,6 +87162,9 @@ "x86_64-unknown-freebsd": [ "x86_64-unknown-freebsd" ], + "x86_64-unknown-fuchsia": [ + "x86_64-unknown-fuchsia" + ], "x86_64-unknown-linux-gnu": [ "x86_64-unknown-linux-gnu", "x86_64-unknown-nixos-gnu" diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 09c62d8bd34..10c29ef4de2 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -96,11 +96,8 @@ sol_register_toolchains( http_archive( name = "rules_rust", - # Back-ported fix: https://github.com/bazelbuild/rules_rust/pull/2981 - patch_args = ["-p1"], - patches = ["//bazel:rules_rust.patch"], - sha256 = "85e2013727ab26fb22abdffe4b2ac0c27a2d5b6296167ba63d8f6e13140f51f9", - urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.53.0/rules_rust-v0.53.0.tar.gz"], + sha256 = "af4f56caae50a99a68bfce39b141b509dd68548c8204b98ab7a1cafc94d5bb02", + urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.54.1/rules_rust-v0.54.1.tar.gz"], ) load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains") diff --git a/bazel/rules_rust.patch b/bazel/rules_rust.patch deleted file mode 100644 index d9252428a0b..00000000000 --- a/bazel/rules_rust.patch +++ /dev/null @@ -1,45 +0,0 @@ -# Backports for https://github.com/bazelbuild/rules_rust/issues/2974 and https://github.com/bazelbuild/rules_rust/pull/2981 -diff --git a/cargo/cargo_build_script_runner/bin.rs b/cargo/cargo_build_script_runner/bin.rs -index 2dab3578..b5bb4fca 100644 ---- a/cargo/cargo_build_script_runner/bin.rs -+++ b/cargo/cargo_build_script_runner/bin.rs -@@ -187,9 +187,9 @@ fn run_buildrs() -> Result<(), String> { - .as_bytes(), - ) - .unwrap_or_else(|_| panic!("Unable to write file {:?}", output_dep_env_path)); -- write(&stdout_path, process_output.stdout) -+ write(&stdout_path, "") - .unwrap_or_else(|_| panic!("Unable to write file {:?}", stdout_path)); -- write(&stderr_path, process_output.stderr) -+ write(&stderr_path, "") - .unwrap_or_else(|_| panic!("Unable to write file {:?}", stderr_path)); - - let CompileAndLinkFlags { -diff --git a/crate_universe/private/crate.bzl b/crate_universe/private/crate.bzl -index c493e9a6..ad317abf 100644 ---- a/crate_universe/private/crate.bzl -+++ b/crate_universe/private/crate.bzl -@@ -230,7 +230,22 @@ def _stringify_label(value): - def _stringify_list(values): - if not values: - return values -- return [str(x) for x in values] -+ -+ if type(values) == "list": -+ return [str(x) for x in values] -+ -+ -+ -+ -+ if type(values) == "struct" and type(values.selects) != "NoneType": -+ new_selects = {} -+ -+ for k, v in values.selects.items(): -+ new_selects[k] = [str(x) for x in values.selects[k]] -+ -+ return struct(common = [str(x) for x in values.common], selects = new_selects) -+ -+ fail("Cannot stringify unknown type for list '{}'".format(values)) - - def _select(common, selects): - """A Starlark Select for `crate.annotation()`. From 323b72f6ffc201b04f28b49d037fa3b10f13149f Mon Sep 17 00:00:00 2001 From: Andriy Berestovskyy Date: Tue, 14 Jan 2025 19:58:42 +0100 Subject: [PATCH 93/98] chore: EXC-1818: Run all benchmarks faster (#3357) This change avoids unnecessary benchmark repetitions when performance remains unchanged compared to the baseline. It also reduces the number of repetitions from 9 to 3. --- rs/execution_environment/benches/run-all-benchmarks.sh | 7 ++++++- rs/execution_environment/benches/summarize-results.sh | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rs/execution_environment/benches/run-all-benchmarks.sh b/rs/execution_environment/benches/run-all-benchmarks.sh index 3e72b0c219d..e13cb38258d 100755 --- a/rs/execution_environment/benches/run-all-benchmarks.sh +++ b/rs/execution_environment/benches/run-all-benchmarks.sh @@ -11,7 +11,7 @@ set -ue ## printf "%-12s := %s\n" \ - "REPEAT" "${REPEAT:=9}" >&2 + "REPEAT" "${REPEAT:=3}" >&2 RUN_BENCHMARK="${0%/*}/run-benchmark.sh" [ -x "${RUN_BENCHMARK}" ] || (echo "Error accessing script: ${RUN_BENCHMARK}" >&2 && exit 1) @@ -39,7 +39,12 @@ run() { # Summarize results if the benchmark was executed or if it's the final iteration. if [ "${counter}" -lt "${i}" -o "${i}" = "${REPEAT}" ]; then echo "==> Summarizing ${name} results:" >&2 + set +e NAME="${name}" MIN_FILE="${min_file}" "${SUMMARIZE_RESULTS}" + local ret="${?}" + set -e + # Stop repeating the benchmark if there are no changes. + [ "${ret}" -eq 0 ] && echo "${REPEAT}" >"${counter_file}" fi } diff --git a/rs/execution_environment/benches/summarize-results.sh b/rs/execution_environment/benches/summarize-results.sh index 8e94a73e1dc..cbd7fb5c20e 100755 --- a/rs/execution_environment/benches/summarize-results.sh +++ b/rs/execution_environment/benches/summarize-results.sh @@ -71,4 +71,7 @@ if [ "${total_diff}" != "0" ]; then echo " - ${name} time improved by ${diff}%" done fi -# rm -f "${TMP_FILE}" +rm -f "${TMP_FILE}" + +# Return an error is there are changes, so the calling script might retry or report an error. +[ "${total_diff}" != "0" ] From 572afbcdbf9507406742007d10f55b8173e4cfa9 Mon Sep 17 00:00:00 2001 From: Andrew Battat <113942931+andrewbattat@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:06:32 -0600 Subject: [PATCH 94/98] feat(node): add fstrim datadir observability (#3322) NODE-1537 Node decommissioning stage 2 was rolled out in a hurry so that we could make the holiday-release cutoff: https://github.com/dfinity/ic/pull/2953 These changes add the missing observability logic. Main commits: - [Add datadir metrics](https://github.com/dfinity/ic/pull/3322/commits/a1e6dbb99e60c8397d5ff9b7b8b1b839a5d0c0e2) - [Update unit tests](https://github.com/dfinity/ic/pull/3322/commits/513ba80c20709d74fd7631fe3566ba6f92bd8679) Screenshot of metrics: image --- Cargo.lock | 1 + rs/ic_os/fstrim_tool/BUILD.bazel | 1 + rs/ic_os/fstrim_tool/Cargo.toml | 1 + rs/ic_os/fstrim_tool/src/lib.rs | 24 +- rs/ic_os/fstrim_tool/src/metrics/mod.rs | 88 ++++- rs/ic_os/fstrim_tool/src/metrics/tests.rs | 107 +++++- rs/ic_os/fstrim_tool/src/tests.rs | 323 +++++++++++------- .../fstrim_tool/tests/integration_tests.rs | 180 +++++----- 8 files changed, 481 insertions(+), 244 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e410db98ce..098b9048d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8394,6 +8394,7 @@ dependencies = [ "maplit", "predicates", "rand 0.8.5", + "regex", "tempfile", ] diff --git a/rs/ic_os/fstrim_tool/BUILD.bazel b/rs/ic_os/fstrim_tool/BUILD.bazel index f387d516321..38abf36e4ec 100644 --- a/rs/ic_os/fstrim_tool/BUILD.bazel +++ b/rs/ic_os/fstrim_tool/BUILD.bazel @@ -17,6 +17,7 @@ DEV_DEPENDENCIES = [ "@crate_index//:assert_matches", "@crate_index//:predicates", "@crate_index//:rand", + "@crate_index//:regex", "@crate_index//:tempfile", ] diff --git a/rs/ic_os/fstrim_tool/Cargo.toml b/rs/ic_os/fstrim_tool/Cargo.toml index 56348b47f9f..d97b8a61d13 100644 --- a/rs/ic_os/fstrim_tool/Cargo.toml +++ b/rs/ic_os/fstrim_tool/Cargo.toml @@ -19,4 +19,5 @@ assert_matches = { workspace = true } ic-crypto-test-utils-reproducible-rng = { path = "../../crypto/test_utils/reproducible_rng" } predicates = { workspace = true } rand = { workspace = true } +regex = { workspace = true } tempfile = { workspace = true } diff --git a/rs/ic_os/fstrim_tool/src/lib.rs b/rs/ic_os/fstrim_tool/src/lib.rs index af39d6c6f5d..1bbe877bf5e 100644 --- a/rs/ic_os/fstrim_tool/src/lib.rs +++ b/rs/ic_os/fstrim_tool/src/lib.rs @@ -61,7 +61,12 @@ fn write_metrics_using_tmp_file(metrics: &FsTrimMetrics, metrics_filename: &str) .context("Failed to write metrics to file") } -fn update_metrics(elapsed: Duration, is_success: bool, metrics_filename: &str) -> Result<()> { +fn update_metrics( + elapsed: Duration, + is_success: bool, + metrics_filename: &str, + is_datadir: bool, +) -> Result<()> { let mut metrics = parse_existing_metrics_from_file(metrics_filename) .unwrap_or_else(|e| { eprintln!("error parsing existing metrics: {}", e); @@ -71,7 +76,13 @@ fn update_metrics(elapsed: Duration, is_success: bool, metrics_filename: &str) - eprintln!("no existing metrics found"); FsTrimMetrics::default() }); - metrics.update(is_success, elapsed)?; + + if is_datadir { + metrics.update_datadir(is_success, elapsed)?; + } else { + metrics.update(is_success, elapsed)?; + } + write_metrics_using_tmp_file(&metrics, metrics_filename) } @@ -101,14 +112,13 @@ pub fn fstrim_tool( let start = std::time::Instant::now(); let res_target = run_command(command, &target); let elapsed_target = start.elapsed(); - update_metrics(elapsed_target, res_target.is_ok(), &metrics_filename)?; + update_metrics(elapsed_target, res_target.is_ok(), &metrics_filename, false)?; if !datadir_target.is_empty() && !is_node_assigned() { - // TODO observability changes needed, expand the metrics logic - // let start_datadir = std::time::Instant::now(); + let start = std::time::Instant::now(); let res_datadir = run_command(command, &datadir_target); - // let elapsed_datadir = start_datadir.elapsed(); - // update_metrics(elapsed_datadir, res_datadir.is_ok(), &metrics_filename)?; + let elapsed = start.elapsed(); + update_metrics(elapsed, res_datadir.is_ok(), &metrics_filename, true)?; res_target.and(res_datadir) } else { res_target diff --git a/rs/ic_os/fstrim_tool/src/metrics/mod.rs b/rs/ic_os/fstrim_tool/src/metrics/mod.rs index 5e42bce8d83..dfa68037edb 100644 --- a/rs/ic_os/fstrim_tool/src/metrics/mod.rs +++ b/rs/ic_os/fstrim_tool/src/metrics/mod.rs @@ -8,11 +8,20 @@ const METRICS_LAST_RUN_DURATION_MILLISECONDS: &str = "fstrim_last_run_duration_m const METRICS_LAST_RUN_SUCCESS: &str = "fstrim_last_run_success"; const METRICS_RUNS_TOTAL: &str = "fstrim_runs_total"; +const METRICS_LAST_RUN_DURATION_MILLISECONDS_DATADIR: &str = + "fstrim_datadir_last_run_duration_milliseconds"; +const METRICS_LAST_RUN_SUCCESS_DATADIR: &str = "fstrim_datadir_last_run_success"; +const METRICS_RUNS_TOTAL_DATADIR: &str = "fstrim_datadir_runs_total"; + #[derive(Debug)] pub struct FsTrimMetrics { pub last_duration_milliseconds: f64, pub last_run_success: bool, pub total_runs: f64, + + pub last_duration_milliseconds_datadir: f64, + pub last_run_success_datadir: bool, + pub total_runs_datadir: f64, } impl Default for FsTrimMetrics { @@ -21,6 +30,10 @@ impl Default for FsTrimMetrics { last_duration_milliseconds: 0f64, last_run_success: true, total_runs: 0f64, + + last_duration_milliseconds_datadir: 0f64, + last_run_success_datadir: true, + total_runs_datadir: 0f64, } } } @@ -33,26 +46,54 @@ impl FsTrimMetrics { Ok(()) } + pub(crate) fn update_datadir(&mut self, success: bool, duration: Duration) -> Result<()> { + self.total_runs_datadir += 1f64; + self.last_run_success_datadir = success; + self.last_duration_milliseconds_datadir = duration.as_millis() as f64; + Ok(()) + } + pub fn to_p8s_metrics_string(&self) -> String { + let fstrim_last_run_duration_milliseconds = to_go_f64(self.last_duration_milliseconds); + let fstrim_last_run_success = if self.last_run_success { "1" } else { "0" }; + let fstrim_runs_total = to_go_f64(self.total_runs); + + let fstrim_datadir_last_run_duration_milliseconds = + to_go_f64(self.last_duration_milliseconds_datadir); + let fstrim_datadir_last_run_success = if self.last_run_success_datadir { + "1" + } else { + "0" + }; + let fstrim_datadir_runs_total = to_go_f64(self.total_runs_datadir); + format!( "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ # TYPE fstrim_last_run_duration_milliseconds gauge\n\ - fstrim_last_run_duration_milliseconds {}\n\ + fstrim_last_run_duration_milliseconds {fstrim_last_run_duration_milliseconds}\n\ # HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)\n\ # TYPE fstrim_last_run_success gauge\n\ - fstrim_last_run_success {}\n\ + fstrim_last_run_success {fstrim_last_run_success}\n\ # HELP fstrim_runs_total Total number of runs of fstrim\n\ # TYPE fstrim_runs_total counter\n\ - fstrim_runs_total {}\n", - to_go_f64(self.last_duration_milliseconds), - if self.last_run_success { "1" } else { "0" }, - to_go_f64(self.total_runs), - ).to_string() + fstrim_runs_total {fstrim_runs_total}\n\ + # HELP fstrim_datadir_last_run_duration_milliseconds Duration of last run of fstrim on datadir in milliseconds\n\ + # TYPE fstrim_datadir_last_run_duration_milliseconds gauge\n\ + fstrim_datadir_last_run_duration_milliseconds {fstrim_datadir_last_run_duration_milliseconds}\n\ + # HELP fstrim_datadir_last_run_success Success status of last run of fstrim on datadir (success: 1, failure: 0)\n\ + # TYPE fstrim_datadir_last_run_success gauge\n\ + fstrim_datadir_last_run_success {fstrim_datadir_last_run_success}\n\ + # HELP fstrim_datadir_runs_total Total number of runs of fstrim on datadir\n\ + # TYPE fstrim_datadir_runs_total counter\n\ + fstrim_datadir_runs_total {fstrim_datadir_runs_total}\n" + ) } fn are_valid(&self) -> bool { is_f64_finite_and_0_or_larger(self.total_runs) && is_f64_finite_and_0_or_larger(self.last_duration_milliseconds) + && is_f64_finite_and_0_or_larger(self.total_runs_datadir) + && is_f64_finite_and_0_or_larger(self.last_duration_milliseconds_datadir) } } @@ -102,27 +143,41 @@ where let mut last_duration_milliseconds: Option = None; let mut last_run_success: Option = None; let mut total_runs: Option = None; + + // Default datadir fields (we treat them as optional in the metrics file) + let mut datadir_last_duration_milliseconds: f64 = 0f64; + let mut datadir_last_run_success: bool = true; + let mut datadir_total_runs: f64 = 0f64; + for line_or_err in lines { let line = line_or_err.map_err(|e| format_err!("failed to read line: {}", e))?; match line.split(' ').collect::>()[..] { ["#", ..] => continue, [key, value] => match key { METRICS_LAST_RUN_DURATION_MILLISECONDS => { - let _ = last_duration_milliseconds - .get_or_insert(parse_metrics_value(key, value)?); + last_duration_milliseconds.get_or_insert(parse_metrics_value(key, value)?); } METRICS_LAST_RUN_SUCCESS => { - let _ = - last_run_success.get_or_insert(parse_metrics_value(key, value)? > 0f64); + last_run_success.get_or_insert(parse_metrics_value(key, value)? > 0f64); } METRICS_RUNS_TOTAL => { - let _ = total_runs.get_or_insert(parse_metrics_value(key, value)?); + total_runs.get_or_insert(parse_metrics_value(key, value)?); + } + METRICS_LAST_RUN_DURATION_MILLISECONDS_DATADIR => { + datadir_last_duration_milliseconds = parse_metrics_value(key, value)?; + } + METRICS_LAST_RUN_SUCCESS_DATADIR => { + datadir_last_run_success = parse_metrics_value(key, value)? > 0f64; + } + METRICS_RUNS_TOTAL_DATADIR => { + datadir_total_runs = parse_metrics_value(key, value)?; } _ => return Err(format_err!("unknown metric key: {}", key)), }, _ => return Err(format_err!("invalid metric line: {:?}", line)), } } + let metrics = FsTrimMetrics { last_duration_milliseconds: last_duration_milliseconds.ok_or(format_err!( "missing metric: {}", @@ -131,6 +186,9 @@ where last_run_success: last_run_success .ok_or(format_err!("missing metric: {}", METRICS_LAST_RUN_SUCCESS))?, total_runs: total_runs.ok_or(format_err!("missing metric: {}", METRICS_RUNS_TOTAL))?, + last_duration_milliseconds_datadir: datadir_last_duration_milliseconds, + last_run_success_datadir: datadir_last_run_success, + total_runs_datadir: datadir_total_runs, }; if !metrics.are_valid() { return Err(format_err!("parsed metrics are invalid")); @@ -148,6 +206,12 @@ impl PartialEq for FsTrimMetrics { other.last_duration_milliseconds, ) && (self.last_run_success == other.last_run_success) + && f64_approx_eq( + self.last_duration_milliseconds_datadir, + other.last_duration_milliseconds_datadir, + ) + && (self.last_run_success_datadir == other.last_run_success_datadir) + && f64_approx_eq(self.total_runs_datadir, other.total_runs_datadir) } } diff --git a/rs/ic_os/fstrim_tool/src/metrics/tests.rs b/rs/ic_os/fstrim_tool/src/metrics/tests.rs index bca2d1e79b4..b21a61f3723 100644 --- a/rs/ic_os/fstrim_tool/src/metrics/tests.rs +++ b/rs/ic_os/fstrim_tool/src/metrics/tests.rs @@ -3,9 +3,11 @@ use assert_matches::assert_matches; use ic_crypto_test_utils_reproducible_rng::reproducible_rng; use rand::Rng; use std::fs::write; +use std::time::Duration; +use tempfile::tempdir; #[test] -fn should_compare_f64() { +fn compare_f64() { assert!(f64_approx_eq(f64::NAN, f64::NAN)); assert!(f64_approx_eq(f64::INFINITY, f64::INFINITY)); assert!(f64_approx_eq(f64::INFINITY + 1f64, f64::INFINITY)); @@ -16,8 +18,8 @@ fn should_compare_f64() { } #[test] -fn should_parse_valid_metrics_file() { - let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); +fn parse_valid_metrics_file() { + let temp_dir = tempdir().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); let metrics_file_content = "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ @@ -30,18 +32,22 @@ fn should_parse_valid_metrics_file() { # TYPE fstrim_runs_total counter\n\ fstrim_runs_total 1\n"; write(&test_file, metrics_file_content).expect("error writing to file"); + let parsed_metrics = parse_existing_metrics_from_file(&test_file.to_string_lossy()).unwrap(); let expected_metrics = FsTrimMetrics { last_duration_milliseconds: 6.0, last_run_success: true, total_runs: 1.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, }; assert_eq!(parsed_metrics, Some(expected_metrics)); } #[test] -fn should_only_consider_first_parsed_value_when_parsing_metrics_file() { - let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); +fn ignore_subsequent_values_for_same_metric() { + let temp_dir = tempdir().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); let metrics_file_content = "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ @@ -57,17 +63,21 @@ fn should_only_consider_first_parsed_value_when_parsing_metrics_file() { fstrim_runs_total 12\n\ fstrim_runs_total 1\n"; write(&test_file, metrics_file_content).expect("error writing to file"); + let parsed_metrics = parse_existing_metrics_from_file(&test_file.to_string_lossy()).unwrap(); let expected_metrics = FsTrimMetrics { last_duration_milliseconds: 6.0, last_run_success: true, total_runs: 12.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, }; assert_eq!(parsed_metrics, Some(expected_metrics)); } #[test] -fn should_return_error_when_parsing_empty_metrics_file() { +fn should_error_on_empty_metrics_file() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); write(&test_file, "").expect("error writing to file"); @@ -76,7 +86,7 @@ fn should_return_error_when_parsing_empty_metrics_file() { } #[test] -fn should_return_error_for_metrics_file_with_too_many_tokens() { +fn should_error_when_metrics_file_has_too_many_tokens() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); write(&test_file, "pineapple on pizza is delicious").expect("error writing to file"); @@ -87,7 +97,7 @@ fn should_return_error_for_metrics_file_with_too_many_tokens() { } #[test] -fn should_return_error_for_metrics_file_with_unknown_metric_name() { +fn should_error_when_unknown_metric_name() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); write(&test_file, "pineapple pizza").expect("error writing to file"); @@ -98,7 +108,7 @@ fn should_return_error_for_metrics_file_with_unknown_metric_name() { } #[test] -fn should_return_error_for_metrics_file_with_timestamp() { +fn should_error_when_metrics_file_has_timestamp() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); write( @@ -113,7 +123,7 @@ fn should_return_error_for_metrics_file_with_timestamp() { } #[test] -fn should_return_error_for_metrics_file_with_non_numeric_value() { +fn should_error_when_metrics_file_has_non_numeric_value() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); write(&test_file, format!("{} pizza", METRICS_RUNS_TOTAL).as_str()) @@ -125,7 +135,7 @@ fn should_return_error_for_metrics_file_with_non_numeric_value() { } #[test] -fn should_return_none_when_parsing_if_metrics_file_does_not_exist() { +fn file_does_not_exist() { let temp_dir = tempfile::TempDir::new().expect("failed to create a temporary directory"); let test_file = temp_dir.as_ref().join("test_file"); let parsed_metrics = parse_existing_metrics_from_file(&test_file.to_string_lossy()).unwrap(); @@ -133,7 +143,7 @@ fn should_return_none_when_parsing_if_metrics_file_does_not_exist() { } #[test] -fn should_set_metrics() { +fn set_metrics() { let mut existing_metrics = FsTrimMetrics::default(); existing_metrics .update(true, Duration::from_millis(110)) @@ -142,12 +152,13 @@ fn should_set_metrics() { last_duration_milliseconds: 110.0, last_run_success: true, total_runs: 1.0, + ..FsTrimMetrics::default() }; assert_eq!(existing_metrics, expected_metrics); } #[test] -fn should_update_metrics() { +fn update_metrics() { let mut rng = reproducible_rng(); for _ in 0..100 { let total_runs: u64 = rng.gen_range(0..10000000); @@ -162,7 +173,7 @@ fn should_update_metrics() { for _ in 0..100 { let success = rng.gen_bool(0.5); let duration = Duration::from_millis(rng.gen_range(0..15000)); - update_metrics(&mut expected_metrics, success, duration); + update_metrics_locally(&mut expected_metrics, success, duration); updated_metrics .update(success, duration) .expect("should update metrics successfully"); @@ -177,14 +188,15 @@ fn should_update_metrics() { } } -fn update_metrics(metrics: &mut FsTrimMetrics, success: bool, duration: Duration) { +// Simple local "update" for the test reference +fn update_metrics_locally(metrics: &mut FsTrimMetrics, success: bool, duration: Duration) { metrics.total_runs += 1f64; metrics.last_run_success = success; metrics.last_duration_milliseconds = duration.as_millis() as f64; } #[test] -fn should_update_metric_with_infinite_values() { +fn update_metrics_with_infinite_values() { let mut existing_metrics = FsTrimMetrics { total_runs: f64::INFINITY, ..FsTrimMetrics::default() @@ -198,13 +210,14 @@ fn should_update_metric_with_infinite_values() { last_duration_milliseconds: duration.as_millis() as f64, last_run_success: success, total_runs: f64::INFINITY, + ..FsTrimMetrics::default() }; assert_eq!(existing_metrics, expected_metrics); } #[test] -fn should_update_metric_with_nan_values() { +fn update_metrics_with_nan_values() { let mut existing_metrics = FsTrimMetrics { total_runs: f64::NAN, ..FsTrimMetrics::default() @@ -218,6 +231,7 @@ fn should_update_metric_with_nan_values() { last_duration_milliseconds: duration.as_millis() as f64, last_run_success: success, total_runs: f64::NAN, + ..FsTrimMetrics::default() }; assert_eq!(existing_metrics, expected_metrics); @@ -230,7 +244,7 @@ fn verify_invariants(i: f64, existing_metrics: &FsTrimMetrics) { } #[test] -fn should_maintain_invariants() { +fn maintain_invariants() { let mut existing_metrics = FsTrimMetrics::default(); let rng = &mut reproducible_rng(); for i in 0..100 { @@ -242,3 +256,60 @@ fn should_maintain_invariants() { verify_invariants(i as f64, &existing_metrics); } } + +#[test] +fn update_datadir_metrics() { + let mut metrics = FsTrimMetrics::default(); + assert_eq!(metrics.total_runs_datadir, 0.0); + assert_eq!(metrics.last_duration_milliseconds_datadir, 0.0); + assert!(metrics.last_run_success_datadir); + + metrics + .update_datadir(false, Duration::from_millis(123)) + .expect("should update datadir metrics"); + + assert_eq!(metrics.total_runs_datadir, 1.0); + assert_eq!(metrics.last_duration_milliseconds_datadir, 123.0); + assert!(!metrics.last_run_success_datadir); + + // Check that normal fields remain untouched + assert_eq!(metrics.total_runs, 0.0); + assert_eq!(metrics.last_duration_milliseconds, 0.0); + assert!(metrics.last_run_success); +} + +#[test] +fn format_metrics_output() { + let metrics = FsTrimMetrics { + last_duration_milliseconds: 123.45, + last_run_success: true, + total_runs: 6.0, + last_duration_milliseconds_datadir: 678.9, + last_run_success_datadir: false, + total_runs_datadir: 4.0, + }; + + let metrics_str = metrics.to_p8s_metrics_string(); + let expected_str = "\ +# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 123.45 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 1 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total 6 +# HELP fstrim_datadir_last_run_duration_milliseconds Duration of last run of fstrim on datadir in milliseconds +# TYPE fstrim_datadir_last_run_duration_milliseconds gauge +fstrim_datadir_last_run_duration_milliseconds 678.9 +# HELP fstrim_datadir_last_run_success Success status of last run of fstrim on datadir (success: 1, failure: 0) +# TYPE fstrim_datadir_last_run_success gauge +fstrim_datadir_last_run_success 0 +# HELP fstrim_datadir_runs_total Total number of runs of fstrim on datadir +# TYPE fstrim_datadir_runs_total counter +fstrim_datadir_runs_total 4 +"; + + assert_eq!(metrics_str, expected_str); +} diff --git a/rs/ic_os/fstrim_tool/src/tests.rs b/rs/ic_os/fstrim_tool/src/tests.rs index 7fbb921466f..6fd146a0b85 100644 --- a/rs/ic_os/fstrim_tool/src/tests.rs +++ b/rs/ic_os/fstrim_tool/src/tests.rs @@ -1,32 +1,34 @@ use super::*; use assert_matches::assert_matches; -use std::fs::write; +use std::fs::{read_to_string, write}; +use std::path::PathBuf; +use std::time::Duration; use tempfile::tempdir; -const EXISTING_METRICS_CONTENT: &str = - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ - # TYPE fstrim_last_run_duration_milliseconds gauge\n\ - fstrim_last_run_duration_milliseconds 0\n\ - # HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)\n\ - # TYPE fstrim_last_run_success gauge\n\ - fstrim_last_run_success 1\n\ - # HELP fstrim_runs_total Total number of runs of fstrim\n\ - # TYPE fstrim_runs_total counter\n\ - fstrim_runs_total 1\n"; - -const EXISTING_METRICS_CONTENT_WITH_SPECIAL_VALUES: &str = - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ - # TYPE fstrim_last_run_duration_milliseconds gauge\n\ - fstrim_last_run_duration_milliseconds 0\n\ - # HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)\n\ - # TYPE fstrim_last_run_success gauge\n\ - fstrim_last_run_success 1\n\ - # HELP fstrim_runs_total Total number of runs of fstrim\n\ - # TYPE fstrim_runs_total counter\n\ - fstrim_runs_total +Inf\n"; +const EXISTING_METRICS_CONTENT: &str = r#"# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 0 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 1 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total 1 +"#; + +const EXISTING_METRICS_CONTENT_WITH_SPECIAL_VALUES: &str = r#"# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 0 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 1 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total +Inf +"#; #[test] -fn should_parse_metrics_from_file() { +fn parse_metrics_without_datadir_fields() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); write(&metrics_file, EXISTING_METRICS_CONTENT).expect("error writing to file"); @@ -38,12 +40,49 @@ fn should_parse_metrics_from_file() { ) .expect("parsing metrics should succeed") .expect("parsed metrics should be some"); - let parsed_metrics_string = parsed_metrics.to_p8s_metrics_string(); - assert_eq!(parsed_metrics_string, EXISTING_METRICS_CONTENT); + + let expected_metrics = FsTrimMetrics { + last_duration_milliseconds: 0.0, + last_run_success: true, + total_runs: 1.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, + }; + + assert_eq!(parsed_metrics, expected_metrics); } #[test] -fn should_return_error_if_metrics_in_file_contain_special_values() { +fn parse_metrics_with_datadir_fields() { + let tmp_dir = tempdir().expect("temp dir creation should succeed"); + let metrics_file = tmp_dir.path().join("fstrim.prom"); + + let initial_metrics = FsTrimMetrics { + last_duration_milliseconds: 42.0, + last_run_success: false, + total_runs: 7.0, + last_duration_milliseconds_datadir: 999.0, + last_run_success_datadir: true, + total_runs_datadir: 12.0, + }; + write_metrics_using_tmp_file( + &initial_metrics, + metrics_file + .to_str() + .expect("metrics file path should be valid"), + ) + .unwrap(); + + let parsed_metrics = parse_existing_metrics_from_file(metrics_file.to_str().unwrap()) + .expect("parsing metrics should succeed") + .expect("parsed metrics should be some"); + + assert_eq!(parsed_metrics, initial_metrics); +} + +#[test] +fn should_error_if_metrics_in_file_has_special_values() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); write(&metrics_file, EXISTING_METRICS_CONTENT_WITH_SPECIAL_VALUES) @@ -58,14 +97,21 @@ fn should_return_error_if_metrics_in_file_contain_special_values() { } #[test] -fn should_write_metrics_to_file() { +fn write_metrics_to_file() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); - let default_metrics = FsTrimMetrics::default(); - let default_metrics_string = default_metrics.to_p8s_metrics_string(); + + let metrics = FsTrimMetrics { + last_duration_milliseconds: 64.0, + last_run_success: false, + total_runs: 60.0, + last_duration_milliseconds_datadir: 3.0, + last_run_success_datadir: true, + total_runs_datadir: 16.0, + }; write_metrics_using_tmp_file( - &default_metrics, + &metrics, metrics_file .to_str() .expect("metrics file path should be valid"), @@ -79,19 +125,30 @@ fn should_write_metrics_to_file() { ) .expect("parsing metrics should succeed") .expect("parsed metrics should be some"); - let parsed_metrics_string = parsed_metrics.to_p8s_metrics_string(); - assert_eq!( - parsed_metrics, default_metrics, - "{}\n{}", - parsed_metrics_string, default_metrics_string - ); + + assert_eq!(parsed_metrics, metrics); } #[test] -fn should_update_metrics() { +fn test_update_metrics() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); - write(&metrics_file, EXISTING_METRICS_CONTENT).expect("error writing to file"); + + let initial_metrics = FsTrimMetrics { + last_duration_milliseconds: 0.0, + last_run_success: true, + total_runs: 1.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, + }; + write_metrics_using_tmp_file( + &initial_metrics, + metrics_file + .to_str() + .expect("metrics file path should be valid"), + ) + .unwrap(); update_metrics( Duration::from_millis(151), @@ -99,8 +156,10 @@ fn should_update_metrics() { metrics_file .to_str() .expect("metrics file path should be valid"), + false, ) .expect("updating metrics should succeed"); + let parsed_metrics = parse_existing_metrics_from_file( metrics_file .to_str() @@ -108,22 +167,68 @@ fn should_update_metrics() { ) .expect("parsing metrics should succeed") .expect("parsed metrics should be some"); - let expected_metrics = - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ - # TYPE fstrim_last_run_duration_milliseconds gauge\n\ - fstrim_last_run_duration_milliseconds 151\n\ - # HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)\n\ - # TYPE fstrim_last_run_success gauge\n\ - fstrim_last_run_success 1\n\ - # HELP fstrim_runs_total Total number of runs of fstrim\n\ - # TYPE fstrim_runs_total counter\n\ - fstrim_runs_total 2\n"; - let parsed_metrics_string = parsed_metrics.to_p8s_metrics_string(); - assert_eq!(parsed_metrics_string, expected_metrics); + + let expected_metrics = FsTrimMetrics { + last_duration_milliseconds: 151.0, + last_run_success: true, + total_runs: 2.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, + }; + assert_eq!(parsed_metrics, expected_metrics); } #[test] -fn should_start_from_empty_metrics_for_update_if_metrics_in_file_contain_special_values() { +fn update_datadir_metrics() { + let tmp_dir = tempdir().expect("temp dir creation should succeed"); + let metrics_file = tmp_dir.path().join("fstrim.prom"); + + let initial_metrics = FsTrimMetrics { + last_duration_milliseconds: 0.0, + last_run_success: true, + total_runs: 1.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, + }; + write_metrics_using_tmp_file( + &initial_metrics, + metrics_file + .to_str() + .expect("metrics file path should be valid"), + ) + .unwrap(); + + update_metrics( + Duration::from_millis(501), + false, + metrics_file + .to_str() + .expect("metrics file path should be valid"), + true, + ) + .expect("updating datadir metrics should succeed"); + + let parsed_metrics = parse_existing_metrics_from_file( + metrics_file.to_str().expect("should convert path to str"), + ) + .expect("parsing metrics should succeed") + .expect("parsed metrics should be some"); + + let expected_metrics = FsTrimMetrics { + last_duration_milliseconds: 0.0, + last_run_success: true, + total_runs: 1.0, + last_duration_milliseconds_datadir: 501.0, + last_run_success_datadir: false, + total_runs_datadir: 1.0, + }; + assert_eq!(parsed_metrics, expected_metrics); +} + +#[test] +fn start_from_empty_metrics_when_file_has_special_values() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); write(&metrics_file, EXISTING_METRICS_CONTENT_WITH_SPECIAL_VALUES) @@ -135,8 +240,10 @@ fn should_start_from_empty_metrics_for_update_if_metrics_in_file_contain_special metrics_file .to_str() .expect("metrics file path should be valid"), + false, ) .expect("updating metrics should succeed"); + let parsed_metrics = parse_existing_metrics_from_file( metrics_file .to_str() @@ -144,37 +251,37 @@ fn should_start_from_empty_metrics_for_update_if_metrics_in_file_contain_special ) .expect("parsing metrics should succeed") .expect("parsed metrics should be some"); - let expected_metrics = - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds\n\ - # TYPE fstrim_last_run_duration_milliseconds gauge\n\ - fstrim_last_run_duration_milliseconds 151\n\ - # HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)\n\ - # TYPE fstrim_last_run_success gauge\n\ - fstrim_last_run_success 1\n\ - # HELP fstrim_runs_total Total number of runs of fstrim\n\ - # TYPE fstrim_runs_total counter\n\ - fstrim_runs_total 1\n"; - let parsed_metrics_string = parsed_metrics.to_p8s_metrics_string(); - assert_eq!(parsed_metrics_string, expected_metrics); + + let expected_metrics = FsTrimMetrics { + last_duration_milliseconds: 151.0, + last_run_success: true, + total_runs: 1.0, + last_duration_milliseconds_datadir: 0.0, + last_run_success_datadir: true, + total_runs_datadir: 0.0, + }; + assert_eq!(parsed_metrics, expected_metrics); } #[test] -fn should_return_ok_from_successfully_run_command() { +fn successfully_run_command() { run_command("true", "/").expect("running command should succeed"); } #[test] -fn should_return_error_from_unsuccessfully_run_command() { +fn unsuccessfully_run_command() { let res = run_command("false", "/"); assert_matches!(res, Err(err) if err.to_string().contains("Failed to run command")); } #[test] -fn should_fail_but_write_metrics_if_command_fails() { +fn command_fails_but_writes_metrics() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let tmp_dir2 = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); + + // This should fail to run the command, but still write updated metrics assert_matches!( fstrim_tool( "/non/existent/command", @@ -198,11 +305,20 @@ fn should_fail_but_write_metrics_if_command_fails() { if err.to_string().contains("Failed to run command") ); - assert_metrics_file_content(&metrics_file, false, 1); + // Verify that the metrics were written with success=0, total_runs=1, etc. + let parsed_metrics = + parse_existing_metrics_from_file(metrics_file.to_str().expect("valid path")) + .expect("parsing metrics should succeed") + .expect("parsed metrics should be some"); + + assert!(!parsed_metrics.last_run_success); + assert_eq!(parsed_metrics.total_runs, 1.0); + assert!(!parsed_metrics.last_run_success_datadir); + assert_eq!(parsed_metrics.total_runs_datadir, 1.0); } #[test] -fn should_fail_if_command_cannot_be_run() { +fn fails_if_command_cannot_be_run() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let tmp_dir2 = tempdir().expect("temp dir creation should succeed"); @@ -232,10 +348,11 @@ fn should_fail_if_command_cannot_be_run() { } #[test] -fn should_not_run_command_but_initialize_metrics_if_flag_set() { +fn init_flag() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let tmp_dir2 = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); + assert!(fstrim_tool( "/non/existent/command", metrics_file @@ -247,7 +364,7 @@ fn should_not_run_command_but_initialize_metrics_if_flag_set() { .to_str() .expect("tmp_dir path should be valid") .to_string(), - true, + true, //init should write out default metrics even though the command fails tmp_dir2 .path() .to_str() @@ -256,11 +373,16 @@ fn should_not_run_command_but_initialize_metrics_if_flag_set() { ) .is_ok()); - assert_metrics_file_content(&metrics_file, true, 0); + let parsed_metrics = + parse_existing_metrics_from_file(metrics_file.to_str().expect("valid path")) + .expect("parsing metrics should succeed") + .expect("parsed metrics should be some"); + + assert_eq!(parsed_metrics, FsTrimMetrics::default()); } #[test] -fn should_not_overwrite_existing_metrics_if_metrics_init_flag_set() { +fn init_flag_does_not_overwrite_existing_metrics() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let tmp_dir2 = tempdir().expect("temp dir creation should succeed"); @@ -305,14 +427,16 @@ fn should_not_overwrite_existing_metrics_if_metrics_init_flag_set() { ) .is_ok()); - assert_metrics_file_content(&metrics_file, true, 1); + let content = read_to_string(&metrics_file).expect("reading metrics should succeed"); + assert!(content.contains("fstrim_runs_total 1")); } #[test] -fn should_fail_if_metrics_file_cannot_be_written_to() { +fn should_fail_if_metrics_file_cannot_be_written() { let metrics_file = PathBuf::from("/non/existent/directory/fstrim.prom"); let tmp_dir = tempdir().expect("temp dir creation should succeed"); let tmp_dir2 = tempdir().expect("temp dir creation should succeed"); + assert_matches!( fstrim_tool( "true", @@ -344,10 +468,8 @@ fn should_fail_if_target_is_not_a_directory() { let metrics_file = tmp_dir.path().join("fstrim.prom"); let target = PathBuf::from("/non/existent/target/directory"); - let expected_error = format!( - "Target {} is not a directory", - target.to_str().expect("target path should be valid") - ); + let expected_error = format!("Target {} is not a directory", target.to_str().unwrap()); + assert_matches!( fstrim_tool( "true", @@ -370,48 +492,3 @@ fn should_fail_if_target_is_not_a_directory() { if err.to_string() == expected_error ); } - -fn assert_metrics_file_content(metrics_filename: &PathBuf, is_success: bool, total_runs: u32) { - let file = File::open(metrics_filename).expect("should succeed in opening metrics file"); - let reader = BufReader::new(file); - let lines = reader.lines(); - for (i, line) in lines.enumerate() { - match i { - 0 => assert_eq!( - line.unwrap(), - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds" - ), - 1 => assert_eq!( - line.unwrap(), - "# TYPE fstrim_last_run_duration_milliseconds gauge" - ), - 2 => assert!(line.unwrap().starts_with("fstrim_last_run_duration_milliseconds")), - 3 => assert_eq!( - line.unwrap(), "# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)" - ), - 4 => assert_eq!( - line.unwrap(), "# TYPE fstrim_last_run_success gauge" - ), - 5 => { - let line_str = line.unwrap(); - let mut tokens = line_str.split(' '); - assert_eq!(tokens.next().unwrap(), "fstrim_last_run_success", "{}", line_str); - let success_str = if is_success { "1" } else { "0" }; - assert_eq!(tokens.next().unwrap(), success_str, "{}", line_str); - }, - 6 => assert_eq!( - line.unwrap(), "# HELP fstrim_runs_total Total number of runs of fstrim" - ), - 7 => assert_eq!( - line.unwrap(), "# TYPE fstrim_runs_total counter" - ), - 8 => { - let line_str = line.unwrap(); - let mut tokens = line_str.split(' '); - assert_eq!(tokens.next().unwrap(), "fstrim_runs_total", "{}", line_str); - assert_eq!(tokens.next().unwrap().parse::().unwrap(), total_runs, "{}", line_str); - }, - _ => panic!("unexpected line: {}", line.unwrap()), - } - } -} diff --git a/rs/ic_os/fstrim_tool/tests/integration_tests.rs b/rs/ic_os/fstrim_tool/tests/integration_tests.rs index 3701250642c..e89c785f3cd 100644 --- a/rs/ic_os/fstrim_tool/tests/integration_tests.rs +++ b/rs/ic_os/fstrim_tool/tests/integration_tests.rs @@ -1,68 +1,39 @@ use assert_cmd::Command; use predicates::prelude::*; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::path::PathBuf; +use regex::Regex; +use std::fs::read_to_string; use tempfile::tempdir; fn new_fstrim_tool_command() -> Command { match Command::cargo_bin("fstrim_tool") { // When in Cargo environment. - Ok(v) => v, + Ok(cmd) => cmd, // When in Bazel environment Err(_) => Command::new("rs/ic_os/fstrim_tool/fstrim_tool_bin"), } } -fn assert_metrics_file_content(metrics_filename: &PathBuf, is_success: bool, total_runs: u32) { - let file = File::open(metrics_filename).expect("should succeed in opening metrics file"); - let reader = BufReader::new(file); - let lines = reader.lines(); - for (i, line) in lines.enumerate() { - match i { - 0 => assert_eq!( - line.unwrap(), - "# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds" - ), - 1 => assert_eq!( - line.unwrap(), - "# TYPE fstrim_last_run_duration_milliseconds gauge" - ), - 2 => assert!(line.unwrap().starts_with("fstrim_last_run_duration_milliseconds")), - 3 => assert_eq!( - line.unwrap(), "# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0)" - ), - 4 => assert_eq!( - line.unwrap(), "# TYPE fstrim_last_run_success gauge" - ), - 5 => { - let line_str = line.unwrap(); - let mut tokens = line_str.split(' '); - assert_eq!(tokens.next().unwrap(), "fstrim_last_run_success", "{}", line_str); - let success_str = if is_success { "1" } else { "0" }; - assert_eq!(tokens.next().unwrap(), success_str, "{}", line_str); - }, - 6 => assert_eq!( - line.unwrap(), "# HELP fstrim_runs_total Total number of runs of fstrim" - ), - 7 => assert_eq!( - line.unwrap(), "# TYPE fstrim_runs_total counter" - ), - 8 => { - let line_str = line.unwrap(); - let mut tokens = line_str.split(' '); - assert_eq!(tokens.next().unwrap(), "fstrim_runs_total", "{}", line_str); - assert_eq!(tokens.next().unwrap().parse::().unwrap(), total_runs, "{}", line_str); - }, - _ => panic!("unexpected line: {}", line.unwrap()), - } - } +/// Replaces lines that contain: +/// - `fstrim_last_run_duration_milliseconds X` +/// - `fstrim_datadir_last_run_duration_milliseconds X` +/// +/// with a placeholder: +/// - `fstrim_last_run_duration_milliseconds ` +/// - `fstrim_datadir_last_run_duration_milliseconds ` +/// +/// This ensures that the duration numeric values do not cause test flakiness. +fn normalize_duration_line(input: &str) -> String { + let re = + Regex::new(r"(?m)^(fstrim(?:_datadir)?_last_run_duration_milliseconds)\s+\d+(\.\d+)?$") + .unwrap(); + re.replace_all(input, "$1 ").into_owned() } #[test] -fn should_successfully_initialize_metrics_if_flag_is_set() { +fn initialize_metrics() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); + new_fstrim_tool_command() .args([ "--metrics", @@ -81,13 +52,34 @@ fn should_successfully_initialize_metrics_if_flag_is_set() { .stderr(predicate::str::is_empty()) .success(); - assert_metrics_file_content(&metrics_file, true, 0); + let actual = read_to_string(&metrics_file).expect("reading metrics file should succeed"); + let expected = r#"# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 0 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 1 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total 0 +# HELP fstrim_datadir_last_run_duration_milliseconds Duration of last run of fstrim on datadir in milliseconds +# TYPE fstrim_datadir_last_run_duration_milliseconds gauge +fstrim_datadir_last_run_duration_milliseconds 0 +# HELP fstrim_datadir_last_run_success Success status of last run of fstrim on datadir (success: 1, failure: 0) +# TYPE fstrim_datadir_last_run_success gauge +fstrim_datadir_last_run_success 1 +# HELP fstrim_datadir_runs_total Total number of runs of fstrim on datadir +# TYPE fstrim_datadir_runs_total counter +fstrim_datadir_runs_total 0 +"#; + assert_eq!(actual, expected); } #[test] -fn should_fail_but_write_metrics_if_target_is_not_a_directory() { +fn should_fail_but_write_metrics_if_target_not_a_directory() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); + new_fstrim_tool_command() .args([ "--metrics", @@ -102,41 +94,36 @@ fn should_fail_but_write_metrics_if_target_is_not_a_directory() { .stderr(predicate::str::contains("not a directory")) .failure(); - assert_metrics_file_content(&metrics_file, false, 1); -} + let actual = read_to_string(&metrics_file).expect("reading metrics file should succeed"); + // The command fails, so success=0, runs=1. Datadir not updated => datadir success=1, runs=0 + let expected = r#"# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 0 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 0 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total 1 +# HELP fstrim_datadir_last_run_duration_milliseconds Duration of last run of fstrim on datadir in milliseconds +# TYPE fstrim_datadir_last_run_duration_milliseconds gauge +fstrim_datadir_last_run_duration_milliseconds 0 +# HELP fstrim_datadir_last_run_success Success status of last run of fstrim on datadir (success: 1, failure: 0) +# TYPE fstrim_datadir_last_run_success gauge +fstrim_datadir_last_run_success 1 +# HELP fstrim_datadir_runs_total Total number of runs of fstrim on datadir +# TYPE fstrim_datadir_runs_total counter +fstrim_datadir_runs_total 0 +"#; -// This fails if not tested under root user as the successful execution of the 1st target calls fstrim -// #[test] -// fn should_fail_but_write_metrics_if_data_target_is_not_a_directory() { -// let tmp_dir = tempdir().expect("temp dir creation should succeed"); -// let metrics_file = tmp_dir.path().join("fstrim.prom"); -// new_fstrim_tool_command() -// .args([ -// "--metrics", -// metrics_file -// .to_str() -// .expect("metrics file path should be valid"), -// "--target", -// tmp_dir -// .path() -// .to_str() -// .expect("tmp_dir path should be valid"), -// "--datadir_target", -// "/not/a/directory", -// ]) -// .assert() -// .stdout(predicate::str::is_empty()) -// .stderr(predicate::str::contains("not a directory")) -// .failure(); -// -// // As metrics now only target the main target, success will be reported -// assert_metrics_file_content(&metrics_file, true, 1); -// } + assert_eq!(actual, expected); +} #[test] -fn should_fail_but_write_metrics_with_discard_not_supported_with_correct_parameters() { +fn should_fail_but_writes_metrics_when_discard_not_supported() { let tmp_dir = tempdir().expect("temp dir creation should succeed"); let metrics_file = tmp_dir.path().join("fstrim.prom"); + new_fstrim_tool_command() .args([ "--metrics", @@ -151,12 +138,37 @@ fn should_fail_but_write_metrics_with_discard_not_supported_with_correct_paramet ]) .assert() .stdout(predicate::str::is_empty()) - .stderr(predicate::str::contains( - "the discard operation is not supported", - )) + .stderr( + predicate::str::contains("the discard operation is not supported") + .or(predicate::str::contains("Operation not permitted")), + ) .failure(); - assert_metrics_file_content(&metrics_file, false, 1); + let actual_raw = read_to_string(&metrics_file).expect("reading metrics file should succeed"); + let actual = normalize_duration_line(&actual_raw); + // The tool fails => success=0, runs=1. Datadir not updated => success=1, runs=0 + let expected_raw = r#"# HELP fstrim_last_run_duration_milliseconds Duration of last run of fstrim in milliseconds +# TYPE fstrim_last_run_duration_milliseconds gauge +fstrim_last_run_duration_milliseconds 2 +# HELP fstrim_last_run_success Success status of last run of fstrim (success: 1, failure: 0) +# TYPE fstrim_last_run_success gauge +fstrim_last_run_success 0 +# HELP fstrim_runs_total Total number of runs of fstrim +# TYPE fstrim_runs_total counter +fstrim_runs_total 1 +# HELP fstrim_datadir_last_run_duration_milliseconds Duration of last run of fstrim on datadir in milliseconds +# TYPE fstrim_datadir_last_run_duration_milliseconds gauge +fstrim_datadir_last_run_duration_milliseconds 0 +# HELP fstrim_datadir_last_run_success Success status of last run of fstrim on datadir (success: 1, failure: 0) +# TYPE fstrim_datadir_last_run_success gauge +fstrim_datadir_last_run_success 1 +# HELP fstrim_datadir_runs_total Total number of runs of fstrim on datadir +# TYPE fstrim_datadir_runs_total counter +fstrim_datadir_runs_total 0 +"#; + let expected = normalize_duration_line(expected_raw); + + assert_eq!(actual, expected); } #[test] From d90e934eb440c730d44d9d9b1ece2cc3f9505d05 Mon Sep 17 00:00:00 2001 From: Paul Liu Date: Wed, 15 Jan 2025 17:38:57 +0800 Subject: [PATCH 95/98] fix: cargo build registry-canister for wasm32 target (#3408) The following command currently failed to compile the registry canister if running from the /ic/rs/registery/canister sub-directory: cargo build --profile canister-release --target wasm32-unknown-unknown --bin registry-canister The fix is to make sure the feature `getrandom/custom` is enabled. Note that the above command would succeed if running from the top-level directory, but would produce incorrect wasm binary. This is because cargo would bring in global dependencies that enable both `getrandom/custom` and `getrandom/js` features, and the latter will lead to wasm binaries having unwanted imports (See #3309 for more details). Since this problem does not affect bazel builds, this fix is only relevant to cargo. --- Cargo.lock | 1 + rs/registry/canister/Cargo.toml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 098b9048d54..9b761dcc7bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18343,6 +18343,7 @@ dependencies = [ "dfn_core", "dfn_http_metrics", "futures", + "getrandom", "ic-base-types", "ic-canister-client-sender", "ic-cdk 0.16.0", diff --git a/rs/registry/canister/Cargo.toml b/rs/registry/canister/Cargo.toml index 25ad4b78899..43ed07df70b 100644 --- a/rs/registry/canister/Cargo.toml +++ b/rs/registry/canister/Cargo.toml @@ -51,6 +51,9 @@ prost = { workspace = true } serde = { workspace = true } url = { workspace = true } +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom = { version = "0.2", features = [ "custom" ] } + [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] assert_matches = { workspace = true } candid_parser = { workspace = true } From f8f274d89991300aad7a7ef850f379a728a50378 Mon Sep 17 00:00:00 2001 From: oggy-dfin <89794951+oggy-dfin@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:53:13 +0100 Subject: [PATCH 96/98] feat(IC-1579): TLA annotations for disburse_to_neuron (#3411) Instrument the `disburse_to_neuron` function to check the test traces for compatibility with the TLA model. --- rs/nns/governance/src/governance.rs | 12 +- .../src/governance/tla/disburse_to_neuron.rs | 29 +++ rs/nns/governance/src/governance/tla/mod.rs | 2 + rs/nns/governance/tests/governance.rs | 2 + rs/nns/governance/tla/Claim_Neuron.tla | 2 +- rs/nns/governance/tla/Disburse_To_Neuron.tla | 193 ++++++++++++++++++ .../tla/Disburse_To_Neuron_Apalache.tla | 70 +++++++ 7 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 rs/nns/governance/src/governance/tla/disburse_to_neuron.rs create mode 100644 rs/nns/governance/tla/Disburse_To_Neuron.tla create mode 100644 rs/nns/governance/tla/Disburse_To_Neuron_Apalache.tla diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index 48a951b8349..ccfeb7948f0 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -147,8 +147,8 @@ use std::collections::BTreeSet; #[cfg(feature = "tla")] pub use tla::{ tla_update_method, InstrumentationState, ToTla, CLAIM_NEURON_DESC, DISBURSE_NEURON_DESC, - MERGE_NEURONS_DESC, SPAWN_NEURONS_DESC, SPAWN_NEURON_DESC, SPLIT_NEURON_DESC, - TLA_INSTRUMENTATION_STATE, TLA_TRACES_LKEY, TLA_TRACES_MUTEX, + DISBURSE_TO_NEURON_DESC, MERGE_NEURONS_DESC, SPAWN_NEURONS_DESC, SPAWN_NEURON_DESC, + SPLIT_NEURON_DESC, TLA_INSTRUMENTATION_STATE, TLA_TRACES_LKEY, TLA_TRACES_MUTEX, }; // 70 KB (for executing NNS functions that are not canister upgrades) @@ -3541,6 +3541,7 @@ impl Governance { /// stake. /// - The amount to split minus the transfer fee is more than the minimum /// stake. + #[cfg_attr(feature = "tla", tla_update_method(DISBURSE_TO_NEURON_DESC.clone()))] pub async fn disburse_to_neuron( &mut self, id: &NeuronId, @@ -3706,6 +3707,13 @@ impl Governance { // Do the transfer from the parent neuron's subaccount to the child neuron's // subaccount. let memo = created_timestamp_seconds; + + tla_log_locals! { + parent_neuron_id: parent_nid.id, + disburse_amount: disburse_to_neuron.amount_e8s, + child_neuron_id: child_nid.id, + child_account_id: tla::account_to_tla(neuron_subaccount(to_subaccount)) + }; let result: Result = self .ledger .transfer_funds( diff --git a/rs/nns/governance/src/governance/tla/disburse_to_neuron.rs b/rs/nns/governance/src/governance/tla/disburse_to_neuron.rs new file mode 100644 index 00000000000..b114e0b9956 --- /dev/null +++ b/rs/nns/governance/src/governance/tla/disburse_to_neuron.rs @@ -0,0 +1,29 @@ +use super::{extract_common_constants, post_process_trace}; +use lazy_static::lazy_static; +use tla_instrumentation::{Label, TlaConstantAssignment, ToTla, Update, VarAssignment}; + +const PID: &str = "Disburse_To_Neuron"; +lazy_static! { + pub static ref DISBURSE_TO_NEURON_DESC: Update = { + let default_locals = VarAssignment::new() + .add("parent_neuron_id", 0_u64.to_tla_value()) + .add("disburse_amount", 0_u64.to_tla_value()) + .add("child_account_id", "".to_tla_value()) + .add("child_neuron_id", 0_u64.to_tla_value()); + Update { + default_start_locals: default_locals.clone(), + default_end_locals: default_locals, + start_label: Label::new("DisburseToNeuron"), + end_label: Label::new("Done"), + process_id: PID.to_string(), + canister_name: "governance".to_string(), + post_process: |trace| { + let constants = TlaConstantAssignment { + constants: extract_common_constants(PID, trace).into_iter().collect(), + }; + post_process_trace(trace); + constants + }, + } + }; +} diff --git a/rs/nns/governance/src/governance/tla/mod.rs b/rs/nns/governance/src/governance/tla/mod.rs index bf8fa7de13d..45e62e439d2 100644 --- a/rs/nns/governance/src/governance/tla/mod.rs +++ b/rs/nns/governance/src/governance/tla/mod.rs @@ -26,6 +26,7 @@ pub use store::{TLA_INSTRUMENTATION_STATE, TLA_TRACES_LKEY, TLA_TRACES_MUTEX}; mod claim_neuron; mod disburse_neuron; +mod disburse_to_neuron; mod merge_neurons; mod spawn_neuron; mod spawn_neurons; @@ -33,6 +34,7 @@ mod split_neuron; pub use claim_neuron::CLAIM_NEURON_DESC; pub use disburse_neuron::DISBURSE_NEURON_DESC; +pub use disburse_to_neuron::DISBURSE_TO_NEURON_DESC; pub use merge_neurons::MERGE_NEURONS_DESC; pub use spawn_neuron::SPAWN_NEURON_DESC; pub use spawn_neurons::SPAWN_NEURONS_DESC; diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index 7a11a736248..f1cde600775 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -4264,6 +4264,7 @@ fn fixture_for_approve_kyc() -> GovernanceProto { /// If we approve KYC for Principals 1 and 2, neurons A, B and C should have /// `kyc_verified=true`, while neuron D still has `kyc_verified=false` #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_approve_kyc() { let governance_proto = fixture_for_approve_kyc(); let driver = fake::FakeDriver::default() @@ -6716,6 +6717,7 @@ async fn test_neuron_with_non_self_authenticating_controller_is_now_allowed() { } #[test] +#[cfg_attr(feature = "tla", with_tla_trace_check)] fn test_disburse_to_neuron() { let from = *TEST_NEURON_1_OWNER_PRINCIPAL; // Compute the subaccount to which the transfer would have been made diff --git a/rs/nns/governance/tla/Claim_Neuron.tla b/rs/nns/governance/tla/Claim_Neuron.tla index cd38eebed88..d88dcecb55a 100644 --- a/rs/nns/governance/tla/Claim_Neuron.tla +++ b/rs/nns/governance/tla/Claim_Neuron.tla @@ -72,7 +72,7 @@ process ( Claim_Neuron \in Claim_Neuron_Process_Ids ) \* instead of await here, to check that assert neuron_id \notin locks; locks := locks \union {neuron_id}; - neuron_id_by_account := account :> neuron_id @@ neuron_id_by_account; +gp neuron_id_by_account := account :> neuron_id @@ neuron_id_by_account; neuron := neuron_id :> [ cached_stake |-> 0, account |-> account, fees |-> 0, maturity |-> 0 ] @@ neuron; \* send_request(self, OP_QUERY_BALANCE, balance_query(account)); governance_to_ledger := Append(governance_to_ledger, request(self, account_balance(account))); diff --git a/rs/nns/governance/tla/Disburse_To_Neuron.tla b/rs/nns/governance/tla/Disburse_To_Neuron.tla new file mode 100644 index 00000000000..622f87505d2 --- /dev/null +++ b/rs/nns/governance/tla/Disburse_To_Neuron.tla @@ -0,0 +1,193 @@ +---- MODULE Disburse_To_Neuron ---- + +EXTENDS TLC, Integers, FiniteSets, Sequences, Variants + +CONSTANTS + Governance_Account_Ids, + Neuron_Ids + +CONSTANTS + Disburse_To_Neuron_Process_Ids + +CONSTANTS + \* Minimum stake a neuron can have + MIN_STAKE, + \* The transfer fee charged by the ledger canister + TRANSACTION_FEE + +CONSTANT + FRESH_NEURON_ID(_) + +\* Initial value used for uninitialized accounts +DUMMY_ACCOUNT == "" + +\* @type: (a -> b, Set(a)) => a -> b; +Remove_Arguments(f, S) == [ x \in (DOMAIN f \ S) |-> f[x]] +Max(x, y) == IF x < y THEN y ELSE x + +request(caller, request_args) == [caller |-> caller, method_and_args |-> request_args] +transfer(from, to, amount, fee) == Variant("Transfer", [from |-> from, to |-> to, amount |-> amount, fee |-> fee]) + +o_deduct(disb_amount) == disb_amount + TRANSACTION_FEE + +(* --algorithm Governance_Ledger_Disburse_To_Neuron { + +variables + + neuron \in [{} -> {}]; + \* Used to decide whether we should refresh or claim a neuron + neuron_id_by_account \in [{} -> {}]; + \* The set of currently locked neurons + locks = {}; + \* The queue of messages sent from the governance canister to the ledger canister + governance_to_ledger = <<>>; + ledger_to_governance = {}; + spawning_neurons = FALSE; + +macro send_request(caller_id, request_args) { + governance_to_ledger := Append(governance_to_ledger, request(caller_id, request_args)) +}; + +process (Disburse_To_Neuron \in Disburse_To_Neuron_Process_Ids) + variables + parent_neuron_id = 0; + disburse_amount = 0; + child_account_id = DUMMY_ACCOUNT; + child_neuron_id = 0; + { + DisburseToNeuron: + either { + \* Simulate calls that just fail early and don't change the state. + \* Not so useful for model checking, but needed to follow the code traces. + goto Done; + } or { + \* Skipping a few checks again: + \* 1. authorization of the caller + \* 2. that the parent neuron has been dissolved + \* 3. kyc checks + \* 4. checks on the presence and shape of new controller + with(pnid \in DOMAIN(neuron) \ locks; + parent_neuron = neuron[pnid]; + amt \in (MIN_STAKE + TRANSACTION_FEE)..(parent_neuron.cached_stake - parent_neuron.fees - MIN_STAKE); + c_acc_id \in Governance_Account_Ids \ { neuron[n].account : n \in DOMAIN(neuron)}; + ) { + parent_neuron_id := pnid; + disburse_amount := amt; + await parent_neuron.maturity <= TRANSACTION_FEE; + child_account_id := c_acc_id; + child_neuron_id := FRESH_NEURON_ID(DOMAIN(neuron)); + neuron_id_by_account := child_account_id :> child_neuron_id @@ neuron_id_by_account; + neuron := child_neuron_id :> [ cached_stake |-> 0, account |-> child_account_id, fees |-> 0, maturity |-> 0 ] @@ neuron; + \* The Rust code throws an error here if the parent neuron is locked. Instead, we prevent the Disburse_To_Neuron process from running. + \* This is OK since the Rust code doesn't change the canister's state before obtaining the parant lock (if it + \* did, the model wouldn't capture this state and we could miss behaviors). + assert child_neuron_id \notin locks; + \* Note that in the implementation this implies that child_neuron_id != parent_neuron_id, + \* as the locks are taken sequentially there; here, we're sure that these neuron IDs differ, + \* so we omit the extra check. + locks := locks \union {parent_neuron_id, child_neuron_id}; + send_request(self, transfer(parent_neuron.account, child_account_id, disburse_amount - TRANSACTION_FEE, TRANSACTION_FEE)); + }; + }; + DisburseToNeuron_WaitForTransfer: + with(answer \in { resp \in ledger_to_governance: resp.caller = self}) { + ledger_to_governance := ledger_to_governance \ {answer}; + if(answer.response = Variant("Fail", UNIT)) { + neuron := Remove_Arguments(neuron, {child_neuron_id}); + neuron_id_by_account := Remove_Arguments(neuron_id_by_account, {child_account_id}); + } else { + neuron := [ neuron EXCEPT ![parent_neuron_id].cached_stake = @ - disburse_amount, + ![child_neuron_id].cached_stake = disburse_amount - TRANSACTION_FEE ]; + }; + locks := locks \ {parent_neuron_id, child_neuron_id}; + parent_neuron_id := 0; + disburse_amount := 0; + child_account_id := DUMMY_ACCOUNT; + child_neuron_id := 0; + }; + + } +} +*) +\* BEGIN TRANSLATION (chksum(pcal) = "d03e80ed" /\ chksum(tla) = "b79d8d63") +VARIABLES pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, spawning_neurons, parent_neuron_id, + disburse_amount, child_account_id, child_neuron_id + +vars == << pc, neuron, neuron_id_by_account, locks, governance_to_ledger, + ledger_to_governance, spawning_neurons, parent_neuron_id, + disburse_amount, child_account_id, child_neuron_id >> + +ProcSet == (Disburse_To_Neuron_Process_Ids) + +Init == (* Global variables *) + /\ neuron \in [{} -> {}] + /\ neuron_id_by_account \in [{} -> {}] + /\ locks = {} + /\ governance_to_ledger = <<>> + /\ ledger_to_governance = {} + /\ spawning_neurons = FALSE + (* Process Disburse_To_Neuron *) + /\ parent_neuron_id = [self \in Disburse_To_Neuron_Process_Ids |-> 0] + /\ disburse_amount = [self \in Disburse_To_Neuron_Process_Ids |-> 0] + /\ child_account_id = [self \in Disburse_To_Neuron_Process_Ids |-> DUMMY_ACCOUNT] + /\ child_neuron_id = [self \in Disburse_To_Neuron_Process_Ids |-> 0] + /\ pc = [self \in ProcSet |-> "DisburseToNeuron"] + +DisburseToNeuron(self) == /\ pc[self] = "DisburseToNeuron" + /\ \/ /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED <> + \/ /\ \E pnid \in DOMAIN(neuron) \ locks: + LET parent_neuron == neuron[pnid] IN + \E amt \in (MIN_STAKE + TRANSACTION_FEE)..(parent_neuron.cached_stake - parent_neuron.fees - MIN_STAKE): + \E c_acc_id \in Governance_Account_Ids \ { neuron[n].account : n \in DOMAIN(neuron)}: + /\ parent_neuron_id' = [parent_neuron_id EXCEPT ![self] = pnid] + /\ disburse_amount' = [disburse_amount EXCEPT ![self] = amt] + /\ parent_neuron.maturity <= TRANSACTION_FEE + /\ child_account_id' = [child_account_id EXCEPT ![self] = c_acc_id] + /\ child_neuron_id' = [child_neuron_id EXCEPT ![self] = FRESH_NEURON_ID(DOMAIN(neuron))] + /\ neuron_id_by_account' = (child_account_id'[self] :> child_neuron_id'[self] @@ neuron_id_by_account) + /\ neuron' = (child_neuron_id'[self] :> [ cached_stake |-> 0, account |-> child_account_id'[self], fees |-> 0, maturity |-> 0 ] @@ neuron) + /\ Assert(child_neuron_id'[self] \notin locks, + "Failure of assertion at line 84, column 17.") + /\ locks' = (locks \union {parent_neuron_id'[self], child_neuron_id'[self]}) + /\ governance_to_ledger' = Append(governance_to_ledger, request(self, (transfer(parent_neuron.account, child_account_id'[self], disburse_amount'[self] - TRANSACTION_FEE, TRANSACTION_FEE)))) + /\ pc' = [pc EXCEPT ![self] = "DisburseToNeuron_WaitForTransfer"] + /\ UNCHANGED << ledger_to_governance, + spawning_neurons >> + +DisburseToNeuron_WaitForTransfer(self) == /\ pc[self] = "DisburseToNeuron_WaitForTransfer" + /\ \E answer \in { resp \in ledger_to_governance: resp.caller = self}: + /\ ledger_to_governance' = ledger_to_governance \ {answer} + /\ IF answer.response = Variant("Fail", UNIT) + THEN /\ neuron' = Remove_Arguments(neuron, {child_neuron_id[self]}) + /\ neuron_id_by_account' = Remove_Arguments(neuron_id_by_account, {child_account_id[self]}) + ELSE /\ neuron' = [ neuron EXCEPT ![parent_neuron_id[self]].cached_stake = @ - disburse_amount[self], + ![child_neuron_id[self]].cached_stake = disburse_amount[self] - TRANSACTION_FEE ] + /\ UNCHANGED neuron_id_by_account + /\ locks' = locks \ {parent_neuron_id[self], child_neuron_id[self]} + /\ parent_neuron_id' = [parent_neuron_id EXCEPT ![self] = 0] + /\ disburse_amount' = [disburse_amount EXCEPT ![self] = 0] + /\ child_account_id' = [child_account_id EXCEPT ![self] = DUMMY_ACCOUNT] + /\ child_neuron_id' = [child_neuron_id EXCEPT ![self] = 0] + /\ pc' = [pc EXCEPT ![self] = "Done"] + /\ UNCHANGED << governance_to_ledger, + spawning_neurons >> + +Disburse_To_Neuron(self) == DisburseToNeuron(self) + \/ DisburseToNeuron_WaitForTransfer(self) + +(* Allow infinite stuttering to prevent deadlock on termination. *) +Terminating == /\ \A self \in ProcSet: pc[self] = "Done" + /\ UNCHANGED vars + +Next == (\E self \in Disburse_To_Neuron_Process_Ids: Disburse_To_Neuron(self)) + \/ Terminating + +Spec == Init /\ [][Next]_vars + +Termination == <>(\A self \in ProcSet: pc[self] = "Done") + +\* END TRANSLATION + +==== diff --git a/rs/nns/governance/tla/Disburse_To_Neuron_Apalache.tla b/rs/nns/governance/tla/Disburse_To_Neuron_Apalache.tla new file mode 100644 index 00000000000..b28dda89c3e --- /dev/null +++ b/rs/nns/governance/tla/Disburse_To_Neuron_Apalache.tla @@ -0,0 +1,70 @@ +---- MODULE Disburse_To_Neuron_Apalache ---- + +EXTENDS TLC, Variants + +(* +@typeAlias: proc = Str; +@typeAlias: account = Str; +@typeAlias: neuronId = Int; +@typeAlias: methodCall = Transfer({ from: $account, to: $account, amount: Int, fee: Int}) | AccountBalance({ account: $account }); +@typeAlias: methodResponse = Fail(UNIT) | TransferOk(UNIT) | BalanceQueryOk(Int); +*) +_type_alias_dummy == TRUE + +\* CODE_LINK_INSERT_CONSTANTS + +(* +CONSTANTS + \* @type: Set($account); + Governance_Account_Ids, + \* @type: Set($neuronId); + Neuron_Ids + +CONSTANTS + \* @type: Set($proc); + Disburse_To_Neuron_Process_Ids + +CONSTANTS + \* Minimum stake a neuron can have + \* @type: Int; + MIN_STAKE, + \* The transfer fee charged by the ledger canister + \* @type: Int; + TRANSACTION_FEE +*) + +VARIABLES + \* @type: $neuronId -> {cached_stake: Int, account: $account, maturity: Int, fees: Int}; + neuron, + \* @type: $account -> $neuronId; + neuron_id_by_account, + \* @type: Set($neuronId); + locks, + \* @type: Seq({caller : $proc, method_and_args: $methodCall }); + governance_to_ledger, + \* @type: Set({caller: $proc, response: $methodResponse }); + ledger_to_governance, + \* @type: $proc -> Str; + pc, + \* @type: $proc -> $neuronId; + parent_neuron_id, + \* @type: $proc -> Int; + disburse_amount, + \* @type: $proc -> $account; + child_account_id, + \* @type: $proc -> $neuronId; + child_neuron_id, + \* Not used by this model, but it's a global variable used by spawn_neurons, so + \* it's the easiest to just add it to all the other models + \* @type: Bool; + spawning_neurons + +\* @type: Set($neuronId) => $neuronId; +FRESH_NEURON_ID(existing_neurons) == CHOOSE nid \in (Neuron_Ids \ existing_neurons): TRUE + +MOD == INSTANCE Disburse_To_Neuron + +Next == [MOD!Next]_MOD!vars + + +==== From 2828131f605b6008351fc57d1eaf2b40635a87f8 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:20:13 +0100 Subject: [PATCH 97/98] fix(PocketIC): safely drop StateMachine (#3450) This PR safely drops every StateMachine in PocketIC to prevent its state directory from being deleted before every Arc to its state manager is dropped. --- rs/pocket_ic_server/src/pocket_ic.rs | 34 ++++++++++++++++++++++++++-- rs/state_machine_tests/src/lib.rs | 14 ++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/rs/pocket_ic_server/src/pocket_ic.rs b/rs/pocket_ic_server/src/pocket_ic.rs index 220099396b0..a74a6011c70 100644 --- a/rs/pocket_ic_server/src/pocket_ic.rs +++ b/rs/pocket_ic_server/src/pocket_ic.rs @@ -384,6 +384,9 @@ impl SubnetsImpl { pub(crate) fn get_all(&self) -> Vec> { self.subnets.read().unwrap().values().cloned().collect() } + fn clear(&self) { + self.subnets.write().unwrap().clear(); + } } impl Subnets for SubnetsImpl { @@ -421,8 +424,8 @@ pub struct PocketIc { impl Drop for PocketIc { fn drop(&mut self) { - let subnets = self.subnets.get_all(); if let Some(ref state_dir) = self.state_dir { + let subnets = self.subnets.get_all(); for subnet in &subnets { subnet.state_machine.checkpointed_tick(); } @@ -452,9 +455,36 @@ impl Drop for PocketIc { let topology_json = serde_json::to_string(&raw_topology).unwrap(); topology_file.write_all(topology_json.as_bytes()).unwrap(); } - for subnet in subnets { + for subnet in self.subnets.get_all() { subnet.state_machine.drop_payload_builder(); } + let state_machines: Vec<_> = self + .subnets + .get_all() + .into_iter() + .map(|subnet| subnet.state_machine.clone()) + .collect(); + self.subnets.clear(); + // for every StateMachine, wait until nobody else has an Arc to that StateMachine + // and then drop that StateMachine + let start = std::time::Instant::now(); + for state_machine in state_machines { + let mut state_machine = Some(state_machine); + while state_machine.is_some() { + match Arc::try_unwrap(state_machine.take().unwrap()) { + Ok(sm) => { + sm.drop(); + break; + } + Err(sm) => { + state_machine = Some(sm); + } + } + if start.elapsed() > std::time::Duration::from_secs(5 * 60) { + panic!("Timed out while dropping PocketIC."); + } + } + } } } diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index 5031290b05a..c096015a556 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -1826,20 +1826,26 @@ impl StateMachine { fn into_components(self) -> (Box, u64, Time, u64) { let state_manager = Arc::downgrade(&self.state_manager); let result = self.into_components_inner(); - let mut i = 0i32; // StateManager is owned by an Arc, that is cloned into multiple components and different // threads. If we return before all the asynchronous components release the Arc, we may // end up with to StateManagers writing to the same directory, resulting in a crash. + let start = std::time::Instant::now(); while state_manager.upgrade().is_some() { std::thread::sleep(std::time::Duration::from_millis(50)); - i += 1; - if i >= 100 { - panic!("Failed to wait for StateManager drop"); + if start.elapsed() > std::time::Duration::from_secs(5 * 60) { + panic!("Timed out while dropping StateMachine."); } } result } + /// Safely drops this `StateMachine`. We cannot achieve this functionality by implementing `Drop` + /// since we have to wait until there are no more `Arc`s for the state manager and + /// this is infeasible in a `Drop` implementation. + pub fn drop(self) { + let _ = self.into_components(); + } + /// Emulates a node restart, including checkpoint recovery. pub fn restart_node(self) -> Self { // We must drop self before setup_form_dir so that we don't have two StateManagers pointing From f491f848c4da05a852186f0c2279e5bcb7ce60f8 Mon Sep 17 00:00:00 2001 From: kpop-dfinity <125868903+kpop-dfinity@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:26:04 +0100 Subject: [PATCH 98/98] refactor(consensus): simplify `IngressPayload` implementation (#3444) Currently the payload is one big bytes buffer which contains all ingress messages in a packed representation. This makes it a big hard to work with. In this PR we simplify the structure by replacing the buffer with a map from `IngressMessageId`s to a _serialized_ ingress messages. The following two important properties are preserved: 1. The individual ingress messages deserialization is delayed until it's actually needed 2. We preserve the original byte representation of the ingress messages I've ran multiple benchmarks and didn't notice a _big_ change: 1. `consensus-performance` system test showed the same throughput / block rates with both implementations 2. the [serialization/deserialization ](https://github.com/dfinity/ic/blob/master/rs/consensus/benches/validate_payload.rs#L374-L404) of ingress payload gets about 2x slower, but it's still in sub 1ms territory --------- Co-authored-by: Leon Tan --- .../src/consensus/malicious_consensus.rs | 4 +- rs/consensus/src/consensus/metrics.rs | 2 +- rs/consensus/src/consensus/purger.rs | 4 +- rs/ingress_manager/src/ingress_selector.rs | 36 ++- rs/interfaces/src/ingress_manager.rs | 10 +- .../src/fetch_stripped_artifact/download.rs | 4 +- .../src/fetch_stripped_artifact/stripper.rs | 2 +- rs/protobuf/def/types/v1/consensus.proto | 10 +- rs/protobuf/src/gen/types/types.v1.rs | 15 +- rs/state_machine_tests/src/lib.rs | 4 +- rs/types/types/src/batch/ingress.rs | 258 +++++++----------- rs/types/types/src/exhaustive.rs | 4 + rs/types/types/src/messages.rs | 1 + 13 files changed, 174 insertions(+), 180 deletions(-) diff --git a/rs/consensus/src/consensus/malicious_consensus.rs b/rs/consensus/src/consensus/malicious_consensus.rs index 4d7cdddee3c..5a9e5be9300 100644 --- a/rs/consensus/src/consensus/malicious_consensus.rs +++ b/rs/consensus/src/consensus/malicious_consensus.rs @@ -87,7 +87,9 @@ fn maliciously_propose_blocks( .get_block_maker_rank(height, &beacon, my_node_id) { Ok(Some(rank)) => Some(rank), - Ok(None) => Some(Rank(0)), + // TODO: introduce a malicious flag which will instruct a malicious node to propose a block + // when it's not elected a block maker; implement a system test which uses the flag. + Ok(None) => None, Err(_) => None, }; diff --git a/rs/consensus/src/consensus/metrics.rs b/rs/consensus/src/consensus/metrics.rs index 7bf58e7c898..b261ecb349d 100644 --- a/rs/consensus/src/consensus/metrics.rs +++ b/rs/consensus/src/consensus/metrics.rs @@ -157,7 +157,7 @@ impl BatchStats { self.ingress_message_bytes_delivered += payload.ingress.count_bytes(); self.xnet_bytes_delivered += payload.xnet.size_bytes(); self.ingress_ids - .extend_from_slice(&payload.ingress.message_ids()); + .extend(payload.ingress.message_ids().cloned()); } } diff --git a/rs/consensus/src/consensus/purger.rs b/rs/consensus/src/consensus/purger.rs index 915e3c944f1..d658233d79b 100644 --- a/rs/consensus/src/consensus/purger.rs +++ b/rs/consensus/src/consensus/purger.rs @@ -905,10 +905,10 @@ mod tests { non_finalized_notarization_2 )), ChangeAction::RemoveFromValidated(ConsensusMessage::BlockProposal( - non_finalized_block_proposal_2_1 + non_finalized_block_proposal_2_0 )), ChangeAction::RemoveFromValidated(ConsensusMessage::BlockProposal( - non_finalized_block_proposal_2_0 + non_finalized_block_proposal_2_1 )), ] ); diff --git a/rs/ingress_manager/src/ingress_selector.rs b/rs/ingress_manager/src/ingress_selector.rs index 02afb96e5fd..ad0f07f69e5 100644 --- a/rs/ingress_manager/src/ingress_selector.rs +++ b/rs/ingress_manager/src/ingress_selector.rs @@ -330,10 +330,29 @@ impl IngressSelector for IngressManager { // Tracks the sum of cycles needed per canister. let mut cycles_needed: BTreeMap = BTreeMap::new(); - for i in 0..payload.message_count() { - let (ingress_id, ingress) = payload - .get(i) - .map_err(InvalidIngressPayloadReason::IngressPayloadError)?; + + // Validate each ingress message in the payload + for (ingress_id, maybe_ingress) in payload.iter() { + let ingress = match maybe_ingress { + Ok(ingress) => ingress, + Err(deserialization_error) => { + return Err(ValidationError::InvalidArtifact( + InvalidIngressPayloadReason::IngressMessageDeserializationFailure( + ingress_id.clone(), + deserialization_error.to_string(), + ), + )); + } + }; + + if IngressMessageId::from(&ingress) != *ingress_id { + return Err(ValidationError::InvalidArtifact( + InvalidIngressPayloadReason::MismatchedMessageId { + expected: ingress_id.clone(), + computed: IngressMessageId::from(&ingress), + }, + )); + } self.validate_ingress( ingress_id.clone(), @@ -373,7 +392,7 @@ impl IngressSelector for IngressManager { let ingress = ingress_payload_cache .entry((*height, payload_hash.clone())) .or_insert_with(|| { - Arc::new(batch.ingress.message_ids().into_iter().collect()) + Arc::new(batch.ingress.message_ids().cloned().collect()) }); Some(ingress.clone()) } @@ -1046,11 +1065,8 @@ mod tests { assert_eq!(first_ingress_payload.message_count(), 1); // we should not get it again because it is part of past payloads - let mut hash_set = HashSet::new(); - for i in 0..first_ingress_payload.message_count() { - let (id, _) = first_ingress_payload.get(i).unwrap(); - hash_set.insert(id); - } + let hash_set = HashSet::from_iter(first_ingress_payload.message_ids().cloned()); + let second_ingress_payload = ingress_manager.get_ingress_payload( &hash_set, &validation_context, diff --git a/rs/interfaces/src/ingress_manager.rs b/rs/interfaces/src/ingress_manager.rs index 6814f89b977..7df69d29416 100644 --- a/rs/interfaces/src/ingress_manager.rs +++ b/rs/interfaces/src/ingress_manager.rs @@ -6,7 +6,7 @@ use crate::{ use ic_interfaces_state_manager::StateManagerError; use ic_types::{ artifact::IngressMessageId, - batch::{IngressPayload, IngressPayloadError, ValidationContext}, + batch::{IngressPayload, ValidationContext}, consensus::Payload, ingress::IngressSets, messages::MessageId, @@ -52,8 +52,14 @@ impl IngressSetQuery for IngressSets { /// Reasons for why an ingress payload might be invalid. #[derive(Eq, PartialEq, Debug)] pub enum InvalidIngressPayloadReason { + /// An [`IngressMessageId`] inside the payload doesn't match the referenced [`SignedIngress`]. + MismatchedMessageId { + expected: IngressMessageId, + computed: IngressMessageId, + }, + /// Failed to deserialize an ingress message. + IngressMessageDeserializationFailure(IngressMessageId, String), IngressValidationError(MessageId, String), - IngressPayloadError(IngressPayloadError), IngressExpired(MessageId, String), IngressMessageTooBig(usize, usize), IngressPayloadTooManyMessages(usize, usize), diff --git a/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/download.rs b/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/download.rs index 43a5f4a770f..4e6d6c0587b 100644 --- a/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/download.rs +++ b/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/download.rs @@ -84,11 +84,11 @@ impl Pools { }; match data_payload.batch.ingress.get_by_id(ingress_message_id) { - Some(ingress_message) => { + Ok(Some(ingress_message)) => { self.metrics.ingress_messages_in_block.inc(); Ok(ingress_message) } - None => { + _ => { self.metrics.ingress_messages_not_found.inc(); Err(PoolsAccessError::IngressMessageNotFound) } diff --git a/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/stripper.rs b/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/stripper.rs index 7bad4d70937..30fab0ed7ff 100644 --- a/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/stripper.rs +++ b/rs/p2p/artifact_downloader/src/fetch_stripped_artifact/stripper.rs @@ -55,7 +55,7 @@ impl Strippable for &IngressPayload { fn strip(self) -> Self::Output { Self::Output { - ingress_messages: self.message_ids(), + ingress_messages: self.message_ids().cloned().collect(), } } } diff --git a/rs/protobuf/def/types/v1/consensus.proto b/rs/protobuf/def/types/v1/consensus.proto index b788a2e1026..8737a307d34 100644 --- a/rs/protobuf/def/types/v1/consensus.proto +++ b/rs/protobuf/def/types/v1/consensus.proto @@ -204,9 +204,15 @@ message IngressIdOffset { uint64 offset = 3; } +message IngressMessage { + bytes message_id = 1; + uint64 expiry = 2; + bytes signed_request_bytes = 3; +} + message IngressPayload { - repeated IngressIdOffset id_and_pos = 1; - bytes buffer = 2; + reserved 1, 2; + repeated IngressMessage ingress_messages = 3; } // Stripped consensus artifacts messages below diff --git a/rs/protobuf/src/gen/types/types.v1.rs b/rs/protobuf/src/gen/types/types.v1.rs index 892c97432d9..1ac349addae 100644 --- a/rs/protobuf/src/gen/types/types.v1.rs +++ b/rs/protobuf/src/gen/types/types.v1.rs @@ -1528,11 +1528,18 @@ pub struct IngressIdOffset { pub offset: u64, } #[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressMessage { + #[prost(bytes = "vec", tag = "1")] + pub message_id: ::prost::alloc::vec::Vec, + #[prost(uint64, tag = "2")] + pub expiry: u64, + #[prost(bytes = "vec", tag = "3")] + pub signed_request_bytes: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] pub struct IngressPayload { - #[prost(message, repeated, tag = "1")] - pub id_and_pos: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", tag = "2")] - pub buffer: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub ingress_messages: ::prost::alloc::vec::Vec, } /// Stripped consensus artifacts messages below #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/rs/state_machine_tests/src/lib.rs b/rs/state_machine_tests/src/lib.rs index c096015a556..a9aa8347b27 100644 --- a/rs/state_machine_tests/src/lib.rs +++ b/rs/state_machine_tests/src/lib.rs @@ -1370,9 +1370,7 @@ impl StateMachine { // used by the function `Self::execute_payload` of the `StateMachine`. let xnet_payload = batch_payload.xnet.clone(); let ingress = &batch_payload.ingress; - let ingress_messages = (0..ingress.message_count()) - .map(|i| ingress.get(i).unwrap().1) - .collect(); + let ingress_messages = ingress.clone().try_into().unwrap(); let (http_responses, _) = CanisterHttpPayloadBuilderImpl::into_messages(&batch_payload.canister_http); let inducted: Vec<_> = http_responses diff --git a/rs/types/types/src/batch/ingress.rs b/rs/types/types/src/batch/ingress.rs index 467136fe982..e1379a92870 100644 --- a/rs/types/types/src/batch/ingress.rs +++ b/rs/types/types/src/batch/ingress.rs @@ -1,45 +1,42 @@ use crate::{ artifact::IngressMessageId, - messages::{MessageId, SignedIngress, SignedRequestBytes, EXPECTED_MESSAGE_ID_LENGTH}, + messages::{ + HttpRequestError, MessageId, SignedIngress, SignedRequestBytes, EXPECTED_MESSAGE_ID_LENGTH, + }, CountBytes, Time, }; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; use ic_protobuf::{proxy::ProxyDecodeError, types::v1 as pb}; use serde::{Deserialize, Serialize}; -use std::{ - convert::TryFrom, - io::{Cursor, Write}, -}; +use std::{collections::BTreeMap, convert::TryFrom, fmt::Display}; /// Payload that contains Ingress messages #[derive(Clone, Eq, PartialEq, Hash, Debug, Default, Deserialize, Serialize)] #[cfg_attr(test, derive(ExhaustiveSet))] pub struct IngressPayload { - /// Pairs of MessageId and its serialized byte position in the buffer. - id_and_pos: Vec<(IngressMessageId, u64)>, - /// All messages are serialized in a single byte buffer, so individual + /// Keep ingress messages in a serialized form, so individual /// deserialization is delayed. This allows faster deserialization of /// IngressPayload when individual message is not needed (e.g. in /// ingress payload deduplication). - #[serde(with = "serde_bytes")] - buffer: Vec, + serialized_ingress_messages: BTreeMap, } impl From<&IngressPayload> for pb::IngressPayload { fn from(ingress_payload: &IngressPayload) -> Self { - Self { - id_and_pos: ingress_payload - .id_and_pos - .iter() - .map(|(msg_id, offset)| pb::IngressIdOffset { - expiry: msg_id.expiry().as_nanos_since_unix_epoch(), - message_id: msg_id.message_id.as_bytes().to_vec(), - offset: *offset, - }) - .collect(), - buffer: ingress_payload.buffer.clone(), - } + let ingress_messages = ingress_payload + .serialized_ingress_messages + .iter() + .map( + |(ingress_message_id, serialized_ingress_message)| pb::IngressMessage { + expiry: ingress_message_id.expiry().as_nanos_since_unix_epoch(), + message_id: ingress_message_id.message_id.as_bytes().to_vec(), + signed_request_bytes: serialized_ingress_message.as_ref().to_vec(), + }, + ) + .collect(); + + pb::IngressPayload { ingress_messages } } } @@ -47,131 +44,99 @@ impl TryFrom for IngressPayload { type Error = ProxyDecodeError; fn try_from(payload: pb::IngressPayload) -> Result { + let mut serialized_ingress_messages = BTreeMap::new(); + + for ingress_message_proto in payload.ingress_messages { + let ingress_message_id = IngressMessageId::new( + Time::from_nanos_since_unix_epoch(ingress_message_proto.expiry), + MessageId::try_from(ingress_message_proto.message_id.as_slice())?, + ); + + serialized_ingress_messages.insert( + ingress_message_id, + SignedRequestBytes::from(ingress_message_proto.signed_request_bytes), + ); + } + Ok(Self { - id_and_pos: payload - .id_and_pos - .iter() - .map(|ingress_offset| { - Ok(( - IngressMessageId::new( - Time::from_nanos_since_unix_epoch(ingress_offset.expiry), - MessageId::try_from(ingress_offset.message_id.as_slice())?, - ), - ingress_offset.offset, - )) - }) - .collect::, ProxyDecodeError>>()?, - buffer: payload.buffer, + serialized_ingress_messages, }) } } -/// Index of an ingress message in the IngressPayload. -type IngressIndex = usize; +#[derive(Debug, PartialEq)] +pub struct IngressPayloadError(HttpRequestError); -/// Position of serialized ingress message in the payload buffer. -type BufferPosition = u64; - -#[derive(Eq, PartialEq, Debug)] -/// Possible errors when accessing messages in an [`IngressPayload`]. -pub enum IngressPayloadError { - IndexOutOfBound(IngressIndex), - IngressPositionOutOfBound(IngressIndex, BufferPosition), - DeserializationFailure(String), - MismatchedMessageIdAtIndex(IngressIndex), +impl Display for IngressPayloadError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } } impl IngressPayload { /// Return the number of ingress messages contained in this payload pub fn message_count(&self) -> usize { - self.id_and_pos.len() + self.serialized_ingress_messages.len() } - /// Return all MessageIds in the payload. - pub fn message_ids(&self) -> Vec { - self.id_and_pos - .iter() - .map(|(id, _)| id.clone()) - .collect::>() + /// Return all [`IngressMessageId`]s in the payload. + pub fn message_ids(&self) -> impl Iterator { + self.serialized_ingress_messages.keys() } /// Return true if the payload is empty. pub fn is_empty(&self) -> bool { - self.id_and_pos.is_empty() + self.serialized_ingress_messages.is_empty() } - // TODO(kpop): run some benchmarks and see if it makes sense to change the type of - // `[IngressPayload::id_and_pos]` - pub fn get_by_id(&self, ingress_message_id: &IngressMessageId) -> Option { - let (index, _) = self - .id_and_pos - .iter() - .enumerate() - .find(|(_, (id, _))| id == ingress_message_id)?; - - self.get(index) - .map(|(_, ingress_message)| ingress_message) - .ok() + /// Return the [`SignedIngress`] referenced by the [`IngressMessageId`]. + /// Return [`IngressPayloadError`] if we fail to deserialize the message. + pub fn get_by_id( + &self, + ingress_message_id: &IngressMessageId, + ) -> Result, IngressPayloadError> { + self.serialized_ingress_messages + .get(ingress_message_id) + .map(|bytes| SignedIngress::try_from(bytes.clone()).map_err(IngressPayloadError)) + .transpose() } - /// Return the ingress message at a given index, which is expected to be - /// less than `message_count`. - pub fn get( + /// Iterates over the ingress messages in their deserialized form. + pub fn iter( &self, - index: usize, - ) -> Result<(IngressMessageId, SignedIngress), IngressPayloadError> { - self.id_and_pos - .get(index) - .ok_or(IngressPayloadError::IndexOutOfBound(index)) - .and_then(|(id, pos)| { - // Return error if pos is out of bound. - if *pos > self.buffer.len() as u64 { - Err(IngressPayloadError::IngressPositionOutOfBound(index, *pos)) - } else { - let end = { - if index == self.id_and_pos.len() - 1 { - self.buffer.len() - } else { - self.id_and_pos[index + 1].1 as usize - } - }; - let ingress = SignedIngress::try_from(SignedRequestBytes::from(Vec::from( - &self.buffer[*pos as usize..end], - ))) - .map_err(|e| IngressPayloadError::DeserializationFailure(e.to_string()))?; - let ingress_id = IngressMessageId::from(&ingress); - if *id == ingress_id { - Ok((ingress_id, ingress)) - } else { - Err(IngressPayloadError::MismatchedMessageIdAtIndex(index)) - } - } - }) + ) -> impl Iterator< + Item = ( + &IngressMessageId, + Result, + ), + > { + self.serialized_ingress_messages.iter().map(|(id, bytes)| { + ( + id, + SignedIngress::try_from(bytes.clone()).map_err(IngressPayloadError), + ) + }) } } impl CountBytes for IngressPayload { fn count_bytes(&self) -> usize { - self.buffer.len() + self.id_and_pos.len() * EXPECTED_MESSAGE_ID_LENGTH + self.serialized_ingress_messages + .values() + .map(|message| EXPECTED_MESSAGE_ID_LENGTH + message.len()) + .sum() } } impl<'a> FromIterator<&'a SignedIngress> for IngressPayload { fn from_iter>(msgs: I) -> Self { - let mut buf = Cursor::new(Vec::new()); - let mut id_and_pos = Vec::new(); - for ingress in msgs { - let id = IngressMessageId::from(ingress); - let pos = buf.position(); - // This panic will only happen when we run out of memory. - buf.write_all(ingress.binary().as_ref()) - .unwrap_or_else(|err| panic!("SignedIngress serialization error: {:?}", err)); + let serialized_ingress_messages = msgs + .into_iter() + .map(|ingress| (IngressMessageId::from(ingress), ingress.binary().clone())) + .collect(); - id_and_pos.push((id, pos)); - } Self { - id_and_pos, - buffer: buf.into_inner(), + serialized_ingress_messages, } } } @@ -184,13 +149,14 @@ impl From> for IngressPayload { impl TryFrom for Vec { type Error = IngressPayloadError; + fn try_from(payload: IngressPayload) -> Result, Self::Error> { payload - .id_and_pos - .iter() - .enumerate() - .map(|(i, _)| payload.get(i).map(|m| m.1)) - .collect::>() + .serialized_ingress_messages + .into_values() + .map(SignedIngress::try_from) + .collect::, _>>() + .map_err(IngressPayloadError) } } @@ -204,7 +170,6 @@ mod tests { }, time::expiry_time_from_now, }; - use assert_matches::assert_matches; use std::convert::TryFrom; fn fake_http_call_content(method_name: &str) -> HttpCallContent { @@ -247,12 +212,19 @@ mod tests { )]), }, ]; - let signed_ingresses: Vec = update_messages + let mut signed_ingresses: Vec = update_messages .into_iter() .map(|msg| SignedIngress::try_from(msg).unwrap()) .collect(); + let ingress_payload = IngressPayload::from(signed_ingresses.clone()); let signed_ingresses1 = Vec::::try_from(ingress_payload).unwrap(); + // ingress messages are sorted by id in the ingress payload, hence the sort below + signed_ingresses.sort_by(|msg_1, msg_2| { + IngressMessageId::from(msg_1) + .partial_cmp(&IngressMessageId::from(msg_2)) + .unwrap() + }); assert_eq!(signed_ingresses, signed_ingresses1); } @@ -274,50 +246,32 @@ mod tests { sender_delegation: None, }; - SignedIngress::try_from(message).unwrap() + let ingress = SignedIngress::try_from(message).unwrap(); + let id = IngressMessageId::from(&ingress); + + (ingress, id) }; // Some test messages. - let m1 = fake_ingress_message("m1"); - let m1_id = m1.id(); - let m2 = fake_ingress_message("m2"); - let m3 = fake_ingress_message("m3"); + let (m1, id1) = fake_ingress_message("m1"); + let (m2, id2) = fake_ingress_message("m2"); + let (m3, id3) = fake_ingress_message("m3"); + let (_m4, id4) = fake_ingress_message("m4"); - let msgs = vec![m1, m2, m3]; + let msgs = vec![m1.clone(), m2.clone(), m3.clone()]; let payload = IngressPayload::from(msgs.clone()); // Serialization/deserialization works. - let mut bytes = bincode::serialize(&payload).unwrap(); + let bytes = bincode::serialize(&payload).unwrap(); assert_eq!( bincode::deserialize::(&bytes).unwrap(), payload ); // Individual lookup works. - assert_matches!(payload.get(0).unwrap(), (_, msg) if msg == msgs[0]); - assert_matches!(payload.get(1).unwrap(), (_, msg) if msg == msgs[1]); - assert_matches!(payload.get(2).unwrap(), (_, msg) if msg == msgs[2]); - // Test IndexOutOfBound. - assert_matches!(payload.get(3), Err(IngressPayloadError::IndexOutOfBound(3))); + assert_eq!(payload.get_by_id(&id1), Ok(Some(m1))); + assert_eq!(payload.get_by_id(&id2), Ok(Some(m2))); + assert_eq!(payload.get_by_id(&id3), Ok(Some(m3))); + assert_eq!(payload.get_by_id(&id4), Ok(None)); // Converting back to messages should match original assert_eq!(msgs, >::try_from(payload).unwrap()); - - // A sub-sequence search function - fn find(array: &[u8], subseq: &[u8]) -> Option { - (0..array.len() - subseq.len() + 1).find(|&i| array[i..i + subseq.len()] == subseq[..]) - } - - // Mutate some byte, deserialization works, but casting back to messages fail. - let pos = find(&bytes, m1_id.as_bytes()).unwrap(); - // `+= 1` may overflow in debug mode. - bytes[pos] ^= 1; - let payload = bincode::deserialize::(&bytes); - assert!(payload.is_ok()); - let payload = payload.unwrap(); - // get(0) should return error. - assert_matches!( - payload.get(0), - Err(IngressPayloadError::MismatchedMessageIdAtIndex(0)) - ); - // Conversion should also fail. - assert!(>::try_from(payload).is_err()); } } diff --git a/rs/types/types/src/exhaustive.rs b/rs/types/types/src/exhaustive.rs index dfeb87fb86f..7589ffdb70e 100644 --- a/rs/types/types/src/exhaustive.rs +++ b/rs/types/types/src/exhaustive.rs @@ -1,5 +1,6 @@ //! Implementations and serialization tests of the ExhaustiveSet trait +use crate::artifact::IngressMessageId; use crate::consensus::hashed::Hashed; use crate::consensus::idkg::common::{PreSignatureInCreation, PreSignatureRef}; use crate::consensus::idkg::ecdsa::QuadrupleInCreation; @@ -28,6 +29,7 @@ use crate::crypto::{ CombinedThresholdSig, CombinedThresholdSigOf, CryptoHash, CryptoHashOf, CryptoHashable, IndividualMultiSig, IndividualMultiSigOf, Signed, ThresholdSigShare, ThresholdSigShareOf, }; +use crate::messages::SignedRequestBytes; use crate::signature::{ BasicSignature, BasicSignatureBatch, MultiSignature, MultiSignatureShare, ThresholdSignature, ThresholdSignatureShare, @@ -1002,6 +1004,8 @@ impl HasId for MasterKeyTranscript { } } +impl HasId for SignedRequestBytes {} + impl HasId for ReshareOfUnmaskedParams {} impl HasId for CompletedSignature {} impl HasId for CompletedReshareRequest {} diff --git a/rs/types/types/src/messages.rs b/rs/types/types/src/messages.rs index 6a348076d36..3a5df6ff044 100644 --- a/rs/types/types/src/messages.rs +++ b/rs/types/types/src/messages.rs @@ -270,6 +270,7 @@ impl TryFrom for StopCanisterContext { /// format. Use `TryFrom` or `TryInto` to convert between `SignedRequestBytes` /// and other types, corresponding to serialization/deserialization. #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] +#[cfg_attr(test, derive(ExhaustiveSet))] pub struct SignedRequestBytes(#[serde(with = "serde_bytes")] Vec); impl AsRef<[u8]> for SignedRequestBytes {