jam_pvm_common/service.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use jam_types::{
AccumulateItem, OnChainContext, PackageInfo, ServiceId, TransferRecord, Vec, WorkOutput,
WorkPayload,
};
/// Declare that this crate is a JAM service characterized by `$service_impl` and create necessary
/// entry points.
///
/// - `$service_impl` must implement the [Service] trait.
#[macro_export]
macro_rules! declare_service {
($service_impl: ty) => {
#[polkavm_derive::polkavm_export]
extern "C" fn refine_ext(ptr: u32, size: u32) -> u64 {
let $crate::jam_types::RefineParams { id, payload, package_info, extrinsics } =
$crate::mem::decode_buf(ptr, size);
let result =
<$service_impl as $crate::Service>::refine(id, payload, package_info, extrinsics);
((&result).as_ptr() as u64) << 32 | (result.len() as u64)
}
#[polkavm_derive::polkavm_export]
extern "C" fn accumulate_ext(ptr: u32, size: u32) -> u64 {
let $crate::jam_types::AccumulateParams { context, results } =
$crate::mem::decode_buf(ptr, size);
<$service_impl as $crate::Service>::accumulate(context, results);
0
}
#[polkavm_derive::polkavm_export]
extern "C" fn on_transfer_ext(ptr: u32, size: u32) -> u64 {
let $crate::jam_types::OnTransferParams { context, transfers } =
$crate::mem::decode_buf(ptr, size);
<$service_impl as $crate::Service>::on_transfer(context, transfers);
0
}
};
}
/// The invocation trait for a JAM service.
///
/// The [declare_service] macro requires that its parameter implement this trait.
pub trait Service {
/// The Refine entry-point, used in-core on a single Work Item.
///
/// - `id`: The service ID of the Work Item.
/// - `payload`: The payload data within the Work Item.
/// - `package_info`: Information concerning the Work Package in which the Work Item sits.
/// - `extrinsics`: The extrinsic data associated with the Work Item.
///
/// Returns the Work Output, which will be passed into [Self::accumulate] in the on-chain
/// (stateful) context.
fn refine(
id: ServiceId,
payload: WorkPayload,
package_info: PackageInfo,
extrinsics: Vec<Vec<u8>>,
) -> WorkOutput;
/// The Accumulate entry-point, used on-chain on one or more Work Item Outputs, or possibly none
/// in the case of an always-accumulate service.
///
/// - `context`: The current time slot and service ID being accumulated.
/// - `results`: The Work Outputs of the Work Items, together with additional information on the
/// Work Packages which brought them about.
fn accumulate(context: OnChainContext, results: Vec<AccumulateItem>);
/// The On Transfer entry-point, used on-chain on one or more Transfers.
///
/// - `context`: The current time slot and service ID being accumulated.
/// - `transfers`: Information on the Transfers to the service ID in question.
fn on_transfer(context: OnChainContext, transfers: Vec<TransferRecord>);
}