From 7f030b039095561932b6d790a094f02d90584ffa Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Sat, 18 May 2024 13:43:13 +0100 Subject: [PATCH] Updated space calculation - Implemented Space trait for dynamic structures - Added constants files - Added require macros for string length and rating range - Added error enum --- .../src/constants.rs | 8 ++++ .../anchor-movie-review-program/src/lib.rs | 42 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 programs/anchor-movie-review-program/src/constants.rs diff --git a/programs/anchor-movie-review-program/src/constants.rs b/programs/anchor-movie-review-program/src/constants.rs new file mode 100644 index 0000000..94aeece --- /dev/null +++ b/programs/anchor-movie-review-program/src/constants.rs @@ -0,0 +1,8 @@ +pub const ANCHOR_DISCRIMINATOR: usize = 8; +pub const PUBKEY_SIZE: usize = 32; +pub const U8_SIZE: usize = 1; +pub const STRING_LENGTH_PREFIX: usize = 4; +pub const MAX_DESCRIPTION_LENGTH: usize = 50; +pub const MAX_TITLE_LENGTH: usize = 20; +pub const MAX_RATING: u8 = 5; +pub const MIN_RATING: u8 = 1; diff --git a/programs/anchor-movie-review-program/src/lib.rs b/programs/anchor-movie-review-program/src/lib.rs index 44392aa..e94d9d6 100644 --- a/programs/anchor-movie-review-program/src/lib.rs +++ b/programs/anchor-movie-review-program/src/lib.rs @@ -1,5 +1,9 @@ use anchor_lang::prelude::*; +pub mod constants; + +pub use constants::*; + declare_id!("FmzAVsBmJWcfkfe7VrvEi7pLA9ALLDWB3NoU2MvLrCZj"); #[program] @@ -7,6 +11,15 @@ pub mod anchor_movie_review_program { use super::*; pub fn add_movie_review(ctx: Context, title: String, description: String, rating: u8) -> Result<()> { + // We require that the rating is between 1 and 5 + require!(rating >= MIN_RATING && rating <= MAX_RATING, MovieReviewError::InvalidRating); + + // We require that the title is not longer than 20 characters + require!(title.len() <= MAX_TITLE_LENGTH, MovieReviewError::TitleTooLong); + + // We require that the description is not longer than 50 characters + require!(description.len() <= MAX_DESCRIPTION_LENGTH, MovieReviewError::DescriptionTooLong); + msg!("Movie review account created"); msg!("Title: {}", title); msg!("Description: {}", description); @@ -22,6 +35,12 @@ pub mod anchor_movie_review_program { } pub fn update_movie_review(ctx: Context, title: String, description: String, rating: u8) -> Result<()> { + // We require that the rating is between 1 and 5 + require!(rating >= MIN_RATING && rating <= MAX_RATING, MovieReviewError::InvalidRating); + + // We require that the description is not longer than 50 characters + require!(description.len() <= MAX_DESCRIPTION_LENGTH, MovieReviewError::DescriptionTooLong); + msg!("Movie review account space reallocated"); msg!("Title: {}", title); msg!("Description: {}", description); @@ -48,7 +67,7 @@ pub struct AddMovieReview<'info> { seeds=[title.as_bytes(), initializer.key().as_ref()], bump, payer = initializer, - space = 8 + 32 + 1 + 4 + title.len() + 4 + description.len() + space = MovieAccountState::INIT_SPACE + title.len() + description.len() // We add the length of the title and description to the init space )] pub movie_review: Account<'info, MovieAccountState>, #[account(mut)] @@ -63,7 +82,7 @@ pub struct UpdateMovieReview<'info> { mut, seeds=[title.as_bytes(), initializer.key().as_ref()], bump, - realloc = 8 + 32 + 1 + 4 + title.len() + 4 + description.len(), + realloc = MovieAccountState::INIT_SPACE + title.len() + description.len(), // We add the length of the title and description to the init space realloc::payer = initializer, realloc::zero = true )] @@ -95,3 +114,22 @@ pub struct MovieAccountState { pub title: String, pub description: String, } + +/* + For the MovieAccountState account, since it is dynamic, we implement the Space trait to calculate the space required for the account. + We add the STRING_LENGTH_PREFIX twice to the space to account for the title and description string prefix. + We need to add the length of the title and description to the space upon initialization. + */ +impl Space for MovieAccountState { + const INIT_SPACE: usize = ANCHOR_DISCRIMINATOR + PUBKEY_SIZE + U8_SIZE + STRING_LENGTH_PREFIX + STRING_LENGTH_PREFIX; +} + +#[error_code] +enum MovieReviewError { + #[msg("Rating must be between 1 and 5")] + InvalidRating, + #[msg("Movie Title too long")] + TitleTooLong, + #[msg("Movie Description too long")] + DescriptionTooLong, +}