#refine #jam #authorizers #logging #vec #jam-pvm-common #my-service #set-storage #declare-service

no-std jam-pvm-common

Common logic for JAM PVM crates including services and authorizers

23 releases

new 0.1.21 Apr 16, 2025
0.1.20 Apr 15, 2025
0.1.12 Jan 16, 2025
0.1.8 Nov 29, 2024

#354 in Magic Beans

Download history 112/week @ 2025-01-03 160/week @ 2025-01-10 131/week @ 2025-01-17 1/week @ 2025-01-24 9/week @ 2025-01-31 4/week @ 2025-02-07 5/week @ 2025-02-14 2/week @ 2025-02-21 2/week @ 2025-02-28 498/week @ 2025-04-11

498 downloads per month
Used in 5 crates (2 directly)

Apache-2.0

145KB
3K SLoC

The JAM PVM Common Logic

This is the main JAM PVM API, containing invocation and host-call logic common across JAM PVM authorizers and services.


lib.rs:

The main JAM PVM API for creating authorizers and services on JAM. This includes a trait-based invocation entry-point API as well as host-calls functions and types for working with them.

In order to create a PVM executable containing a JAM service or authorizer, you must implement the [Service] or [Authorizer] in some type and then pass your type into the declare_service! or declare_authorizer! macro, respectively. This will generate the necessary entry-points for the PVM to call into your implementation.

Example Service

extern crate alloc;
use alloc::vec::Vec;
use jam_pvm_common::{declare_service, Service, accumulate::set_storage};
use jam_types::*;

struct MyService;
declare_service!(MyService);

impl Service for MyService {
    fn refine(
        _id: ServiceId,
        payload: WorkPayload,
        _package_hash: WorkPackageHash,
        _context: RefineContext,
        _auth_code_hash: CodeHash,
    ) -> WorkOutput {
        [&b"Hello "[..], payload.take().as_slice()].concat().into()
    }
    fn accumulate(_slot: Slot, _id: ServiceId, items: Vec<AccumulateItem>) -> Option<Hash> {
        for item in items.into_iter() {
            if let Ok(data) = item.result {
                set_storage(item.package.as_slice(), &data).expect("not enough balance?!");
            }
        }
        None
    }
    fn on_transfer(_slot: Slot, _id: ServiceId, _items: Vec<TransferRecord>) {}
}

Host-calls

The host-calls available to a service or authorizer are split into four modules:

Each module contains a set of functions that can be called from the respective entry-point function. These functions are used to interact with the PVM and the blockchain state.

Logging

Five logging macros are provided similar to those of the log crate, [debug], [info], [warn], [error], and [trace]. These macros are used with the non-standard PolkaJam log host-call and the format macro. The host environment is responsible for forwarding these logs to the appropriate destination.

Features

  • authorizer: Enables the authorizer API.
  • service: Enables the service API.
  • logging: Enables the logging service; without the logging macros will evaluate any operands but otherwise have no effect.

Dependencies

~4.5MB
~101K SLoC