Skip to content

Commit

Permalink
Feature owen mock move action (#436)
Browse files Browse the repository at this point in the history
* feat: add deps

* feat: impl Arbitrary for MoveAction

* feat: ok for move_action proptest

* feat: mock move_action ok

* feat: fix moveos_types dep error
  • Loading branch information
yubing744 authored Jul 9, 2023
1 parent 01642f1 commit e00d022
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 3 deletions.
5 changes: 3 additions & 2 deletions crates/rooch-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ ethers = { workspace = true }
enum_dispatch = { workspace = true }
hex = { workspace = true }
once_cell = { workspace = true }
proptest = { default-features = false, optional = true, workspace = true }
proptest-derive = { default-features = false, optional = true, workspace = true }
rand = { workspace = true }
thiserror = { workspace = true }
smt = { workspace = true }
Expand All @@ -47,6 +45,9 @@ moveos-types = { workspace = true }
moveos-stdlib = { workspace = true }
moveos = { workspace = true }

proptest = { default-features = false, optional = true, workspace = true }
proptest-derive = { default-features = false, optional = true, workspace = true }

[dev-dependencies]
proptest = { workspace = true }
proptest-derive = { workspace = true }
Expand Down
17 changes: 16 additions & 1 deletion moveos/moveos-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,19 @@ move-resource-viewer = { workspace = true }
move-bytecode-utils = { workspace = true }
fastcrypto = { workspace = true }

smt = { workspace = true }
smt = { workspace = true }

proptest = { default-features = false, optional = true, workspace = true }
proptest-derive = { default-features = false, optional = true, workspace = true }

[dev-dependencies]
proptest = { workspace = true }
proptest-derive = { workspace = true }
move-core-types = { workspace = true, features = ["fuzzing"] }

[features]
default = []
fuzzing = [
"proptest",
"proptest-derive",
]
50 changes: 50 additions & 0 deletions moveos/moveos-types/src/move_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use serde::{Deserialize, Serialize, Serializer};
use std::fmt;
use std::str::FromStr;

#[cfg(any(test, feature = "fuzzing"))]
use proptest::prelude::*;

/// Identifier of a module function
/// The FunctionId is of the form <address>::<module>::<function>
#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, Serialize, Deserialize, Hash)]
Expand Down Expand Up @@ -224,3 +227,50 @@ pub fn as_struct_tag(type_tag: TypeTag) -> Result<StructTag> {
bail!("invalid struct tag: {:?}", type_tag)
}
}

#[cfg(any(test, feature = "fuzzing"))]
pub fn type_tag_prop_strategy() -> impl Strategy<Value = TypeTag> {
let leaf = prop_oneof![
Just(TypeTag::Bool),
Just(TypeTag::U8),
Just(TypeTag::U16),
Just(TypeTag::U32),
Just(TypeTag::U64),
Just(TypeTag::U128),
Just(TypeTag::U256),
Just(TypeTag::Address),
Just(TypeTag::Signer),
];

let type_tag_strategy = leaf.prop_recursive(
8, // Arbitrarily chosen depth, adjust to suit your needs
256, // Arbitrarily chosen size limit, adjust to suit your needs
10, // Per-vec limit, adjust to suit your needs
|elem| {
prop_oneof![
// Recursively generate TypeTag for Vector
elem.clone().prop_map(|t| TypeTag::Vector(Box::new(t))),
// Recursively generate TypeTag for StructTag
any::<Vec<TypeTag>>()
.prop_flat_map(move |type_params| {
(
any::<Identifier>(),
any::<Identifier>(),
Just(AccountAddress::random()),
Just(type_params),
)
})
.prop_map(|(module, name, address, type_params)| {
TypeTag::Struct(Box::new(StructTag {
address,
module,
name,
type_params,
}))
}),
]
},
);

type_tag_strategy
}
74 changes: 74 additions & 0 deletions moveos/moveos-types/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ use move_core_types::{
use serde::{Deserialize, Serialize};
use std::fmt::Display;

#[cfg(any(test, feature = "fuzzing"))]
use crate::move_types::type_tag_prop_strategy;
#[cfg(any(test, feature = "fuzzing"))]
use move_core_types::identifier::Identifier;
#[cfg(any(test, feature = "fuzzing"))]
use proptest::prelude::*;
#[cfg(any(test, feature = "fuzzing"))]
use proptest_derive::Arbitrary;

/// Call a Move script
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct ScriptCall {
Expand All @@ -24,6 +33,29 @@ pub struct ScriptCall {
pub args: Vec<Vec<u8>>,
}

// Generates random ScriptCall
#[cfg(any(test, feature = "fuzzing"))]
impl Arbitrary for ScriptCall {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;

fn arbitrary_with(_args: ()) -> Self::Strategy {
let ty_args_strategy = prop::collection::vec(type_tag_prop_strategy(), 0..10);

(
any::<Vec<u8>>(),
ty_args_strategy,
Vec::<Vec<u8>>::arbitrary(),
)
.prop_map(|(code, ty_args, args)| ScriptCall {
code,
ty_args,
args,
})
.boxed()
}
}

/// Call a Move function
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct FunctionCall {
Expand All @@ -43,7 +75,34 @@ impl FunctionCall {
}
}

// Generates random FunctionCall
#[cfg(any(test, feature = "fuzzing"))]
#[cfg(any(test, feature = "fuzzing"))]
impl Arbitrary for FunctionCall {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
let function_id_strategy = (any::<ModuleId>(), any::<Identifier>())
.prop_map(|(module_id, identifier)| FunctionId::new(module_id, identifier));
let ty_args_strategy = prop::collection::vec(type_tag_prop_strategy(), 0..10);

(
function_id_strategy,
ty_args_strategy,
any::<Vec<Vec<u8>>>(),
)
.prop_map(|(function_id, ty_args, args)| FunctionCall {
function_id,
ty_args,
args,
})
.boxed()
}
}

#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
pub enum MoveAction {
//Execute a Move script
Script(ScriptCall),
Expand Down Expand Up @@ -208,3 +267,18 @@ impl TransactionExecutionInfo {
h256::sha3_256_of(bcs::to_bytes(self).unwrap().as_slice())
}
}

#[cfg(test)]
mod tests {
use super::MoveAction;
use proptest::prelude::*;

proptest! {
#[test]
fn test_move_action_bcs_serde(input in any::<MoveAction>()) {
let serialized = bcs::to_bytes(&input).unwrap();
let deserialized: MoveAction = bcs::from_bytes(&serialized).unwrap();
assert_eq!(input, deserialized);
}
}
}

0 comments on commit e00d022

Please sign in to comment.