jam_pvm_common/lib.rs
1//! The main JAM PVM API for creating authorizers and services on JAM. This includes a trait-based
2//! invocation entry-point API as well as host-calls functions and types for working with them.
3//!
4//! In order to create a PVM executable containing a JAM service or authorizer, you must implement
5//! the [Service] or [Authorizer] in some type and then pass your type into the `declare_service!`
6//! or `declare_authorizer!` macro, respectively. This will generate the necessary entry-points for
7//! the PVM to call into your implementation.
8//!
9//! ## Example Service
10//! ```rust
11//! extern crate alloc;
12//! use alloc::vec::Vec;
13//! use jam_pvm_common::{declare_service, Service, accumulate::set_storage};
14//! use jam_types::*;
15//!
16//! struct MyService;
17//! declare_service!(MyService);
18//!
19//! impl Service for MyService {
20//! fn refine(
21//! _id: ServiceId,
22//! payload: WorkPayload,
23//! _package_info: PackageInfo,
24//! _extrinsics: Vec<Vec<u8>>,
25//! ) -> WorkOutput {
26//! [&b"Hello "[..], payload.take().as_slice()].concat().into()
27//! }
28//! fn accumulate(_slot: Slot, _id: ServiceId, items: Vec<AccumulateItem>) -> Option<Hash> {
29//! for item in items.into_iter() {
30//! if let Ok(data) = item.result {
31//! set_storage(item.package.as_slice(), &data).expect("not enough balance?!");
32//! }
33//! }
34//! None
35//! }
36//! fn on_transfer(_slot: Slot, _id: ServiceId, _items: Vec<TransferRecord>) {}
37//! }
38//! ```
39//!
40//! ## Host-calls
41//! The host-calls available to a service or authorizer are split into four modules:
42//! - [is_authorized] for authorizers, to be called from the [Authorizer::is_authorized] function.
43//! - [refine] for services, to be called from the [Service::refine] function.
44//! - [accumulate] for services, to be called from the [Service::accumulate] function.
45//! - [on_transfer] for services, to be called from the [Service::on_transfer] function.
46//!
47//! Each module contains a set of functions that can be called from the respective entry-point
48//! function. These functions are used to interact with the PVM and the blockchain state.
49//!
50//! ## Logging
51//! Five logging macros are provided similar to those of the `log` crate, [debug], [info], [warn],
52//! [error], and [trace]. These macros are used with the non-standard PolkaJam `log` host-call and
53//! the `format` macro. The host environment is responsible for forwarding these logs to the
54//! appropriate destination.
55//!
56//! ## Features
57//! - `authorizer`: Enables the authorizer API.
58//! - `service`: Enables the service API.
59//! - `logging`: Enables the logging service; without the logging macros will evaluate any operands
60//! but otherwise have no effect.
61#![no_std]
62#![allow(clippy::unwrap_used)]
63
64extern crate alloc;
65
66#[doc(hidden)]
67pub use jam_types;
68
69#[cfg(any(feature = "authorizer", doc))]
70mod authorizer;
71#[cfg(any(feature = "authorizer", doc))]
72pub use authorizer::Authorizer;
73
74#[cfg(any(feature = "service", doc))]
75mod service;
76#[cfg(any(feature = "service", doc))]
77pub use service::Service;
78
79#[allow(dead_code)]
80mod host_calls;
81
82/// Host-call APIs available for the [Authorizer::is_authorized] entry-point.
83#[cfg(any(feature = "authorizer", doc))]
84pub mod is_authorized {
85 pub use super::host_calls::gas;
86}
87
88/// Host-call APIs available for the [Service::refine] entry-point.
89#[cfg(any(feature = "service", doc))]
90pub mod refine {
91 pub use super::host_calls::{
92 export, export_slice, expunge, foreign_historical_lookup as foreign_lookup,
93 foreign_historical_lookup_into as foreign_lookup_into, gas, historical_lookup as lookup,
94 historical_lookup_into as lookup_into, import, import_into, invoke,
95 is_foreign_historical_available as is_foreign_available,
96 is_historical_available as is_available, machine, peek, peek_into, peek_value, poke,
97 poke_value, void, zero,
98 };
99}
100
101/// Host-call APIs available for the [Service::accumulate] entry-point.
102#[cfg(any(feature = "service", doc))]
103pub mod accumulate {
104 pub use super::host_calls::{
105 assign, bless, checkpoint, create_service, designate, eject, foreign_lookup,
106 foreign_lookup_into, forget, gas, get, get_foreign, get_foreign_storage, get_storage,
107 is_available, is_foreign_available, lookup, lookup_into, my_info, query, remove,
108 remove_storage, service_info, set, set_storage, solicit, transfer, upgrade, yield_hash,
109 zombify, ForgetImplication, LookupRequestStatus,
110 };
111}
112
113/// Host-call APIs available for the [Service::on_transfer] entry-point.
114#[cfg(any(feature = "service", doc))]
115pub mod on_transfer {
116 pub use super::host_calls::{
117 foreign_lookup, foreign_lookup_into, forget, gas, get, get_foreign, get_foreign_storage,
118 get_storage, is_available, is_foreign_available, lookup, lookup_into, my_info, remove,
119 remove_storage, service_info, set, set_storage, solicit,
120 };
121}
122
123pub(crate) mod imports;
124
125#[doc(hidden)]
126pub mod logging;
127
128#[doc(hidden)]
129pub mod mem;
130
131mod result;
132pub use result::{ApiError, ApiResult, InvokeOutcome, InvokeResult};