Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deferred_calls #335

Merged
merged 33 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5a858d7
update proto rev
modship Mar 28, 2024
c21d4fa
Add new ABIs for ASC.
AurelienFT May 9, 2024
6e2250f
Change ID type to string
AurelienFT May 9, 2024
f01ad17
Update all abi names
AurelienFT May 9, 2024
4b57c66
Update naming asc call fees
AurelienFT May 9, 2024
64638e0
update proto
AurelienFT May 9, 2024
e19017b
return bytes for call asc id
AurelienFT May 9, 2024
d841539
Merge remote-tracking branch 'aurelien/new_asc' into deferred_calls
modship Jul 4, 2024
ca1b867
refactor asc call
modship Jul 25, 2024
116dd8a
params order
modship Jul 29, 2024
7c0a487
Pr comment
modship Aug 28, 2024
3d6ccdb
try_into u64
modship Aug 28, 2024
4c44288
update from bytes to string
modship Aug 29, 2024
5a9cdc7
add abi_deferred_call_quote wasmv1
modship Aug 30, 2024
ee11f55
abi_deferred_call_exists
modship Aug 30, 2024
25bb52c
deferred call cancel && register
modship Sep 2, 2024
033ac6e
fix mod test
modship Sep 2, 2024
48d42c5
remove bool on cancel call
modship Sep 5, 2024
b582bcd
update execution-trace (cancel)
modship Sep 17, 2024
7129201
update proto
modship Sep 25, 2024
8a07a50
update proto
modship Sep 25, 2024
77c87b6
update proto
modship Sep 26, 2024
3f2a370
update proto
modship Sep 26, 2024
f51d247
update proto
modship Sep 26, 2024
4220039
update proto
modship Sep 27, 2024
f5fd64c
Fix name of get_deferred_call_quote
modship Oct 2, 2024
7289367
deferred call quote add params size
modship Oct 16, 2024
3993311
Merge remote-tracking branch 'origin/next_breaking_update' into defer…
modship Oct 17, 2024
1af1688
fix merge main_2_3
modship Oct 17, 2024
27afc0f
fix clone
modship Oct 21, 2024
82dd714
fix call id
modship Oct 21, 2024
299d6e5
Merge remote-tracking branch 'origin/next_breaking_update' into defer…
modship Dec 6, 2024
1ed1fea
deferred calls gas cost
modship Dec 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ chrono = { version = "=0.4", features = ["clock"], default-features = false }
displaydoc = "0.2"
function_name = "0.3"
loupe = "0.1"
#massa-proto-rs = { git = "https://github.com/massalabs/massa-proto-rs.git", rev = "426fd325a55dfcc4033920bed2de075a7e7ad4b7" }
massa-proto-rs = { git = "https://github.com/massalabs/massa-proto-rs.git", rev = "38950875a7aa406fedc4f0b8336864e5ff290f2c" }
more-asserts = "0.3"
num_enum = "0.7"
Expand Down
143 changes: 143 additions & 0 deletions src/as_execution/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,149 @@ pub(crate) fn assembly_script_chain_id(mut ctx: FunctionEnvMut<ASEnv>) -> ABIRes
Ok(chain_id as u64)
}

/// Return the price in nMAS to book an deferred call space in a specific slot.
#[named]
pub(crate) fn assembly_script_get_deferred_call_quote(
mut ctx: FunctionEnvMut<ASEnv>,
deferred_call_period: i64,
deferred_call_thread: i32,
max_gas: i64,
) -> ABIResult<u64> {
let env = get_env(&ctx)?;
sub_remaining_gas_abi(&env, &mut ctx, function_name!())?;
let asc_slot: (u64, u8) = match (
deferred_call_period.try_into(),
deferred_call_thread.try_into(),
) {
(Ok(p), Ok(t)) => (p, t),
(Err(_), _) => abi_bail!("negative validity end period"),
(_, Err(_)) => abi_bail!("invalid validity end thread"),
};
if max_gas.is_negative() {
abi_bail!("negative max gas");
}
let (available, mut price) = env
.get_interface()
.deferred_call_quote(asc_slot, max_gas as u64)?;
if !available {
price = 0;
}
#[cfg(feature = "execution-trace")]
ctx.data_mut().trace.push(AbiTrace {
name: function_name!().to_string(),
params: vec![
into_trace_value!(deferred_call_period),
into_trace_value!(deferred_call_thread),
into_trace_value!(max_gas),
],
return_value: price.into(),
sub_calls: None,
});
Ok(price)
}

