#[macro_export]
macro_rules! state {
{$($token:tt)*} => {
$crate::__lyquid_state_preprocess!({$($token)*}, {});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_state_preprocess {
({}, {$($token:tt)*}) => { $crate::__lyquid_state_generate!($($token)*); };
({network oracle $var:ident; $($rest:tt)*}, {$($token:tt)*}) => {
$crate::__lyquid_state_preprocess!({$($rest)*}, {(oracle $var) $($token)*});
};
({$cat:ident $var:ident: $type:ty = $init:expr; $($rest:tt)*}, {$($token:tt)*}) => {
$crate::__lyquid_state_preprocess!({$($rest)*}, {($cat $var $type $init) $($token)*});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_state_generate {
($($token:tt)*) => {
pub mod __lyquid {
use super::*;
use $crate::prelude::*;
use $crate::lyquor_primitives::StateCategory;
use $crate::runtime;
runtime::internal::setup_lyquid_state_variables!(
State
__lyquid_initialize_state_variables
[(network Network StateCategory::Network)
(instance Instance StateCategory::Instance)] $($token)*);
pub type NetworkContext = $crate::runtime::NetworkContextImpl<NetworkState>;
pub type CertifiedContext = $crate::runtime::CertifiedContextImpl<NetworkState>;
pub type ImmutableNetworkContext = $crate::runtime::ImmutableNetworkContextImpl<NetworkState>;
pub type InstanceContext = $crate::runtime::InstanceContextImpl<NetworkState, InstanceState>;
pub type ImmutableInstanceContext = $crate::runtime::ImmutableInstanceContextImpl<NetworkState, InstanceState>;
pub type UpcPrepareContext = $crate::runtime::upc::PrepareContextImpl<NetworkState>;
pub type UpcRequestContext = $crate::runtime::upc::RequestContextImpl<NetworkState, InstanceState>;
pub type UpcResponseContext = $crate::runtime::upc::ResponseContextImpl<NetworkState>;
#[doc(hidden)]
const _: () = {
#[unsafe(link_section = "lyquor.ldk.version")]
#[used]
static LDK_INFO: [u8; $crate::consts::LDK_PAYLOAD.len()] = $crate::consts::LDK_PAYLOAD;
};
$crate::__lyquid_define_oracle_internal_methods!();
$crate::__lyquid_define_oracle_epoch_vote_handlers!($($token)*);
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_categorize_methods {
({network(oracle::certified::$first:ident::__epoch) export($export:tt) fn __lyquor_oracle_on_epoch_finalize(&mut $handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*
oracle::certified::$first::__epoch (true, $export) fn __lyquor_oracle_on_epoch_finalize(oc: $crate::runtime::oracle::OracleCert, input_raw: $crate::prelude::Bytes) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
let topic = stringify!($first);
let group = concat!(stringify!($first), "::__epoch");
let params = $crate::lyquor_primitives::CallParams {
origin: ctx.origin,
caller: ctx.caller,
group: group.to_string(),
method: "__lyquor_oracle_on_epoch_finalize".to_string(),
input: input_raw.clone(),
abi: $crate::lyquor_primitives::InputABI::Lyquor,
};
let mut $handle = crate::__lyquid::CertifiedContext::new(ctx, oc, topic)?;
if !$handle.__lyquid_verify_oracle_finalize_cert(¶ms) {
return Err(LyquidError::InputCert)
}
let input = $crate::lyquor_primitives::decode_by_fields!(&input_raw, $($name: $type),*).ok_or(LyquidError::LyquorInput)?;
$(let $name = input.$name;)*
let result = $body;
drop($handle);
result
}}
},
{$($instance_funcs)*},
{$($internal_funcs)*}
);
};
({network(oracle::certified::$first:ident $(:: $tail:ident)*) export($export:tt) fn $fn:ident(&mut $handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*}, {$($network_funcs)* oracle::certified::$first $(:: $tail)* (true, $export) fn $fn(oc: $crate::runtime::oracle::OracleCert, input_raw: $crate::prelude::Bytes) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
let topic = stringify!($first);
let group = concat!(stringify!($first), $( "::", stringify!($tail) ),*);
let params = $crate::lyquor_primitives::CallParams {
origin: ctx.origin,
caller: ctx.caller,
group: group.to_string(),
method: stringify!($fn).to_string(),
input: input_raw.clone(),
abi: $crate::lyquor_primitives::InputABI::Lyquor,
};
let mut $handle = crate::__lyquid::CertifiedContext::new(ctx, oc, topic)?;
if !$handle.__lyquid_verify_oracle_dest_cert(params) {
return Err(LyquidError::InputCert)
}
let input = $crate::lyquor_primitives::decode_by_fields!(&input_raw, $($name: $type),*).ok_or(LyquidError::LyquorInput)?;
$(let $name = input.$name;)*
let result = $body; drop($handle); result
}}
},
{$($instance_funcs)*}, {$($internal_funcs)*}
);
};
({network($($group:ident)::*) export($export:tt) fn $fn:ident(&mut $handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*}, {$($network_funcs)* $($group)::* (true, $export) fn $fn($($name: $type),*) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
use crate::__lyquid;
let mut $handle = __lyquid::NetworkContext::new(ctx)?;
let result = $body; drop($handle); result
}}
},
{$($instance_funcs)*}, {$($internal_funcs)*}
);
};
({network($($group:ident)::*) export($export:tt) fn $fn:ident(&$handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*}, {$($network_funcs)* $($group)::* (false, $export) fn $fn($($name: $type),*) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
use crate::__lyquid;
let $handle = __lyquid::ImmutableNetworkContext::new(ctx)?;
let result = $body; drop($handle); result
}}
},
{$($instance_funcs)*}, {$($internal_funcs)*}
);
};
({network fn $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({network(main) export(false) fn $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({network($($group:ident)::*) export($export:tt) fn $fn:ident(&mut $handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({network($($group)::*) export($export) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({network($($group:ident)::*) export($export:tt) fn $fn:ident(&$handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({network($($group)::*) export($export) fn $fn(&$handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({network($($group:ident)::*) fn $fn:ident(&mut $handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({network($($group)::*) export(false) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({network($($group:ident)::*) fn $fn:ident(&$handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({network($($group)::*) export(false) fn $fn(&$handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({constructor($($args:tt)*) $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({
network(main) export(false) fn __lyquid_constructor($($args)*) -> LyquidResult<bool> {$body; Ok(true)} $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({upc($role:ident$($group:tt)*) $($rest:tt)*}, {$($network_funcs:tt)*}, {$($instance_funcs:tt)*}, {$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!({instance(upc::$role$($group)*) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*});
};
({instance(upc::prepare$($group:tt)*) fn $fn:ident(&$handle:ident) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
upc::prepare$($group)* (true, false) fn $fn(client_params: $crate::lyquor_primitives::Bytes) -> LyquidResult<$crate::upc::PrepareOutput> {|ctx: $crate::CallContext| -> LyquidResult<$crate::upc::PrepareOutput> {
use crate::__lyquid;
let mut $handle = __lyquid::UpcPrepareContext::new(ctx)?;
let result: LyquidResult<Vec<NodeID>> = (|| {$body})();
let cache = $handle.cache.take_cache();
drop($handle);
result.map(|r| $crate::upc::PrepareOutput {
result: r,
cache: cache.map(|c| Box::into_raw(c) as $crate::upc::CachePtr)
})
}}
},
{$($internal_funcs)*}
);
};
({instance(upc::prepare$($group:tt)*) fn $fn:ident(&$handle:ident, $($params:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
upc::prepare$($group)* (true, false) fn $fn(client_params: $crate::lyquor_primitives::Bytes) -> LyquidResult<$crate::upc::PrepareOutput> {|ctx: $crate::CallContext| -> LyquidResult<$crate::upc::PrepareOutput> {
use crate::__lyquid;
let mut $handle = __lyquid::UpcPrepareContext::new(ctx)?;
let input = $crate::lyquor_primitives::decode_by_fields!(&client_params, $($params: $type),*).ok_or(LyquidError::LyquorInput)?;
$(let $params = input.$params;)*
let result: LyquidResult<Vec<NodeID>> = (|| {$body})();
let cache = $handle.cache.take_cache();
drop($handle);
result.map(|r| $crate::upc::PrepareOutput {
result: r,
cache: cache.map(|c| Box::into_raw(c) as $crate::upc::CachePtr)
})
}}
},
{$($internal_funcs)*}
);
};
({instance(upc::request$($group:tt)*) fn $fn:ident(&mut $handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
upc::request$($group)* (true, false) fn $fn(from: $crate::prelude::NodeID, id: u64, input: Vec<u8>) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
use crate::__lyquid;
let mut $handle = __lyquid::UpcRequestContext::new(ctx, from, id)?;
let input = $crate::lyquor_primitives::decode_by_fields!(&input, $($name: $type),*).ok_or(LyquidError::LyquorInput)?;
$(let $name = input.$name;)*
let result = $body;
drop($handle);
result
}}
},
{$($internal_funcs)*}
);
};
({instance(upc::request$($group:tt)*) fn $fn:ident(&mut $handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance(upc::request$($group)*) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance(upc::request$($group:tt)*) fn $fn:ident(&$handle:ident, $($name:ident: $type:ty),*) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance(upc::request$($group)*) fn $fn(&mut $handle, $($name: $type),*) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance(upc::request$($group:tt)*) fn $fn:ident(&$handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance(upc::request$($group)*) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance(upc::response$($group:tt)*) fn $fn:ident(&$handle:ident, $returned:ident: LyquidResult<$rt:ty>) -> LyquidResult<Option<$rt_:ty>> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
upc::response$($group)* (true, false) fn $fn(from: $crate::prelude::NodeID, id: u64, returned: Vec<u8>, cache: Option<$crate::upc::CachePtr>) -> LyquidResult<$crate::upc::ResponseOutput> {|ctx: $crate::CallContext| -> LyquidResult<$crate::upc::ResponseOutput> {
use crate::__lyquid;
let mut $handle = __lyquid::UpcResponseContext::new(ctx, from, id, cache)?;
let $returned = $crate::lyquor_primitives::decode_object::<LyquidResult<$rt>>(&returned).ok_or(LyquidError::LyquorInput)?;
let result: LyquidResult<Option<$rt_>> = (|| {$body})();
let cache = $handle.cache.take_cache();
drop($handle);
result.map(|r|
match r {
Some(r) => $crate::upc::ResponseOutput::Return(Vec::from(&$crate::lyquor_primitives::encode_object(&r)[..])),
None => $crate::upc::ResponseOutput::Continue(cache.map(|c| Box::into_raw(c) as $crate::upc::CachePtr)),
})
}}
},
{$($internal_funcs)*}
);
};
({instance(oracle::two_phase::$name:ident) export($export:tt) fn aggregate(&$handle:ident) -> LyquidResult<Option<CertifiedCallParams>> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!({$($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*},
{$($internal_funcs)*
#[$crate::runtime::internal::prefix_item("__lyquid_method_instance", (oracle::two_phase::$name))]
#[unsafe(no_mangle)]
pub fn aggregate(ctx: $crate::runtime::oracle::ProposalAggregationContext) -> LyquidResult<Option<CertifiedCallParams>> {
let $handle = ctx;
$body
}
$crate::__lyquid_emit_method_info!(
"__lyquid_method_instance",
(oracle::two_phase::$name),
false,
aggregate
);
});
};
({instance(oracle::two_phase::$name:ident$($group:tt)*) export($export:tt) fn propose(&mut $handle:ident, $($params:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!({
instance(upc::prepare::oracle::two_phase::$name$($group)*) fn propose(
&ctx,
callee: Vec<NodeID>,
init: $crate::lyquor_primitives::Bytes,
nonce: $crate::lyquor_primitives::HashBytes,
config: $crate::runtime::oracle::OracleConfig
) -> LyquidResult<Vec<NodeID>> {
ctx.cache.set($crate::runtime::oracle::ProposalAggregation::new(
init,
nonce,
config,
));
Ok(callee)
}
instance(upc::response::oracle::two_phase::$name$($group)*) fn propose(
&ctx,
resp: LyquidResult<$crate::runtime::oracle::ProposeResponse>
) -> LyquidResult<Option< Option<$crate::runtime::oracle::Proposal> >> {
let cache: &mut $crate::runtime::oracle::ProposalAggregation =
ctx.cache.get_mut().expect("NEAT: proposal aggregation cache should have been set.");
if let Ok(resp) = resp {
return Ok(cache.add_response(
ctx.from,
resp,
prefix_call!(("__lyquid_method_instance", (oracle::two_phase::$name)), aggregate),
ctx.lyquid_id,
stringify!($name),
concat!(stringify!($name) $(, "::", stringify!($group))*),
ctx.node_id))
}
Ok(None)
}
instance(upc::request::oracle::two_phase::$name$($group)*) fn propose(
&mut ctx,
msg: $crate::runtime::oracle::ProposeRequest
) -> LyquidResult<$crate::runtime::oracle::ProposeResponse> {
let $handle = &mut ctx;
let input = $crate::lyquor_primitives::decode_by_fields!(&msg.init, $($params: $type),*)
.ok_or(LyquidError::LyquorInput)?;
$(let $params = input.$params;)*
let result: $rt = $body?;
let result = $crate::lyquor_primitives::Bytes::from($crate::lyquor_primitives::encode_object(&result));
ctx.network.$name.clone().__post_propose(
ctx.lyquid_id,
concat!(stringify!($name) $(, "::", stringify!($group))*),
ctx.from,
msg.init,
msg.nonce,
result
)
}
instance(oracle::single_phase::$name::two_phase$($group)*) export(false) fn validate(
&mut ctx,
params: CallParams,
extra: Bytes,
_target: OracleTarget,
header: $crate::runtime::oracle::OracleHeader
) -> LyquidResult<bool> {
let (init, _nonce, inputs) = match ctx.network.$name.clone()
.__pre_validation_two_phase(
&header,
&extra,
ctx.lyquid_id,
concat!(stringify!($name) $(, "::", stringify!($group))*),
ctx.from,
)? {
Some(v) => v,
None => return Ok(false),
};
let agg_ctx = $crate::runtime::oracle::ProposalAggregationContext {
init: &init,
inputs: &inputs,
lyquid_id: ctx.lyquid_id,
};
let output = prefix_call!(("__lyquid_method_instance", (oracle::two_phase::$name)), aggregate(agg_ctx))?;
let _params = match output {
Some(o) => o,
None => return Ok(false),
};
let caller: Address = ctx.lyquid_id.into();
Ok(params.origin == _params.origin &&
params.caller == caller &&
params.method == _params.method &&
params.input == _params.input)
}
$($rest)*
}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*});
};
({instance(oracle::single_phase::$name:ident$(:: $group:ident)*) export($export:tt) fn validate(&mut $handle:ident, $params:ident: CallParams, $extra:ident: Bytes, $target:ident: OracleTarget $(, $header:ident: $header_ty:path)? ) -> LyquidResult<bool> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!({
instance(upc::prepare::oracle::single_phase::$name$(:: $group)*) fn validate(
&ctx, callee: Vec<NodeID>,
header: $crate::runtime::oracle::OracleHeader,
yea_msg: $crate::lyquor_primitives::Bytes,
nay_msg: $crate::lyquor_primitives::Bytes,
config: $crate::runtime::oracle::OracleConfig
) -> LyquidResult<Vec<NodeID>> {
ctx.cache.set($crate::runtime::oracle::ValidateAggregation::new(
header,
yea_msg,
nay_msg,
config,
));
Ok(callee)
}
instance(upc::response::oracle::single_phase::$name$(:: $group)*) fn validate(
&ctx,
resp: LyquidResult<$crate::runtime::oracle::ValidateResponse>
) -> LyquidResult<Option< Option<$crate::runtime::oracle::OracleCert> >> {
let cache: &mut $crate::runtime::oracle::ValidateAggregation =
ctx.cache.get_mut().expect("NEAT: validation aggregation cache should have been set.");
if let Ok(resp) = resp {
return Ok(cache.add_response(ctx.from, resp))
}
Ok(None)
}
instance(upc::request::oracle::single_phase::$name$(:: $group)*) fn validate(
&mut ctx,
msg: $crate::runtime::oracle::ValidateRequest
) -> LyquidResult<$crate::runtime::oracle::ValidateResponse> {
let expected_group = concat!(stringify!($name) $(, "::", stringify!($group))*);
let src = ctx.network.$name.clone();
let epoch_advance = match src.__pre_validation(
&msg.header,
&msg.params,
expected_group,
ctx.from,
ctx.lyquid_id
) {
Some(skip) => skip,
None => return Err(LyquidError::LyquidRuntime("Mismatch config".into()))
};
let approval = epoch_advance || {
(|| -> LyquidResult<bool> {
let $params = msg.params.clone();
let $extra = msg.extra.clone();
let $target = msg.header.target;
$(let $header: $header_ty = msg.header;)?
let $handle = &mut ctx;
$body
})()?
};
src.__post_validation(msg.header, msg.params, approval)
}
$($rest)*
}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*});
};
({instance($($group:ident)::*) export($export:tt) fn $fn:ident(&mut $handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
$($group)::* (true, $export) fn $fn($($name: $type),*) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
use crate::__lyquid;
let mut $handle = __lyquid::InstanceContext::new(ctx)?;
let result = $body;
drop($handle);
result
}}
},
{$($internal_funcs)*}
);
};
({instance($($group:ident)::*) export($export:tt) fn $fn:ident(&$handle:ident, $($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => {
$crate::__lyquid_categorize_methods!(
{$($rest)*},
{$($network_funcs)*},
{$($instance_funcs)*
$($group)::* (false, $export) fn $fn($($name: $type),*) -> LyquidResult<$rt> {|ctx: $crate::CallContext| -> LyquidResult<$rt> {
use crate::__lyquid;
let $handle = __lyquid::ImmutableInstanceContext::new(ctx)?;
let result = $body;
drop($handle);
result
}}
},
{$($internal_funcs)*}
);
};
({instance($($group:ident)::*) export($export:tt) fn $fn:ident(&mut $handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance($($group)::*) export($export) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance($($group:ident)::*) export($export:tt) fn $fn:ident(&$handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance($($group)::*) export($export) fn $fn(&$handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance($($group:ident)::*) fn $fn:ident(&mut $handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance($($group)::*) export(false) fn $fn(&mut $handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance($($group:ident)::*) fn $fn:ident(&$handle:ident) $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance($($group)::*) export(false) fn $fn(&$handle,) $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({instance fn $($rest:tt)*},
{$($network_funcs:tt)*},
{$($instance_funcs:tt)*},
{$($internal_funcs:tt)*}) => { $crate::__lyquid_categorize_methods!({instance(main) export(false) fn $($rest)*}, {$($network_funcs)*}, {$($instance_funcs)*}, {$($internal_funcs)*}); };
({}, {$($network_funcs:tt)*}, {$($instance_funcs:tt)*}, {$($internal_funcs:tt)*}) => {
const _: () = {
use $crate::LyquidError;
$crate::__lyquid_wrap_methods!("__lyquid_method_network", $($network_funcs)*);
$crate::__lyquid_wrap_methods!("__lyquid_method_instance", $($instance_funcs)*);
};
$($internal_funcs)*
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_method_alias {
("__lyquid_method_network" $($group:ident)::* (false) $fn:ident) => {
$crate::__lyquid_emit_method_info!("__lyquid_method_instance", ($($group)::*) , false, $fn);
#[prefix_item("__lyquid_method_instance", ($($group)::*))]
#[unsafe(no_mangle)]
fn $fn(base: GuestUsize, len: GuestUsize, abi: u32) -> GuestUsize {
prefix_call!(("__lyquid_method_network", ($($group)::*)), $fn(base, len, abi))
}
};
("__lyquid_method_network" $($group:ident)::* (true) $fn:ident) => {};
("__lyquid_method_instance" $($group:ident)::* (false) $fn:ident) => {};
("__lyquid_method_instance" $($group:ident)::* (true) $fn:ident) => {};
}
#[macro_export]
macro_rules! decode_eth_call_params {
($input:expr, $($name:ident: $type:ty),*) => {
<($($type,)*) as $crate::runtime::ethabi::EthAbiParams>::decode_params($input)
};
}
#[macro_export]
macro_rules! encode_eth_call_params {
($($val:expr),*) => {
{
use $crate::prelude::Bytes;
let vals = ($($val,)*);
Bytes::from($crate::runtime::ethabi::EthAbiParams::encode_params(vals))
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_group_string {
($single:ident) => {
stringify!($single)
};
($head:ident :: $($tail:ident)::+) => {
concat!(stringify!($head), "::", $crate::__lyquid_group_string!($($tail)::+))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_method_category {
("__lyquid_method_network") => {
$crate::consts::CATEGORY_NETWORK
};
("__lyquid_method_instance") => {
$crate::consts::CATEGORY_INSTANCE
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_emit_method_info {
($prefix:tt, ($($group:ident)::*) , $mutable:tt, $fn:ident) => {
#[doc(hidden)]
const _: () = {
const GROUP: &str = $crate::__lyquid_group_string!($($group)::*);
const METHOD: &str = stringify!($fn);
const LEN: usize = $crate::consts::info_len(GROUP, METHOD);
#[unsafe(link_section = "lyquor.method.info")]
#[used]
static INFO: [u8; LEN] = $crate::consts::info_encode::<LEN>(
$crate::__lyquid_method_category!($prefix),
$mutable,
GROUP,
METHOD,
);
};
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_invoke_lyquor {
($raw:ident, ($($name:ident: $type:ty),*), $rt:ty, $body:block) => {{
let result = (|| -> Result<$rt, LyquidError> {
let (input, ctx) = (|| {
let ctx: $crate::CallContext = decode_object(&$raw)?;
Some((decode_by_fields!(&ctx.input, $($name: $type),*)?, ctx))
})().ok_or(LyquidError::LyquorInput)?;
drop($raw);
$(let $name = input.$name;)*
($body)(ctx)
})();
encode_object(&result)
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_emit_method_fn {
(true, $prefix:tt, ($($group:ident)::*) , $fn:ident, ($($name:ident: $type:ty),*), $rt:ty, $body:block) => {
#[prefix_item($prefix, ($($group)::*))]
#[unsafe(no_mangle)]
fn $fn(base: GuestUsize, len: GuestUsize, abi: u32) -> GuestUsize {
let raw = unsafe { HostInput::new(base, len) };
let output = if abi == $crate::ABI_ETH {
let result = (|| -> Result<$rt, LyquidError> {
let (input, ctx) = (|| {
let ctx: $crate::CallContext = decode_object(&raw)?;
let ($($name,)*) =
<($($type,)*) as $crate::runtime::ethabi::EthAbiParams>::decode_params(&ctx.input)?;
struct Parameters {$($name: $type),*}
Some((Parameters {
$($name),*
}, ctx))
})().ok_or(LyquidError::LyquorInput)?;
drop(raw);
$(let $name = input.$name;)*
($body)(ctx)
})().map(|rt| {
<$rt as $crate::runtime::ethabi::EthAbiReturnValue>::encode_return(rt)
});
encode_object(&result)
} else {
$crate::__lyquid_invoke_lyquor!(raw, ($($name: $type),*), $rt, $body)
};
output_to_host(&output)
}
};
(false, $prefix:tt, ($($group:ident)::*) , $fn:ident, ($($name:ident: $type:ty),*), $rt:ty, $body:block) => {
#[prefix_item($prefix, ($($group)::*))]
#[unsafe(no_mangle)]
fn $fn(base: GuestUsize, len: GuestUsize, _abi: u32) -> GuestUsize {
let raw = unsafe { HostInput::new(base, len) };
let output = $crate::__lyquid_invoke_lyquor!(raw, ($($name: $type),*), $rt, $body);
output_to_host(&output)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __lyquid_wrap_methods {
($prefix:tt, $($group:ident)::* ($mutable:tt, $export:tt) fn $fn:ident($($name:ident: $type:ty),*) -> LyquidResult<$rt:ty> $body:block $($rest:tt)*) => {
$crate::__lyquid_emit_method_info!($prefix, ($($group)::*) , $mutable, $fn);
#[$crate::runtime::internal::prefix_item($prefix, ($($group)::*))]
mod $fn {
use super::*;
use $crate::runtime::*;
use $crate::runtime::internal::*;
use $crate::lyquor_primitives::{encode_object, decode_object, decode_by_fields};
$crate::__lyquid_emit_method_fn!($export, $prefix, ($($group)::*) , $fn, ($($name: $type),*), $rt, $body);
$crate::__lyquid_method_alias!($prefix $($group)::* ($mutable) $fn);
}
$crate::__lyquid_wrap_methods!($prefix, $($rest)*);
};
($prefix:tt,) => {}
}