use crate::{ActorId, CodeId, MessageId, prog, util::with_optimized_encode};
use gcore::errors::Result;
use gstd_codegen::wait_create_program_for_reply;
use scale_info::scale::{Encode, alloc::vec::Vec};
pub struct ProgramGenerator(u64);
static mut PROGRAM_GENERATOR: ProgramGenerator = ProgramGenerator(0);
impl ProgramGenerator {
const UNIQUE_KEY: [u8; 14] = *b"salt_generator";
pub fn get_salt() -> Vec<u8> {
let message_id = crate::msg::id();
let creator_nonce;
unsafe {
creator_nonce = PROGRAM_GENERATOR.0.to_be_bytes();
PROGRAM_GENERATOR.0 = PROGRAM_GENERATOR.0.saturating_add(1);
}
[&Self::UNIQUE_KEY, message_id.as_ref(), &creator_nonce].concat()
}
#[wait_create_program_for_reply(Self)]
pub fn create_program_bytes(
code_id: CodeId,
payload: impl AsRef<[u8]>,
value: u128,
) -> Result<(MessageId, ActorId)> {
Self::create_program_bytes_delayed(code_id, payload, value, 0)
}
pub fn create_program_bytes_delayed(
code_id: CodeId,
payload: impl AsRef<[u8]>,
value: u128,
delay: u32,
) -> Result<(MessageId, ActorId)> {
prog::create_program_bytes_delayed(code_id, Self::get_salt(), payload, value, delay)
}
#[cfg(not(feature = "ethexe"))]
#[wait_create_program_for_reply(Self)]
pub fn create_program_bytes_with_gas(
code_id: CodeId,
payload: impl AsRef<[u8]>,
gas_limit: u64,
value: u128,
) -> Result<(MessageId, ActorId)> {
Self::create_program_bytes_with_gas_delayed(code_id, payload, gas_limit, value, 0)
}
#[cfg(not(feature = "ethexe"))]
pub fn create_program_bytes_with_gas_delayed(
code_id: CodeId,
payload: impl AsRef<[u8]>,
gas_limit: u64,
value: u128,
delay: u32,
) -> Result<(MessageId, ActorId)> {
prog::create_program_bytes_with_gas_delayed(
code_id,
Self::get_salt(),
payload,
gas_limit,
value,
delay,
)
}
#[wait_create_program_for_reply(Self)]
pub fn create_program<E: Encode>(
code_id: CodeId,
payload: E,
value: u128,
) -> Result<(MessageId, ActorId)> {
with_optimized_encode(payload, |buffer| {
Self::create_program_bytes(code_id, buffer, value)
})
}
pub fn create_program_delayed<E: Encode>(
code_id: CodeId,
payload: E,
value: u128,
delay: u32,
) -> Result<(MessageId, ActorId)> {
with_optimized_encode(payload, |buffer| {
Self::create_program_bytes_delayed(code_id, buffer, value, delay)
})
}
#[cfg(not(feature = "ethexe"))]
#[wait_create_program_for_reply(Self)]
pub fn create_program_with_gas<E: Encode>(
code_id: CodeId,
payload: E,
gas_limit: u64,
value: u128,
) -> Result<(MessageId, ActorId)> {
with_optimized_encode(payload, |buffer| {
Self::create_program_bytes_with_gas(code_id, buffer, gas_limit, value)
})
}
#[cfg(not(feature = "ethexe"))]
pub fn create_program_with_gas_delayed<E: Encode>(
code_id: CodeId,
payload: E,
gas_limit: u64,
value: u128,
delay: u32,
) -> Result<(MessageId, ActorId)> {
with_optimized_encode(payload, |buffer| {
Self::create_program_bytes_with_gas_delayed(code_id, buffer, gas_limit, value, delay)
})
}
}