/// Register a new deferred call in the target slot with the given parameters.
#[named]
#[allow(clippy::too_many_arguments)]
pub(crate) fn assembly_script_deferred_call_register(
mut ctx: FunctionEnvMut<ASEnv>,
target_address: i32,
target_function: i32,
target_period: i64,
target_thread: i32,
max_gas: i64,
raw_coins: i64,
params: i32,
) -> ABIResult<i32> {
let env = get_env(&ctx)?;
sub_remaining_gas_abi(&env, &mut ctx, function_name!())?;
let asc_target_slot: (u64, u8) = match (target_period.try_into(), target_thread.try_into()) {
(Ok(p), Ok(t)) => (p, t),
(Err(_), _) => abi_bail!("negative validity end period"),
(_, Err(_)) => abi_bail!("invalid validity end thread"),
};
if max_gas.is_negative() {
abi_bail!("negative max gas");
}
if raw_coins.is_negative() {
abi_bail!("negative coins")
}
let memory = get_memory!(env);
let target_address = read_string(memory, &ctx, target_address)?;
let target_function = read_string(memory, &ctx, target_function)?;
let params = read_buffer(memory, &ctx, params)?;
let response = env.get_interface().deferred_call_register(
&target_address,
&target_function,
asc_target_slot,
max_gas as u64,
raw_coins as u64,
&params,
)?;
let res = match BufferPtr::alloc(&response, env.get_ffi_env(), &mut ctx) {
Ok(ret) => Ok(ret.offset() as i32),
_ => abi_bail!("Cannot allocate response in asc call register"),
};
#[cfg(feature = "execution-trace")]
ctx.data_mut().trace.push(AbiTrace {
name: function_name!().to_string(),
params: vec![
into_trace_value!(target_address),
into_trace_value!(target_function),
into_trace_value!(target_period),
into_trace_value!(target_thread),
into_trace_value!(max_gas as u64),
into_trace_value!(raw_coins as u64),
into_trace_value!(params),
],
return_value: response.to_owned().into(),
sub_calls: None,
});
res
}

/// Check if an deferred call exists with the given deferred_call_id (exists meaning to be executed in the future).
#[named]
pub(crate) fn assembly_script_deferred_call_exists(
mut ctx: FunctionEnvMut<ASEnv>,
deferred_id: i32,
) -> ABIResult<i32> {
let env = get_env(&ctx)?;
sub_remaining_gas_abi(&env, &mut ctx, function_name!())?;
let memory = get_memory!(env);
let asc_id = read_buffer(memory, &ctx, deferred_id)?;
let exists = env.get_interface().deferred_call_exists(&asc_id)?;
#[cfg(feature = "execution-trace")]
ctx.data_mut().trace.push(AbiTrace {
name: function_name!().to_string(),
params: vec![into_trace_value!(asc_id)],
return_value: exists.into(),
sub_calls: None,
});
Ok(exists as i32)
}

/// Cancel an deferred call with the given deferred_call_id. This will reimburse the user with the coins they provided
#[named]
pub(crate) fn assembly_script_deferred_call_cancel(
mut ctx: FunctionEnvMut<ASEnv>,
deferred_call_id: i32,
) -> ABIResult<()> {
let env = get_env(&ctx)?;
sub_remaining_gas_abi(&env, &mut ctx, function_name!())?;
let memory = get_memory!(env);
let deferred_id = read_buffer(memory, &ctx, deferred_call_id)?;
env.get_interface().deferred_call_cancel(&deferred_id)?;
#[cfg(feature = "execution-trace")]
ctx.data_mut().trace.push(AbiTrace {
name: function_name!().to_string(),
params: vec![into_trace_value!(deferred_id)],
return_value: (),
sub_calls: None,
});
Ok(())
}

