Skip to content

Commit

Permalink
feat(poc): extension system (#27)
Browse files Browse the repository at this point in the history
* Every Extension is represented by a trait 
* Extension trait has corresponding Dispatchables (enum generic on extension impl)
* dummy implementations for trait like extension_core and extension_fungibles
* An ExtensionExecutor which supports initializing extension impls tuple, dispatching polkavm host calls
* A PermController safeguards extensions according to invocation source
  • Loading branch information
indirection42 authored Jun 6, 2024
1 parent f811522 commit f1b7052
Show file tree
Hide file tree
Showing 15 changed files with 398 additions and 7 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"poc/hosts/*",
"poc/runtime",
"poc/executor",
"poc/extensions",

"xcq-api",
"xcq-executor",
Expand Down Expand Up @@ -51,8 +52,13 @@ polkavm = { path = "vendor/polkavm/crates/polkavm", default-features = false }
sp-api = { version = "29.0.0", default-features = false }

# nostd
parity-scale-codec = { version = "3.6.12", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { version = "2.11.3", default-features = false, features = ["derive"] }
parity-scale-codec = { version = "3.6.12", default-features = false, features = [
"derive",
"max-encoded-len",
] }
scale-info = { version = "2.11.3", default-features = false, features = [
"derive",
] }
tracing = { version = "0.1.40", default-features = false }

# std
Expand Down
9 changes: 7 additions & 2 deletions poc/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ impl<Ctx: XcqExecutorContext> XcqExecutor<Ctx> {
}
}

pub fn execute(&mut self, raw_blob: &[u8], input: &[u8]) -> Result<Vec<u8>, XcqExecutorError> {
pub fn execute(
&mut self,
raw_blob: &[u8],
method: impl AsRef<[u8]>,
input: &[u8],
) -> Result<Vec<u8>, XcqExecutorError> {
let blob = ProgramBlob::parse(raw_blob.into())?;
let module = Module::from_blob(&self.engine, &Default::default(), blob)?;
let instance_pre = self.linker.instantiate_pre(&module)?;
Expand All @@ -71,7 +76,7 @@ impl<Ctx: XcqExecutorContext> XcqExecutor<Ctx> {
0
};

let res = instance.call_typed::<(u32, u32), u64>(&mut self.context, "main", (input_ptr, input.len() as u32))?;
let res = instance.call_typed::<(u32, u32), u64>(&mut self.context, method, (input_ptr, input.len() as u32))?;
let res_ptr = (res >> 32) as u32;
let res_size = (res & 0xffffffff) as u32;
let result = instance
Expand Down
14 changes: 14 additions & 0 deletions poc/extensions/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "poc-extension"
version = "0.1.0"
edition = "2021"

[dependencies]
parity-scale-codec = { version = "3.6.12", default-features = false }
scale-info = { version = "2.6.0", default-features = false }
poc-executor = { path = "../executor", default-features = false }
impl-trait-for-tuples = "0.2.2"

[features]
default = ["std"]
std = ["parity-scale-codec/std", "scale-info/std", "poc-executor/std"]
7 changes: 7 additions & 0 deletions poc/extensions/src/dispatchable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub trait Dispatchable {
fn dispatch(self) -> Result<Vec<u8>, DispatchError>;
}

pub enum DispatchError {
PhantomData,
}
10 changes: 10 additions & 0 deletions poc/extensions/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// TODO: contain source error
use crate::DispatchError;
use parity_scale_codec::Error as CodeCError;
pub enum ExtensionError {
PermissionError,
PolkavmError,
DecodeError(CodeCError),
DispatchError(DispatchError),
UnsupportedExtension,
}
48 changes: 48 additions & 0 deletions poc/extensions/src/extension_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use crate::{DispatchError, Dispatchable};
use crate::{ExtensionId, ExtensionIdTy};
use parity_scale_codec::{Decode, Encode};

pub trait ExtensionCore {
type Config: Config;
fn some_host_function(
args: <Self::Config as Config>::ArgsOfSomeHostFunction,
) -> <Self::Config as Config>::ResultOfSomeHostFunction;
}

pub trait Config {
type ArgsOfSomeHostFunction: Decode;
type ResultOfSomeHostFunction: Encode;
}

// #[extension(ExtensionCore)]
// type Call;

mod generated_by_extension_decl {
use super::*;

#[derive(Decode)]
pub enum ExtensionCoreCall<Impl: ExtensionCore> {
SomeHostFunction {
args: <Impl::Config as Config>::ArgsOfSomeHostFunction,
},
}

impl<Impl: ExtensionCore> Dispatchable for ExtensionCoreCall<Impl> {
fn dispatch(self) -> Result<Vec<u8>, DispatchError> {
match self {
Self::SomeHostFunction { args } => Ok(Impl::some_host_function(args).encode()),
}
}
}

impl<Impl: ExtensionCore> ExtensionId for ExtensionCoreCall<Impl> {
const EXTENSION_ID: ExtensionIdTy = 0u64;
}

// TODO: remove this when formalized
#[allow(dead_code)]
pub type Call<Impl> = ExtensionCoreCall<Impl>;
}

#[allow(unused_imports)]
pub use generated_by_extension_decl::*;
44 changes: 44 additions & 0 deletions poc/extensions/src/extension_fungibles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::{DispatchError, Dispatchable};
use crate::{ExtensionId, ExtensionIdTy};
use core::marker::PhantomData;
use parity_scale_codec::{Decode, Encode};

pub trait ExtensionFungibles {
fn free_balance_of(who: [u8; 32]) -> u32;
fn reserved_balance_of(who: [u8; 32]) -> u32;
}

// #[extension(ExtensionFungibles)]
// type Call;

mod generated_by_extension_decl {

use super::*;
#[derive(Decode)]
pub enum ExtensionFungiblesCall<Impl: ExtensionFungibles> {
FreeBalanceOf { who: [u8; 32] },
ReservedBalanceOf { who: [u8; 32] },
_Marker(PhantomData<Impl>),
}

impl<Impl: ExtensionFungibles> Dispatchable for ExtensionFungiblesCall<Impl> {
fn dispatch(self) -> Result<Vec<u8>, DispatchError> {
match self {
Self::FreeBalanceOf { who } => Ok(Impl::free_balance_of(who).encode()),
Self::ReservedBalanceOf { who } => Ok(Impl::reserved_balance_of(who).encode()),
Self::_Marker(_) => Err(DispatchError::PhantomData),
}
}
}

impl<Impl: ExtensionFungibles> ExtensionId for ExtensionFungiblesCall<Impl> {
const EXTENSION_ID: ExtensionIdTy = 1u64;
}

// TODO: remove this when formalized
#[allow(dead_code)]
pub type Call<Impl> = ExtensionFungiblesCall<Impl>;
}

#[allow(unused_imports)]
pub use generated_by_extension_decl::*;
5 changes: 5 additions & 0 deletions poc/extensions/src/extension_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub type ExtensionIdTy = u64;

pub trait ExtensionId {
const EXTENSION_ID: ExtensionIdTy;
}
10 changes: 10 additions & 0 deletions poc/extensions/src/guest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pub trait Guest {
fn program(&self) -> &[u8];
}

pub type Method = String;

pub trait Input {
fn method(&self) -> Method;
fn args(&self) -> &[u8];
}
Loading

0 comments on commit f1b7052

Please sign in to comment.