Skip to content

Commit

Permalink
Merge Preparation: Latest IC with Integrated EOP (#4638)
Browse files Browse the repository at this point in the history
* Adjust to new system API

* Port to latest IC 64-bit system API

* Update to new IC with Wasm64

* Updating nix hashes

* Update IC dependency (Wasm64 enabled)

* Update expected test results

* Fix migration test

* Use latest `drun`

* Adjust expected test results

* Updating nix hashes

* Update expected test results

* Fix `drun` nix build for Linux

* Disable DTS in `drun`, refactor `drun` patches

* Update expected test results for new `drun`

* Limiting amount of stable memory accessed per graph copy increment

* Reformat

* Manual merge conflict resolution

* Manual merge conflict resolution

* Adjust expected test result

---------

Co-authored-by: Nix hash updater <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
luc-blaeser and github-actions[bot] authored Aug 20, 2024
1 parent 1f7c2f3 commit edb23df
Show file tree
Hide file tree
Showing 106 changed files with 653 additions and 368 deletions.
4 changes: 2 additions & 2 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ let
};
})

# Rust 1.69
# Rust stable
(self: super: let
rust-channel = self.moz_overlay.rustChannelOf { date = "2023-04-20"; channel = "stable"; };
rust-channel = self.moz_overlay.rustChannelOf { version = "1.78.0"; channel = "stable"; };
in {
rustPlatform_moz_stable = self.makeRustPlatform {
rustc = rust-channel.rust;
Expand Down
67 changes: 60 additions & 7 deletions nix/drun.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pkgs:
{ drun =
pkgs.rustPlatform.buildRustPackage {
pkgs.rustPlatform_moz_stable.buildRustPackage {
name = "drun";

src = pkgs.sources.ic;
Expand All @@ -19,12 +19,10 @@ pkgs:
lockFile = "${pkgs.sources.ic}/Cargo.lock";
outputHashes = {
"build-info-0.0.27" = "sha256-SkwWwDNrTsntkNiCv6rsyTFGazhpRDnKtVzPpYLKF9U=";
"derive_more-0.99.8-alpha.0" = "sha256-tEsfYC9oCAsDjinCsUDgRg3q6ruvayuA1lRmsEP9cys=";
"ic-btc-interface-0.1.0" = "sha256-JoVg1t62C2FIe0la1oQzidybLj1CyAQy80gkRh/MTn0=";
"ic-btc-test-utils-0.1.0" = "sha256-VecEMFjoeiRi0VgJ9CeDoOzdyJbJNiZ5MBmiV1+b7As=";
"icrc1-test-env-0.1.1" = "sha256-yWJF+KM8l65Nr0pwR9QeltkqbHDzOLNPVnLhf1mRukQ=";
"cloudflare-0.11.0" = "sha256-bJYiypmDI4KEy/VWt/7UcOv+g2CZLb9qUA9c1xlLxhM=";
"ic-agent-0.36.0" = "sha256-vDONIVjz0cwVgiszVRIjTKcqRUMHdVwTURflAMqmzHM=";
"icrc1-test-env-0.1.1" = "sha256-2PB7e64Owin/Eji3k8UoeWs+pfDfOOTaAyXjvjOZ/4g=";
"jsonrpc-0.12.1" = "sha256-3FtdZlt2PqVDkE5iKWYIp1eiIELsaYlUPRSP2Xp8ejM=";
"libssh2-sys-0.2.23" = "sha256-9Hb7CnPF+lxrVO1NAhS7EXcPVWZutJXr6UWxpptzk4U=";
"lmdb-rkv-0.14.99" = "sha256-5WcUzapkrc/s3wCBNCuUDhtbp17n67rTbm2rx0qtITg=";
};
};
Expand All @@ -43,9 +41,64 @@ pkgs:
for file in lib_sources {
EOF
cd -
# Disable DTS for `drun`
patch rs/config/src/subnet_config.rs << EOF
@@ -290,9 +290,9 @@ impl SchedulerConfig {
}
pub fn system_subnet() -> Self {
- let max_instructions_per_message_without_dts = NumInstructions::from(50 * B);
+ let max_instructions_per_message_without_dts =
+ MAX_INSTRUCTIONS_PER_MESSAGE_WITHOUT_DTS * SYSTEM_SUBNET_FACTOR;
let max_instructions_per_install_code = NumInstructions::from(1_000 * B);
- let max_instructions_per_slice = NumInstructions::from(10 * B);
Self {
scheduler_cores: NUMBER_OF_EXECUTION_THREADS,
max_paused_executions: MAX_PAUSED_EXECUTIONS,
@@ -300,20 +300,19 @@ impl SchedulerConfig {
// TODO(RUN-993): Enable heap delta rate limiting for system subnets.
// Setting initial reserve to capacity effectively disables the rate limiting.
heap_delta_initial_reserve: SUBNET_HEAP_DELTA_CAPACITY,
- // Round limit is set to allow on average 2B instructions.
- // See also comment about \`MAX_INSTRUCTIONS_PER_ROUND\`.
- max_instructions_per_round: max_instructions_per_message_without_dts
- .max(max_instructions_per_slice)
- + NumInstructions::from(2 * B),
+ max_instructions_per_round: MAX_INSTRUCTIONS_PER_ROUND * SYSTEM_SUBNET_FACTOR,
+ // Effectively disable DTS on system subnets.
max_instructions_per_message: max_instructions_per_message_without_dts,
max_instructions_per_message_without_dts,
- max_instructions_per_slice,
+ // Effectively disable DTS on system subnets.
+ max_instructions_per_slice: max_instructions_per_message_without_dts,
instruction_overhead_per_execution: INSTRUCTION_OVERHEAD_PER_EXECUTION,
instruction_overhead_per_canister: INSTRUCTION_OVERHEAD_PER_CANISTER,
instruction_overhead_per_canister_for_finalization:
INSTRUCTION_OVERHEAD_PER_CANISTER_FOR_FINALIZATION,
max_instructions_per_install_code,
- max_instructions_per_install_code_slice: max_instructions_per_slice,
+ // Effectively disable DTS on system subnets.
+ max_instructions_per_install_code_slice: max_instructions_per_install_code,
max_heap_delta_per_iteration: MAX_HEAP_DELTA_PER_ITERATION * SYSTEM_SUBNET_FACTOR,
max_message_duration_before_warn_in_seconds:
MAX_MESSAGE_DURATION_BEFORE_WARN_IN_SECONDS,
EOF
# static linking of libunwind fails under nix Linux
patch rs/monitoring/backtrace/build.rs << EOF
@@ -1,8 +1,2 @@
fn main() {
- if std::env::var("TARGET").unwrap() == "x86_64-unknown-linux-gnu" {
- println!("cargo:rustc-link-lib=static=unwind");
- println!("cargo:rustc-link-lib=static=unwind-ptrace");
- println!("cargo:rustc-link-lib=static=unwind-x86_64");
- println!("cargo:rustc-link-lib=dylib=lzma");
- }
}
EOF
mkdir -p .cargo
cat > .cargo/config.toml << EOF
[target.x86_64-apple-darwin]
Expand Down
10 changes: 5 additions & 5 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
"version": "3.2.25"
},
"ic": {
"branch": "pull/143/head",
"branch": "luc/latest-ic-wasm64-test",
"description": "Internet Computer blockchain source: the client/replica software run by nodes",
"homepage": "",
"owner": "dfinity",
"owner": "luc-blaeser",
"repo": "ic",
"rev": "31f02c1b08aef1c6ee4c1b6bb9d25c21c5a4ff41",
"sha256": "04k278900kv082axrgv6vga0n8sw6c3lcc9298ih9gjyx8hanfb1",
"rev": "7921f5f3dc0d9fb774e3222f8ff6b1c00a086f1a",
"sha256": "1ykawbpaqnf1y508vh81m30p813ykmnbffxc3p0hw0p0k1ynq6zz",
"type": "tarball",
"url": "https://github.com/dfinity/ic/archive/31f02c1b08aef1c6ee4c1b6bb9d25c21c5a4ff41.tar.gz",
"url": "https://github.com/luc-blaeser/ic/archive/7921f5f3dc0d9fb774e3222f8ff6b1c00a086f1a.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ic-hs": {
Expand Down
23 changes: 13 additions & 10 deletions rts/motoko-rts/src/stabilization/deserialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use self::{scan_stack::ScanStack, stable_memory_access::StableMemoryAccess};

use super::{
clear_stable_memory,
graph_copy::{limit::InstructionLimit, GraphCopy},
graph_copy::{limit::ExecutionLimit, GraphCopy},
layout::{deserialize, StableValue},
moc_stabilization_instruction_limit,
};
Expand All @@ -25,7 +25,7 @@ pub struct Deserialization {
stable_start: u64,
stable_size: u64,
stable_root: Option<Value>,
limit: InstructionLimit,
limit: ExecutionLimit,
clear_position: u64,
}

Expand Down Expand Up @@ -62,7 +62,7 @@ impl Deserialization {
pub fn start<M: Memory>(mem: &mut M, stable_start: u64, stable_size: u64) -> Deserialization {
let from_space = StableMemoryAccess::open(stable_start, stable_size);
let scan_stack = unsafe { ScanStack::new(mem) };
let limit = InstructionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let limit = ExecutionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let mut deserialization = Deserialization {
from_space,
scan_stack,
Expand Down Expand Up @@ -115,6 +115,13 @@ impl Deserialization {
fn stable_end(&self) -> u64 {
self.stable_start.checked_add(self.stable_size).unwrap()
}

fn processed_memory(&self) -> u64 {
let deserialized_memory = unsafe { deserialized_size() as u64 };
debug_assert!(self.clear_position >= self.stable_start);
let cleared_memory = self.clear_position - self.stable_start;
deserialized_memory + cleared_memory
}
}

impl GraphCopy<StableValue, Value, u32> for Deserialization {
Expand Down Expand Up @@ -196,16 +203,12 @@ impl GraphCopy<StableValue, Value, u32> for Deserialization {
}

fn time_over(&mut self) -> bool {
let deserialized_memory = unsafe { deserialized_size() as u64 };
debug_assert!(self.clear_position >= self.stable_start);
let cleared_memory = self.clear_position - self.stable_start;
let processed_memory = deserialized_memory + cleared_memory;
self.limit.is_exceeded(processed_memory)
self.limit.is_exceeded(self.processed_memory())
}

fn reset_time(&mut self) {
let limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(limit);
let instruction_limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(instruction_limit, self.processed_memory());
}
}

Expand Down
54 changes: 38 additions & 16 deletions rts/motoko-rts/src/stabilization/graph_copy/limit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
use crate::{constants::KB, stabilization::ic0_performance_counter};
use crate::{
constants::{GB, KB},
stabilization::ic0_performance_counter,
};

/// Instruction limit for the graph copy increment.
/// Monitoring the message instruction counter.
/// Maximum amount of memory that is processed per increment.
/// The IC configures a maximum of 2 GB of stable memory that can
/// be accessed per message. We keep a conservative reserve of 1 GB.
const MEMORY_PROCESSING_LIMIT_PER_INCREMENT: u64 = GB as u64;

/// Execution limit for the graph copy increment.
/// Monitoring the message instruction counter and
/// the amount of processed memory.
/// The latter is relevant to avoid exceeding the limit
/// of how much stable memory be accessed in a message.
/// Optimization: Avoiding frequent repeated calls to
/// `ic0_performance_counter()` as this incurs 200
/// instructions itself.
Expand All @@ -18,11 +29,13 @@ use crate::{constants::KB, stabilization::ic0_performance_counter};
/// Once the limit has been exceeded, the heuristics
/// continuously returns exceeded until the monitoring
/// is reset.
pub struct InstructionLimit {
pub struct ExecutionLimit {
/// Instruction counter at the beginning of the measurement.
start: u64,
initial_instruction_counter: u64,
/// Limit of processed instructions since measurment start.
limit: u64,
instruction_limit: u64,
/// Amount of processed memory before the measurement.
initial_processed_memory: u64,
// Only used for sporadic synchronization heuristics:
/// Number of `is_exceeded` calls since the last instruction
/// counter synchronization.
Expand All @@ -34,25 +47,33 @@ pub struct InstructionLimit {
exceeded: bool,
}

impl InstructionLimit {
impl ExecutionLimit {
/// Threshold on the number of `is_exceeded` calls since the
/// last instruction counter synchronization.
const CALL_THRESHOLD: usize = 1_000;
/// Threshold on the amount of processed memory since the last
/// instruction counter synchronization.
const MEMORY_THRESHOLD: u64 = 256 * KB as u64;

pub fn new(limit: u64) -> InstructionLimit {
InstructionLimit {
start: Self::instruction_counter(),
limit,
pub fn new(instruction_limit: u64) -> ExecutionLimit {
ExecutionLimit {
initial_instruction_counter: Self::instruction_counter(),
instruction_limit,
initial_processed_memory: 0,
call_counter: 0,
last_processed: 0,
exceeded: false,
}
}

pub fn is_exceeded(&mut self, processed_memory: u64) -> bool {
debug_assert!(self.initial_processed_memory <= processed_memory);
// Check the memory limit.
if processed_memory - self.initial_processed_memory > MEMORY_PROCESSING_LIMIT_PER_INCREMENT
{
return true;
}
// Check the instruction limit.
// Sporadic instruction counter synchronization, see above.
self.call_counter += 1;
if processed_memory >= self.last_processed.saturating_add(Self::MEMORY_THRESHOLD)
Expand All @@ -63,15 +84,16 @@ impl InstructionLimit {
self.last_processed = processed_memory;
// Check actual instruction counter.
let current = Self::instruction_counter();
debug_assert!(self.start <= current);
let elapsed = current - self.start;
self.exceeded = elapsed > self.limit;
debug_assert!(self.initial_instruction_counter <= current);
let elapsed = current - self.initial_instruction_counter;
self.exceeded = elapsed > self.instruction_limit;
}
self.exceeded
}

pub fn reset(&mut self, limit: u64) {
*self = Self::new(limit);
pub fn reset(&mut self, instruction_limit: u64, processed_memory: u64) {
*self = Self::new(instruction_limit);
self.initial_processed_memory = processed_memory;
}

fn instruction_counter() -> u64 {
Expand Down
16 changes: 10 additions & 6 deletions rts/motoko-rts/src/stabilization/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use crate::{
use self::stable_memory_stream::{ScanStream, StableMemoryStream};

use super::{
graph_copy::{limit::InstructionLimit, GraphCopy},
graph_copy::{limit::ExecutionLimit, GraphCopy},
layout::{scan_serialized, StableToSpace, StableValue},
moc_stabilization_instruction_limit, DUMMY_VALUE,
};

pub struct Serialization {
to_space: StableMemoryStream,
limit: InstructionLimit,
limit: ExecutionLimit,
array_slice: Option<ArraySlice>,
}

Expand Down Expand Up @@ -65,7 +65,7 @@ impl Serialization {
/// The start is followed by a series of copy increments before the serialization is completed.
pub fn start<M: Memory>(mem: &mut M, root: Value, stable_start: u64) -> Serialization {
let to_space = StableMemoryStream::open(stable_start);
let limit = InstructionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let limit = ExecutionLimit::new(unsafe { moc_stabilization_instruction_limit() });
let mut serialization = Serialization {
limit,
to_space,
Expand Down Expand Up @@ -115,6 +115,10 @@ impl Serialization {
pub fn set_array_slice(&mut self, slice: ArraySlice) {
self.array_slice = Some(slice);
}

fn processed_memory(&self) -> u64 {
self.serialized_data_length()
}
}

impl GraphCopy<Value, StableValue, u32> for Serialization {
Expand Down Expand Up @@ -183,12 +187,12 @@ impl GraphCopy<Value, StableValue, u32> for Serialization {
}

fn time_over(&mut self) -> bool {
self.limit.is_exceeded(self.serialized_data_length())
self.limit.is_exceeded(self.processed_memory())
}

fn reset_time(&mut self) {
let limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(limit);
let instruction_limit = unsafe { moc_stabilization_instruction_limit() };
self.limit.reset(instruction_limit, self.processed_memory());
}
}

Expand Down
Loading

0 comments on commit edb23df

Please sign in to comment.