/// Assembly script builtin `abort` function.
///
/// It prints the origin filename, an error messag, the line and column.
Expand Down
4 changes: 4 additions & 0 deletions src/as_execution/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ impl ASContext {
"assembly_script_caller_has_write_access" => Function::new_typed_with_env(store, &fenv, assembly_script_caller_has_write_access),
"assembly_script_function_exists" => Function::new_typed_with_env(store, &fenv, assembly_script_function_exists),
"assembly_script_chain_id" => Function::new_typed_with_env(store, &fenv, assembly_script_chain_id),
"assembly_script_get_deferred_call_quote" => Function::new_typed_with_env(store, &fenv, assembly_script_get_deferred_call_quote),
"assembly_script_deferred_call_register" => Function::new_typed_with_env(store, &fenv, assembly_script_deferred_call_register),
"assembly_script_deferred_call_exists" => Function::new_typed_with_env(store, &fenv, assembly_script_deferred_call_exists),
"assembly_script_deferred_call_cancel" => Function::new_typed_with_env(store, &fenv, assembly_script_deferred_call_cancel),
},
};

Expand Down
34 changes: 34 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,40 @@ impl Interface for TestInterface {
fn save_gas_remaining_before_subexecution(&self, gas_used_until: u64) {
println!("save_gas_remaining_before_subexecution: {}", gas_used_until);
}

fn deferred_call_quote(&self, target_slot: (u64, u8), gas_limit: u64) -> Result<(bool, u64)> {
println!(
"get_asc_call_fee: target_slot: {:?}, gas_limit: {}",
target_slot, gas_limit
);
Ok((true, 0))
}

fn deferred_call_register(
&self,
target_slot: (u64, u8),
target_addr: &str,
target_func: &str,
params: &[u8],
coins: u64,
max_gas: u64,
) -> Result<Vec<u8>> {
println!(
"asc_call_register: target_slot: {:?}, target_addr: {}, target_func: {}, params: {:?}, coins: {}, max_gas: {}",
target_slot, target_addr, target_func, params, coins, max_gas
);
Ok(vec![])
}

fn deferred_call_exists(&self, id: &[u8]) -> Result<bool> {
println!("asc_call_exists: id: {:?}", id);
Ok(true)
}

fn deferred_call_cancel(&self, id: &[u8]) -> Result<()> {
println!("asc_call_cancel: id: {:?}", id);
Ok(())
}
}

#[cfg(feature = "gas_calibration")]
Expand Down
24 changes: 24 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ impl Default for GasCosts {
abi_costs.insert(String::from("assembly_script_get_bytecode_for"), 11);
abi_costs.insert(String::from("assembly_script_caller_has_write_access"), 11);
abi_costs.insert(String::from("assembly_script_function_exists"), 11);
abi_costs.insert(String::from("assembly_script_get_deferred_call_quote"), 11);
abi_costs.insert(String::from("assembly_script_deferred_call_register"), 11);
abi_costs.insert(String::from("assembly_script_deferred_call_exists"), 11);
abi_costs.insert(String::from("assembly_script_deferred_call_cancel"), 11);
abi_costs.insert(String::from("assembly_script_seed"), 11);
abi_costs.insert(String::from("assembly_script_abort"), 11);
abi_costs.insert(String::from("assembly_script_date_now"), 11);
Expand Down Expand Up @@ -573,6 +577,26 @@ pub trait Interface: Send + Sync + InterfaceClone {
// Return the current chain id
fn chain_id(&self) -> Result<u64>;

// Return a boolean that determine if there is place in this slot and an amount of fee needed to take the space
fn deferred_call_quote(&self, target_slot: (u64, u8), gas_limit: u64) -> Result<(bool, u64)>;

// Register a new deferred call and return his id
fn deferred_call_register(
&self,
target_addr: &str,
target_func: &str,
target_slot: (u64, u8),
max_gas: u64,
coins: u64,
params: &[u8],
) -> Result<Vec<u8>>;

// Return true if the current deferred call exists
fn deferred_call_exists(&self, id: &[u8]) -> Result<bool>;

// Cancel a deferred call (will return the coins)
fn deferred_call_cancel(&self, id: &[u8]) -> Result<()>;

fn native_amount_from_str_wasmv1(&self, amount: &str) -> Result<NativeAmount>;

fn native_amount_to_string_wasmv1(&self, amount: &NativeAmount) -> Result<String>;
Expand Down
Loading