Skip to content

Commit

Permalink
Fixing where bounds for rpc_gen (#726)
Browse files Browse the repository at this point in the history
  • Loading branch information
citizen-stig authored Aug 24, 2023
1 parent 203d839 commit 04408b8
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

10 changes: 6 additions & 4 deletions module-system/sov-modules-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ name = "tests"
path = "tests/all_tests.rs"

[dev-dependencies]
serde_json = "1"
tempfile = "3"

clap = { workspace = true }
jsonrpsee = { workspace = true, features = ["macros", "http-client", "server"] }
serde = { workspace = true }
serde_json = { workspace = true }
tempfile = { workspace = true }
trybuild = "1.0"

sov-modules-api = { path = "../sov-modules-api", version = "0.1" }
sov-state = { path = "../sov-state", version = "0.1" }
sov-bank = { path = "../module-implementations/sov-bank", version = "0.1", features = ["native"] }
serde = { workspace = true }
clap = { workspace = true }
sov-modules-macros = { path = ".", features = ["native"] }

[dependencies]
anyhow = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion module-system/sov-modules-macros/src/rpc/expose_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl ExposeRpcMacro {
}

let get_rpc_methods: proc_macro2::TokenStream = quote! {
pub fn get_rpc_methods #impl_generics (storage: <#context_type as ::sov_modules_api::Spec>::Storage) -> jsonrpsee::RpcModule<()> #where_clause{
pub fn get_rpc_methods #impl_generics (storage: <#context_type as ::sov_modules_api::Spec>::Storage) -> jsonrpsee::RpcModule<()> #where_clause {
let mut module = jsonrpsee::RpcModule::new(());
let r = RpcStorage::<#context_type> {
storage: storage.clone(),
Expand Down
17 changes: 10 additions & 7 deletions module-system/sov-modules-macros/src/rpc/rpc_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::{
parenthesized, Attribute, FnArg, ImplItem, Meta, MetaList, PatType, Path, PathSegment,
Signature, Type,
Signature,
};

/// Returns an attribute with the name `rpc_method` replaced with `method`, and the index
Expand Down Expand Up @@ -64,7 +64,7 @@ fn find_working_set_argument(sig: &Signature) -> Option<(usize, syn::Type)> {
struct RpcImplBlock {
pub(crate) type_name: Ident,
pub(crate) methods: Vec<RpcEnabledMethod>,
pub(crate) working_set_type: Option<Type>,
pub(crate) working_set_type: Option<syn::Type>,
pub(crate) generics: syn::Generics,
}

Expand Down Expand Up @@ -164,14 +164,14 @@ impl RpcImplBlock {

let rpc_impl_trait = if let Some(ref working_set_type) = self.working_set_type {
quote! {
pub trait #impl_trait_name #generics {
pub trait #impl_trait_name #generics #where_clause {
fn get_working_set(&self) -> #working_set_type;
#(#impl_trait_methods)*
}
}
} else {
quote! {
pub trait #impl_trait_name #generics {
pub trait #impl_trait_name #generics #where_clause {
#(#impl_trait_methods)*
}
}
Expand Down Expand Up @@ -303,13 +303,16 @@ fn build_rpc_trait(
#input
};

let where_clause = &generics.where_clause;

let rpc_output = quote! {
#simplified_impl

#impl_rpc_trait_impl


#rpc_attribute
pub trait #intermediate_trait_name #generics {
pub trait #intermediate_trait_name #generics #where_clause {

#(#intermediate_trait_items)*

Expand All @@ -335,12 +338,12 @@ pub(crate) fn rpc_gen(
build_rpc_trait(attrs, type_name.clone(), input)
}

struct TypeList(pub Punctuated<Type, syn::token::Comma>);
struct TypeList(pub Punctuated<syn::Type, syn::token::Comma>);

impl Parse for TypeList {
fn parse(input: ParseStream) -> syn::Result<Self> {
let content;
parenthesized!(content in input);
Ok(TypeList(content.parse_terminated(Type::parse)?))
Ok(TypeList(content.parse_terminated(syn::Type::parse)?))
}
}
5 changes: 2 additions & 3 deletions module-system/sov-modules-macros/tests/all_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ fn module_dispatch_tests() {
t.compile_fail("tests/dispatch/missing_serialization.rs");
}

#[cfg(feature = "native")]
#[test]
fn rpc_tests() {
let t = trybuild::TestCases::new();
t.pass("tests/derive_rpc.rs");
t.pass("tests/rpc/derive_rpc.rs");
t.pass("tests/rpc/derive_rpc_with_where.rs");
}

#[cfg(feature = "native")]
#[test]
fn cli_wallet_arg_tests() {
let t: trybuild::TestCases = trybuild::TestCases::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,5 @@ fn main() {
assert_eq!(result, ());
}

println!("All tests passed!")
println!("All tests passed!");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use std::hash::Hasher;

use jsonrpsee::core::RpcResult;
use sov_modules_api::default_context::ZkDefaultContext;
use sov_modules_api::macros::rpc_gen;
use sov_modules_api::{Context, ModuleInfo};
use sov_state::{WorkingSet, ZkStorage};

#[derive(ModuleInfo)]
pub struct TestStruct<C: ::sov_modules_api::Context, D>
where
D: std::hash::Hash
+ std::clone::Clone
+ borsh::BorshSerialize
+ borsh::BorshDeserialize
+ serde::Serialize
+ serde::de::DeserializeOwned
+ 'static,
{
#[address]
pub(crate) address: C::Address,
#[state]
pub(crate) data: ::sov_state::StateValue<D>,
}

#[rpc_gen(client, server, namespace = "test")]
impl<C: sov_modules_api::Context, D> TestStruct<C, D>
where
D: std::hash::Hash
+ std::clone::Clone
+ borsh::BorshSerialize
+ borsh::BorshDeserialize
+ serde::Serialize
+ serde::de::DeserializeOwned
+ 'static,
{
#[rpc_method(name = "firstMethod")]
pub fn first_method(&self, _working_set: &mut WorkingSet<C::Storage>) -> RpcResult<u32> {
Ok(11)
}

#[rpc_method(name = "secondMethod")]
pub fn second_method(
&self,
result: D,
_working_set: &mut WorkingSet<C::Storage>,
) -> RpcResult<(D, u64)> {
let mut hasher = std::collections::hash_map::DefaultHasher::new();
let value = result.clone();
value.hash(&mut hasher);
let hashed_value = hasher.finish();

Ok((value, hashed_value))
}
}

pub struct TestRuntime<C: Context> {
test_struct: TestStruct<C, u32>,
}

// This is generated by a macro annotating the state transition runner,
// but we do not have that in scope here so generating the struct manually.
struct RpcStorage<C: Context> {
pub storage: C::Storage,
}

impl TestStructRpcImpl<ZkDefaultContext, u32> for RpcStorage<ZkDefaultContext> {
fn get_working_set(
&self,
) -> ::sov_state::WorkingSet<<ZkDefaultContext as ::sov_modules_api::Spec>::Storage> {
::sov_state::WorkingSet::new(self.storage.clone())
}
}

fn main() {
let storage = ZkStorage::new([1u8; 32]);
let r: RpcStorage<ZkDefaultContext> = RpcStorage {
storage: storage.clone(),
};
{
let result =
<RpcStorage<ZkDefaultContext> as TestStructRpcServer<ZkDefaultContext, u32>>::first_method(
&r,
)
.unwrap();
assert_eq!(result, 11);
}

{
let result =
<RpcStorage<ZkDefaultContext> as TestStructRpcServer<ZkDefaultContext, u32>>::second_method(
&r, 22,
)
.unwrap();
assert_eq!(result, (22, 15733059416522709050));
}

println!("All tests passed!");
}

0 comments on commit 04408b8

Please sign in to comment.