Skip to content

Commit

Permalink
Mocks for sov-modules-api (Sovereign-Labs#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkolad authored Feb 7, 2023
1 parent 81f6b81 commit 9c3a5a5
Show file tree
Hide file tree
Showing 22 changed files with 177 additions and 102 deletions.
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ members = [


[workspace.dependencies]
# Internal dependencies
sovereign-sdk = {path= "sdk" }
jellyfish-merkle-generic = {path= "jmt" }
first-read-last-write-cache = {path = "first-read-last-write-cache"}
sov-state = {path = "sov-modules/sov-state"}
sov-modules-api = {path = "sov-modules/sov-modules-api"}
sov-modules-macros = {path = "sov-modules/sov-modules-macros"}

# External dependencies
anyhow = "1.0.68"
borsh = { version = "0.10.0", features = ["rc"]}
Expand Down
9 changes: 6 additions & 3 deletions sov-modules/sov-modules-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ name = "sov-modules-api"
version = "0.1.0"
edition = "2021"


[dependencies]
sov-state = { path = "../sov-state" }
sovereign-sdk = { git = "https://github.com/Sovereign-Labs/sovereign-sdk" }
sov-state = { workspace = true }
sovereign-sdk = { workspace = true }
borsh = { workspace = true, optional = true}

[features]
mocks = ["dep:borsh"]
21 changes: 16 additions & 5 deletions sov-modules/sov-modules-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#![feature(associated_type_defaults)]

#[cfg(feature = "mocks")]
pub mod mocks;

use sov_state::Storage;
use sovereign_sdk::{
serial::{Decode, DecodeBorrowed},
Expand All @@ -9,24 +13,31 @@ use std::{convert::Infallible, io::Read};
// A unique identifier for each state variable in a module.
#[derive(Debug, PartialEq, Eq)]
pub struct Prefix {
storage_name: String,
module_path: String,
module_name: String,
storage_name: String,
}

impl Prefix {
pub fn new(module_path: String, module_name: String, storage_name: String) -> Self {
Self {
storage_name,
module_path,
module_name,
storage_name,
}
}
}

impl From<Prefix> for sov_state::Prefix {
fn from(_value: Prefix) -> Self {
todo!()
fn from(prefix: Prefix) -> Self {
let mut combined_prefix = Vec::with_capacity(
prefix.module_path.len() + prefix.module_name.len() + prefix.storage_name.len(),
);

combined_prefix.extend(prefix.module_path.as_bytes());
combined_prefix.extend(prefix.module_name.as_bytes());
combined_prefix.extend(prefix.storage_name.as_bytes());
sov_state::Prefix::new(combined_prefix)
}
}

Expand All @@ -47,7 +58,7 @@ pub trait Context {
type PublicKey: Decode + Eq;

// Sender of the transaction.
fn sender(&self) -> Self::PublicKey;
fn sender(&self) -> &Self::PublicKey;
}

// A type that can't be instantiated.
Expand Down
68 changes: 68 additions & 0 deletions sov-modules/sov-modules-api/src/mocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::Context;
use sov_state::storage::{StorageKey, StorageValue};
use std::{collections::HashMap, sync::Arc};

/// Mock for Context::PublicKey, useful for testing.
#[derive(borsh::BorshDeserialize, PartialEq, Eq)]
pub struct MockPublicKey {
pub_key: Vec<u8>,
}

impl MockPublicKey {
pub fn new(pub_key: Vec<u8>) -> Self {
Self { pub_key }
}
}

/// Mock for Context::Signature, useful for testing.
#[derive(borsh::BorshDeserialize, PartialEq, Eq)]
pub struct MockSignature {
sig: Vec<u8>,
}

impl MockSignature {
pub fn new(sig: Vec<u8>) -> Self {
Self { sig }
}
}

/// Mock for Context::Storage, useful for testing.
// TODO: as soon as we have JMT storage implemented, we should remove this mock and use a real db even in tests.
// see https://github.com/Sovereign-Labs/sovereign/issues/40
#[derive(Clone, Default)]
pub struct MockStorage {
storage: HashMap<Arc<Vec<u8>>, Arc<Vec<u8>>>,
}

impl sov_state::Storage for MockStorage {
fn get(&mut self, key: StorageKey, _version: u64) -> Option<StorageValue> {
self.storage
.get(&key.key)
.map(|v| StorageValue { value: v.clone() })
}

fn set(&mut self, key: StorageKey, _version: u64, value: StorageValue) {
self.storage.insert(key.key, value.value);
}

fn delete(&mut self, key: StorageKey, _version: u64) {
self.storage.remove(&key.key);
}
}

/// Mock for Context, useful for testing.
pub struct MockContext {
sender: MockPublicKey,
}

impl Context for MockContext {
type Storage = MockStorage;

type Signature = MockSignature;

type PublicKey = MockPublicKey;

fn sender(&self) -> &Self::PublicKey {
&self.sender
}
}
10 changes: 4 additions & 6 deletions sov-modules/sov-modules-impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ name = "sov-modules-impl"
version = "0.1.0"
edition = "2021"



[dependencies]
sov-modules-api = { path = "../sov-modules-api" }
sov-modules-macros = { path = "../sov-modules-macros" }
sov-state = { path = "../sov-state" }
sovereign-sdk = { git = "https://github.com/Sovereign-Labs/sovereign-sdk" }
sov-modules-api = { workspace = true }
sov-modules-macros = { workspace = true }
sov-state = { workspace = true }
sovereign-sdk = { workspace = true }

4 changes: 2 additions & 2 deletions sov-modules/sov-modules-impl/src/example/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ impl<C: sov_modules_api::Context> Bank<C> {
transfer: Transfer<C>,
context: C,
) -> Result<sov_modules_api::CallResponse, <Self as sov_modules_api::Module>::CallError> {
if transfer.from != context.sender() {
if &transfer.from != context.sender() {
todo!()
}

Expand All @@ -18,7 +18,7 @@ impl<C: sov_modules_api::Context> Bank<C> {
delete: Delete<C>,
context: C,
) -> Result<sov_modules_api::CallResponse, <Self as sov_modules_api::Module>::CallError> {
if delete.id != context.sender() {
if &delete.id != context.sender() {
todo!()
}

Expand Down
6 changes: 3 additions & 3 deletions sov-modules/sov-modules-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ version = "0.1.0"
edition = "2021"
autotests = false



[lib]
proc-macro = true

Expand All @@ -15,9 +13,11 @@ path = "tests/all_tests.rs"

[dev-dependencies]
trybuild = "1.0"
sov-modules-api = { workspace = true , features = ["mocks"]}
sov-state = {workspace = true}

[dependencies]
sov-modules-api = { path = "../sov-modules-api" }
sov-modules-api = { workspace = true }

syn = { version = "1.0", features = ["full"] }
quote = "1.0"
Expand Down
2 changes: 0 additions & 2 deletions sov-modules/sov-modules-macros/tests/all_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
mod utils;

#[test]
fn tests() {
let t = trybuild::TestCases::new();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
mod utils;
use sov_modules_api::Context;
use sov_modules_macros::ModuleInfo;
use utils::{Context, TestState};
use sov_state::StateMap;

#[derive(ModuleInfo)]
enum TestStruct<C: Context> {
#[state]
TestState1(TestState<C::Storage>),
TestState1(StateMap<String, String, C::Storage>),

#[state]
TestState2(TestState<C::Storage>),
TestState2(StateMap<String, String, C::Storage>),
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
mod utils;
use sov_modules_api::Context;
use sov_modules_macros::ModuleInfo;
use utils::{Context, TestState};
use sov_state::StateMap;

#[derive(ModuleInfo)]
struct TestStruct<C: Context> {
test_state1: TestState<C::Storage>,
test_state1: StateMap<u32, u32, C::Storage>,

#[state]
test_state2: TestState<C::Storage>,
test_state2: StateMap<Vec<u8>, u64, C::Storage>,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: This field is missing an attribute: add `#[module]` or `#[state]`.
--> tests/field_missing_attribute.rs:7:5
|
7 | test_state1: TestState<C::Storage>,
7 | test_state1: StateMap<u32, u32, C::Storage>,
| ^^^^^^^^^^^
27 changes: 15 additions & 12 deletions sov-modules/sov-modules-macros/tests/mod_and_state.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
pub mod utils;

use sov_modules_api::mocks::{MockContext, MockStorage};
use sov_modules_api::Context;
use sov_modules_macros::ModuleInfo;
use utils::{Context, TestContext, TestState, TestStorage};
use sov_state::StateMap;

pub mod first_test_module {
use super::*;

#[derive(ModuleInfo)]
pub(crate) struct FirstTestStruct<C: Context> {
#[state]
pub state_in_first_struct_1: TestState<C::Storage>,
pub state_in_first_struct_1: StateMap<C::PublicKey, u32, C::Storage>,

#[state]
pub state_in_first_struct_2: TestState<C::Storage>,
pub state_in_first_struct_2: StateMap<String, String, C::Storage>,
}
}

Expand All @@ -22,41 +22,44 @@ mod second_test_module {
#[derive(ModuleInfo)]
pub(crate) struct SecondTestStruct<C: Context> {
#[state]
pub state_in_second_struct_1: TestState<C::Storage>,
pub state_in_second_struct_1: StateMap<String, u32, C::Storage>,

#[module]
pub module_in_second_struct_1: first_test_module::FirstTestStruct<C>,
}
}

fn main() {
let test_storage = TestStorage {};
let test_storage = MockStorage::default();

let second_test_struct =
second_test_module::SecondTestStruct::<TestContext>::_new(test_storage);
second_test_module::SecondTestStruct::<MockContext>::_new(test_storage);

let prefix2 = second_test_struct.state_in_second_struct_1.prefix;
let prefix2 = second_test_struct.state_in_second_struct_1.prefix();
assert_eq!(
prefix2,
*prefix2,
sov_modules_api::Prefix::new(
// The tests compile inside trybuild.
"trybuild001::second_test_module".to_owned(),
"SecondTestStruct".to_owned(),
"state_in_second_struct_1".to_owned()
)
.into()
);

let prefix1 = second_test_struct
.module_in_second_struct_1
.state_in_first_struct_1
.prefix;
.prefix();

assert_eq!(
prefix1,
*prefix1,
sov_modules_api::Prefix::new(
// The tests compile inside trybuild.
"trybuild001::first_test_module".to_owned(),
"FirstTestStruct".to_owned(),
"state_in_first_struct_1".to_owned()
)
.into()
);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
mod utils;
use sov_modules_api::Context;
use sov_modules_macros::ModuleInfo;
use utils::{Context, TestState};
use sov_state::StateMap;

#[derive(ModuleInfo)]
struct TestStruct<C: Context> {
#[other]
test_state1: TestState<C::Storage>,
test_state1: StateMap<u32, String, C::Storage>,

#[state]
test_state2: TestState<C::Storage>,
test_state2: StateMap<C::PublicKey, String, C::Storage>,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error: Only `#[module]` or `#[state]` attributes are supported.
--> tests/not_supported_attribute.rs:8:5
|
8 | test_state1: TestState<C::Storage>,
8 | test_state1: StateMap<u32, String, C::Storage>,
| ^^^^^^^^^^^

error: cannot find attribute `other` in this scope
Expand Down
7 changes: 3 additions & 4 deletions sov-modules/sov-modules-macros/tests/not_supported_type.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
mod utils;

use sov_modules_api::Context;
use sov_modules_macros::ModuleInfo;
use utils::{Context, TestState};
use sov_state::StateMap;

#[derive(ModuleInfo)]
struct TestStruct<C: Context> {
#[state]
test_state1: [usize; 22],

#[state]
test_state2: TestState<C::Storage>,
test_state2: StateMap<u32, u32, C::Storage>,
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: Type not supported by the `ModuleInfo` macro
--> tests/not_supported_type.rs:9:18
--> tests/not_supported_type.rs:8:18
|
9 | test_state1: [usize; 22],
8 | test_state1: [usize; 22],
| ^^^^^^^^^^^
Loading

0 comments on commit 9c3a5a5

Please sign in to comment.