jam_pvm_common/
service.rs

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