From 4b81ae16722792c4b7f3a2b0d2c3051e506d99c1 Mon Sep 17 00:00:00 2001 From: ondratra Date: Thu, 9 Jul 2020 18:07:35 +0200 Subject: [PATCH 01/15] forum - dead code removal --- node/src/forum_config/from_serialized.rs | 4 ---- runtime-modules/forum/src/lib.rs | 20 -------------------- runtime-modules/forum/src/mock.rs | 16 ---------------- 3 files changed, 40 deletions(-) diff --git a/node/src/forum_config/from_serialized.rs b/node/src/forum_config/from_serialized.rs index 079938e7bc..b56c51a7d1 100644 --- a/node/src/forum_config/from_serialized.rs +++ b/node/src/forum_config/from_serialized.rs @@ -47,11 +47,7 @@ pub fn create() -> ForumConfig { // TODO: get rid of mocks and setup valid values category_by_moderator: Vec::new(), reaction_by_post: Vec::new(), - poll_desc_constraint: new_validation(10, 90), poll_items_constraint: new_validation(1, 10), - user_name_constraint: new_validation(10, 90), - user_self_introduction_constraint: new_validation(10, 90), - post_footer_constraint: new_validation(10, 90), data_migration_done: true, } } diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 09ad42d88c..0604ce2f56 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -392,14 +392,6 @@ const ERROR_DATA_MIGRATION_NOT_DONE: &str = "data migration not done yet."; use system::ensure_signed; -/// Represents a revision of the text of a Post -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)] -pub struct PostTextChange { - /// Text that expired - pub text_hash: Hash, -} - /// Represents all poll alternatives and vote count for each one #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)] @@ -539,21 +531,9 @@ decl_storage! { /// Each account 's reaction to a post. pub ReactionByPost get(reaction_by_post) config(): double_map T::PostId, blake2_256(T::ForumUserId) => T::PostReactionId; - /// Input constraints for description text of each item in poll. - pub PollDescConstraint get(poll_desc_constraint) config(): InputValidationLengthConstraint; - /// Input constraints for number of items in poll. pub PollItemsConstraint get(poll_items_constraint) config(): InputValidationLengthConstraint; - /// Input constraints for user name. - pub UserNameConstraint get(user_name_constraint) config(): InputValidationLengthConstraint; - - /// Input constraints for user introduction. - pub UserSelfIntroductionConstraint get(user_self_introduction_constraint) config(): InputValidationLengthConstraint; - - /// Input constraints for post footer. - pub PostFooterConstraint get(post_footer_constraint) config(): InputValidationLengthConstraint; - /// If data migration is done, set as configible for unit test purpose pub DataMigrationDone get(data_migration_done) config(): bool; } diff --git a/runtime-modules/forum/src/mock.rs b/runtime-modules/forum/src/mock.rs index acbc42b669..00aa4e7923 100644 --- a/runtime-modules/forum/src/mock.rs +++ b/runtime-modules/forum/src/mock.rs @@ -667,26 +667,10 @@ pub fn create_genesis_config(data_migration_done: bool) -> GenesisConfig Date: Thu, 9 Jul 2020 19:06:01 +0200 Subject: [PATCH 02/15] forum - typed errors --- runtime-modules/forum/src/lib.rs | 328 +++++++++++++++++------------ runtime-modules/forum/src/mock.rs | 30 +-- runtime-modules/forum/src/tests.rs | 96 ++++----- 3 files changed, 262 insertions(+), 192 deletions(-) diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 0604ce2f56..010d23ec58 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -217,7 +217,7 @@ use rstd::prelude::*; pub use runtime_io::clear_prefix; use runtime_primitives::traits::{MaybeSerialize, Member, One, SimpleArithmetic}; use srml_support::{ - decl_event, decl_module, decl_storage, dispatch, ensure, traits::Get, Parameter, + decl_error, decl_event, decl_module, decl_storage, ensure, traits::Get, Parameter, }; mod mock; @@ -323,12 +323,12 @@ impl InputValidationLengthConstraint { self.min + self.max_min_diff } - pub fn ensure_valid( + pub fn ensure_valid( &self, len: usize, - too_short_msg: &'static str, - too_long_msg: &'static str, - ) -> Result<(), &'static str> { + too_short_msg: ErrorType, + too_long_msg: ErrorType, + ) -> Result<(), ErrorType> { let length = len as u16; if length < self.min { Err(too_short_msg) @@ -340,49 +340,6 @@ impl InputValidationLengthConstraint { } } -/// Error about users -const ERROR_ORIGIN_NOT_FORUM_LEAD: &str = "Origin not forum lead."; -const ERROR_FORUM_USER_ID_NOT_MATCH_ACCOUNT: &str = "Forum user id not match its account."; -const ERROR_MODERATOR_ID_NOT_MATCH_ACCOUNT: &str = "Moderator id not match its account."; - -// Errors about thread. -const ERROR_ACCOUNT_DOES_NOT_MATCH_THREAD_AUTHOR: &str = "Thread not authored by the given user."; -const ERROR_THREAD_DOES_NOT_EXIST: &str = "Thread does not exist"; -const ERROR_MODERATOR_MODERATE_ORIGIN_CATEGORY: &str = - "Moderator can't moderate category containing thread."; -const ERROR_MODERATOR_MODERATE_DESTINATION_CATEGORY: &str = - "Moderator can't moderate destination category."; -const ERROR_THREAD_MOVE_INVALID: &str = "Origin is the same as the destination."; -const ERROR_THREAD_NOT_BEING_UPDATED: &str = "Thread not being updated."; -const ERROR_THREAD_IMMUTABLE: &str = "Thread is immutable, i.e. archived."; - -// Errors about post. -const ERROR_POST_DOES_NOT_EXIST: &str = "Post does not exist."; -const ERROR_ACCOUNT_DOES_NOT_MATCH_POST_AUTHOR: &str = "Account does not match post author."; - -// Errors about category. -const ERROR_CATEGORY_NOT_BEING_UPDATED: &str = "Category not being updated."; -const ERROR_MODERATOR_MODERATE_CATEGORY: &str = "Moderator can not moderate category."; -const ERROR_ANCESTOR_CATEGORY_IMMUTABLE: &str = - "Ancestor category immutable, i.e. deleted or archived"; -const ERROR_MAX_VALID_CATEGORY_DEPTH_EXCEEDED: &str = "Maximum valid category depth exceeded."; -const ERROR_CATEGORY_DOES_NOT_EXIST: &str = "Category does not exist."; -const ERROR_CATEGORY_NOT_EMPTY_THREADS: &str = "Category still contains some threads."; -const ERROR_CATEGORY_NOT_EMPTY_CATEGORIES: &str = "Category still contains some subcategories."; -const ERROR_MODERATOR_CANT_DELETE_CATEGORY: &str = "No permissions to delete category."; -const ERROR_MODERATOR_CANT_UPDATE_CATEGORY: &str = "No permissions to update category."; - -// Errors about poll. -const ERROR_POLL_ALTERNATIVES_TOO_SHORT: &str = "Poll items number too short."; -const ERROR_POLL_ALTERNATIVES_TOO_LONG: &str = "Poll items number too long."; -const ERROR_POLL_NOT_EXIST: &str = "Poll not exist."; -const ERROR_POLL_TIME_SETTING: &str = "Poll date setting is wrong."; -const ERROR_POLL_DATA: &str = "Poll data committed is wrong."; -const ERROR_POLL_COMMIT_EXPIRED: &str = "Poll data committed after poll expired."; - -// Error data migration -const ERROR_DATA_MIGRATION_NOT_DONE: &str = "data migration not done yet."; - //use srml_support::storage::*; //use sr_io::{StorageOverlay, ChildrenStorageOverlay}; //#[cfg(feature = "std")] @@ -505,6 +462,116 @@ type CategoryTreePath = Vec = [Category]; +decl_error! { + /// Forum predefined errors + #[derive(Copy)] + pub enum Error { + /// Origin doesn't correspond to any lead account + OriginNotForumLead, + + /// Forum user id not match its account. + ForumUserIdNotMatchAccount, + + /// Moderator id not match its account. + ModeratorIdNotMatchAccount, + + // Errors about thread. + + /// Thread not authored by the given user. + AccountDoesNotMatchThreadAuthor, + + /// Thread does not exist + ThreadDoesNotExist, + + /// Moderator can't moderate category containing thread. + ModeratorModerateOriginCategory, + + /// Moderator can't moderate destination category. + ModeratorModerateDestinationCategory, + + /// Origin is the same as the destination. + ThreadMoveInvalid, + + /// Thread not being updated. + ThreadNotBeingUpdated, + + /// Thread is immutable, i.e. archived. + ThreadImmutable, + + // Errors about post. + + /// Post does not exist. + PostDoesNotExist, + + /// Account does not match post author. + AccountDoesNotMatchPostAuthor, + + // Errors about category. + + /// Category not being updated. + CategoryNotBeingUpdated, + + /// Moderator can not moderate category. + ModeratorModerateCategory, + + /// Ancestor category immutable, i.e. deleted or archived + AncestorCategoryImmutable, + + /// Maximum valid category depth exceeded. + MaxValidCategoryDepthExceeded, + + /// Category does not exist. + CategoryDoesNotExist, + + /// Category still contains some threads. + CategoryNotEmptyThreads, + + /// Category still contains some subcategories. + CategoryNotEmptyCategories, + + /// No permissions to delete category. + ModeratorCantDeleteCategory, + + /// No permissions to update category. + ModeratorCantUpdateCategory, + + // Errors about poll. + + /// Poll items number too short. + PollAlternativesTooShort, + + /// Poll items number too long. + PollAlternativesTooLong, + + /// Poll not exist. + PollNotExist, + + /// Poll date setting is wrong. + PollTimeSetting, + + /// Poll data committed is wrong. + PollData, + + /// Poll data committed after poll expired. + PollCommitExpired, + + // Error data migration + + /// data migration not done yet. + DataMigrationNotDone, + } +} + +impl From for Error { + fn from(error: system::Error) -> Self { + match error { + system::Error::Other(msg) => Error::Other(msg), + system::Error::RequireRootOrigin => Error::OriginNotForumLead, + _ => Error::Other(error.into()), + } + } +} + decl_storage! { trait Store for Module as Forum_1_1 { /// Map category identifier to corresponding category. @@ -601,10 +668,13 @@ decl_event!( decl_module! { pub struct Module for enum Call where origin: T::Origin { + /// Predefined errors + type Error = Error; + fn deposit_event() = default; /// Enable a moderator can moderate a category and its sub categories. - fn update_category_membership_of_moderator(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, new_value: bool) -> dispatch::Result { + fn update_category_membership_of_moderator(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, new_value: bool) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; clear_prefix(b"Forum ForumUserById"); @@ -615,7 +685,7 @@ decl_module! { // ensure category exists. ensure!( >::exists(&category_id), - ERROR_CATEGORY_DOES_NOT_EXIST + Error::CategoryDoesNotExist ); if new_value { @@ -629,7 +699,7 @@ decl_module! { } /// Add a new category. - fn create_category(origin, parent: Option, title: Vec, description: Vec) -> dispatch::Result { + fn create_category(origin, parent: Option, title: Vec, description: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -679,7 +749,7 @@ decl_module! { } /// Update category - fn update_category_archival_status(origin, actor: PrivilegedActor, category_id: T::CategoryId, new_archival_status: bool) -> dispatch::Result { + fn update_category_archival_status(origin, actor: PrivilegedActor, category_id: T::CategoryId, new_archival_status: bool) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -700,7 +770,7 @@ decl_module! { // No change, invalid transaction if new_archival_status == category.archived { - return Err(ERROR_CATEGORY_NOT_BEING_UPDATED) + return Err(Error::CategoryNotBeingUpdated) } // Mutate category, and set possible new change parameters @@ -712,7 +782,7 @@ decl_module! { Ok(()) } - fn delete_category(origin, actor: PrivilegedActor, category_id: T::CategoryId) -> dispatch::Result { + fn delete_category(origin, actor: PrivilegedActor, category_id: T::CategoryId) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -733,7 +803,7 @@ decl_module! { /// Create new thread in category with poll fn create_thread(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, title: Vec, text: Vec, poll: Option>, - ) -> dispatch::Result { + ) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -752,7 +822,7 @@ decl_module! { Ok(()) } - fn edit_thread_title(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, new_title: Vec) -> dispatch::Result { + fn edit_thread_title(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, new_title: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -769,7 +839,7 @@ decl_module! { } /// Update category - fn update_thread_archival_status(origin, actor: PrivilegedActor, category_id: T::CategoryId, thread_id: T::ThreadId, new_archival_status: bool) -> dispatch::Result { + fn update_thread_archival_status(origin, actor: PrivilegedActor, category_id: T::CategoryId, thread_id: T::ThreadId, new_archival_status: bool) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -781,13 +851,13 @@ decl_module! { let category_tree_path = Self::ensure_valid_category_and_build_category_tree_path(&tmp_parent_category_id)?; if new_archival_status && Self::ensure_can_mutate_in_path_leaf(&category_tree_path).is_err() { - return Ok(()) + return Ok(()); } } // No change, invalid transaction if new_archival_status == thread.archived { - return Err(ERROR_THREAD_NOT_BEING_UPDATED) + return Err(Error::ThreadNotBeingUpdated); } // Mutate thread, and set possible new change parameters @@ -800,7 +870,7 @@ decl_module! { } - fn delete_thread(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId) -> dispatch::Result { + fn delete_thread(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -819,7 +889,7 @@ decl_module! { Ok(()) } - fn move_thread_to_category(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, new_category_id: T::CategoryId) -> dispatch::Result { + fn move_thread_to_category(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, new_category_id: T::CategoryId) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -838,7 +908,7 @@ decl_module! { } /// submit a poll - fn vote_on_poll(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, index: u32) -> dispatch::Result { + fn vote_on_poll(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, index: u32) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -884,7 +954,7 @@ decl_module! { } /// Moderate thread - fn moderate_thread(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, rationale: Vec) -> dispatch::Result { + fn moderate_thread(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, rationale: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -904,7 +974,7 @@ decl_module! { } /// Edit post text - fn add_post(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, text: Vec) -> dispatch::Result { + fn add_post(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, text: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -928,7 +998,7 @@ decl_module! { } /// like or unlike a post. - fn react_post(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, react: T::PostReactionId) -> dispatch::Result { + fn react_post(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, react: T::PostReactionId) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -951,7 +1021,7 @@ decl_module! { } /// Edit post text - fn edit_post_text(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, new_text: Vec) -> dispatch::Result { + fn edit_post_text(origin, forum_user_id: T::ForumUserId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, new_text: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -962,7 +1032,7 @@ decl_module! { let post = Self::ensure_post_is_mutable(&category_id, &thread_id, &post_id)?; // Signer does not match creator of post with identifier postId - ensure!(post.author_id == forum_user_id, ERROR_ACCOUNT_DOES_NOT_MATCH_POST_AUTHOR); + ensure!(post.author_id == forum_user_id, Error::AccountDoesNotMatchPostAuthor); // Update post text let text_hash = T::calculate_hash(&new_text); @@ -975,7 +1045,7 @@ decl_module! { } /// Moderate post - fn moderate_post(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, rationale: Vec) -> dispatch::Result { + fn moderate_post(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, thread_id: T::ThreadId, post_id: T::PostId, rationale: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -995,7 +1065,7 @@ decl_module! { } /// Set stickied threads for category - fn set_stickied_threads(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, stickied_ids: Vec) -> dispatch::Result { + fn set_stickied_threads(origin, moderator_id: T::ModeratorId, category_id: T::CategoryId, stickied_ids: Vec) -> Result<(), Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -1035,7 +1105,7 @@ impl Module { title: &[u8], text: &[u8], poll: &Option>, - ) -> Result, &'static str> { + ) -> Result, Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -1094,7 +1164,7 @@ impl Module { thread_id: T::ThreadId, text: &[u8], author_id: T::ForumUserId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Ensure data migration is done Self::ensure_data_migration_done()?; @@ -1128,10 +1198,10 @@ impl Module { } // Ensure poll is valid - fn ensure_poll_is_valid(poll: &Poll) -> dispatch::Result { + fn ensure_poll_is_valid(poll: &Poll) -> Result<(), Error> { // Poll end time must larger than now if poll.end_time < >::now() { - return Err(ERROR_POLL_TIME_SETTING); + return Err(Error::PollTimeSetting); } Ok(()) @@ -1140,7 +1210,7 @@ impl Module { // Ensure all poll alternative valid fn ensure_poll_alternatives_valid( alternatives: &[PollAlternative], - ) -> dispatch::Result { + ) -> Result<(), Error> { let len = alternatives.len(); // Check alternative amount Self::ensure_poll_alternatives_length_is_valid(len)?; @@ -1149,11 +1219,11 @@ impl Module { } // Ensure poll alternative size is valid - fn ensure_poll_alternatives_length_is_valid(len: usize) -> dispatch::Result { + fn ensure_poll_alternatives_length_is_valid(len: usize) -> Result<(), Error> { PollItemsConstraint::get().ensure_valid( len, - ERROR_POLL_ALTERNATIVES_TOO_SHORT, - ERROR_POLL_ALTERNATIVES_TOO_LONG, + Error::PollAlternativesTooShort, + Error::PollAlternativesTooLong, ) } @@ -1161,7 +1231,7 @@ impl Module { category_id: &T::CategoryId, thread_id: &T::ThreadId, post_id: &T::PostId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Make sure post exists let post = Self::ensure_post_exists(thread_id, post_id)?; @@ -1174,9 +1244,9 @@ impl Module { fn ensure_post_exists( thread_id: &T::ThreadId, post_id: &T::PostId, - ) -> Result, &'static str> { + ) -> Result, Error> { if !>::exists(thread_id, post_id) { - return Err(ERROR_POST_DOES_NOT_EXIST); + return Err(Error::PostDoesNotExist); } Ok(>::get(thread_id, post_id)) @@ -1188,7 +1258,7 @@ impl Module { category_id: &T::CategoryId, thread_id: &T::ThreadId, post_id: &T::PostId, - ) -> dispatch::Result { + ) -> Result<(), Error> { // Get moderator id. let who = ensure_signed(origin)?; @@ -1204,12 +1274,12 @@ impl Module { fn ensure_thread_is_mutable( category_id: &T::CategoryId, thread_id: &T::ThreadId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Make sure thread exists let thread = Self::ensure_thread_exists(category_id, thread_id)?; if thread.archived { - return Err(ERROR_THREAD_IMMUTABLE); + return Err(Error::ThreadImmutable); } // and corresponding category is mutable @@ -1228,7 +1298,7 @@ impl Module { Category, Thread, ), - &'static str, + Error, > { // Check actor's role match actor { @@ -1242,9 +1312,9 @@ impl Module { let category = >::get(category_id); // Closure ensuring moderator can delete category - let ensure_moderator_can_update = |moderator_id: &T::ModeratorId| -> dispatch::Result { + let ensure_moderator_can_update = |moderator_id: &T::ModeratorId| -> Result<(), Error> { Self::ensure_can_moderate_category_path(moderator_id, &category_id) - .map_err(|_| ERROR_MODERATOR_CANT_UPDATE_CATEGORY)?; + .map_err(|_| Error::ModeratorCantUpdateCategory)?; Ok(()) }; @@ -1261,9 +1331,9 @@ impl Module { fn ensure_thread_exists( category_id: &T::CategoryId, thread_id: &T::ThreadId, - ) -> Result, &'static str> { + ) -> Result, Error> { if !>::exists(category_id, thread_id) { - return Err(ERROR_THREAD_DOES_NOT_EXIST); + return Err(Error::ThreadDoesNotExist); } Ok(>::get(category_id, thread_id)) @@ -1274,7 +1344,7 @@ impl Module { category_id: &T::CategoryId, thread_id: &T::ThreadId, forum_user_id: &T::ForumUserId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Check that account is forum member Self::ensure_is_forum_user(origin, &forum_user_id)?; @@ -1288,18 +1358,18 @@ impl Module { category_id: &T::CategoryId, thread_id: &T::ThreadId, forum_user_id: &T::ForumUserId, - ) -> Result, &'static str> { + ) -> Result, Error> { let thread = Self::ensure_thread_is_mutable(category_id, thread_id)?; if thread.author_id != *forum_user_id { - return Err(ERROR_ACCOUNT_DOES_NOT_MATCH_THREAD_AUTHOR); + return Err(Error::AccountDoesNotMatchThreadAuthor); } Ok(thread) } /// Ensure forum user is lead - fn ensure_is_forum_lead(origin: T::Origin) -> Result { + fn ensure_is_forum_lead(origin: T::Origin) -> Result { let who = ensure_signed(origin)?; Self::ensure_is_forum_lead_account(&who)?; @@ -1308,10 +1378,10 @@ impl Module { } // Ensure forum user is lead - check via account - fn ensure_is_forum_lead_account(account_id: &T::AccountId) -> dispatch::Result { + fn ensure_is_forum_lead_account(account_id: &T::AccountId) -> Result<(), Error> { let is_lead = T::is_lead(account_id); - ensure!(is_lead, ERROR_ORIGIN_NOT_FORUM_LEAD); + ensure!(is_lead, Error::OriginNotForumLead); Ok(()) } @@ -1319,12 +1389,12 @@ impl Module { fn ensure_is_forum_user( origin: T::Origin, forum_user_id: &T::ForumUserId, - ) -> Result { + ) -> Result { let who = ensure_signed(origin)?; let is_member = T::is_forum_member(&who, forum_user_id); - ensure!(is_member, ERROR_FORUM_USER_ID_NOT_MATCH_ACCOUNT); + ensure!(is_member, Error::ForumUserIdNotMatchAccount); Ok(who) } @@ -1332,7 +1402,7 @@ impl Module { fn ensure_is_moderator( origin: T::Origin, moderator_id: &T::ModeratorId, - ) -> Result { + ) -> Result { let who = ensure_signed(origin)?; Self::ensure_is_moderator_account(&who, &moderator_id)?; @@ -1344,10 +1414,10 @@ impl Module { fn ensure_is_moderator_account( account_id: &T::AccountId, moderator_id: &T::ModeratorId, - ) -> dispatch::Result { + ) -> Result<(), Error> { let is_moderator = T::is_moderator(&account_id, moderator_id); - ensure!(is_moderator, ERROR_MODERATOR_ID_NOT_MATCH_ACCOUNT); + ensure!(is_moderator, Error::ModeratorIdNotMatchAccount); Ok(()) } @@ -1362,7 +1432,7 @@ impl Module { T::AccountId, Thread, ), - &'static str, + Error, > { // Check that account is forum member let who = Self::ensure_is_moderator(origin, &moderator_id)?; @@ -1385,21 +1455,21 @@ impl Module { T::AccountId, Thread, ), - &'static str, + Error, > { - ensure!(category_id != new_category_id, ERROR_THREAD_MOVE_INVALID,); + ensure!(category_id != new_category_id, Error::ThreadMoveInvalid,); let (account_id, thread) = Self::ensure_can_moderate_thread(origin, moderator_id, category_id, thread_id) - .map_err(|_| ERROR_MODERATOR_MODERATE_ORIGIN_CATEGORY)?; + .map_err(|_| Error::ModeratorModerateOriginCategory)?; Self::ensure_can_moderate_category(&account_id, moderator_id, new_category_id) - .map_err(|_| ERROR_MODERATOR_MODERATE_DESTINATION_CATEGORY)?; + .map_err(|_| Error::ModeratorModerateDestinationCategory)?; Ok((account_id, thread)) } - fn ensure_category_is_mutable(category_id: T::CategoryId) -> dispatch::Result { + fn ensure_category_is_mutable(category_id: T::CategoryId) -> Result<(), Error> { let category_tree_path = Self::build_category_tree_path(&category_id); Self::ensure_can_mutate_in_path_leaf(&category_tree_path) @@ -1407,13 +1477,13 @@ impl Module { fn ensure_can_mutate_in_path_leaf( category_tree_path: &CategoryTreePathArg, - ) -> dispatch::Result { + ) -> Result<(), Error> { // Is parent category directly or indirectly deleted or archived category ensure!( !category_tree_path .iter() .any(|c: &Category| c.archived), - ERROR_ANCESTOR_CATEGORY_IMMUTABLE + Error::AncestorCategoryImmutable ); Ok(()) @@ -1421,7 +1491,7 @@ impl Module { fn ensure_can_add_subcategory_path_leaf( parent_category_id: &T::CategoryId, - ) -> dispatch::Result { + ) -> Result<(), Error> { // Get the path from parent category to root let category_tree_path = Self::ensure_valid_category_and_build_category_tree_path(parent_category_id)?; @@ -1430,7 +1500,7 @@ impl Module { // Check if max depth reached if category_tree_path.len() as u64 >= max_category_depth { - return Err(ERROR_MAX_VALID_CATEGORY_DEPTH_EXCEEDED); + return Err(Error::MaxValidCategoryDepthExceeded); } Self::ensure_can_mutate_in_path_leaf(&category_tree_path)?; @@ -1441,10 +1511,10 @@ impl Module { /// Build category tree path and validate them fn ensure_valid_category_and_build_category_tree_path( category_id: &T::CategoryId, - ) -> Result, &'static str> { + ) -> Result, Error> { ensure!( >::exists(category_id), - ERROR_CATEGORY_DOES_NOT_EXIST + Error::CategoryDoesNotExist ); // Get path from parent to root of category tree. @@ -1492,7 +1562,7 @@ impl Module { origin: T::Origin, actor: &PrivilegedActor, category_id: &T::CategoryId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Check actor's role match actor { PrivilegedActor::Lead => Self::ensure_is_forum_lead(origin)?, @@ -1503,7 +1573,7 @@ impl Module { // Ensure category exists if !>::exists(category_id) { - return Err(ERROR_CATEGORY_DOES_NOT_EXIST); + return Err(Error::CategoryDoesNotExist); } let category = >::get(category_id); @@ -1511,11 +1581,11 @@ impl Module { // Ensure category is empty ensure!( category.num_direct_threads == 0, - ERROR_CATEGORY_NOT_EMPTY_THREADS, + Error::CategoryNotEmptyThreads, ); ensure!( category.num_direct_subcategories == 0, - ERROR_CATEGORY_NOT_EMPTY_CATEGORIES, + Error::CategoryNotEmptyCategories, ); // Closure ensuring moderator can delete category @@ -1524,12 +1594,12 @@ impl Module { category: Category| { if let Some(parent_category_id) = category.parent_category_id { Self::ensure_can_moderate_category_path(moderator_id, &parent_category_id) - .map_err(|_| ERROR_MODERATOR_CANT_DELETE_CATEGORY)?; + .map_err(|_| Error::ModeratorCantDeleteCategory)?; return Ok(category); } - Err(ERROR_MODERATOR_CANT_DELETE_CATEGORY) + Err(Error::ModeratorCantDeleteCategory) }; // Decide if actor can delete category @@ -1545,7 +1615,7 @@ impl Module { origin: T::Origin, actor: &PrivilegedActor, category_id: &T::CategoryId, - ) -> Result, &'static str> { + ) -> Result, Error> { // Check actor's role match actor { PrivilegedActor::Lead => Self::ensure_is_forum_lead(origin)?, @@ -1556,7 +1626,7 @@ impl Module { // Ensure category exists if !>::exists(category_id) { - return Err(ERROR_CATEGORY_DOES_NOT_EXIST); + return Err(Error::CategoryDoesNotExist); } let category = >::get(category_id); @@ -1566,7 +1636,7 @@ impl Module { |moderator_id: &T::ModeratorId, category: Category| { Self::ensure_can_moderate_category_path(moderator_id, &category_id) - .map_err(|_| ERROR_MODERATOR_CANT_UPDATE_CATEGORY)?; + .map_err(|_| Error::ModeratorCantUpdateCategory)?; Ok(category) }; @@ -1585,7 +1655,7 @@ impl Module { account_id: &T::AccountId, moderator_id: &T::ModeratorId, category_id: &T::CategoryId, - ) -> Result<(), &'static str> { + ) -> Result<(), Error> { // Ensure moderator account registered before Self::ensure_is_moderator_account(account_id, moderator_id)?; @@ -1598,7 +1668,7 @@ impl Module { fn ensure_can_moderate_category_path( moderator_id: &T::ModeratorId, category_id: &T::CategoryId, - ) -> Result<(), &'static str> { + ) -> Result<(), Error> { // Get path from category to root let category_tree_path = Self::build_category_tree_path(category_id); @@ -1608,28 +1678,28 @@ impl Module { } } - Err(ERROR_MODERATOR_MODERATE_CATEGORY) + Err(Error::ModeratorModerateCategory) } /// Check the vote is valid fn ensure_vote_is_valid( thread: &Thread, index: u32, - ) -> Result<(), &'static str> { + ) -> Result<(), Error> { // Poll not existed if thread.poll.is_none() { - return Err(ERROR_POLL_NOT_EXIST); + return Err(Error::PollNotExist); } let poll = thread.poll.as_ref().unwrap(); // Poll not expired if poll.end_time < >::now() { - Err(ERROR_POLL_COMMIT_EXPIRED) + Err(Error::PollCommitExpired) } else { let alternative_length = poll.poll_alternatives.len(); // The selected alternative index is valid if index as usize >= alternative_length { - Err(ERROR_POLL_DATA) + Err(Error::PollData) } else { Ok(()) } @@ -1637,11 +1707,11 @@ impl Module { } /// Ensure data migration is done - fn ensure_data_migration_done() -> Result<(), &'static str> { + fn ensure_data_migration_done() -> Result<(), Error> { if DataMigrationDone::get() { Ok(()) } else { - Err(ERROR_DATA_MIGRATION_NOT_DONE) + Err(Error::DataMigrationNotDone) } } } diff --git a/runtime-modules/forum/src/mock.rs b/runtime-modules/forum/src/mock.rs index 00aa4e7923..975269a568 100644 --- a/runtime-modules/forum/src/mock.rs +++ b/runtime-modules/forum/src/mock.rs @@ -218,7 +218,7 @@ pub fn create_category_mock( parent: Option<::CategoryId>, title: Vec, description: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::CategoryId { let category_id = TestForumModule::next_category_id(); assert_eq!( @@ -249,7 +249,7 @@ pub fn create_thread_mock( poll_data: Option< Poll<::Moment, ::Hash>, >, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::ThreadId { let thread_id = TestForumModule::next_thread_id(); assert_eq!( @@ -279,7 +279,7 @@ pub fn edit_thread_title_mock( category_id: ::CategoryId, thread_id: ::PostId, new_title: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::PostId { assert_eq!( TestForumModule::edit_thread_title( @@ -309,7 +309,7 @@ pub fn delete_thread_mock( moderator_id: ::ModeratorId, category_id: ::CategoryId, thread_id: ::PostId, - result: Result<(), &'static str>, + result: Result<(), Error>, ) { assert_eq!( TestForumModule::delete_thread( @@ -335,7 +335,7 @@ pub fn move_thread_mock( category_id: ::CategoryId, thread_id: ::PostId, new_category_id: ::CategoryId, - result: Result<(), &'static str>, + result: Result<(), Error>, ) { assert_eq!( TestForumModule::move_thread_to_category( @@ -362,7 +362,7 @@ pub fn update_thread_archival_status_mock( category_id: ::CategoryId, thread_id: ::ThreadId, new_archival_status: bool, - result: Result<(), &'static str>, + result: Result<(), Error>, ) { assert_eq!( TestForumModule::update_thread_archival_status( @@ -388,7 +388,7 @@ pub fn create_post_mock( category_id: ::CategoryId, thread_id: ::ThreadId, text: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::PostId { let post_id = TestForumModule::next_post_id(); assert_eq!( @@ -418,7 +418,7 @@ pub fn edit_post_text_mock( thread_id: ::ThreadId, post_id: ::PostId, new_text: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::PostId { assert_eq!( TestForumModule::edit_post_text( @@ -453,7 +453,7 @@ pub fn update_category_membership_of_moderator_mock( moderator_id: ::ModeratorId, category_id: ::CategoryId, new_value: bool, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::CategoryId { assert_eq!( TestForumModule::update_category_membership_of_moderator( @@ -479,7 +479,7 @@ pub fn vote_on_poll_mock( category_id: ::CategoryId, thread_id: ::ThreadId, index: u32, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::ThreadId { let thread = TestForumModule::thread_by_id(category_id, thread_id); assert_eq!( @@ -514,7 +514,7 @@ pub fn update_category_archival_status_mock( actor: PrivilegedActor, category_id: ::CategoryId, new_archival_status: bool, - result: Result<(), &'static str>, + result: Result<(), Error>, ) { assert_eq!( TestForumModule::update_category_archival_status( @@ -537,7 +537,7 @@ pub fn delete_category_mock( origin: OriginType, moderator_id: PrivilegedActor, category_id: ::CategoryId, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> () { assert_eq!( TestForumModule::delete_category(mock_origin(origin), moderator_id, category_id), @@ -558,7 +558,7 @@ pub fn moderate_thread_mock( category_id: ::CategoryId, thread_id: ::ThreadId, rationale: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::ThreadId { assert_eq!( TestForumModule::moderate_thread( @@ -589,7 +589,7 @@ pub fn moderate_post_mock( thread_id: ::ThreadId, post_id: ::PostId, rationale: Vec, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::PostId { assert_eq!( TestForumModule::moderate_post( @@ -620,7 +620,7 @@ pub fn set_stickied_threads_mock( moderator_id: ::ModeratorId, category_id: ::CategoryId, stickied_ids: Vec<::ThreadId>, - result: Result<(), &'static str>, + result: Result<(), Error>, ) -> ::CategoryId { assert_eq!( TestForumModule::set_stickied_threads( diff --git a/runtime-modules/forum/src/tests.rs b/runtime-modules/forum/src/tests.rs index 3e110db18c..0df15e2081 100644 --- a/runtime-modules/forum/src/tests.rs +++ b/runtime-modules/forum/src/tests.rs @@ -36,7 +36,7 @@ fn update_category_membership_of_moderator_origin() { moderator_id, category_id, true, - Err(ERROR_ORIGIN_NOT_FORUM_LEAD), + Err(Error::OriginNotForumLead), ); }); } @@ -68,7 +68,7 @@ fn update_category_membership_of_moderator_category() { moderator_id, INVLAID_CATEGORY_ID, true, - Err(ERROR_CATEGORY_DOES_NOT_EXIST), + Err(Error::CategoryDoesNotExist), ); }); } @@ -77,7 +77,7 @@ fn update_category_membership_of_moderator_category() { // test case for check if origin is forum lead fn create_category_origin() { let origins = vec![FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_ORIGIN_NOT_FORUM_LEAD)]; + let results = vec![Ok(()), Err(Error::OriginNotForumLead)]; for index in 0..origins.len() { let config = default_genesis_config(); build_test_externalities(config).execute_with(|| { @@ -86,7 +86,7 @@ fn create_category_origin() { None, good_category_title(), good_category_description(), - results[index], + results[index].clone(), ); }); } @@ -98,8 +98,8 @@ fn create_category_parent() { let parents = vec![Some(1), Some(2), Some(3)]; let results = vec![ Ok(()), - Err(ERROR_ANCESTOR_CATEGORY_IMMUTABLE), - Err(ERROR_CATEGORY_DOES_NOT_EXIST), + Err(Error::AncestorCategoryImmutable), + Err(Error::CategoryDoesNotExist), ]; for index in 0..parents.len() { @@ -154,7 +154,7 @@ fn create_category_depth() { _ => Some(i), }; let expected_result = match i { - _ if i >= max_depth => Err(ERROR_MAX_VALID_CATEGORY_DEPTH_EXCEEDED), + _ if i >= max_depth => Err(Error::MaxValidCategoryDepthExceeded), _ => Ok(()), }; @@ -176,7 +176,7 @@ fn create_category_depth() { // test if category updator is forum lead fn update_category_archival_status_origin() { let origins = [FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_ORIGIN_NOT_FORUM_LEAD)]; + let results = vec![Ok(()), Err(Error::OriginNotForumLead)]; for index in 0..origins.len() { let config = default_genesis_config(); @@ -220,7 +220,7 @@ fn update_category_archival_status_no_change() { PrivilegedActor::Lead, category_id, false, - Err(ERROR_CATEGORY_NOT_BEING_UPDATED), + Err(Error::CategoryNotBeingUpdated), ); }); } @@ -251,7 +251,7 @@ fn update_category_archival_status_category_exists() { PrivilegedActor::Lead, 2, true, - Err(ERROR_CATEGORY_DOES_NOT_EXIST), + Err(Error::CategoryDoesNotExist), ); }); } @@ -280,7 +280,7 @@ fn update_category_archival_status_moderator() { PrivilegedActor::Moderator(moderators[0]), category_id, true, - Err(ERROR_MODERATOR_CANT_UPDATE_CATEGORY), + Err(Error::ModeratorCantUpdateCategory), ); // give permision to moderate category itself @@ -353,7 +353,7 @@ fn update_category_archival_status_lock_works() { good_thread_title(), good_thread_text(), None, - Err(ERROR_ANCESTOR_CATEGORY_IMMUTABLE), + Err(Error::AncestorCategoryImmutable), ); // can't add more posts to thread inside category @@ -363,7 +363,7 @@ fn update_category_archival_status_lock_works() { category_id, thread_id, good_post_text(), - Err(ERROR_ANCESTOR_CATEGORY_IMMUTABLE), + Err(Error::AncestorCategoryImmutable), ); // can't update post @@ -374,7 +374,7 @@ fn update_category_archival_status_lock_works() { thread_id, post_id, good_post_new_text(), - Err(ERROR_ANCESTOR_CATEGORY_IMMUTABLE), + Err(Error::AncestorCategoryImmutable), ); // can't update thread @@ -384,7 +384,7 @@ fn update_category_archival_status_lock_works() { category_id, thread_id, good_thread_new_title(), - Err(ERROR_ANCESTOR_CATEGORY_IMMUTABLE), + Err(Error::AncestorCategoryImmutable), ); }); } @@ -434,7 +434,7 @@ fn delete_category_non_empty_subcategories() { origin.clone(), PrivilegedActor::Lead, category_id, - Err(ERROR_CATEGORY_NOT_EMPTY_CATEGORIES), + Err(Error::CategoryNotEmptyCategories), ); }); } @@ -467,7 +467,7 @@ fn delete_category_non_empty_threads() { origin.clone(), PrivilegedActor::Lead, category_id, - Err(ERROR_CATEGORY_NOT_EMPTY_THREADS), + Err(Error::CategoryNotEmptyThreads), ); }); } @@ -502,7 +502,7 @@ fn delete_category_need_ancestor_moderation() { origins[0].clone(), PrivilegedActor::Moderator(moderators[0]), category_id_2, - Err(ERROR_MODERATOR_CANT_DELETE_CATEGORY), + Err(Error::ModeratorCantDeleteCategory), ); // give permision to moderate category itself @@ -519,7 +519,7 @@ fn delete_category_need_ancestor_moderation() { origins[0].clone(), PrivilegedActor::Moderator(moderators[0]), category_id_2, - Err(ERROR_MODERATOR_CANT_DELETE_CATEGORY), + Err(Error::ModeratorCantDeleteCategory), ); // give permision to moderate parent category @@ -580,7 +580,7 @@ fn delete_category_root_by_lead() { fn create_thread_origin() { let origins = [NOT_FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_2_ORIGIN]; let forum_user_id = NOT_FORUM_LEAD_ORIGIN_ID; - let results = vec![Ok(()), Err(ERROR_FORUM_USER_ID_NOT_MATCH_ACCOUNT)]; + let results = vec![Ok(()), Err(Error::ForumUserIdNotMatchAccount)]; for index in 0..origins.len() { let config = default_genesis_config(); let forum_lead = FORUM_LEAD_ORIGIN_ID; @@ -610,7 +610,7 @@ fn create_thread_origin() { // test if timestamp of poll start time and end time are valid fn create_thread_poll_timestamp() { let expiration_diff = 10; - let results = vec![Ok(()), Err(ERROR_POLL_TIME_SETTING)]; + let results = vec![Ok(()), Err(Error::PollTimeSetting)]; for index in 0..results.len() { let config = default_genesis_config(); @@ -688,7 +688,7 @@ fn edit_thread_title() { category_id, thread_id, good_thread_new_title(), - Err(ERROR_ACCOUNT_DOES_NOT_MATCH_THREAD_AUTHOR), + Err(Error::AccountDoesNotMatchThreadAuthor), ); }); } @@ -700,7 +700,7 @@ fn edit_thread_title() { // test if category updator is forum lead fn update_thread_archival_status_origin() { let origins = [FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_ORIGIN_NOT_FORUM_LEAD)]; + let results = vec![Ok(()), Err(Error::OriginNotForumLead)]; for index in 0..origins.len() { let config = default_genesis_config(); @@ -765,7 +765,7 @@ fn update_thread_archival_status_no_change() { category_id, thread_id, false, - Err(ERROR_THREAD_NOT_BEING_UPDATED), + Err(Error::ThreadNotBeingUpdated), ); }); } @@ -807,7 +807,7 @@ fn update_thread_archival_status_thread_exists() { category_id, thread_id + 1, true, - Err(ERROR_THREAD_DOES_NOT_EXIST), + Err(Error::ThreadDoesNotExist), ); }); } @@ -846,7 +846,7 @@ fn update_thread_archival_status_moderator() { category_id, thread_id, true, - Err(ERROR_MODERATOR_CANT_UPDATE_CATEGORY), + Err(Error::ModeratorCantUpdateCategory), ); // give permision to moderate category itself @@ -920,7 +920,7 @@ fn update_thread_archival_status_lock_works() { category_id, thread_id, good_post_text(), - Err(ERROR_THREAD_IMMUTABLE), + Err(Error::ThreadImmutable), ); // can't update post @@ -931,7 +931,7 @@ fn update_thread_archival_status_lock_works() { thread_id, post_id, good_post_new_text(), - Err(ERROR_THREAD_IMMUTABLE), + Err(Error::ThreadImmutable), ); // can't update thread @@ -941,7 +941,7 @@ fn update_thread_archival_status_lock_works() { category_id, thread_id, good_thread_new_title(), - Err(ERROR_THREAD_IMMUTABLE), + Err(Error::ThreadImmutable), ); }); } @@ -1011,7 +1011,7 @@ fn delete_thread() { moderators[2], category_id, thread_id, - Err(ERROR_MODERATOR_ID_NOT_MATCH_ACCOUNT), + Err(Error::ModeratorIdNotMatchAccount), ); // moderator not associated with thread will fail to delete it @@ -1020,7 +1020,7 @@ fn delete_thread() { moderators[1], category_id, thread_id, - Err(ERROR_MODERATOR_MODERATE_CATEGORY), + Err(Error::ModeratorModerateCategory), ); // moderator will delete thread @@ -1088,7 +1088,7 @@ fn move_thread_moderator_permissions() { category_id_1, thread_id, category_id_2, - Err(ERROR_MODERATOR_MODERATE_ORIGIN_CATEGORY), + Err(Error::ModeratorModerateOriginCategory), ); // set incomplete permissions for first user (only category 1) @@ -1115,7 +1115,7 @@ fn move_thread_moderator_permissions() { category_id_1, thread_id, category_id_2, - Err(ERROR_MODERATOR_MODERATE_ORIGIN_CATEGORY), + Err(Error::ModeratorModerateOriginCategory), ); // moderator associated only with the second category will fail to move thread @@ -1125,7 +1125,7 @@ fn move_thread_moderator_permissions() { category_id_1, thread_id, category_id_2, - Err(ERROR_MODERATOR_MODERATE_DESTINATION_CATEGORY), + Err(Error::ModeratorModerateDestinationCategory), ); // give the rest of necessary permissions to the first moderator @@ -1212,7 +1212,7 @@ fn move_thread_invalid_move() { category_id, thread_id, category_id, - Err(ERROR_THREAD_MOVE_INVALID), + Err(Error::ThreadMoveInvalid), ); }); } @@ -1224,7 +1224,7 @@ fn move_thread_invalid_move() { // test if poll submitter is a forum user fn vote_on_poll_origin() { let origins = vec![FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_FORUM_USER_ID_NOT_MATCH_ACCOUNT)]; + let results = vec![Ok(()), Err(Error::ForumUserIdNotMatchAccount)]; let expiration_diff = 10; for index in 0..origins.len() { @@ -1290,7 +1290,7 @@ fn vote_on_poll_exists() { thread_id, category_id, 1, - Err(ERROR_POLL_NOT_EXIST), + Err(Error::PollNotExist), ); }); } @@ -1327,7 +1327,7 @@ fn vote_on_poll_expired() { category_id, thread_id, 1, - Err(ERROR_POLL_COMMIT_EXPIRED), + Err(Error::PollCommitExpired), ); }); } @@ -1386,7 +1386,7 @@ fn moderate_thread_origin_ok() { // test if post origin registered as forum user fn add_post_origin() { let origins = vec![FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_FORUM_USER_ID_NOT_MATCH_ACCOUNT)]; + let results = vec![Ok(()), Err(Error::ForumUserIdNotMatchAccount)]; for index in 0..origins.len() { let config = default_genesis_config(); let forum_lead = FORUM_LEAD_ORIGIN_ID; @@ -1479,7 +1479,7 @@ fn edit_post_text() { thread_id, post_id, good_post_new_text(), - Err(ERROR_ACCOUNT_DOES_NOT_MATCH_POST_AUTHOR), + Err(Error::AccountDoesNotMatchPostAuthor), ); }); } @@ -1550,7 +1550,7 @@ fn react_post() { // test if post moderator registered fn moderate_post_origin() { let origins = vec![FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN]; - let results = vec![Ok(()), Err(ERROR_MODERATOR_ID_NOT_MATCH_ACCOUNT)]; + let results = vec![Ok(()), Err(Error::ModeratorIdNotMatchAccount)]; for index in 0..origins.len() { let config = default_genesis_config(); let forum_lead = FORUM_LEAD_ORIGIN_ID; @@ -1666,7 +1666,7 @@ fn set_stickied_threads_wrong_moderator() { moderator_id, category_id, vec![thread_id], - Err(ERROR_MODERATOR_MODERATE_CATEGORY), + Err(Error::ModeratorModerateCategory), ); }); } @@ -1707,7 +1707,7 @@ fn set_stickied_threads_thread_not_exists() { moderator_id, category_id, vec![wrong_thread_id], - Err(ERROR_THREAD_DOES_NOT_EXIST), + Err(Error::ThreadDoesNotExist), ); }); } @@ -1731,7 +1731,7 @@ fn test_migration_not_done() { good_category_title(), good_category_description() ), - Err(ERROR_DATA_MIGRATION_NOT_DONE), + Err(Error::DataMigrationNotDone), ); assert_eq!( @@ -1743,7 +1743,7 @@ fn test_migration_not_done() { good_thread_text(), None, ), - Err(ERROR_DATA_MIGRATION_NOT_DONE), + Err(Error::DataMigrationNotDone), ); assert_eq!( @@ -1754,7 +1754,7 @@ fn test_migration_not_done() { thread_id, good_post_text(), ), - Err(ERROR_DATA_MIGRATION_NOT_DONE), + Err(Error::DataMigrationNotDone), ); assert_eq!( @@ -1765,7 +1765,7 @@ fn test_migration_not_done() { thread_id, good_moderation_rationale(), ), - Err(ERROR_DATA_MIGRATION_NOT_DONE), + Err(Error::DataMigrationNotDone), ); assert_eq!( @@ -1777,7 +1777,7 @@ fn test_migration_not_done() { post_id, good_moderation_rationale(), ), - Err(ERROR_DATA_MIGRATION_NOT_DONE), + Err(Error::DataMigrationNotDone), ); }); } From 421d71ca44c78f6bb3e8295626f988153e8831bc Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 10 Jul 2020 11:33:29 +0200 Subject: [PATCH 03/15] forum - extrinsic mutability comments --- runtime-modules/forum/src/lib.rs | 80 +++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 010d23ec58..66d2d61b44 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -688,6 +688,10 @@ decl_module! { Error::CategoryDoesNotExist ); + // + // == MUTATION SAFE == + // + if new_value { >::insert(category_id, moderator_id, ()); return Ok(()); @@ -721,6 +725,10 @@ decl_module! { }); } + // + // == MUTATION SAFE == + // + // Get next category id let next_category_id = >::get(); @@ -773,6 +781,10 @@ decl_module! { return Err(Error::CategoryNotBeingUpdated) } + // + // == MUTATION SAFE == + // + // Mutate category, and set possible new change parameters >::mutate(category_id, |c| c.archived = new_archival_status); @@ -788,6 +800,10 @@ decl_module! { let category = Self::ensure_can_delete_category(origin, &actor, &category_id)?; + // + // == MUTATION SAFE == + // + // Delete thread >::remove(category_id); if let Some(parent_category_id) = category.parent_category_id { @@ -810,6 +826,10 @@ decl_module! { // Check that account is forum member Self::ensure_is_forum_user(origin, &forum_user_id)?; + // + // == MUTATION SAFE == + // + // Keep next thread id let next_thread_id = >::get(); @@ -828,13 +848,17 @@ decl_module! { let thread = Self::ensure_can_edit_thread_title(origin, &category_id, &thread_id, &forum_user_id)?; - // Store the event - Self::deposit_event(RawEvent::ThreadTitleUpdated(thread_id)); + // + // == MUTATION SAFE == + // // Update thread title let title_hash = T::calculate_hash(&new_title); >::mutate(thread.category_id, thread_id, |thread| thread.title_hash = title_hash); + // Store the event + Self::deposit_event(RawEvent::ThreadTitleUpdated(thread_id)); + Ok(()) } @@ -860,6 +884,10 @@ decl_module! { return Err(Error::ThreadNotBeingUpdated); } + // + // == MUTATION SAFE == + // + // Mutate thread, and set possible new change parameters >::mutate(category_id, thread_id, |c| c.archived = new_archival_status); @@ -876,6 +904,10 @@ decl_module! { let (_, thread) = Self::ensure_can_moderate_thread(origin, &moderator_id, &category_id, &thread_id)?; + // + // == MUTATION SAFE == + // + // Delete thread >::remove(thread.category_id, thread_id); >::remove_prefix(thread_id); @@ -896,6 +928,10 @@ decl_module! { // Make sure moderator move between selected categories let (_, thread) = Self::ensure_can_move_thread(origin, &moderator_id, &category_id, &thread_id, &new_category_id)?; + // + // == MUTATION SAFE == + // + >::remove(category_id, thread_id); >::insert(new_category_id, thread_id, thread); >::mutate(category_id, |category| category.num_direct_threads -= 1); @@ -921,6 +957,10 @@ decl_module! { // Make sure poll exist Self::ensure_vote_is_valid(&thread, index)?; + // + // == MUTATION SAFE == + // + // Store new poll alternative statistics let poll = thread.poll.unwrap(); let new_poll_alternatives: Vec> = poll.poll_alternatives @@ -961,6 +1001,10 @@ decl_module! { // Ensure moderator is allowed to moderate post Self::ensure_can_moderate_thread(origin, &moderator_id, &category_id, &thread_id)?; + // + // == MUTATION SAFE == + // + // Calculate rationale's hash let rationale_hash = T::calculate_hash(rationale.as_slice()); @@ -978,13 +1022,13 @@ decl_module! { // Ensure data migration is done Self::ensure_data_migration_done()?; - /* - * Update SPEC with new errors, - */ - // Check that account is forum member Self::ensure_is_forum_user(origin, &forum_user_id)?; + // + // == MUTATION SAFE == + // + // Keep next post id let next_post_id = >::get(); @@ -1008,6 +1052,10 @@ decl_module! { // Make sure there exists a mutable post with post id `post_id` let _ = Self::ensure_post_is_mutable(&category_id, &thread_id, &post_id)?; + // + // == MUTATION SAFE == + // + // Get old value in map let old_value = >::get(post_id, forum_user_id); @@ -1034,6 +1082,10 @@ decl_module! { // Signer does not match creator of post with identifier postId ensure!(post.author_id == forum_user_id, Error::AccountDoesNotMatchPostAuthor); + // + // == MUTATION SAFE == + // + // Update post text let text_hash = T::calculate_hash(&new_text); >::mutate(post.thread_id, post_id, |p| p.text_hash = text_hash); @@ -1052,6 +1104,10 @@ decl_module! { // Ensure moderator is allowed to moderate post Self::ensure_can_moderate_post(origin, &moderator_id, &category_id, &thread_id, &post_id)?; + // + // == MUTATION SAFE == + // + // Calculate rationale's hash let rationale_hash = T::calculate_hash(rationale.as_slice()); @@ -1080,6 +1136,10 @@ decl_module! { Self::ensure_thread_exists(&category_id, item)?; } + // + // == MUTATION SAFE == + // + // Update category >::mutate(category_id, |category| category.sticky_thread_ids = stickied_ids.clone()); @@ -1125,6 +1185,10 @@ impl Module { Self::ensure_poll_is_valid(&data)?; } + // + // == MUTATION SAFE == + // + // Create and add new thread let new_thread_id = >::get(); @@ -1178,6 +1242,10 @@ impl Module { // No ancestor is blocking us doing mutation in this category Self::ensure_can_mutate_in_path_leaf(&category_tree_path)?; + // + // == MUTATION SAFE == + // + // Make and add initial post let new_post_id = >::get(); From dbd0011acd753bea99122c02b197eff35553058a Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 10 Jul 2020 16:17:31 +0200 Subject: [PATCH 04/15] forum - better check & mutate split --- runtime-modules/forum/src/lib.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 66d2d61b44..eb2a45c2db 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -717,12 +717,6 @@ decl_module! { if let Some(tmp_parent_category_id) = parent { // Can we mutate in this category? Self::ensure_can_add_subcategory_path_leaf(&tmp_parent_category_id)?; - - // Increment number of subcategories to reflect this new category being - // added as a child - >::mutate(tmp_parent_category_id, |c| { - c.num_direct_subcategories += 1; - }); } // @@ -750,6 +744,13 @@ decl_module! { // Update other next category id >::mutate(|value| *value += One::one()); + // If not root, increase parent's subcategories counter + if let Some(tmp_parent_category_id) = parent { + >::mutate(tmp_parent_category_id, |c| { + c.num_direct_subcategories += 1; + }); + } + // Generate event Self::deposit_event(RawEvent::CategoryCreated(next_category_id)); From a2ec28086f184975e98e004f9440b62198d7e3e8 Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 10 Jul 2020 16:44:52 +0200 Subject: [PATCH 05/15] forum - better check & mutate split II --- runtime-modules/forum/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index eb2a45c2db..89b2725665 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -710,9 +710,6 @@ decl_module! { // Not signed by forum LEAD Self::ensure_is_forum_lead(origin)?; - // Set a temporal mutable variable - let parent_category_id = parent; - // If not root, then check that we can create in parent category if let Some(tmp_parent_category_id) = parent { // Can we mutate in this category? @@ -734,7 +731,7 @@ decl_module! { archived: false, num_direct_subcategories: 0, num_direct_threads: 0, - parent_category_id, + parent_category_id: parent, sticky_thread_ids: vec![], }; From f3f66dd23f4c4c1fead14e2ec75e97425720235a Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 10 Jul 2020 17:08:09 +0200 Subject: [PATCH 06/15] forum - ensures simplification I --- runtime-modules/forum/src/lib.rs | 77 ++++++++++++-------------------- 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 89b2725665..fae2b4651b 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -762,18 +762,6 @@ decl_module! { // Ensure actor can update category let category = Self::ensure_can_update_category_archival_status(origin, &actor, &category_id)?; - if let Some(tmp_parent_category_id) = category.parent_category_id { - // Get path from parent to root of category tree. - let category_tree_path = Self::ensure_valid_category_and_build_category_tree_path(&tmp_parent_category_id)?; - - if new_archival_status && Self::ensure_can_mutate_in_path_leaf(&category_tree_path).is_err() { - return Ok(()) - } - } - - // Get the category - let category = >::get(category_id); - // No change, invalid transaction if new_archival_status == category.archived { return Err(Error::CategoryNotBeingUpdated) @@ -866,16 +854,7 @@ decl_module! { Self::ensure_data_migration_done()?; // Ensure actor can update category - let (category, thread) = Self::ensure_can_update_thread_archival_status(origin, &actor, &category_id, &thread_id)?; - - if let Some(tmp_parent_category_id) = category.parent_category_id { - // Get path from parent to root of category tree. - let category_tree_path = Self::ensure_valid_category_and_build_category_tree_path(&tmp_parent_category_id)?; - - if new_archival_status && Self::ensure_can_mutate_in_path_leaf(&category_tree_path).is_err() { - return Ok(()); - } - } + let (_, thread) = Self::ensure_can_update_thread_archival_status(origin, &actor, &category_id, &thread_id)?; // No change, invalid transaction if new_archival_status == thread.archived { @@ -950,7 +929,7 @@ decl_module! { Self::ensure_is_forum_user(origin, &forum_user_id)?; // Get thread - let thread = Self::ensure_thread_exists(&category_id, &thread_id)?; + let thread = Self::ensure_thread_is_mutable(&category_id, &thread_id)?; // Make sure poll exist Self::ensure_vote_is_valid(&thread, index)?; @@ -1123,16 +1102,7 @@ decl_module! { // Ensure data migration is done Self::ensure_data_migration_done()?; - // Get moderator id. - let who = Self::ensure_is_moderator(origin, &moderator_id)?; - - // ensure the moderator can moderate the category - Self::ensure_can_moderate_category(&who, &moderator_id, &category_id)?; - - // Ensure all thread id valid and is under the category - for item in &stickied_ids { - Self::ensure_thread_exists(&category_id, item)?; - } + Self::ensure_can_set_stickied_threads(origin, &moderator_id, &category_id, &stickied_ids)?; // // == MUTATION SAFE == @@ -1167,12 +1137,8 @@ impl Module { // Ensure data migration is done Self::ensure_data_migration_done()?; - // Get path from parent to root of category tree. - let category_tree_path = - Self::ensure_valid_category_and_build_category_tree_path(&category_id)?; - - // No ancestor is blocking us doing mutation in this category - Self::ensure_can_mutate_in_path_leaf(&category_tree_path)?; + // Check that thread can be added to category + Self::ensure_category_is_mutable(&category_id)?; // Unwrap poll if let Some(data) = poll { @@ -1231,14 +1197,7 @@ impl Module { Self::ensure_data_migration_done()?; // Make sure thread exists and is mutable - let thread = Self::ensure_thread_is_mutable(&category_id, &thread_id)?; - - // Get path from parent to root of category tree. - let category_tree_path = - Self::ensure_valid_category_and_build_category_tree_path(&thread.category_id)?; - - // No ancestor is blocking us doing mutation in this category - Self::ensure_can_mutate_in_path_leaf(&category_tree_path)?; + Self::ensure_thread_is_mutable(&category_id, &thread_id)?; // // == MUTATION SAFE == @@ -1349,7 +1308,7 @@ impl Module { } // and corresponding category is mutable - Self::ensure_category_is_mutable(thread.category_id)?; + Self::ensure_category_is_mutable(category_id)?; Ok(thread) } @@ -1535,7 +1494,7 @@ impl Module { Ok((account_id, thread)) } - fn ensure_category_is_mutable(category_id: T::CategoryId) -> Result<(), Error> { + fn ensure_category_is_mutable(category_id: &T::CategoryId) -> Result<(), Error> { let category_tree_path = Self::build_category_tree_path(&category_id); Self::ensure_can_mutate_in_path_leaf(&category_tree_path) @@ -1747,6 +1706,26 @@ impl Module { Err(Error::ModeratorModerateCategory) } + fn ensure_can_set_stickied_threads( + origin: T::Origin, + moderator_id: &T::ModeratorId, + category_id: &T::CategoryId, + stickied_ids: &[T::ThreadId], + ) -> Result<(), Error> { + // Get moderator id. + let who = Self::ensure_is_moderator(origin, &moderator_id)?; + + // ensure the moderator can moderate the category + Self::ensure_can_moderate_category(&who, &moderator_id, &category_id)?; + + // Ensure all thread id valid and is under the category + for item in stickied_ids { + Self::ensure_thread_exists(&category_id, item)?; + } + + Ok(()) + } + /// Check the vote is valid fn ensure_vote_is_valid( thread: &Thread, From 7aff9cacbb61fd5d1e4f39ec3ff040e8897bbd3b Mon Sep 17 00:00:00 2001 From: ondratra Date: Mon, 13 Jul 2020 12:58:52 +0200 Subject: [PATCH 07/15] fuzz testing - libfuzzer integration stub --- runtime-modules/forum/fuzz/.gitignore | 4 + runtime-modules/forum/fuzz/Cargo.lock | 1862 +++++++++++++++++ runtime-modules/forum/fuzz/Cargo.toml | 26 + .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 9 + 4 files changed, 1901 insertions(+) create mode 100644 runtime-modules/forum/fuzz/.gitignore create mode 100644 runtime-modules/forum/fuzz/Cargo.lock create mode 100644 runtime-modules/forum/fuzz/Cargo.toml create mode 100644 runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs diff --git a/runtime-modules/forum/fuzz/.gitignore b/runtime-modules/forum/fuzz/.gitignore new file mode 100644 index 0000000000..572e03bdf3 --- /dev/null +++ b/runtime-modules/forum/fuzz/.gitignore @@ -0,0 +1,4 @@ + +target +corpus +artifacts diff --git a/runtime-modules/forum/fuzz/Cargo.lock b/runtime-modules/forum/fuzz/Cargo.lock new file mode 100644 index 0000000000..ea731f0912 --- /dev/null +++ b/runtime-modules/forum/fuzz/Cargo.lock @@ -0,0 +1,1862 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "ahash" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" +dependencies = [ + "const-random", +] + +[[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "arbitrary" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitmask" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" + +[[package]] +name = "bitvec" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-slice-cast" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cc" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "clear_on_drop" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9cc5db465b294c3fa986d5bbb0f3017cd850bff6dd6c52f9ccff8b4d21b7b08" +dependencies = [ + "cc", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "const-random" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" +dependencies = [ + "const-random-macro", + "proc-macro-hack 0.5.16", +] + +[[package]] +name = "const-random-macro" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" +dependencies = [ + "getrandom", + "proc-macro-hack 0.5.16", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array", + "subtle 1.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "405681bfe2b7b25ad8660dfd90b6e8be9e470e224ff49e36b587d43f29a22601" +dependencies = [ + "byteorder", + "clear_on_drop", + "digest", + "rand_core 0.3.1", + "subtle 2.2.3", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ed25519-dalek" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" +dependencies = [ + "clear_on_drop", + "curve25519-dalek", + "failure", + "rand 0.6.5", +] + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" + +[[package]] +name = "elastic-array" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580f3768bd6465780d063f5b8213a2ebd506e139b345e4a81eb301ceae3d61e1" +dependencies = [ + "heapsize", +] + +[[package]] +name = "environmental" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +dependencies = [ + "byteorder", + "libc", + "rand 0.7.3", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" +dependencies = [ + "byteorder", + "scopeguard 0.3.3", +] + +[[package]] +name = "hashbrown" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" +dependencies = [ + "ahash", + "autocfg 0.1.7", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +dependencies = [ + "winapi", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" + +[[package]] +name = "hex-literal" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc2928beef125e519d69ae1baa8c37ea2e0d3848545217f6db0179c5eb1d639" +dependencies = [ + "hex-literal-impl", + "proc-macro-hack 0.4.2", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda" +dependencies = [ + "proc-macro-hack 0.4.2", +] + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "hmac-drbg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" +dependencies = [ + "digest", + "generic-array", + "hmac", +] + +[[package]] +name = "impl-codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" + +[[package]] +name = "libfuzzer-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d718794b8e23533b9069bd2c4597d69e41cc7ab1c02700a502971aca0cdcf24" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +dependencies = [ + "arrayref", + "crunchy", + "digest", + "hmac-drbg", + "rand 0.7.3", + "sha2", + "subtle 2.2.3", + "typenum", +] + +[[package]] +name = "lock_api" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +dependencies = [ + "scopeguard 0.3.3", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard 1.1.0", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_size_of_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37c5d4cd9473c5f4c9c111f033f15d4df9bd378fdf615944e360a4f55a05f0b" +dependencies = [ + "proc-macro2 1.0.18", + "syn 1.0.34", + "synstructure", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "memory-db" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dabfe0a8c69954ae3bcfc5fc14260a85fb80e1bf9f86a155f668d10a67e93dd" +dependencies = [ + "ahash", + "hash-db", + "hashbrown 0.6.3", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.4.2", + "zeroize 1.1.0", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" +dependencies = [ + "adler", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg 1.0.0", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg 1.0.0", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg 1.0.0", +] + +[[package]] +name = "object" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" + +[[package]] +name = "once_cell" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" +dependencies = [ + "parking_lot 0.7.1", +] + +[[package]] +name = "once_cell" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "parity-scale-codec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74f02beb35d47e0706155c9eac554b50c671e0d868fe8296bcdf44a9a4847bf" +dependencies = [ + "arrayvec 0.5.1", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "parity-util-mem" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "570093f39f786beea92dcc09e45d8aae7841516ac19a50431953ac82a0e8f85c" +dependencies = [ + "cfg-if", + "malloc_size_of_derive", + "winapi", +] + +[[package]] +name = "parity-wasm" +version = "0.40.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e39faaa292a687ea15120b1ac31899b13586446521df6c149e46f1584671e0f" + +[[package]] +name = "parking_lot" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +dependencies = [ + "lock_api 0.1.5", + "parking_lot_core 0.4.0", +] + +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.6.2", + "rustc_version", +] + +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +dependencies = [ + "libc", + "rand 0.6.5", + "rustc_version", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" +dependencies = [ + "paste-impl", + "proc-macro-hack 0.5.16", +] + +[[package]] +name = "paste-impl" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" +dependencies = [ + "proc-macro-hack 0.5.16", +] + +[[package]] +name = "pbkdf2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +dependencies = [ + "byteorder", + "crypto-mac", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" + +[[package]] +name = "primitive-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde 0.3.1", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463bf29e7f11344e58c9e01f171470ab15c925c6822ad75028cc1c0e1d1eb63b" +dependencies = [ + "proc-macro-hack-impl", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c47dcb1594802de8c02f3b899e2018c78291168a22c281be21ea0fb4796842" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +dependencies = [ + "unicode-xid 0.2.1", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2 1.0.18", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "safe-mix" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "schnorrkel" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +dependencies = [ + "curve25519-dalek", + "failure", + "merlin", + "rand 0.6.5", + "rand_core 0.4.2", + "rand_os", + "sha2", + "subtle 2.2.3", + "zeroize 0.9.3", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "sr-api-macros" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "blake2-rfc", + "proc-macro-crate", + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "sr-arithmetic" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sr-std", + "substrate-debug-derive", +] + +[[package]] +name = "sr-io" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec", + "rustc_version", + "sr-std", + "substrate-externalities", + "substrate-primitives", + "substrate-state-machine", + "substrate-trie", + "tiny-keccak", +] + +[[package]] +name = "sr-primitives" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "paste", + "rand 0.7.3", + "serde", + "sr-arithmetic", + "sr-io", + "sr-std", + "substrate-application-crypto", + "substrate-primitives", +] + +[[package]] +name = "sr-std" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "sr-version" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "impl-serde 0.2.3", + "parity-scale-codec", + "serde", + "sr-primitives", + "sr-std", +] + +[[package]] +name = "srml-balances" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "parity-scale-codec", + "safe-mix", + "serde", + "sr-primitives", + "sr-std", + "srml-support", + "srml-system", + "substrate-keyring", +] + +[[package]] +name = "srml-metadata" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "parity-scale-codec", + "serde", + "sr-std", + "substrate-primitives", +] + +[[package]] +name = "srml-support" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "bitmask", + "impl-trait-for-tuples", + "log", + "once_cell 0.2.4", + "parity-scale-codec", + "paste", + "serde", + "sr-io", + "sr-primitives", + "sr-std", + "srml-metadata", + "srml-support-procedural", + "substrate-inherents", + "substrate-primitives", +] + +[[package]] +name = "srml-support-procedural" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "sr-api-macros", + "srml-support-procedural-tools", + "syn 1.0.34", +] + +[[package]] +name = "srml-support-procedural-tools" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.18", + "quote 1.0.7", + "srml-support-procedural-tools-derive", + "syn 1.0.34", +] + +[[package]] +name = "srml-support-procedural-tools-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "srml-system" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "safe-mix", + "serde", + "sr-io", + "sr-primitives", + "sr-std", + "sr-version", + "srml-support", + "substrate-primitives", +] + +[[package]] +name = "srml-timestamp" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sr-primitives", + "sr-std", + "srml-support", + "srml-system", + "substrate-inherents", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" + +[[package]] +name = "strum_macros" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" +dependencies = [ + "heck", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "substrate-application-crypto" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "parity-scale-codec", + "serde", + "sr-io", + "sr-std", + "substrate-primitives", +] + +[[package]] +name = "substrate-bip39" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +dependencies = [ + "hmac", + "pbkdf2", + "schnorrkel", + "sha2", +] + +[[package]] +name = "substrate-debug-derive" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + +[[package]] +name = "substrate-externalities" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "environmental", + "primitive-types", + "sr-std", + "substrate-primitives-storage", +] + +[[package]] +name = "substrate-forum-module" +version = "1.1.0" +dependencies = [ + "hex-literal", + "parity-scale-codec", + "serde", + "serde_derive", + "sr-io", + "sr-primitives", + "sr-std", + "srml-balances", + "srml-support", + "srml-support-procedural", + "srml-system", + "srml-timestamp", +] + +[[package]] +name = "substrate-forum-module-fuzz" +version = "0.0.0" +dependencies = [ + "libfuzzer-sys", + "substrate-forum-module", +] + +[[package]] +name = "substrate-inherents" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "parity-scale-codec", + "parking_lot 0.9.0", + "sr-primitives", + "sr-std", +] + +[[package]] +name = "substrate-keyring" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "lazy_static", + "sr-primitives", + "strum", + "strum_macros", + "substrate-primitives", +] + +[[package]] +name = "substrate-panic-handler" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "backtrace", + "log", +] + +[[package]] +name = "substrate-primitives" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "ed25519-dalek", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde 0.2.3", + "lazy_static", + "libsecp256k1", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hex", + "schnorrkel", + "serde", + "sha2", + "sr-std", + "substrate-bip39", + "substrate-debug-derive", + "substrate-externalities", + "substrate-primitives-storage", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize 0.10.1", +] + +[[package]] +name = "substrate-primitives-storage" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "impl-serde 0.2.3", + "serde", + "sr-std", + "substrate-debug-derive", +] + +[[package]] +name = "substrate-state-machine" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "rand 0.7.3", + "substrate-externalities", + "substrate-panic-handler", + "substrate-primitives", + "substrate-trie", + "trie-db", + "trie-root", +] + +[[package]] +name = "substrate-trie" +version = "2.0.0" +source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec", + "sr-std", + "substrate-primitives", + "trie-db", + "trie-root", +] + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "unicode-xid 0.2.1", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", + "unicode-xid 0.2.1", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tiny-bip39" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" +dependencies = [ + "failure", + "hashbrown 0.1.8", + "hmac", + "once_cell 0.1.8", + "pbkdf2", + "rand 0.6.5", + "sha2", +] + +[[package]] +name = "tiny-keccak" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "trie-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b62d27e8aa1c07414549ac872480ac82380bab39e730242ab08d82d7cc098a" +dependencies = [ + "elastic-array", + "hash-db", + "hashbrown 0.6.3", + "log", + "rand 0.6.5", +] + +[[package]] +name = "trie-root" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +dependencies = [ + "rand 0.7.3", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "uint" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173cd16430c206dc1a430af8a89a0e9c076cf15cb42b4aedb10e8cc8fee73681" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasmi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31d26deb2d9a37e6cfed420edce3ed604eab49735ba89035e13c98f9a528313" +dependencies = [ + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" + +[[package]] +name = "zeroize" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4090487fa66630f7b166fba2bbb525e247a5449f41c468cc1d98f8ae6ac03120" + +[[package]] +name = "zeroize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", + "synstructure", +] diff --git a/runtime-modules/forum/fuzz/Cargo.toml b/runtime-modules/forum/fuzz/Cargo.toml new file mode 100644 index 0000000000..5b771e10e8 --- /dev/null +++ b/runtime-modules/forum/fuzz/Cargo.toml @@ -0,0 +1,26 @@ + +[package] +name = "substrate-forum-module-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.3" + +[dependencies.substrate-forum-module] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzz_target_1" +path = "fuzz_targets/fuzz_target_1.rs" +test = false +doc = false diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs new file mode 100644 index 0000000000..eb8991da2c --- /dev/null +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -0,0 +1,9 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +// run basic fuzzing via `cargo fuzz run fuzz_target_1 -- -max_len=256 -runs=10` + +fuzz_target!(|data: &[u8]| { + println!("fuzz &[u8]: {:?} ", data); + // fuzzed code goes here +}); From c18c22217c12347a31a800f7af0138334fae783c Mon Sep 17 00:00:00 2001 From: ondratra Date: Mon, 13 Jul 2020 17:36:40 +0200 Subject: [PATCH 08/15] fuzz testing - honggfuzz stub + libfuzzer connection to existing code --- Cargo.lock | 48 ++ Cargo.toml | 1 + runtime-modules/forum/Cargo.toml | 9 +- runtime-modules/forum/README.md | 17 + runtime-modules/forum/fuzz/Cargo.lock | 13 + runtime-modules/forum/fuzz/Cargo.toml | 27 +- .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 9 + .../forum/fuzz/fuzz_targets/mock.rs | 698 ++++++++++++++++++ runtime-modules/forum/fuzzer/.gitignore | 3 + runtime-modules/forum/fuzzer/Cargo.lock | 5 + runtime-modules/forum/fuzzer/Cargo.toml | 47 ++ .../forum/fuzzer/src/test_fuzzing.rs | 45 ++ runtime-modules/forum/fuzzer/src/tmp_mock.rs | 195 +++++ runtime-modules/forum/src/lib.rs | 2 +- runtime-modules/forum/src/mock.rs | 2 +- 15 files changed, 1117 insertions(+), 4 deletions(-) create mode 100644 runtime-modules/forum/README.md create mode 100644 runtime-modules/forum/fuzz/fuzz_targets/mock.rs create mode 100644 runtime-modules/forum/fuzzer/.gitignore create mode 100644 runtime-modules/forum/fuzzer/Cargo.lock create mode 100644 runtime-modules/forum/fuzzer/Cargo.toml create mode 100644 runtime-modules/forum/fuzzer/src/test_fuzzing.rs create mode 100644 runtime-modules/forum/fuzzer/src/tmp_mock.rs diff --git a/Cargo.lock b/Cargo.lock index f11a752145..c321acce18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,6 +88,12 @@ dependencies = [ "xdg", ] +[[package]] +name = "arbitrary" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" + [[package]] name = "arc-swap" version = "0.4.5" @@ -1341,6 +1347,27 @@ dependencies = [ "proc-macro-hack 0.5.15", ] +[[package]] +name = "hfuzz" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.4", + "honggfuzz", + "parity-scale-codec", + "serde", + "serde_derive", + "sr-io", + "sr-primitives", + "sr-std", + "srml-balances", + "srml-support", + "srml-support-procedural", + "srml-system", + "srml-timestamp", + "substrate-forum-module", + "substrate-primitives", +] + [[package]] name = "hmac" version = "0.7.1" @@ -1362,6 +1389,17 @@ dependencies = [ "hmac", ] +[[package]] +name = "honggfuzz" +version = "0.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832bac18a82ec7d6c21887daa8616b238fe90d5d5e762d0d4b9372cdaa9e097f" +dependencies = [ + "arbitrary", + "lazy_static", + "memmap", +] + [[package]] name = "http" version = "0.1.21" @@ -2398,6 +2436,16 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "memoffset" version = "0.5.4" diff --git a/Cargo.toml b/Cargo.toml index 9651f9333e..f2dabb32c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "runtime-modules/common", "runtime-modules/content-working-group", "runtime-modules/forum", + "runtime-modules/forum/fuzzer", "runtime-modules/governance", "runtime-modules/hiring", "runtime-modules/membership", diff --git a/runtime-modules/forum/Cargo.toml b/runtime-modules/forum/Cargo.toml index 8e14cf5142..8b6695af9a 100755 --- a/runtime-modules/forum/Cargo.toml +++ b/runtime-modules/forum/Cargo.toml @@ -28,6 +28,12 @@ git = 'https://github.com/paritytech/substrate.git' package = 'sr-io' rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' +[dependencies.primitives] +package = 'substrate-primitives' +git = 'https://github.com/paritytech/substrate.git' +rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' +#optional = true + # [dependencies.old-forum] # default_features = false # git = 'https://github.com/juniuszhou/substrate-forum-module' @@ -36,7 +42,6 @@ rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' [dev-dependencies] # runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} -primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} [features] default = ['std'] @@ -53,3 +58,5 @@ std = [ 'timestamp/std', # 'old-forum/std', ] +fuzzing = [] +#fuzzing = ["primitives"] diff --git a/runtime-modules/forum/README.md b/runtime-modules/forum/README.md new file mode 100644 index 0000000000..14a30a4769 --- /dev/null +++ b/runtime-modules/forum/README.md @@ -0,0 +1,17 @@ +## Fuzzing + +### Install dependencies +``` +sudo apt install build-essential binutils-dev libunwind-dev libblocksruntime-dev liblzma-dev +``` + +### Run +Variant I - honggfuzz +``` +HFUZZ_RUN_ARGS="-N 8 --exit_upon_crash --keep_output" cargo hfuzz run test_fuzzing +``` + +Variant II - libfuzzer +``` +cargo fuzz run fuzz_target_1 -- -max_len=256 -runs=10 +``` diff --git a/runtime-modules/forum/fuzz/Cargo.lock b/runtime-modules/forum/fuzz/Cargo.lock index ea731f0912..f859f68f7a 100644 --- a/runtime-modules/forum/fuzz/Cargo.lock +++ b/runtime-modules/forum/fuzz/Cargo.lock @@ -1498,6 +1498,7 @@ dependencies = [ "srml-support-procedural", "srml-system", "srml-timestamp", + "substrate-primitives", ] [[package]] @@ -1505,7 +1506,19 @@ name = "substrate-forum-module-fuzz" version = "0.0.0" dependencies = [ "libfuzzer-sys", + "parity-scale-codec", + "serde", + "serde_derive", + "sr-io", + "sr-primitives", + "sr-std", + "srml-balances", + "srml-support", + "srml-support-procedural", + "srml-system", + "srml-timestamp", "substrate-forum-module", + "substrate-primitives", ] [[package]] diff --git a/runtime-modules/forum/fuzz/Cargo.toml b/runtime-modules/forum/fuzz/Cargo.toml index 5b771e10e8..d8bf1d70dc 100644 --- a/runtime-modules/forum/fuzz/Cargo.toml +++ b/runtime-modules/forum/fuzz/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "substrate-forum-module-fuzz" version = "0.0.0" -authors = ["Automatically generated"] +authors = ["Joystream contributors"] publish = false edition = "2018" @@ -12,6 +12,31 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.3" +serde = { version = '1.0.101', optional = true} +serde_derive = { version = '1.0.101', optional = true } +rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] } +primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} + +[dependencies.timestamp] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-timestamp' +rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' + +[dependencies.runtime-io] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'sr-io' +rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' + + + [dependencies.substrate-forum-module] path = ".." diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index eb8991da2c..20cdbfdabc 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -1,9 +1,18 @@ #![no_main] use libfuzzer_sys::fuzz_target; +use substrate_forum_module::mock::*; +//use mock::Test; +//pub mod mock; +//use crate::mock::*; + // run basic fuzzing via `cargo fuzz run fuzz_target_1 -- -max_len=256 -runs=10` fuzz_target!(|data: &[u8]| { println!("fuzz &[u8]: {:?} ", data); // fuzzed code goes here + let config = default_genesis_config(); + build_test_externalities(config).execute_with(|| { + println!("{:?}", TestForumModule::next_category_id()); + }) }); diff --git a/runtime-modules/forum/fuzz/fuzz_targets/mock.rs b/runtime-modules/forum/fuzz/fuzz_targets/mock.rs new file mode 100644 index 0000000000..bd50fb0d69 --- /dev/null +++ b/runtime-modules/forum/fuzz/fuzz_targets/mock.rs @@ -0,0 +1,698 @@ + +use crate::*; +use substrate_forum_module::*; + +use primitives::H256; + +use substrate_forum_module::{GenesisConfig, Module, Trait}; + +use runtime_primitives::{ + testing::Header, + traits::{BlakeTwo256, Hash, IdentityLookup}, + Perbill, +}; +use srml_support::{impl_outer_event, impl_outer_origin, parameter_types}; + +impl_outer_origin! { + pub enum Origin for Runtime {} +} + +mod forum_mod { + pub use substrate_forum_module::Event; +} + +impl_outer_event! { + pub enum TestEvent for Runtime { + forum_mod, + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const MinimumPeriod: u64 = 5; +} + +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + // type WeightMultiplierUpdate = (); + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +impl timestamp::Trait for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; +} + +parameter_types! { + pub const MaxCategoryDepth: u64 = 20; +} + +impl Trait for Runtime { + type Event = TestEvent; + type ForumUserId = u64; + type ModeratorId = u64; + type CategoryId = u64; + type ThreadId = u64; + type PostId = u64; + type PostReactionId = u64; + type MaxCategoryDepth = MaxCategoryDepth; + + fn is_lead(account_id: &::AccountId) -> bool { + *account_id == FORUM_LEAD_ORIGIN_ID + } + + fn is_forum_member( + account_id: &::AccountId, + forum_user_id: &Self::ForumUserId, + ) -> bool { + let allowed_accounts = [ + FORUM_LEAD_ORIGIN_ID, + NOT_FORUM_LEAD_ORIGIN_ID, + NOT_FORUM_LEAD_2_ORIGIN_ID, + ]; + + allowed_accounts.contains(account_id) && account_id == forum_user_id + } + + fn is_moderator(account_id: &Self::AccountId, moderator_id: &Self::ModeratorId) -> bool { + let allowed_accounts = [ + FORUM_LEAD_ORIGIN_ID, + FORUM_MODERATOR_ORIGIN_ID, + FORUM_MODERATOR_2_ORIGIN_ID, + ]; + + allowed_accounts.contains(account_id) && account_id == moderator_id + } + + fn calculate_hash(text: &[u8]) -> Self::Hash { + Self::Hashing::hash(text) + } +} + +#[derive(Clone)] +pub enum OriginType { + Signed(::AccountId), + //Inherent, <== did not find how to make such an origin yet +} + +pub fn mock_origin(origin: OriginType) -> mock::Origin { + match origin { + OriginType::Signed(account_id) => Origin::signed(account_id), + //OriginType::Inherent => Origin::inherent, + } +} + +pub const FORUM_LEAD_ORIGIN_ID: ::AccountId = 110; + +pub const FORUM_LEAD_ORIGIN: OriginType = OriginType::Signed(FORUM_LEAD_ORIGIN_ID); + +pub const NOT_FORUM_LEAD_ORIGIN_ID: ::AccountId = 111; + +pub const NOT_FORUM_LEAD_ORIGIN: OriginType = OriginType::Signed(NOT_FORUM_LEAD_ORIGIN_ID); + +pub const NOT_FORUM_LEAD_2_ORIGIN_ID: ::AccountId = 112; + +pub const NOT_FORUM_LEAD_2_ORIGIN: OriginType = OriginType::Signed(NOT_FORUM_LEAD_2_ORIGIN_ID); + +pub const INVLAID_CATEGORY_ID: ::CategoryId = 333; + +pub const FORUM_MODERATOR_ORIGIN_ID: ::AccountId = 123; + +pub const FORUM_MODERATOR_ORIGIN: OriginType = OriginType::Signed(FORUM_MODERATOR_ORIGIN_ID); + +pub const FORUM_MODERATOR_2_ORIGIN_ID: ::AccountId = 124; + +pub const FORUM_MODERATOR_2_ORIGIN: OriginType = OriginType::Signed(FORUM_MODERATOR_2_ORIGIN_ID); + +pub fn good_category_title() -> Vec { + b"Great new category".to_vec() +} + +pub fn good_category_description() -> Vec { + b"This is a great new category for the forum".to_vec() +} + +pub fn good_thread_title() -> Vec { + b"Great new thread".to_vec() +} + +pub fn good_thread_text() -> Vec { + b"The first post in this thread".to_vec() +} + +pub fn good_thread_new_title() -> Vec { + b"Brand new thread title".to_vec() +} + +pub fn good_post_text() -> Vec { + b"A response in the thread".to_vec() +} + +pub fn good_post_new_text() -> Vec { + b"Changed post's text".to_vec() +} + +pub fn good_moderation_rationale() -> Vec { + b"Moderation rationale".to_vec() +} + +pub fn good_poll_description() -> Vec { + b"poll description".to_vec() +} + +pub fn good_poll_alternative_text() -> Vec { + b"poll alternative".to_vec() +} + +pub fn generate_poll( + expiration_diff: u64, +) -> Poll<::Moment, ::Hash> { + Poll { + description_hash: Runtime::calculate_hash(good_poll_description().as_slice()), + end_time: Timestamp::now() + expiration_diff, + poll_alternatives: { + let mut alternatives = vec![]; + for _ in 0..5 { + alternatives.push(PollAlternative { + alternative_text_hash: Runtime::calculate_hash( + good_poll_alternative_text().as_slice(), + ), + vote_count: 0, + }); + } + alternatives + }, + } +} + +pub fn generate_poll_timestamp_cases( + index: usize, + expiration_diff: u64, +) -> Poll<::Moment, ::Hash> { + let test_cases = vec![generate_poll(expiration_diff), generate_poll(1)]; + test_cases[index].clone() +} + +pub fn create_category_mock( + origin: OriginType, + parent: Option<::CategoryId>, + title: Vec, + description: Vec, + result: Result<(), Error>, +) -> ::CategoryId { + let category_id = TestForumModule::next_category_id(); + assert_eq!( + TestForumModule::create_category( + mock_origin(origin), + parent, + title.clone(), + description.clone(), + ), + result + ); + if result.is_ok() { + assert_eq!(TestForumModule::next_category_id(), category_id + 1); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::CategoryCreated(category_id)) + ); + } + category_id +} + +pub fn create_thread_mock( + origin: OriginType, + forum_user_id: ::ForumUserId, + category_id: ::CategoryId, + title: Vec, + text: Vec, + poll_data: Option< + Poll<::Moment, ::Hash>, + >, + result: Result<(), Error>, +) -> ::ThreadId { + let thread_id = TestForumModule::next_thread_id(); + assert_eq!( + TestForumModule::create_thread( + mock_origin(origin.clone()), + forum_user_id, + category_id, + title, + text, + poll_data.clone(), + ), + result + ); + if result.is_ok() { + assert_eq!(TestForumModule::next_thread_id(), thread_id + 1); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadCreated(thread_id)) + ); + } + thread_id +} + +pub fn edit_thread_title_mock( + origin: OriginType, + forum_user_id: ::ForumUserId, + category_id: ::CategoryId, + thread_id: ::PostId, + new_title: Vec, + result: Result<(), Error>, +) -> ::PostId { + assert_eq!( + TestForumModule::edit_thread_title( + mock_origin(origin), + forum_user_id, + category_id, + thread_id, + new_title.clone(), + ), + result + ); + if result.is_ok() { + assert_eq!( + TestForumModule::thread_by_id(category_id, thread_id).title_hash, + Runtime::calculate_hash(new_title.as_slice()), + ); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadTitleUpdated(thread_id,)) + ); + } + thread_id +} + +pub fn delete_thread_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + thread_id: ::PostId, + result: Result<(), Error>, +) { + assert_eq!( + TestForumModule::delete_thread( + mock_origin(origin.clone()), + moderator_id, + category_id, + thread_id, + ), + result + ); + if result.is_ok() { + assert!(!>::exists(category_id, thread_id)); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadDeleted(thread_id)) + ); + } +} + +pub fn move_thread_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + thread_id: ::PostId, + new_category_id: ::CategoryId, + result: Result<(), Error>, +) { + assert_eq!( + TestForumModule::move_thread_to_category( + mock_origin(origin.clone()), + moderator_id, + category_id, + thread_id, + new_category_id, + ), + result + ); + if result.is_ok() { + assert!(>::exists(new_category_id, thread_id),); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadMoved(thread_id, new_category_id)) + ); + } +} + +pub fn update_thread_archival_status_mock( + origin: OriginType, + actor: PrivilegedActor, + category_id: ::CategoryId, + thread_id: ::ThreadId, + new_archival_status: bool, + result: Result<(), Error>, +) { + assert_eq!( + TestForumModule::update_thread_archival_status( + mock_origin(origin), + actor, + category_id, + thread_id, + new_archival_status + ), + result + ); + if result.is_ok() { + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadUpdated(thread_id, new_archival_status)) + ); + } +} + +pub fn create_post_mock( + origin: OriginType, + forum_user_id: ::ForumUserId, + category_id: ::CategoryId, + thread_id: ::ThreadId, + text: Vec, + result: Result<(), Error>, +) -> ::PostId { + let post_id = TestForumModule::next_post_id(); + assert_eq!( + TestForumModule::add_post( + mock_origin(origin.clone()), + forum_user_id, + category_id, + thread_id, + text + ), + result + ); + if result.is_ok() { + assert_eq!(TestForumModule::next_post_id(), post_id + 1); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::PostAdded(post_id)) + ); + }; + post_id +} + +pub fn edit_post_text_mock( + origin: OriginType, + forum_user_id: ::ForumUserId, + category_id: ::CategoryId, + thread_id: ::ThreadId, + post_id: ::PostId, + new_text: Vec, + result: Result<(), Error>, +) -> ::PostId { + assert_eq!( + TestForumModule::edit_post_text( + mock_origin(origin), + forum_user_id, + category_id, + thread_id, + post_id, + new_text.clone(), + ), + result + ); + if result.is_ok() { + assert_eq!( + TestForumModule::post_by_id(thread_id, post_id).text_hash, + Runtime::calculate_hash(new_text.as_slice()), + ); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::PostTextUpdated(post_id)) + ); + } + post_id +} + +pub fn change_current_time(diff: u64) -> () { + Timestamp::set_timestamp(Timestamp::now() + diff); +} + +pub fn update_category_membership_of_moderator_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + new_value: bool, + result: Result<(), Error>, +) -> ::CategoryId { + assert_eq!( + TestForumModule::update_category_membership_of_moderator( + mock_origin(origin), + moderator_id, + category_id, + new_value + ), + result + ); + if result.is_ok() { + assert_eq!( + >::exists(category_id, moderator_id), + new_value + ); + }; + category_id +} + +pub fn vote_on_poll_mock( + origin: OriginType, + forum_user_id: ::ForumUserId, + category_id: ::CategoryId, + thread_id: ::ThreadId, + index: u32, + result: Result<(), Error>, +) -> ::ThreadId { + let thread = TestForumModule::thread_by_id(category_id, thread_id); + assert_eq!( + TestForumModule::vote_on_poll( + mock_origin(origin), + forum_user_id, + category_id, + thread_id, + index + ), + result + ); + if result.is_ok() { + assert_eq!( + TestForumModule::thread_by_id(category_id, thread_id) + .poll + .unwrap() + .poll_alternatives[index as usize] + .vote_count, + thread.poll.unwrap().poll_alternatives[index as usize].vote_count + 1 + ); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::VoteOnPoll(thread_id, index,)) + ); + }; + thread_id +} + +pub fn update_category_archival_status_mock( + origin: OriginType, + actor: PrivilegedActor, + category_id: ::CategoryId, + new_archival_status: bool, + result: Result<(), Error>, +) { + assert_eq!( + TestForumModule::update_category_archival_status( + mock_origin(origin), + actor, + category_id, + new_archival_status + ), + result + ); + if result.is_ok() { + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::CategoryUpdated(category_id, new_archival_status)) + ); + } +} + +pub fn delete_category_mock( + origin: OriginType, + moderator_id: PrivilegedActor, + category_id: ::CategoryId, + result: Result<(), Error>, +) -> () { + assert_eq!( + TestForumModule::delete_category(mock_origin(origin), moderator_id, category_id), + result, + ); + if result.is_ok() { + assert!(!>::exists(category_id)); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::CategoryDeleted(category_id)) + ); + }; +} + +pub fn moderate_thread_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + thread_id: ::ThreadId, + rationale: Vec, + result: Result<(), Error>, +) -> ::ThreadId { + assert_eq!( + TestForumModule::moderate_thread( + mock_origin(origin), + moderator_id, + category_id, + thread_id, + rationale.clone(), + ), + result + ); + if result.is_ok() { + assert!(!>::exists(category_id, thread_id)); + + let rationale_hash = Runtime::calculate_hash(rationale.clone().as_slice()); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::ThreadModerated(thread_id, rationale_hash)) + ); + } + thread_id +} + +pub fn moderate_post_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + thread_id: ::ThreadId, + post_id: ::PostId, + rationale: Vec, + result: Result<(), Error>, +) -> ::PostId { + assert_eq!( + TestForumModule::moderate_post( + mock_origin(origin), + moderator_id, + category_id, + thread_id, + post_id, + rationale.clone(), + ), + result + ); + if result.is_ok() { + assert!(!>::exists(thread_id, post_id)); + + let rationale_hash = Runtime::calculate_hash(rationale.clone().as_slice()); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::PostModerated(post_id, rationale_hash)) + ); + } + + post_id +} + +pub fn set_stickied_threads_mock( + origin: OriginType, + moderator_id: ::ModeratorId, + category_id: ::CategoryId, + stickied_ids: Vec<::ThreadId>, + result: Result<(), Error>, +) -> ::CategoryId { + assert_eq!( + TestForumModule::set_stickied_threads( + mock_origin(origin), + moderator_id, + category_id, + stickied_ids.clone(), + ), + result + ); + if result.is_ok() { + assert_eq!( + TestForumModule::category_by_id(category_id).sticky_thread_ids, + stickied_ids.clone() + ); + assert_eq!( + System::events().last().unwrap().event, + TestEvent::forum_mod(RawEvent::CategoryStickyThreadUpdate( + category_id, + stickied_ids.clone(), + )) + ); + }; + category_id +} + +pub fn default_genesis_config() -> GenesisConfig { + create_genesis_config(true) +} + +pub fn migration_not_done_config() -> GenesisConfig { + create_genesis_config(false) +} + +pub fn create_genesis_config(data_migration_done: bool) -> GenesisConfig { + GenesisConfig:: { + category_by_id: vec![], // endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), + next_category_id: 1, + thread_by_id: vec![], + next_thread_id: 1, + post_by_id: vec![], + next_post_id: 1, + + category_by_moderator: vec![], + reaction_by_post: vec![], + + poll_items_constraint: InputValidationLengthConstraint { + min: 4, + max_min_diff: 20, + }, + + // data migration part + data_migration_done: data_migration_done, + } +} + +// NB!: +// Wanted to have payload: a: &GenesisConfig +// but borrow checker made my life miserabl, so giving up for now. +pub fn build_test_externalities(config: GenesisConfig) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + config.assimilate_storage(&mut t).unwrap(); + + t.into() +} + +pub type System = system::Module; + +pub type Timestamp = timestamp::Module; + +/// Export forum module on a test runtime +pub type TestForumModule = Module; diff --git a/runtime-modules/forum/fuzzer/.gitignore b/runtime-modules/forum/fuzzer/.gitignore new file mode 100644 index 0000000000..dbc7481f1c --- /dev/null +++ b/runtime-modules/forum/fuzzer/.gitignore @@ -0,0 +1,3 @@ +target +hfuzz_workspace +hfuzz_target diff --git a/runtime-modules/forum/fuzzer/Cargo.lock b/runtime-modules/forum/fuzzer/Cargo.lock new file mode 100644 index 0000000000..4bbac1e889 --- /dev/null +++ b/runtime-modules/forum/fuzzer/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hfuzz" +version = "0.1.0" diff --git a/runtime-modules/forum/fuzzer/Cargo.toml b/runtime-modules/forum/fuzzer/Cargo.toml new file mode 100644 index 0000000000..c77a9b87c7 --- /dev/null +++ b/runtime-modules/forum/fuzzer/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "hfuzz" +version = "0.1.0" +authors = ["Joystream contributors"] +edition = "2018" + +# Prevent this from interfering with workspaces +#[workspace] +#members = ["."] + +[dependencies] +honggfuzz = "0.5" +hex-literal = '0.1.0' +serde = { version = '1.0.101', optional = true} +serde_derive = { version = '1.0.101', optional = true } +rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] } +primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} + +[dependencies.timestamp] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-timestamp' +rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' + +[dependencies.runtime-io] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'sr-io' +rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' + + +[dependencies.substrate-forum-module] +path = ".." + +[features] +default = ["fuzzy_test"] +fuzzy_test = [] + +[[bin]] +name = "test_fuzzing" +path = "src/test_fuzzing.rs" \ No newline at end of file diff --git a/runtime-modules/forum/fuzzer/src/test_fuzzing.rs b/runtime-modules/forum/fuzzer/src/test_fuzzing.rs new file mode 100644 index 0000000000..c4363e8442 --- /dev/null +++ b/runtime-modules/forum/fuzzer/src/test_fuzzing.rs @@ -0,0 +1,45 @@ +//#![cfg(test)] +//#![cfg_attr(feature = "fuzzy_test", test)] + +use honggfuzz::fuzz; +//use mock::*; +//use mock::TestForumModule; +//mod mock; +//mod mock; + + + +//#[cfg(fuzzing)] +use substrate_forum_module::mock::*; +//use crate::mock::*; + +// HFUZZ_RUN_ARGS="-n 8" cargo hfuzz run test_fuzzing +/* +println!("fuzz &[u8]: {:?} ", data); +// fuzzed code goes here +println!("{:?}", TestForumModule::next_category_id()); + +*/ +fn main() { + println!("Starting fuzzer"); + loop { + fuzz!(|data: &[u8]| { + println!("{:?}", data); + +// let config = default_genesis_config(); + let forum_lead = FORUM_LEAD_ORIGIN_ID; + let origin = OriginType::Signed(forum_lead); + + create_category_mock( + origin, + None, + b"adsfqwer".to_vec(), + b"vcbcvbcv".to_vec(), + //Err(Error::OriginNotForumLead) + Ok(()), + ); + + //panic!("AAAAAAAAAAAAAAAAAAA"); + }) + } +} diff --git a/runtime-modules/forum/fuzzer/src/tmp_mock.rs b/runtime-modules/forum/fuzzer/src/tmp_mock.rs new file mode 100644 index 0000000000..5b35215485 --- /dev/null +++ b/runtime-modules/forum/fuzzer/src/tmp_mock.rs @@ -0,0 +1,195 @@ + +use crate::*; + +use primitives::H256; + +use substrate_forum_module::{GenesisConfig, Module, Trait, InputValidationLengthConstraint}; + +use runtime_primitives::{ + testing::Header, + traits::{BlakeTwo256, Hash, IdentityLookup}, + Perbill, +}; +use srml_support::{impl_outer_event, impl_outer_origin, parameter_types}; + +impl_outer_origin! { + pub enum Origin for Runtime {} +} + +mod forum_mod { + pub use substrate_forum_module::Event; +} + +impl_outer_event! { + pub enum TestEvent for Runtime { + forum_mod, + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const MinimumPeriod: u64 = 5; +} + +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + // type WeightMultiplierUpdate = (); + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); +} + +impl timestamp::Trait for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; +} + +parameter_types! { + pub const MaxCategoryDepth: u64 = 20; +} + +impl Trait for Runtime { + type Event = TestEvent; + type ForumUserId = u64; + type ModeratorId = u64; + type CategoryId = u64; + type ThreadId = u64; + type PostId = u64; + type PostReactionId = u64; + type MaxCategoryDepth = MaxCategoryDepth; + + fn is_lead(account_id: &::AccountId) -> bool { + *account_id == FORUM_LEAD_ORIGIN_ID + } + + fn is_forum_member( + account_id: &::AccountId, + forum_user_id: &Self::ForumUserId, + ) -> bool { + let allowed_accounts = [ + FORUM_LEAD_ORIGIN_ID, + NOT_FORUM_LEAD_ORIGIN_ID, + NOT_FORUM_LEAD_2_ORIGIN_ID, + ]; + + allowed_accounts.contains(account_id) && account_id == forum_user_id + } + + fn is_moderator(account_id: &Self::AccountId, moderator_id: &Self::ModeratorId) -> bool { + let allowed_accounts = [ + FORUM_LEAD_ORIGIN_ID, + FORUM_MODERATOR_ORIGIN_ID, + FORUM_MODERATOR_2_ORIGIN_ID, + ]; + + allowed_accounts.contains(account_id) && account_id == moderator_id + } + + fn calculate_hash(text: &[u8]) -> Self::Hash { + Self::Hashing::hash(text) + } +} + +#[derive(Clone)] +pub enum OriginType { + Signed(::AccountId), + //Inherent, <== did not find how to make such an origin yet +} + +pub fn mock_origin(origin: OriginType) -> mock::Origin { + match origin { + OriginType::Signed(account_id) => Origin::signed(account_id), + //OriginType::Inherent => Origin::inherent, + } +} + +pub const FORUM_LEAD_ORIGIN_ID: ::AccountId = 110; + +pub const FORUM_LEAD_ORIGIN: OriginType = OriginType::Signed(FORUM_LEAD_ORIGIN_ID); + +pub const NOT_FORUM_LEAD_ORIGIN_ID: ::AccountId = 111; + +pub const NOT_FORUM_LEAD_ORIGIN: OriginType = OriginType::Signed(NOT_FORUM_LEAD_ORIGIN_ID); + +pub const NOT_FORUM_LEAD_2_ORIGIN_ID: ::AccountId = 112; + +pub const NOT_FORUM_LEAD_2_ORIGIN: OriginType = OriginType::Signed(NOT_FORUM_LEAD_2_ORIGIN_ID); + +pub const INVLAID_CATEGORY_ID: ::CategoryId = 333; + +pub const FORUM_MODERATOR_ORIGIN_ID: ::AccountId = 123; + +pub const FORUM_MODERATOR_ORIGIN: OriginType = OriginType::Signed(FORUM_MODERATOR_ORIGIN_ID); + +pub const FORUM_MODERATOR_2_ORIGIN_ID: ::AccountId = 124; + +pub const FORUM_MODERATOR_2_ORIGIN: OriginType = OriginType::Signed(FORUM_MODERATOR_2_ORIGIN_ID); + + +pub fn default_genesis_config() -> GenesisConfig { + create_genesis_config(true) +} + +pub fn migration_not_done_config() -> GenesisConfig { + create_genesis_config(false) +} + +pub fn create_genesis_config(data_migration_done: bool) -> GenesisConfig { + GenesisConfig:: { + category_by_id: vec![], // endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), + next_category_id: 1, + thread_by_id: vec![], + next_thread_id: 1, + post_by_id: vec![], + next_post_id: 1, + + category_by_moderator: vec![], + reaction_by_post: vec![], + + poll_items_constraint: InputValidationLengthConstraint { + min: 4, + max_min_diff: 20, + }, + + // data migration part + data_migration_done: data_migration_done, + } +} + +// NB!: +// Wanted to have payload: a: &GenesisConfig +// but borrow checker made my life miserabl, so giving up for now. +pub fn build_test_externalities(config: GenesisConfig) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + config.assimilate_storage(&mut t).unwrap(); + + t.into() +} + +pub type System = system::Module; + +pub type Timestamp = timestamp::Module; + +/// Export forum module on a test runtime +pub type TestForumModule = Module; diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index fae2b4651b..193b9248fe 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -220,7 +220,7 @@ use srml_support::{ decl_error, decl_event, decl_module, decl_storage, ensure, traits::Get, Parameter, }; -mod mock; +pub mod mock; mod tests; pub trait Trait: system::Trait + timestamp::Trait + Sized { diff --git a/runtime-modules/forum/src/mock.rs b/runtime-modules/forum/src/mock.rs index 975269a568..0efced246e 100644 --- a/runtime-modules/forum/src/mock.rs +++ b/runtime-modules/forum/src/mock.rs @@ -1,4 +1,4 @@ -#![cfg(test)] +#![cfg(any(test, fuzzing))] use crate::*; From ff6db4ddef9f9f2be94be272f2545b148ff35243 Mon Sep 17 00:00:00 2001 From: ondratra Date: Tue, 14 Jul 2020 23:05:29 +0200 Subject: [PATCH 09/15] fuzzy testing - test prototype --- runtime-modules/forum/Cargo.toml | 2 + runtime-modules/forum/README.md | 1 + runtime-modules/forum/fuzz/Cargo.lock | 38 ++++++++++++++++++- runtime-modules/forum/fuzz/Cargo.toml | 6 ++- .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 29 +++++++++++--- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/runtime-modules/forum/Cargo.toml b/runtime-modules/forum/Cargo.toml index 8b6695af9a..acce13819a 100755 --- a/runtime-modules/forum/Cargo.toml +++ b/runtime-modules/forum/Cargo.toml @@ -16,6 +16,8 @@ system = { package = 'srml-system', default-features = false, git = 'https://git balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] } +arbitrary = { version = "0.3.0", optional = true, features = ["derive"] } + [dependencies.timestamp] default_features = false git = 'https://github.com/paritytech/substrate.git' diff --git a/runtime-modules/forum/README.md b/runtime-modules/forum/README.md index 14a30a4769..c12a945cc9 100644 --- a/runtime-modules/forum/README.md +++ b/runtime-modules/forum/README.md @@ -2,6 +2,7 @@ ### Install dependencies ``` +# needed by honggfuzz sudo apt install build-essential binutils-dev libunwind-dev libblocksruntime-dev liblzma-dev ``` diff --git a/runtime-modules/forum/fuzz/Cargo.lock b/runtime-modules/forum/fuzz/Cargo.lock index f859f68f7a..b2fb8eaebd 100644 --- a/runtime-modules/forum/fuzz/Cargo.lock +++ b/runtime-modules/forum/fuzz/Cargo.lock @@ -33,11 +33,23 @@ dependencies = [ "memchr", ] +[[package]] +name = "arbitrary" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "491d5e42b1a073ff1fc1e0a02744b3f8bee9cf4bfd552053cac36c64b879795d" +dependencies = [ + "derive_arbitrary 0.3.3", +] + [[package]] name = "arbitrary" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" +dependencies = [ + "derive_arbitrary 0.4.5", +] [[package]] name = "arrayref" @@ -248,6 +260,28 @@ dependencies = [ "subtle 2.2.3", ] +[[package]] +name = "derive_arbitrary" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab2f0544254a47cabc58956cc7ebda74c3b796bb2761e3fe8f29fdde632ad95" +dependencies = [ + "proc-macro2 1.0.18", + "syn 1.0.34", + "synstructure", +] + +[[package]] +name = "derive_arbitrary" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b43185d3e7ce7dcd44a23ca761ec026359753ebf480283a571e6463853d2ef" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + [[package]] name = "digest" version = "0.8.1" @@ -530,7 +564,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d718794b8e23533b9069bd2c4597d69e41cc7ab1c02700a502971aca0cdcf24" dependencies = [ - "arbitrary", + "arbitrary 0.4.5", "cc", ] @@ -1486,6 +1520,7 @@ dependencies = [ name = "substrate-forum-module" version = "1.1.0" dependencies = [ + "arbitrary 0.3.3", "hex-literal", "parity-scale-codec", "serde", @@ -1505,6 +1540,7 @@ dependencies = [ name = "substrate-forum-module-fuzz" version = "0.0.0" dependencies = [ + "arbitrary 0.4.5", "libfuzzer-sys", "parity-scale-codec", "serde", diff --git a/runtime-modules/forum/fuzz/Cargo.toml b/runtime-modules/forum/fuzz/Cargo.toml index d8bf1d70dc..40c265fd8b 100644 --- a/runtime-modules/forum/fuzz/Cargo.toml +++ b/runtime-modules/forum/fuzz/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" cargo-fuzz = true [dependencies] -libfuzzer-sys = "0.3" +libfuzzer-sys = { version = "^0.3", features = ["arbitrary-derive"]} serde = { version = '1.0.101', optional = true} serde_derive = { version = '1.0.101', optional = true } @@ -23,6 +23,9 @@ balances = { package = 'srml-balances', default-features = false, git = 'https:/ codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] } primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'} +arbitrary = { version = "^0.4", features = ["derive"] } + + [dependencies.timestamp] default_features = false git = 'https://github.com/paritytech/substrate.git' @@ -39,6 +42,7 @@ rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' [dependencies.substrate-forum-module] path = ".." +features = ["arbitrary"] # Prevent this from interfering with workspaces [workspace] diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index 20cdbfdabc..ee32b4127e 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -2,17 +2,34 @@ use libfuzzer_sys::fuzz_target; use substrate_forum_module::mock::*; -//use mock::Test; -//pub mod mock; -//use crate::mock::*; -// run basic fuzzing via `cargo fuzz run fuzz_target_1 -- -max_len=256 -runs=10` +use libfuzzer_sys::arbitrary::Arbitrary; +#[derive(Debug, Arbitrary)] +pub struct Texts { + text: [Vec; 2], +} -fuzz_target!(|data: &[u8]| { - println!("fuzz &[u8]: {:?} ", data); +fuzz_target!(|texts: Texts| { + + println!("fuzz: {:?} ", 64); + println!("fuzz: {:?} ", texts); // fuzzed code goes here let config = default_genesis_config(); build_test_externalities(config).execute_with(|| { println!("{:?}", TestForumModule::next_category_id()); + + println!("starting category mock"); + + let forum_lead = FORUM_LEAD_ORIGIN_ID; + let origin = OriginType::Signed(forum_lead); + create_category_mock( + origin.clone(), + None, + texts.text[0].clone(), + texts.text[1].clone(), + Ok(()), + ); + + println!("category mock finished"); }) }); From 6498db8267d82498f0fd8a172291d71997e0becb Mon Sep 17 00:00:00 2001 From: ondratra Date: Wed, 15 Jul 2020 19:06:52 +0200 Subject: [PATCH 10/15] fuzzy testing - automatic module testing I --- Cargo.lock | 142 +++++++++++------- runtime-modules/forum/Cargo.toml | 3 + runtime-modules/forum/fuzz/Cargo.lock | 10 ++ runtime-modules/forum/fuzz/Cargo.toml | 3 + .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 26 ++++ runtime-modules/forum/reflection/Cargo.toml | 13 ++ runtime-modules/forum/reflection/src/lib.rs | 31 ++++ runtime-modules/forum/src/lib.rs | 3 + 8 files changed, 175 insertions(+), 56 deletions(-) create mode 100644 runtime-modules/forum/reflection/Cargo.toml create mode 100644 runtime-modules/forum/reflection/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c321acce18..4a130cf9f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,6 +88,15 @@ dependencies = [ "xdg", ] +[[package]] +name = "arbitrary" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "491d5e42b1a073ff1fc1e0a02744b3f8bee9cf4bfd552053cac36c64b879795d" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arbitrary" version = "0.4.5" @@ -137,7 +146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -656,9 +665,20 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1eae4d76b7cefedd1b4f8cc24378b2fbd1ac1b66e3bbebe8e2192d3be81cb355" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", +] + +[[package]] +name = "derive_arbitrary" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab2f0544254a47cabc58956cc7ebda74c3b796bb2761e3fe8f29fdde632ad95" +dependencies = [ + "proc-macro2 1.0.18", + "syn 1.0.34", + "synstructure", ] [[package]] @@ -830,9 +850,9 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", "synstructure", ] @@ -1067,9 +1087,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack 0.5.15", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -1395,7 +1415,7 @@ version = "0.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "832bac18a82ec7d6c21887daa8616b238fe90d5d5e762d0d4b9372cdaa9e097f" dependencies = [ - "arbitrary", + "arbitrary 0.4.5", "lazy_static", "memmap", ] @@ -1540,9 +1560,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -1776,9 +1796,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -2413,8 +2433,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e37c5d4cd9473c5f4c9c111f033f15d4df9bd378fdf615944e360a4f55a05f0b" dependencies = [ - "proc-macro2 1.0.10", - "syn 1.0.17", + "proc-macro2 1.0.18", + "syn 1.0.34", "synstructure", ] @@ -2570,9 +2590,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5a615a1ad92048ad5d9633251edb7492b8abc057d7a679a9898476aef173935" dependencies = [ "cfg-if", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -2725,9 +2745,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -2861,9 +2881,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -3029,9 +3049,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" dependencies = [ "proc-macro-hack 0.5.15", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -3151,9 +3171,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -3194,9 +3214,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.10" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" dependencies = [ "unicode-xid 0.2.0", ] @@ -3280,7 +3300,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", ] [[package]] @@ -3708,9 +3728,9 @@ version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -3899,9 +3919,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a1232 dependencies = [ "blake2-rfc", "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4218,9 +4238,9 @@ version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4263,11 +4283,11 @@ name = "srml-support-procedural" version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", "sr-api-macros", "srml-support-procedural-tools", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4276,10 +4296,10 @@ version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", "srml-support-procedural-tools-derive", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4287,9 +4307,9 @@ name = "srml-support-procedural-tools-derive" version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4412,9 +4432,9 @@ checksum = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4530,9 +4550,9 @@ version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ "proc-macro-crate", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4767,9 +4787,9 @@ name = "substrate-debug-derive" version = "2.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=c37bb08535c49a12320af7facfd555ce05cce2e8#c37bb08535c49a12320af7facfd555ce05cce2e8" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", ] [[package]] @@ -4853,6 +4873,7 @@ dependencies = [ name = "substrate-forum-module" version = "1.1.0" dependencies = [ + "arbitrary 0.3.3", "hex-literal 0.1.4", "parity-scale-codec", "serde", @@ -4865,9 +4886,18 @@ dependencies = [ "srml-support-procedural", "srml-system", "srml-timestamp", + "substrate-forum-module-reflection", "substrate-primitives", ] +[[package]] +name = "substrate-forum-module-reflection" +version = "0.0.0" +dependencies = [ + "proc-macro2 1.0.18", + "syn 1.0.34", +] + [[package]] name = "substrate-governance-module" version = "1.0.0" @@ -5640,11 +5670,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.17" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -5655,9 +5685,9 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", "unicode-xid 0.2.0", ] @@ -6251,9 +6281,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", "wasm-bindgen-shared", ] @@ -6286,9 +6316,9 @@ version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6516,8 +6546,8 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", "quote 1.0.3", - "syn 1.0.17", + "syn 1.0.34", "synstructure", ] diff --git a/runtime-modules/forum/Cargo.toml b/runtime-modules/forum/Cargo.toml index acce13819a..2e80ef5541 100755 --- a/runtime-modules/forum/Cargo.toml +++ b/runtime-modules/forum/Cargo.toml @@ -18,6 +18,9 @@ codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = arbitrary = { version = "0.3.0", optional = true, features = ["derive"] } +[dependencies.substrate-forum-module-reflection] +path = "./reflection" + [dependencies.timestamp] default_features = false git = 'https://github.com/paritytech/substrate.git' diff --git a/runtime-modules/forum/fuzz/Cargo.lock b/runtime-modules/forum/fuzz/Cargo.lock index b2fb8eaebd..5419a28c44 100644 --- a/runtime-modules/forum/fuzz/Cargo.lock +++ b/runtime-modules/forum/fuzz/Cargo.lock @@ -1533,6 +1533,7 @@ dependencies = [ "srml-support-procedural", "srml-system", "srml-timestamp", + "substrate-forum-module-reflection", "substrate-primitives", ] @@ -1554,9 +1555,18 @@ dependencies = [ "srml-system", "srml-timestamp", "substrate-forum-module", + "substrate-forum-module-reflection", "substrate-primitives", ] +[[package]] +name = "substrate-forum-module-reflection" +version = "0.0.1" +dependencies = [ + "proc-macro2 1.0.18", + "syn 1.0.34", +] + [[package]] name = "substrate-inherents" version = "2.0.0" diff --git a/runtime-modules/forum/fuzz/Cargo.toml b/runtime-modules/forum/fuzz/Cargo.toml index 40c265fd8b..9cac381e67 100644 --- a/runtime-modules/forum/fuzz/Cargo.toml +++ b/runtime-modules/forum/fuzz/Cargo.toml @@ -44,6 +44,9 @@ rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8' path = ".." features = ["arbitrary"] +[dependencies.substrate-forum-module-reflection] +path = "../reflection" + # Prevent this from interfering with workspaces [workspace] members = ["."] diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index ee32b4127e..6d2076ab9d 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -31,5 +31,31 @@ fuzz_target!(|texts: Texts| { ); println!("category mock finished"); + + + println!("{:?}", ReflectionTest {a: 1, b:2}); }) }); + +//use crate::*; +use substrate_forum_module_reflection::*; + +#[derive(FieldCount, Debug)] +struct ReflectionTest { + a: u64, + b: u32, +} + + +type MyFunction = Fn(i32) -> i32; + +//fn retrieve_module_endpoints i32>(module: Runtime) -> T { +fn retrieve_module_endpoints i32>(module: Runtime) -> () { +//fn retrieve_module_endpoints(module: Runtime) -> T where T: MyFunction { + //ReflectionTest::derive_field_count(); + +} + +fn autowire_parameters_and_run i32>(function: T) -> () { + +} diff --git a/runtime-modules/forum/reflection/Cargo.toml b/runtime-modules/forum/reflection/Cargo.toml new file mode 100644 index 0000000000..f9792ff005 --- /dev/null +++ b/runtime-modules/forum/reflection/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "substrate-forum-module-reflection" +version = "0.0.1" +edition = "2018" + + +[dependencies] +proc-macro2 = "1.0.18" +syn = "1.0.34" + +[lib] +name="substrate_forum_module_reflection" +proc-macro = true diff --git a/runtime-modules/forum/reflection/src/lib.rs b/runtime-modules/forum/reflection/src/lib.rs new file mode 100644 index 0000000000..aa740620c7 --- /dev/null +++ b/runtime-modules/forum/reflection/src/lib.rs @@ -0,0 +1,31 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +use syn::{parse_macro_input, ItemStruct}; + +#[proc_macro_derive(FieldCount)] +pub fn derive_field_count(input: TokenStream) -> TokenStream { + /* + let tmp_input = parse_macro_input!(input as ItemStruct); + + let field_count = input.fields.iter().count(); + + //field_count + input + */ + + println!("{:?}", input); + + let tmp_input = parse_macro_input!(input as ItemStruct); +println!("{:?}", tmp_input); +/* + println!("print one by one"); + + println!("{:?}", tmp_input.fields.iter().next()); + //tmp_input.fields.iter().map(|a| println!("-------- {:?}", a)); + tmp_input.fields.iter().map(|a| {println!("-------- {:?}", a)}); + println!("print done"); +*/ + //input + TokenStream::new() +} diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 193b9248fe..8d0a805853 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -666,7 +666,10 @@ decl_event!( } ); +use substrate_forum_module_reflection::*; + decl_module! { + #[derive(FieldCount)] pub struct Module for enum Call where origin: T::Origin { /// Predefined errors type Error = Error; From a65a5e1fc2f96acb247866aed35919cb3fcd4d8c Mon Sep 17 00:00:00 2001 From: ondratra Date: Thu, 16 Jul 2020 19:29:24 +0200 Subject: [PATCH 11/15] fuzzy testing - automatic module testing II --- Cargo.lock | 2 +- .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 3 +- .../src/extract_module_functions.rs | 118 ++++++++++++++++++ runtime-modules/forum/reflection/src/lib.rs | 103 ++++++++++++++- runtime-modules/forum/src/lib.rs | 2 +- 5 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 runtime-modules/forum/reflection/src/extract_module_functions.rs diff --git a/Cargo.lock b/Cargo.lock index 4a130cf9f8..d4d371f0c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4892,7 +4892,7 @@ dependencies = [ [[package]] name = "substrate-forum-module-reflection" -version = "0.0.0" +version = "0.0.1" dependencies = [ "proc-macro2 1.0.18", "syn 1.0.34", diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index 6d2076ab9d..0d7e066a74 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -40,7 +40,8 @@ fuzz_target!(|texts: Texts| { //use crate::*; use substrate_forum_module_reflection::*; -#[derive(FieldCount, Debug)] +//#[derive(FieldCount, Debug)] +#[derive(Debug)] struct ReflectionTest { a: u64, b: u32, diff --git a/runtime-modules/forum/reflection/src/extract_module_functions.rs b/runtime-modules/forum/reflection/src/extract_module_functions.rs new file mode 100644 index 0000000000..7420144719 --- /dev/null +++ b/runtime-modules/forum/reflection/src/extract_module_functions.rs @@ -0,0 +1,118 @@ +use syn::{ItemStruct, ItemEnum, Fields, FieldsUnnamed, Type, Ident, PathSegment}; +use syn::token::Colon2; +use syn::punctuated::Punctuated; +use std::fmt; + +pub struct ModuleFunction { + name: Ident, + arguments: Vec>, +} + +impl fmt::Debug for ModuleFunction { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + //let arguments = &self.arguments.iter().as_slice().join(", "); + //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::>().as_slice().join(", "); + //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::().to_string().as_slice().join(", "); + //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::(); + let arguments = &self.arguments.iter() + .map(|item| { + //item.ident.to_string() + /* + item.iter() + .map(|tmp_item| tmp_item.ident.to_string()) + .collect::() + //.into_bytes(); + .to_string() + */ + println!("xxx {:?}", item); + item.iter() + .map(|path_segment| path_segment.ident.to_string()) + .collect::>() + .join(", ") + }) + .collect::(); + //.into_bytes(); + //.to_string(); + + f.write_str(&format!("ModuleFunction - {}({})", &self.name, arguments)) + +/* + f.debug_struct("ModuleFunction") + .field("name", &self.name) + .field("arguments", &self.arguments) + //.field("arguments", &self.arguments.iter().as_slice().join(", ")) + .finish() +*/ + } +} + +//pub struct ModuleFunctionArgument(Vec); + +pub fn extract_module_functions(input: &ItemEnum) -> Vec { + let mut functions = vec![]; + + let len = input.variants.len(); + for i in 0..len { + + let ident = &input.variants[i].ident; + if ident.to_string() == "__PhantomItem" { // some weird item present at the start of an array + continue; + } + + let field_type_names = match &input.variants[i].fields { + Fields::Unnamed(unnamed_fields) => process_unnamed_fields(unnamed_fields), + _ => panic!("not implemented"), + }; + + let function = ModuleFunction { + //name: input.variants[i].ident.to_string().into_bytes(), + name: ident.clone(), + arguments: field_type_names, + }; + functions.push(function); + } + + functions +} + +fn process_unnamed_fields(unnamed_fields: &FieldsUnnamed) -> Vec> { + //println!("{:?}", unnamed_fields); + let mut arguments = vec![]; + + let len = unnamed_fields.unnamed.len(); + for i in 0..len { + let argument_type = process_ident_path(&unnamed_fields.unnamed[i].ty); + + arguments.push(argument_type); + } + + arguments +} + +fn process_ident_path(ty: &Type) -> Punctuated { + println!("----------- {:?}", ty); + + match ty { + Type::Path(type_path) => { + let argument_type = type_path.path.segments.clone(); + /* + let argument_type = type_path.path.segments + .iter() + .map(|item| item.ident.to_string()) + .collect::() + //.into_bytes(); + .to_string(); + */ + + //println!("{:?}", type_path.path.segments[0].ident.to_string()); + //println!("{:?}", type_path.path.segments[0].ident.to_string()); + //println!("{:?}", type_path.path.segments.to_string()); + //println!("{:?}", type_path.path.segments.iter().map(|item| item.ident.to_string()).collect::().join()); + + //println!("{:?}", argument_type); + + argument_type + }, + _ => panic!("not implemented"), + } +} diff --git a/runtime-modules/forum/reflection/src/lib.rs b/runtime-modules/forum/reflection/src/lib.rs index aa740620c7..7cbf415480 100644 --- a/runtime-modules/forum/reflection/src/lib.rs +++ b/runtime-modules/forum/reflection/src/lib.rs @@ -1,9 +1,13 @@ extern crate proc_macro; use proc_macro::TokenStream; -use syn::{parse_macro_input, ItemStruct}; +use syn::{parse_macro_input, ItemStruct, ItemEnum, Fields, Type}; -#[proc_macro_derive(FieldCount)] +mod extract_module_functions; +//use extract_module_functions +//use crate::extract_module_functions::*; + +#[proc_macro_derive(FuzzyModule)] pub fn derive_field_count(input: TokenStream) -> TokenStream { /* let tmp_input = parse_macro_input!(input as ItemStruct); @@ -14,10 +18,98 @@ pub fn derive_field_count(input: TokenStream) -> TokenStream { input */ - println!("{:?}", input); +//return input; - let tmp_input = parse_macro_input!(input as ItemStruct); -println!("{:?}", tmp_input); + //println!("iiiinput {:?}", input); +println!("xxx"); + //let tmp_input = parse_macro_input!(input as ItemStruct); + let tmp_input = parse_macro_input!(input as ItemEnum); +println!("xxx"); + + + +println!("---------"); +/* +// various debug prints follows +/* +println!("attrs {:?}", tmp_input.attrs); +println!("---------"); +println!("vis {:?}", tmp_input.vis); +println!("---------"); +println!("enum_token {:?}", tmp_input.enum_token); +println!("---------"); +println!("ident {:?}", tmp_input.ident); +println!("---------"); +println!("generics {:?}", tmp_input.generics); +println!("---------"); +println!("brace_token {:?}", tmp_input.brace_token); +println!("---------"); +*/ +//println!("variants {:?}", tmp_input); +//return TokenStream::new(); +/* +tmp_input.variants.iter().map(|a| {println!("-------- {:?}", a)}); + +let len = tmp_input.variants.len(); +for i in 0..len { + println!("{} ----- {:?}", i, tmp_input.variants[i]); +} +*/ +//tmp_input.variants.iter().map(|a| {println!("-------- {:?}", a); ()}).collect::<()>(); +tmp_input.variants.iter().map(|a| println!("-------- {:?}", a)).collect::<()>(); + +println!("variant attrs {:?}", tmp_input.variants[1].attrs); +println!("variant ident {:?}", tmp_input.variants[1].ident); +println!("variant fields {:?}", tmp_input.variants[1].fields); +println!("variant discriminant {:?}", tmp_input.variants[1].discriminant); + +println!("---------"); + +/* +let len = tmp_input.variants[1].attrs.len(); +for i in 0..len { + println!("{:?}", tmp_input.variants[1].attrs); +} +*/ +match &tmp_input.variants[1].fields { + Fields::Unnamed(unnamed_fields) => { + println!("{:?}", unnamed_fields); + + let len = unnamed_fields.unnamed.len(); + for i in 0..len { + //println!("{:?}", unnamed_fields.unnamed[i]); + println!("{:?}", unnamed_fields.unnamed[i].ty); + + match &unnamed_fields.unnamed[i].ty { + Type::Path(type_path) => { + println!("{:?}", type_path.path.segments[0].ident.to_string()); + }, + _ => panic!("not implemented"), + } + } + }, + _ => panic!("not implemented"), +} + + + + + // some usefull prints + println!("found module methods:"); + let len = tmp_input.variants.len(); + for i in 0..len { + println!("{:?}", tmp_input.variants[i].ident); + } + +*/ + + + println!("-----------------xxxxxxxxxxx-------------"); + let tmp = extract_module_functions::extract_module_functions(&tmp_input); + println!("hello {:?}", tmp); + + +//println!("------- {:?}", tmp_input); /* println!("print one by one"); @@ -28,4 +120,5 @@ println!("{:?}", tmp_input); */ //input TokenStream::new() + //input } diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 8d0a805853..688d9fb784 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -669,7 +669,7 @@ decl_event!( use substrate_forum_module_reflection::*; decl_module! { - #[derive(FieldCount)] + #[derive(FuzzyModule)] pub struct Module for enum Call where origin: T::Origin { /// Predefined errors type Error = Error; From 5862d02bc6f51088f2a6c3f4cfb0cf013c6f3c5f Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 17 Jul 2020 12:15:49 +0200 Subject: [PATCH 12/15] fuzzy testing - automatic module testing III --- .../src/extract_module_functions.rs | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/runtime-modules/forum/reflection/src/extract_module_functions.rs b/runtime-modules/forum/reflection/src/extract_module_functions.rs index 7420144719..a0a0759a6a 100644 --- a/runtime-modules/forum/reflection/src/extract_module_functions.rs +++ b/runtime-modules/forum/reflection/src/extract_module_functions.rs @@ -1,52 +1,71 @@ -use syn::{ItemStruct, ItemEnum, Fields, FieldsUnnamed, Type, Ident, PathSegment}; +use syn::{ItemStruct, ItemEnum, Fields, FieldsUnnamed, Type, Ident, PathSegment, PathArguments, GenericArgument, AngleBracketedGenericArguments}; use syn::token::Colon2; use syn::punctuated::Punctuated; use std::fmt; +pub struct ModuleFunctionArgument(Punctuated); + pub struct ModuleFunction { name: Ident, - arguments: Vec>, + arguments: Vec, } -impl fmt::Debug for ModuleFunction { +impl fmt::Debug for ModuleFunctionArgument { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - //let arguments = &self.arguments.iter().as_slice().join(", "); - //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::>().as_slice().join(", "); - //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::().to_string().as_slice().join(", "); - //let arguments = &self.arguments.iter().map(|item| item.to_string()).collect::(); - let arguments = &self.arguments.iter() - .map(|item| { - //item.ident.to_string() - /* - item.iter() - .map(|tmp_item| tmp_item.ident.to_string()) - .collect::() - //.into_bytes(); - .to_string() - */ - println!("xxx {:?}", item); - item.iter() - .map(|path_segment| path_segment.ident.to_string()) - .collect::>() - .join(", ") - }) - .collect::(); - //.into_bytes(); - //.to_string(); + fn format_generic(parameter_data: &AngleBracketedGenericArguments) -> String { + let mut generics = vec![]; - f.write_str(&format!("ModuleFunction - {}({})", &self.name, arguments)) + for i in 0..parameter_data.args.len() { + let formated_generic = match ¶meter_data.args[i] { + GenericArgument::Type(ty) => format!("{:?}", process_ident_path(&ty)), + _ => panic!("not implemented"), + }; + + generics.push(formated_generic); + } + + format!("<{}>", generics.join(", ")) + } + + fn format_argument_segment(segment: &PathSegment) -> String { + let segment_detail = match &segment.arguments { + PathArguments::AngleBracketed(parameter_data) => format_generic(parameter_data), + PathArguments::Parenthesized(_) => panic!("not implemented"), + PathArguments::None => "".to_string(), + }; + + format!("{}{}", segment.ident.to_string(), segment_detail) + } + + fn format_argument(argument: &Punctuated) -> String { + argument + .iter() + .map(format_argument_segment) + .collect::>() + .join("::") + } + + let arguments = format_argument(&self.0); -/* - f.debug_struct("ModuleFunction") - .field("name", &self.name) - .field("arguments", &self.arguments) - //.field("arguments", &self.arguments.iter().as_slice().join(", ")) - .finish() -*/ + f.write_str(&format!("{}", arguments)) } } -//pub struct ModuleFunctionArgument(Vec); +impl fmt::Debug for ModuleFunction { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn format_arguments(arguments: &Vec) -> String { + arguments + .iter() + .map(|item| format!("{:?}", item)) + .collect::>() + .join(", ") + } + + let arguments = format_arguments(&self.arguments); + + f.write_str(&format!("ModuleFunction - {}({})", &self.name, arguments)) + } +} pub fn extract_module_functions(input: &ItemEnum) -> Vec { let mut functions = vec![]; @@ -75,8 +94,7 @@ pub fn extract_module_functions(input: &ItemEnum) -> Vec { functions } -fn process_unnamed_fields(unnamed_fields: &FieldsUnnamed) -> Vec> { - //println!("{:?}", unnamed_fields); +fn process_unnamed_fields(unnamed_fields: &FieldsUnnamed) -> Vec { let mut arguments = vec![]; let len = unnamed_fields.unnamed.len(); @@ -89,29 +107,12 @@ fn process_unnamed_fields(unnamed_fields: &FieldsUnnamed) -> Vec Punctuated { - println!("----------- {:?}", ty); - +fn process_ident_path(ty: &Type) -> ModuleFunctionArgument { match ty { Type::Path(type_path) => { let argument_type = type_path.path.segments.clone(); - /* - let argument_type = type_path.path.segments - .iter() - .map(|item| item.ident.to_string()) - .collect::() - //.into_bytes(); - .to_string(); - */ - - //println!("{:?}", type_path.path.segments[0].ident.to_string()); - //println!("{:?}", type_path.path.segments[0].ident.to_string()); - //println!("{:?}", type_path.path.segments.to_string()); - //println!("{:?}", type_path.path.segments.iter().map(|item| item.ident.to_string()).collect::().join()); - - //println!("{:?}", argument_type); - argument_type + ModuleFunctionArgument(argument_type) }, _ => panic!("not implemented"), } From 59449fa2d234619e7fe3d1893ec2c44ff6693015 Mon Sep 17 00:00:00 2001 From: ondratra Date: Fri, 17 Jul 2020 14:52:08 +0200 Subject: [PATCH 13/15] fuzzy testing - automatic module testing IV --- .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 22 +++++ .../src/extract_module_functions.rs | 1 - runtime-modules/forum/reflection/src/lib.rs | 95 +------------------ 3 files changed, 23 insertions(+), 95 deletions(-) diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index 0d7e066a74..fbd6674946 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -1,4 +1,5 @@ #![no_main] +#![feature(fn_traits)] use libfuzzer_sys::fuzz_target; use substrate_forum_module::mock::*; @@ -34,6 +35,27 @@ fuzz_target!(|texts: Texts| { println!("{:?}", ReflectionTest {a: 1, b:2}); + + + + // test function call with array of arguments + create_category_mock.call(( + origin.clone(), + None, + texts.text[0].clone(), + texts.text[1].clone(), + Ok(()), + )); +/* + let a = vec![( + origin.clone(), + None, + texts.text[0].clone(), + texts.text[1].clone(), + Ok(()), + )]; + create_category_mock.call(a); +*/ }) }); diff --git a/runtime-modules/forum/reflection/src/extract_module_functions.rs b/runtime-modules/forum/reflection/src/extract_module_functions.rs index a0a0759a6a..7ea1c6b14b 100644 --- a/runtime-modules/forum/reflection/src/extract_module_functions.rs +++ b/runtime-modules/forum/reflection/src/extract_module_functions.rs @@ -84,7 +84,6 @@ pub fn extract_module_functions(input: &ItemEnum) -> Vec { }; let function = ModuleFunction { - //name: input.variants[i].ident.to_string().into_bytes(), name: ident.clone(), arguments: field_type_names, }; diff --git a/runtime-modules/forum/reflection/src/lib.rs b/runtime-modules/forum/reflection/src/lib.rs index 7cbf415480..a8a5ce8ebb 100644 --- a/runtime-modules/forum/reflection/src/lib.rs +++ b/runtime-modules/forum/reflection/src/lib.rs @@ -8,101 +8,8 @@ mod extract_module_functions; //use crate::extract_module_functions::*; #[proc_macro_derive(FuzzyModule)] -pub fn derive_field_count(input: TokenStream) -> TokenStream { - /* - let tmp_input = parse_macro_input!(input as ItemStruct); - - let field_count = input.fields.iter().count(); - - //field_count - input - */ - -//return input; - - //println!("iiiinput {:?}", input); -println!("xxx"); - //let tmp_input = parse_macro_input!(input as ItemStruct); +pub fn derive_fuzzy_module(input: TokenStream) -> TokenStream { let tmp_input = parse_macro_input!(input as ItemEnum); -println!("xxx"); - - - -println!("---------"); -/* -// various debug prints follows -/* -println!("attrs {:?}", tmp_input.attrs); -println!("---------"); -println!("vis {:?}", tmp_input.vis); -println!("---------"); -println!("enum_token {:?}", tmp_input.enum_token); -println!("---------"); -println!("ident {:?}", tmp_input.ident); -println!("---------"); -println!("generics {:?}", tmp_input.generics); -println!("---------"); -println!("brace_token {:?}", tmp_input.brace_token); -println!("---------"); -*/ -//println!("variants {:?}", tmp_input); -//return TokenStream::new(); -/* -tmp_input.variants.iter().map(|a| {println!("-------- {:?}", a)}); - -let len = tmp_input.variants.len(); -for i in 0..len { - println!("{} ----- {:?}", i, tmp_input.variants[i]); -} -*/ -//tmp_input.variants.iter().map(|a| {println!("-------- {:?}", a); ()}).collect::<()>(); -tmp_input.variants.iter().map(|a| println!("-------- {:?}", a)).collect::<()>(); - -println!("variant attrs {:?}", tmp_input.variants[1].attrs); -println!("variant ident {:?}", tmp_input.variants[1].ident); -println!("variant fields {:?}", tmp_input.variants[1].fields); -println!("variant discriminant {:?}", tmp_input.variants[1].discriminant); - -println!("---------"); - -/* -let len = tmp_input.variants[1].attrs.len(); -for i in 0..len { - println!("{:?}", tmp_input.variants[1].attrs); -} -*/ -match &tmp_input.variants[1].fields { - Fields::Unnamed(unnamed_fields) => { - println!("{:?}", unnamed_fields); - - let len = unnamed_fields.unnamed.len(); - for i in 0..len { - //println!("{:?}", unnamed_fields.unnamed[i]); - println!("{:?}", unnamed_fields.unnamed[i].ty); - - match &unnamed_fields.unnamed[i].ty { - Type::Path(type_path) => { - println!("{:?}", type_path.path.segments[0].ident.to_string()); - }, - _ => panic!("not implemented"), - } - } - }, - _ => panic!("not implemented"), -} - - - - - // some usefull prints - println!("found module methods:"); - let len = tmp_input.variants.len(); - for i in 0..len { - println!("{:?}", tmp_input.variants[i].ident); - } - -*/ - println!("-----------------xxxxxxxxxxx-------------"); let tmp = extract_module_functions::extract_module_functions(&tmp_input); From 251c81226e1a9901f705187016e83943f7c81b76 Mon Sep 17 00:00:00 2001 From: ondratra Date: Tue, 21 Jul 2020 00:05:47 +0200 Subject: [PATCH 14/15] fuzzy testing - automatic module testing V --- Cargo.lock | 1 + runtime-modules/forum/fuzz/Cargo.lock | 1 + .../forum/fuzz/fuzz_targets/fuzz_target_1.rs | 3 ++ runtime-modules/forum/reflection/Cargo.toml | 1 + runtime-modules/forum/reflection/src/lib.rs | 29 ++++++++++++++++--- runtime-modules/forum/src/lib.rs | 6 ++++ 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4d371f0c7..e662c5c57e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4895,6 +4895,7 @@ name = "substrate-forum-module-reflection" version = "0.0.1" dependencies = [ "proc-macro2 1.0.18", + "quote 1.0.3", "syn 1.0.34", ] diff --git a/runtime-modules/forum/fuzz/Cargo.lock b/runtime-modules/forum/fuzz/Cargo.lock index 5419a28c44..0e3e98bfa2 100644 --- a/runtime-modules/forum/fuzz/Cargo.lock +++ b/runtime-modules/forum/fuzz/Cargo.lock @@ -1564,6 +1564,7 @@ name = "substrate-forum-module-reflection" version = "0.0.1" dependencies = [ "proc-macro2 1.0.18", + "quote 1.0.7", "syn 1.0.34", ] diff --git a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs index fbd6674946..5857986975 100644 --- a/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/runtime-modules/forum/fuzz/fuzz_targets/fuzz_target_1.rs @@ -46,6 +46,9 @@ fuzz_target!(|texts: Texts| { texts.text[1].clone(), Ok(()), )); + + TestForumModule::i_believe_i_can_fly(); + println!("{:?}", TestForumModule::i_believe_i_can_fly()); /* let a = vec![( origin.clone(), diff --git a/runtime-modules/forum/reflection/Cargo.toml b/runtime-modules/forum/reflection/Cargo.toml index f9792ff005..58350d96fe 100644 --- a/runtime-modules/forum/reflection/Cargo.toml +++ b/runtime-modules/forum/reflection/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] proc-macro2 = "1.0.18" syn = "1.0.34" +quote = "1.0" [lib] name="substrate_forum_module_reflection" diff --git a/runtime-modules/forum/reflection/src/lib.rs b/runtime-modules/forum/reflection/src/lib.rs index a8a5ce8ebb..9818bd342e 100644 --- a/runtime-modules/forum/reflection/src/lib.rs +++ b/runtime-modules/forum/reflection/src/lib.rs @@ -2,6 +2,7 @@ extern crate proc_macro; use proc_macro::TokenStream; use syn::{parse_macro_input, ItemStruct, ItemEnum, Fields, Type}; +use quote::quote; mod extract_module_functions; //use extract_module_functions @@ -13,7 +14,8 @@ pub fn derive_fuzzy_module(input: TokenStream) -> TokenStream { println!("-----------------xxxxxxxxxxx-------------"); let tmp = extract_module_functions::extract_module_functions(&tmp_input); - println!("hello {:?}", tmp); + //println!("hello {:?}", tmp); + //println!("------- {:?}", tmp_input); @@ -25,7 +27,26 @@ pub fn derive_fuzzy_module(input: TokenStream) -> TokenStream { tmp_input.fields.iter().map(|a| {println!("-------- {:?}", a)}); println!("print done"); */ - //input - TokenStream::new() - //input + + //TokenStream::new() + + quote_test(tmp_input) +} + +fn quote_test(input: ItemEnum) -> TokenStream { + //impl #input.ident { + let my_ident = input.ident; + let my_generics = input.generics; + + let tmp = quote! { + impl#my_generics #my_ident { + fn i_believe_i_can_fly() -> Vec { + b"adfadfad".to_vec() + } + } + }; + + println!("QQQQuote {:?}", tmp.to_string()); + + TokenStream::from(tmp) } diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 688d9fb784..3869546ada 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -668,6 +668,12 @@ decl_event!( use substrate_forum_module_reflection::*; +impl< T : Trait > Call { + fn i_believe_i_can_fly() -> Vec { + b"adfadfad" . to_vec() + } +} + decl_module! { #[derive(FuzzyModule)] pub struct Module for enum Call where origin: T::Origin { From 43abfc128724282046597bb0a6ca8f6ebc498986 Mon Sep 17 00:00:00 2001 From: ondratra Date: Wed, 22 Jul 2020 17:02:52 +0200 Subject: [PATCH 15/15] fuzzy testing - automatic module testing VI --- runtime-modules/forum/reflection/src/lib.rs | 9 ++++++--- runtime-modules/forum/src/lib.rs | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/runtime-modules/forum/reflection/src/lib.rs b/runtime-modules/forum/reflection/src/lib.rs index 9818bd342e..f187e50a98 100644 --- a/runtime-modules/forum/reflection/src/lib.rs +++ b/runtime-modules/forum/reflection/src/lib.rs @@ -34,13 +34,16 @@ pub fn derive_fuzzy_module(input: TokenStream) -> TokenStream { } fn quote_test(input: ItemEnum) -> TokenStream { - //impl #input.ident { let my_ident = input.ident; let my_generics = input.generics; + // strangely name `Module` is not present in my_ident -> let's hardcode it + // impl#my_generics #my_ident { + //impl#my_generics #my_ident { + let tmp = quote! { - impl#my_generics #my_ident { - fn i_believe_i_can_fly() -> Vec { + impl#my_generics Module { + pub fn i_believe_i_can_fly() -> Vec { b"adfadfad".to_vec() } } diff --git a/runtime-modules/forum/src/lib.rs b/runtime-modules/forum/src/lib.rs index 3869546ada..fde07b1cbe 100755 --- a/runtime-modules/forum/src/lib.rs +++ b/runtime-modules/forum/src/lib.rs @@ -667,12 +667,14 @@ decl_event!( ); use substrate_forum_module_reflection::*; - -impl< T : Trait > Call { - fn i_believe_i_can_fly() -> Vec { +/* +//impl< T : Trait > Call { +impl Module { + pub fn i_believe_i_can_fly() -> Vec { b"adfadfad" . to_vec() } } +*/ decl_module! { #[derive(FuzzyModule)]