Skip to content

Commit

Permalink
rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
techraed committed Dec 4, 2023
2 parents 3c4836c + 162cec1 commit 1de36bd
Show file tree
Hide file tree
Showing 26 changed files with 641 additions and 172 deletions.
20 changes: 17 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 5 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,8 @@ base64 = "0.21.5"
byteorder = { version = "1.5.0", default-features = false }
blake2-rfc = { version = "0.2.18", default-features = false }
bs58 = { version = "0.5.0", default-features = false }
# TODO: upgrade this package ( issue #2694 )
cargo_metadata = "=0.15.3"
clap = { version = "4.4.10" }
cargo_metadata = "0.18.1"
clap = "4.4.8"
codec = { package = "parity-scale-codec", version = "3.6.4", default-features = false }
color-eyre = "0.6.2"
colored = "2.0.0"
Expand Down Expand Up @@ -148,22 +147,9 @@ serde_json = "^1"
serde_yaml = "0.8.26"
sha-1 = "0.10.1"
static_assertions = "1"
# # NOTE
#
# 1. subxt v0.29.0 breaks the logging in gsdk, our fork is based on the
# unpublished v0.29.0 from the main repo with fixes.
#
# 2. subxt v0.29.0 upgrades the substrate dependencies which are not
# compatible with our current dependencies.
#
# 3. changing but patching the source here for making these work out of
# workspace.
#
# 4. subxt-metadata and subxt-codegen are just used by gsdk-codegen for now
# gathering them here for easy management.
subxt = { version = "0.32.1" }
subxt-metadata = { version = "0.32.1" }
subxt-codegen = { version = "0.32.1" }
subxt = "0.32.1"
subxt-metadata = "0.32.1"
subxt-codegen = "0.32.1"
syn = "2.0.39"
thiserror = "1.0.50"
tokio = { version = "1.34.0" }
Expand Down
1 change: 1 addition & 0 deletions core-backend/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ where

builder.add_func(Alloc, wrap_syscall!(alloc));
builder.add_func(Free, wrap_syscall!(free));
builder.add_func(FreeRange, wrap_syscall!(free_range));
}
}

Expand Down
32 changes: 26 additions & 6 deletions core-backend/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ impl From<u32> for SyscallValue {
}
}

impl From<i64> for SyscallValue {
fn from(value: i64) -> Self {
SyscallValue(Value::I64(value))
}
}

impl TryFrom<SyscallValue> for u32 {
type Error = HostError;

Expand Down Expand Up @@ -675,6 +669,32 @@ where
})
}

pub fn free_range(start: u32, end: u32) -> impl Syscall<Ext, i32> {
InfallibleSyscall::new(RuntimeCosts::FreeRange, move |ctx: &mut CallerWrap<Ext>| {
let page_err = |_| {
UndefinedTerminationReason::Actor(ActorTerminationReason::Trap(
TrapExplanation::Unknown,
))
};

let start = WasmPage::new(start).map_err(page_err)?;
let end = WasmPage::new(end).map_err(page_err)?;

let result = ctx.ext_mut().free_range(start, end);

match ctx.process_alloc_func_result(result)? {
Ok(()) => {
log::trace!("Free range {start:?}:{end:?} success");
Ok(0)
}
Err(e) => {
log::trace!("Free range {start:?}:{end:?} failed: {e}");
Ok(1)
}
}
})
}

