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>);
}