Skip to content
1 change: 1 addition & 0 deletions rs/execution_environment/tests/execution_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2874,6 +2874,7 @@ fn resource_limits() {
let maximum_state_size = NumBytes::new(1 << 30);
let resource_limits = ResourceLimits {
maximum_state_size: Some(maximum_state_size),
maximum_state_delta: None,
};
let subnet_config = SubnetConfig::new(SubnetType::Application);
let hypervisor_config = HypervisorConfig {
Expand Down
9 changes: 9 additions & 0 deletions rs/messaging/src/message_routing/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ fn try_read_registry_succeeds_with_fully_specified_registry_records() {
// Own subnet characteristics.
let own_subnet_id = subnet_test_id(13);
let own_maximum_state_size = NumBytes::new(1 << 30);
let own_maximum_state_delta = NumBytes::new(1 << 20);
let own_subnet_record = SubnetRecord {
membership: &[node_test_id(1), node_test_id(2)],
subnet_type: SubnetType::Application,
Expand Down Expand Up @@ -763,6 +764,7 @@ fn try_read_registry_succeeds_with_fully_specified_registry_records() {

resource_limits: ResourceLimits {
maximum_state_size: Some(own_maximum_state_size),
maximum_state_delta: Some(own_maximum_state_delta),
},

..Default::default()
Expand Down Expand Up @@ -1067,6 +1069,13 @@ fn try_read_registry_succeeds_with_fully_specified_registry_records() {
latest_state.metadata.own_resource_limits.maximum_state_size,
Some(own_maximum_state_size)
);
assert_eq!(
latest_state
.metadata
.own_resource_limits
.maximum_state_delta,
Some(own_maximum_state_delta)
);
assert_eq!(
*registry_settings.lock().unwrap(),
registry_execution_settings,
Expand Down
5 changes: 3 additions & 2 deletions rs/protobuf/def/registry/subnet/v1/subnet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ message SubnetRecord {
// they check the latest registry version for recalled_replica_version_ids.
repeated string recalled_replica_version_ids = 33;

// Limits on resource consumption (e.g., disk usage).
// Limits on resource consumption (e.g., memory usage).
ResourceLimits resource_limits = 34;

reserved 1, 2, 4, 6, 13, 20, 21, 22, 27;
Expand Down Expand Up @@ -402,7 +402,8 @@ enum CanisterCyclesCostSchedule {
CANISTER_CYCLES_COST_SCHEDULE_FREE = 2;
}

// Limits on resource consumption (e.g., disk usage).
// Limits on resource consumption (e.g., memory usage).
message ResourceLimits {
optional uint64 maximum_state_size = 1;
optional uint64 maximum_state_delta = 2;
}
6 changes: 4 additions & 2 deletions rs/protobuf/src/gen/registry/registry.subnet.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub struct SubnetRecord {
/// they check the latest registry version for recalled_replica_version_ids.
#[prost(string, repeated, tag = "33")]
pub recalled_replica_version_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[prost(message, optional, tag = "34")]
pub resource_limits: ::core::option::Option<ResourceLimits>,
}
Expand Down Expand Up @@ -417,7 +417,7 @@ pub struct ChainKeyConfig {
#[prost(uint32, optional, tag = "4")]
pub max_parallel_pre_signature_transcripts_in_creation: ::core::option::Option<u32>,
}
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[derive(
serde::Serialize,
serde::Deserialize,
Expand All @@ -431,6 +431,8 @@ pub struct ChainKeyConfig {
pub struct ResourceLimits {
#[prost(uint64, optional, tag = "1")]
pub maximum_state_size: ::core::option::Option<u64>,
#[prost(uint64, optional, tag = "2")]
pub maximum_state_delta: ::core::option::Option<u64>,
}
#[derive(
serde::Serialize,
Expand Down
6 changes: 4 additions & 2 deletions rs/protobuf/src/gen/state/registry.subnet.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub struct SubnetRecord {
/// they check the latest registry version for recalled_replica_version_ids.
#[prost(string, repeated, tag = "33")]
pub recalled_replica_version_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[prost(message, optional, tag = "34")]
pub resource_limits: ::core::option::Option<ResourceLimits>,
}
Expand Down Expand Up @@ -408,11 +408,13 @@ pub struct ChainKeyConfig {
#[prost(uint32, optional, tag = "4")]
pub max_parallel_pre_signature_transcripts_in_creation: ::core::option::Option<u32>,
}
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct ResourceLimits {
#[prost(uint64, optional, tag = "1")]
pub maximum_state_size: ::core::option::Option<u64>,
#[prost(uint64, optional, tag = "2")]
pub maximum_state_delta: ::core::option::Option<u64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
Expand Down
6 changes: 4 additions & 2 deletions rs/protobuf/src/gen/types/registry.subnet.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub struct SubnetRecord {
/// they check the latest registry version for recalled_replica_version_ids.
#[prost(string, repeated, tag = "33")]
pub recalled_replica_version_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[prost(message, optional, tag = "34")]
pub resource_limits: ::core::option::Option<ResourceLimits>,
}
Expand Down Expand Up @@ -408,11 +408,13 @@ pub struct ChainKeyConfig {
#[prost(uint32, optional, tag = "4")]
pub max_parallel_pre_signature_transcripts_in_creation: ::core::option::Option<u32>,
}
/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct ResourceLimits {
#[prost(uint64, optional, tag = "1")]
pub maximum_state_size: ::core::option::Option<u64>,
#[prost(uint64, optional, tag = "2")]
pub maximum_state_delta: ::core::option::Option<u64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
Expand Down
1 change: 1 addition & 0 deletions rs/registry/canister/canister/registry.did
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type CompleteCanisterMigrationPayload = record {

type ResourceLimits = record {
maximum_state_size : opt nat64;
maximum_state_delta : opt nat64;
};

type CreateSubnetPayload = record {
Expand Down
1 change: 1 addition & 0 deletions rs/registry/canister/canister/registry_test.did
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type CompleteCanisterMigrationPayload = record {

type ResourceLimits = record {
maximum_state_size : opt nat64;
maximum_state_delta : opt nat64;
};

type CreateSubnetPayload = record {
Expand Down
2 changes: 2 additions & 0 deletions rs/registry/canister/unreleased_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on the process that this file is part of, see
# Next Upgrade Proposal

## Added
* Added an optional field `maximum_state_delta` to `ResourceLimits` in `CreateSubnetPayload` which, when present,
sets a soft limit on the maximum (replicated) state *delta* (kept in main memory) in bytes.

## Changed

Expand Down
12 changes: 10 additions & 2 deletions rs/registry/resource_limits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@ use ic_protobuf::registry::subnet::v1 as pb;
use ic_types::NumBytes;
use serde::{Deserialize, Serialize};

/// Limits on resource consumption (e.g., disk usage).
/// Limits on resource consumption (e.g., memory usage).
#[derive(CandidType, Copy, Clone, Eq, PartialEq, Debug, Default, Serialize, Deserialize)]
pub struct ResourceLimits {
// The maximum size of the (replicated) state in bytes.
/// The maximum size of the (replicated) state in bytes.
/// This is a hard limit, i.e., messages that attempt to increase the state size
/// beyond the limit fail.
pub maximum_state_size: Option<NumBytes>,
/// The maximum size of the (replicated) state *delta* (kept in main memory) in bytes.
/// This is a soft limit, i.e., the actual size of the state delta can exceed the limit,
/// but no more messages are executed while the limit is exceeded.
pub maximum_state_delta: Option<NumBytes>,
}

impl From<ResourceLimits> for pb::ResourceLimits {
fn from(resource_limits: ResourceLimits) -> Self {
Self {
maximum_state_size: resource_limits.maximum_state_size.map(|x| x.get()),
maximum_state_delta: resource_limits.maximum_state_delta.map(|x| x.get()),
}
}
}
Expand All @@ -25,6 +32,7 @@ impl From<pb::ResourceLimits> for ResourceLimits {
fn from(resource_limits: pb::ResourceLimits) -> Self {
Self {
maximum_state_size: resource_limits.maximum_state_size.map(NumBytes::from),
maximum_state_delta: resource_limits.maximum_state_delta.map(NumBytes::from),
}
}
}
Loading