pub fn env_vars(vars_ver: u32, vars_ptr: u32) -> impl Syscall<Ext> {
InfallibleSyscall::new(RuntimeCosts::EnvVars, move |ctx: &mut CallerWrap<Ext>| {
let vars = ctx.ext_mut().env_vars(vars_ver)?;
Expand Down
10 changes: 9 additions & 1 deletion core-backend/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ mod tests {
Ok(137.into())
);

// if we have 2 in a row we can allocate even 2
// if we free 2 in a row we can allocate even 2
ctx.free(117.into()).unwrap();
ctx.free(118.into()).unwrap();

Expand All @@ -543,6 +543,14 @@ mod tests {
Ok(117.into())
);

// same as above, if we free_range 2 in a row we can allocate 2
ctx.free_range(117.into()..=118.into()).unwrap();

assert_eq!(
ctx.alloc::<NoopGrowHandler>(2.into(), &mut mem_wrap, |_| Ok(())),
Ok(117.into())
);

// but if 2 are not in a row, bad luck
ctx.free(117.into()).unwrap();
ctx.free(158.into()).unwrap();
Expand Down
3 changes: 3 additions & 0 deletions core-backend/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ impl Externalities for MockExt {
fn free(&mut self, _page: WasmPage) -> Result<(), Self::AllocError> {
Err(Error)
}
fn free_range(&mut self, _start: WasmPage, _end: WasmPage) -> Result<(), Self::AllocError> {
Err(Error)
}
fn env_vars(&self, version: u32) -> Result<EnvVars, Self::UnrecoverableError> {
match version {
1 => Ok(EnvVars::V1(EnvVarsV1 {
Expand Down
35 changes: 28 additions & 7 deletions core-processor/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use gear_core::{
ContextOutcomeDrain, ContextStore, Dispatch, GasLimit, HandlePacket, InitPacket,
MessageContext, Packet, ReplyPacket,
},
pages::{GearPage, PageU32Size, WasmPage},
pages::{GearPage, PageNumber, PageU32Size, WasmPage},
program::MemoryInfix,
reservation::GasReserver,
};
Expand Down Expand Up @@ -799,6 +799,30 @@ impl Externalities for Ext {
.map_err(Into::into)
}

fn free_range(&mut self, start: WasmPage, end: WasmPage) -> Result<(), Self::AllocError> {
let page_count: u32 = end
.checked_sub(start)
.ok_or(AllocExtError::Alloc(AllocError::InvalidFreeRange(
start.into(),
end.into(),
)))?
.into();

Ext::charge_gas_if_enough(
&mut self.context.gas_counter,
&mut self.context.gas_allowance_counter,
self.context
.host_fn_weights
.free_range_per_page
.saturating_mul(page_count as u64),
)?;

self.context
.allocations_context
.free_range(start..=end)
.map_err(Into::into)
}

fn env_vars(&self, version: u32) -> Result<EnvVars, Self::UnrecoverableError> {
match version {
1 => Ok(EnvVars::V1(EnvVarsV1 {
Expand Down Expand Up @@ -1243,10 +1267,7 @@ impl Externalities for Ext {
mod tests {
use super::*;
use alloc::vec;
use gear_core::{
message::{ContextSettings, IncomingDispatch, Payload, MAX_PAYLOAD_SIZE},
pages::PageNumber,
};
use gear_core::message::{ContextSettings, IncomingDispatch, Payload, MAX_PAYLOAD_SIZE};

struct MessageContextBuilder {
incoming_dispatch: IncomingDispatch,
Expand Down Expand Up @@ -1363,12 +1384,12 @@ mod tests {
);

// Freeing existing page.
// Counters still shouldn't be changed.
// Counters shouldn't be changed.
assert!(ext.free(existing_page).is_ok());
assert_eq!(ext.gas_left(), gas_left);

// Freeing non existing page.
// Counters shouldn't be changed.
// Counters still shouldn't be changed.
assert_eq!(
ext.free(non_existing_page),
Err(AllocExtError::Alloc(AllocError::InvalidFree(
Expand Down
14 changes: 13 additions & 1 deletion core/src/costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,15 @@ pub struct HostFnWeights {
/// Weight per allocated page for `alloc`.
pub alloc_per_page: u64,

/// Weight of calling `alloc`.
/// Weight of calling `free`.
pub free: u64,

/// Weight of calling `free_range`
pub free_range: u64,

/// Weight of calling `free_range` per page
pub free_range_per_page: u64,

/// Weight of calling `gr_reserve_gas`.
pub gr_reserve_gas: u64,

Expand Down Expand Up @@ -326,6 +332,10 @@ pub enum RuntimeCosts {
Alloc(u32),
/// Weight of calling `free`.
Free,
/// Base weight of calling `free_range`
FreeRange,
/// Weight of calling `free_range` per amount of pages.
FreeRangePerPage(u32),
/// Weight of calling `gr_reserve_gas`.
ReserveGas,
/// Weight of calling `gr_unreserve_gas`.
Expand Down Expand Up @@ -467,6 +477,8 @@ impl RuntimeCosts {
Null => 0,
Alloc(pages) => cost_with_weight_per_page(s.alloc, s.alloc_per_page, pages),
Free => s.free,
FreeRange => s.free_range,
FreeRangePerPage(pages) => cost_with_weight_per_page(0, s.free_range_per_page, pages),
ReserveGas => s.gr_reserve_gas,
UnreserveGas => s.gr_unreserve_gas,
SystemReserveGas => s.gr_system_reserve_gas,
Expand Down
8 changes: 4 additions & 4 deletions core/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ pub trait Externalities {
mem: &mut impl Memory,
) -> Result<WasmPage, Self::AllocError>;

/// Free specific memory page.
///
/// Unlike traditional allocator, if multiple pages allocated via `alloc`, all pages
/// should be `free`-d separately.
/// Free specific page.
fn free(&mut self, page: WasmPage) -> Result<(), Self::AllocError>;

/// Free specific memory range.
fn free_range(&mut self, start: WasmPage, end: WasmPage) -> Result<(), Self::AllocError>;

/// Get environment variables currently set in the system and in the form
/// corresponded to the requested version.
fn env_vars(&self, version: u32) -> Result<EnvVars, Self::UnrecoverableError>;
Expand Down
Loading

0 comments on commit 1de36bd

Please sign in to comment.