#![no_std]
use core::mem;
pub type ErrorCode = u32;
pub type BlockNumber = u32;
pub type BlockCount = u32;
pub type BlockTimestamp = u64;
pub type BufferStart = u8;
pub type SizedBufferStart = u8;
pub type Gas = u64;
pub type Handle = u32;
pub type Hash = [u8; 32];
pub type Offset = u32;
pub type Length = u32;
pub type ReplyCode = [u8; 4];
pub type SignalCode = u32;
pub type Value = u128;
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct BlockNumberWithHash {
pub bn: BlockNumber,
pub hash: Hash,
}
impl BlockNumberWithHash {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
#[repr(C, packed)]
#[derive(Default, Debug, Clone)]
pub struct HashWithValue {
pub hash: Hash,
pub value: Value,
}
impl HashWithValue {
pub const fn as_ptr(&self) -> *const Self {
self as _
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithReplyCode {
pub error_code: ErrorCode,
pub reply_code: ReplyCode,
}
impl ErrorWithReplyCode {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl From<Result<ReplyCode, ErrorCode>> for ErrorWithReplyCode {
fn from(result: Result<ReplyCode, ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok(code) => res.reply_code = code,
Err(length) => res.error_code = length,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithSignalCode {
pub error_code: ErrorCode,
pub signal_code: SignalCode,
}
impl ErrorWithSignalCode {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl From<Result<SignalCode, ErrorCode>> for ErrorWithSignalCode {
fn from(result: Result<SignalCode, ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok(code) => res.signal_code = code,
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithGas {
pub error_code: ErrorCode,
pub gas: Gas,
}
impl ErrorWithGas {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl From<Result<Gas, ErrorCode>> for ErrorWithGas {
fn from(result: Result<Gas, ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok(gas) => res.gas = gas,
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithHandle {
pub error_code: ErrorCode,
pub handle: Handle,
}
impl ErrorWithHandle {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl From<Result<Handle, ErrorCode>> for ErrorWithHandle {
fn from(result: Result<Handle, ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok(handle) => res.handle = handle,
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorBytes([u8; mem::size_of::<ErrorCode>()]);
impl From<Result<(), ErrorCode>> for ErrorBytes {
fn from(value: Result<(), ErrorCode>) -> Self {
Self(value.err().unwrap_or_default().to_le_bytes())
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithHash {
pub error_code: ErrorCode,
pub hash: Hash,
}
impl ErrorWithHash {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl<T: Into<[u8; 32]>> From<Result<T, ErrorCode>> for ErrorWithHash {
fn from(result: Result<T, ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok(v) => res.hash = v.into(),
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithTwoHashes {
pub error_code: ErrorCode,
pub hash1: Hash,
pub hash2: Hash,
}
impl ErrorWithTwoHashes {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl<T1, T2> From<Result<(T1, T2), ErrorCode>> for ErrorWithTwoHashes
where
T1: Into<[u8; 32]>,
T2: Into<[u8; 32]>,
{
fn from(result: Result<(T1, T2), ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok((v1, v2)) => {
res.hash1 = v1.into();
res.hash2 = v2.into();
}
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct ErrorWithBlockNumberAndValue {
pub error_code: ErrorCode,
pub bn: BlockNumber,
pub value: Value,
}
impl ErrorWithBlockNumberAndValue {
pub fn as_mut_ptr(&mut self) -> *mut Self {
self as _
}
}
impl From<Result<(Value, BlockNumber), ErrorCode>> for ErrorWithBlockNumberAndValue {
fn from(result: Result<(Value, BlockNumber), ErrorCode>) -> Self {
let mut res: Self = Default::default();
match result {
Ok((v, bn)) => {
res.value = v;
res.bn = bn;
}
Err(code) => res.error_code = code,
}
res
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct TwoHashes {
pub hash1: Hash,
pub hash2: Hash,
}
impl TwoHashes {
pub const fn as_ptr(&self) -> *const Self {
self as _
}
}
#[repr(C, packed)]
#[derive(Default, Debug)]
pub struct TwoHashesWithValue {
pub hash1: Hash,
pub hash2: Hash,
pub value: Value,
}
impl TwoHashesWithValue {
pub const fn as_ptr(&self) -> *const Self {
self as _
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct EnvVars {
pub performance_multiplier: Percent,
pub existential_deposit: Value,
pub mailbox_threshold: Gas,
pub gas_multiplier: GasMultiplier,
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Percent(u32);
impl Percent {
pub fn new(value: u32) -> Self {
Self(value)
}
pub fn value(&self) -> u32 {
self.0
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct GasMultiplier {
gas_per_value: Gas,
value_per_gas: Value,
}
impl GasMultiplier {
pub fn from_gas_per_value(gas_per_value: Gas) -> Self {
Self {
gas_per_value,
value_per_gas: 0,
}
}
pub fn from_value_per_gas(value_per_gas: Value) -> Self {
Self {
gas_per_value: 0,
value_per_gas,
}
}
pub fn gas_to_value(&self, gas: Gas) -> Value {
if self.value_per_gas == 0 {
unimplemented!("Currently unsupported that 1 Value > 1 Gas");
}
(gas as u128).saturating_mul(self.value_per_gas)
}
}
#[allow(improper_ctypes)]
extern "C" {
pub fn gr_env_vars(version: u32, vars: *mut BufferStart);
pub fn gr_block_height(height: *mut BlockNumber);
pub fn gr_block_timestamp(timestamp: *mut BlockTimestamp);
pub fn gr_create_program_wgas(
cid_value: *const HashWithValue,
salt: *const SizedBufferStart,
salt_len: Length,
payload: *const SizedBufferStart,
payload_len: Length,
gas_limit: Gas,
delay: BlockNumber,
err_mid_pid: *mut ErrorWithTwoHashes,
);
pub fn gr_create_program(
cid_value: *const HashWithValue,
salt: *const SizedBufferStart,
salt_len: Length,
payload: *const SizedBufferStart,
payload_len: Length,
delay: BlockNumber,
err_mid_pid: *mut ErrorWithTwoHashes,
);
pub fn gr_reply_deposit(message_id: *const Hash, gas: Gas, err: *mut ErrorCode);
pub fn gr_debug(payload: *const SizedBufferStart, len: Length);
pub fn gr_panic(payload: *const SizedBufferStart, len: Length) -> !;
pub fn gr_oom_panic() -> !;
pub fn gr_reply_code(err_code: *mut ErrorWithReplyCode);
pub fn gr_signal_code(err_code: *mut ErrorWithSignalCode);
pub fn gr_exit(inheritor_id: *const Hash) -> !;
pub fn gr_gas_available(gas: *mut Gas);
pub fn gr_leave() -> !;
pub fn gr_message_id(message_id: *mut Hash);
pub fn gr_pay_program_rent(
rent_pid: *const HashWithValue,
err_bn_value: *mut ErrorWithBlockNumberAndValue,
);
pub fn gr_program_id(program_id: *mut Hash);
pub fn gr_random(subject: *const Hash, bn_random: *mut BlockNumberWithHash);
pub fn gr_read(at: Offset, len: Length, buffer: *mut SizedBufferStart, err: *mut ErrorCode);
pub fn gr_reply_commit_wgas(gas_limit: Gas, value: *const Value, err_mid: *mut ErrorWithHash);
pub fn gr_reply_commit(value: *const Value, err_mid: *mut ErrorWithHash);
pub fn gr_reply_push(payload: *const SizedBufferStart, len: Length, err: *mut ErrorCode);
pub fn gr_reply_push_input(offset: Offset, len: Length, err: *mut ErrorCode);
pub fn gr_reply_to(err_mid: *mut ErrorWithHash);
pub fn gr_signal_from(err_mid: *mut ErrorWithHash);
pub fn gr_reply_input_wgas(
offset: Offset,
len: Length,
gas_limit: Gas,
value: *const Value,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reply_wgas(
payload: *const SizedBufferStart,
len: Length,
gas_limit: Gas,
value: *const Value,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reply(
payload: *const SizedBufferStart,
len: Length,
value: *const Value,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reply_input(
offset: Offset,
len: Length,
value: *const Value,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reservation_reply_commit(
rid_value: *const HashWithValue,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reservation_reply(
rid_value: *const HashWithValue,
payload: *const SizedBufferStart,
len: Length,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reservation_send_commit(
handle: Handle,
rid_pid_value: *const TwoHashesWithValue,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reservation_send(
rid_pid_value: *const TwoHashesWithValue,
payload: *const SizedBufferStart,
len: Length,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_reserve_gas(gas: Gas, duration: BlockNumber, err_rid: *mut ErrorWithHash);
pub fn gr_send_commit_wgas(
handle: Handle,
pid_value: *const HashWithValue,
gas_limit: Gas,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_send_commit(
handle: Handle,
pid_value: *const HashWithValue,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_send_init(err_handle: *mut ErrorWithHandle);
pub fn gr_send_push(
handle: Handle,
payload: *const SizedBufferStart,
len: Length,
err: *mut ErrorCode,
);
pub fn gr_send_push_input(handle: Handle, offset: Offset, len: Length, err: *mut ErrorCode);
pub fn gr_send_input_wgas(
pid_value: *const HashWithValue,
offset: Offset,
len: Length,
gas_limit: Gas,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_send_wgas(
pid_value: *const HashWithValue,
payload: *const SizedBufferStart,
len: Length,
gas_limit: Gas,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_send(
pid_value: *const HashWithValue,
payload: *const SizedBufferStart,
len: Length,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_send_input(
pid_value: *const HashWithValue,
offset: Offset,
len: Length,
delay: BlockNumber,
err_mid: *mut ErrorWithHash,
);
pub fn gr_size(length: *mut Length);
pub fn gr_source(program_id: *mut Hash);
pub fn gr_system_reserve_gas(gas: Gas, err: *mut ErrorCode);
pub fn gr_unreserve_gas(reservation_id: *const Hash, err_unreserved: *mut ErrorWithGas);
pub fn gr_value_available(value: *mut Value);
pub fn gr_value(value: *mut Value);
pub fn gr_wait_for(duration: BlockNumber) -> !;
pub fn gr_wait_up_to(duration: BlockNumber) -> !;
pub fn gr_wait() -> !;
pub fn gr_wake(message_id: *const Hash, delay: BlockNumber, err: *mut ErrorCode);
}